Reputation: 845
I am making an application similar to GeekTool. I'm not very familiar with how GeekTool works on the inside but it looks and behaves similar. Basically I have a border less window that covers the entire screen, this works fine. I currently have the window on the 'kCGDesktopIconWindowLevel' layer, however I can not interact with anything on the desktop (Moving/Opening files, etc.). When I have the window one layer below this level (kCGDesktopIconWindowLevel-1) I can interact with the desktop but not my window, and I need to be able to interact. Is there anyway I can receive click from an above layer or send them to a lower layer?
By the way, if you have a better idea on how to achive this but avoiding this problem I will greatly appreciate it.
Upvotes: 1
Views: 439
Reputation: 990
I suggest you create an event tap like this (lifted from this answer) in applicationDidFinishLaunching:
:
CGEventMask emask;
CFMachPortRef myEventTap;
CFRunLoopSourceRef eventTapRLSrc;
// We only want one kind of event at the moment: Left mouse down
emask = CGEventMaskBit(kCGEventLeftMouseDown);
// Create the Tap
myEventTap = CGEventTapCreate (
kCGSessionEventTap, // Catch all events for current user session
kCGTailAppendEventTap, // Append to end of EventTap list
kCGEventTapOptionListenOnly, // We only listen, we don't modify
emask,
&myEventTapCallback,
NULL // We need no extra data in the callback
);
// Create a RunLoop Source for it
eventTapRLSrc = CFMachPortCreateRunLoopSource(
kCFAllocatorDefault,
myEventTap,
0
);
// Add the source to the current RunLoop
CFRunLoopAddSource(
CFRunLoopGetCurrent(),
eventTapRLSrc,
kCFRunLoopDefaultMode
);
Set your window to normally ignore mouse events -- [myWindow setIgnoresMouseEvents: YES];
Then your event tap will look for mouse clicks it wants to "catch" -- something like this:
static CGEventRef myEventTapCallback (
CGEventTapProxy proxy,
CGEventType type,
CGEventRef event,
void * refcon
) {
CGPoint mouseLocation;
// If we would get different kind of events, we can distinguish them
// by the variable "type", but we know we only get mouse moved events
mouseLocation = CGEventGetLocation(event);
// Figure out if the mouse is clicking on something we want to "catch"
if (/* want this click */)
[myWindow setIgnoresMouseEvents: NO];
// Pass on the event, we must not modify it anyway, we are a listener
return event;
}
After the mouse event is completed, return your window to ignoring mouse events.
Upvotes: 1