'Click through custom NSWindow
I have custom NSWindow with custom NSView set as its contentView.
The window gets initialized with:
[window setOpaque:NO];
[window setBackgroundColor: [NSColor clearColor]];
[window setHasShadow: NO];
[window setAcceptsMouseMovedEvents: YES];
[window setLevel: NSFloatingWindowLevel];
Content view, in its drawRect
draws simple circle filled by solid color.
All this works OK - the window appears on desktop and I see that circle.
The only thing that does not work: the whole window rectangle is not transparent for mouse clicks. If I will click outside the circle (but inside invisible window box) my view receives mouseDown events but I expect underlying windows (or desktop) to be activated instead.
It appears that I need something like hitTest method to be overridden on my NSWindow class but unfortunately there is no such menthod.
So is the question: is it possible to have NSWindow with custom click through areas in OS X. If "yes" then how?
UPDATE:
Looking on RoundTransparentWindow sample that works as expected - the window is click through in transparent areas. Seems like this piece:
- (void)drawRect:(NSRect)rect {
...
// Reset the window shape and shadow.
if (shouldDisplayWindow) {
[[self window] display];
[[self window] setHasShadow:NO];
[[self window] setHasShadow:YES];
}
}
in CustomView.m is related to the problem but even with it (in my case) I cannot achieve transparency for mouse clicks :(
Solution 1:[1]
Answering my own question:
On OS X, in order to have windows with custom shapes with click through on transparent areas following conditions must be met:
The window must be created with only
NSBorderlessWindowMask
set by[window setStyleMask: NSBorderlessWindowMask]
for example.You MUST NOT call
[window setIgnoresMouseEvent: NO]
on it. As that method clearly contains a bug on Apple's side.contentView of the window MUST NOT use layers. So something like this
[[window contentView] setWantsLayer: YES]
effectively disables click through too.
Just in case: all this was about layered windows handling in Sciter on OS X
Solution 2:[2]
Thanks to the absolutely incredible answer of c-smile and the absolutely incredible comment of KenThomases,
Here's the basic and simple way to do a "full screen floating app thing" where clicks go through, and conversely you can click on "your" stuff.
You'll need this (for reasons I don't fully understand, the window won't expand fully without it),
and then ...
override func viewWillAppear() {
super.viewWillAppear()
guard let w = view.window else {
print("what the?")
return
}
w.styleMask = .borderless
// note that you DO NOT do this: w.ignoresMouseEvents = true
// see comments: https://stackoverflow.com/a/29451199/294884
w.collectionBehavior = [.fullScreenPrimary]
w.level = .floating
w.isMovable = false
w.titleVisibility = .hidden
w.titlebarAppearsTransparent = true
w.standardWindowButton(.closeButton)?.isHidden = true
w.standardWindowButton(.miniaturizeButton)?.isHidden = true
w.standardWindowButton(.zoomButton)?.isHidden = true
w.hasShadow = false
w.isOpaque = false
w.backgroundColor = NSColor(red: 1, green: 1, blue: 1, alpha: 0)
w.zoom(self)
guard let screen = w.screen ?? NSScreen.main else {
print("what the???")
return
}
w.setFrame(screen.visibleFrame, display: true)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Fattie |