8

I want to have some UI controls on top of a NSWebView and because of this problem " https://stackoverflow.com/questions/9120868/video-in-nswebview-hides-views-on-top-of-the-nswebview " I now want to add a "transparent" NSWindow, so without the close buttons etc., on top of my NSWebView, hence, on top of my current NSWindow.

How can I achieve this and make sure that this "overlay window" stays in place, even if I move the underlying window?

EDIT:: While @dzolanta's approach works fine, I wonder if it is possible to do it by using an NSWindowController which would allow me to properly use Outlets etc.

Community
  • 1
  • 1
Besi
  • 22,579
  • 24
  • 131
  • 223

2 Answers2

21

Child window is what you need.

Create NSWindow with NSBorderlessWindowMask and define it to be transparent using - setOpaque: and - setBackgroundColor: methods. Then add newly created window as a child of window containing an instance of NSWebView (using NSWindow's - addChildWindow:ordered: method). Moving parent window will automatically cause child window to move.

Update with working code:

CGRect wRect = self.window.frame;
NSView *contentView  =self.window.contentView;
CGRect cRect = contentView.frame;

CGRect rect = CGRectMake(wRect.origin.x, wRect.origin.y, cRect.size.width, cRect.size.height);
NSWindow *overlayWindow = [[NSWindow alloc]initWithContentRect:rect 
                                                     styleMask:NSBorderlessWindowMask 
                                                       backing:NSBackingStoreBuffered 
                                                         defer:NO];
overlayWindow.backgroundColor = [NSColor redColor];
[overlayWindow setOpaque:NO];
overlayWindow.alphaValue = 0.5f;

[self.window addChildWindow:overlayWindow ordered:NSWindowAbove];
Besi
  • 22,579
  • 24
  • 131
  • 223
dzolanta
  • 641
  • 7
  • 10
  • I managed to display the window, and it is also on top of my video stream. The only think that does not yet work is that the window should stretch together with the containing window when it gets resized. – Besi Feb 03 '12 at 16:32
  • 4
    To achieve that register your window controller (or another object, depending on your app architecture) as an observer of NSWindowDidResizeNotification. Notification selector should specify a method which change the frame of child window on the base of parent's frame (just like when creating an overlay window). You could also use - windowDidResize: method of NSWindowDelegate if you prefer. – dzolanta Feb 03 '12 at 17:16
0

Swift 3 version using window controller:

final class OverlayWindowController: NSWindowController {
  init(frame: NSRect) {
    let window = NSWindow(contentRect: frame, styleMask: .borderless, backing: .buffered, defer: false)
    super.init(window: window)

    window.contentViewController = MyViewController()
    window.backgroundColor = NSColor.clear
    window.isOpaque = false
  }

  @available(*, unavailable)
  required init?(coder: NSCoder) {
    fatalError("init(coder:) is unavailable")
  }
}
Pavel Smejkal
  • 3,600
  • 6
  • 27
  • 45