3
votes

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 :(

1
Have you set the ignoresMouseEvents property of the window at any point? (You shouldn't.) Rather than that code from RoundTransparentWindow, try just calling -invalidateShadow from the content view's -drawRect:. You say the -drawRect: just draws the circle. Does it attempt to fill its bounds before doing so? Finally, try it without turning on the window's acceptsMouseMovedEvents.Ken Thomases
I am not touching ignoresMouseEvents. invalidateShadow does not help. As of drawing - nothing really fancy CGContextAddEllipseInRect/CGContextFillPath.c-smile

1 Answers

6
votes

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:

  1. The window must be created with only NSBorderlessWindowMask set by [window setStyleMask: NSBorderlessWindowMask] for example.

  2. You MUST NOT call [window setIgnoresMouseEvent: NO] on it. As that method clearly contains a bug on Apple's side.

  3. 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

"Sciter clock" sample on Windows, OS X and Linux