Reputation: 121
I have an app built [in Objective C] for MacOS using SKScene and GameScene that has a floating window with some text in it (a clock). It works great, floats and shows the text. I have implemented hit detection so if you click on the text (a Sprite), I can take action.
Note: I have read the other posts like 29441015 Click through custom NSWindow and 77131354 Transparent window can't click through in macos sonoma but those suggested solutions do not work. I think it's because I'm using GameScene within the window, as described below. I need to catch some clicks (on sprites) but pass others through. This is not a duplicate question.
The problem I'm having is that if you click elsewhere in the transparent window, I want to pass the event through to the underlying app, so that only clicks that hit the sprite are handled by my app, and all others pass through.
I've tried several approaches, like overriding mouseDown: (which works, except for the passthrough), and NS Event addLocalMonitorForEventsMatchingMask, which also works, but even if I return nil or return event, it never makes it to the other apps behind my window.
I believe this to be an interaction with the WindowServer, which decides who gets the mouse click. The way hit detection usually works is you send the event to the topmost window (mine), and it either handles the event or says "nope, this is not for me", and returns the event to the WindowServer who then goes down the window stack and sends it to the next window below. In the code below, that seems to be happening (return nil or return event) but the WindowServer is not passing the event through. How do I tell the WindowServer that I want that behavior?
I have this code, which works, except the "else" clause which returns the event doesn't pass it through as I had hoped:
[NSEvent addLocalMonitorForEventsMatchingMask:(NSLeftMouseDown | NSLeftMouseDownMask | NSRightMouseDown | NSRightMouseDownMask | NSEventMaskLeftMouseDragged )
handler:^NSEvent *(NSEvent *event)
{
CGPoint location = [event locationInNode:self]; //get location of touch
SKSpriteNode *spriteTouched = (SKSpriteNode*)[self nodeAtPoint:location]; //get a node if touched at that location
if ( spriteTouched != self ) {
switch ( event.type ) {
case NSEventTypeLeftMouseDown:
mClickPt = [event locationInNode:self];
break;
case NSEventTypeLeftMouseDragged:
[self moveWindowTo:[event locationInNode:self]];
break;
}
return nil;
} else {
return event;
}
}];
Upvotes: 0
Views: 37