Custom Carbon key event handler fails after mouse events
up vote
4
down vote
favorite
I'm trying to write a custom NSMenu which will be able to list for key input and intercept the necessary events. This is to provide a simple search-as-you-type functionality for my open source clipboard manager.
It seems like the only way to do this is to install a custom Carbon event handler which will listen for key events and handler them accordingly, but it seems like there is an issue with such a custom handler.
Normally, I can propagate events downwards to other handlers (e.g. system ones) and they should be gracefully handled. This can be done by a simple callback:
let eventHandlerCallback: EventHandlerUPP = { eventHandlerCallRef, eventRef, userData in
let response = CallNextEventHandler(eventHandlerCallRef, eventRef!)
print("Response (response)")
return response
}
This callback works perfectly and prints Response 0
all the time. This response means that the event is handled correctly.
However, things get weird once we send mouse events before keyboard events. In such case, the callback fails and prints Response -9874
. This response means that the event was not handled correctly.
It seems like the event fails to be handled somewhere below my custom view and I don't know where exactly or how to overcome this issue.
To reproduce, I've uploaded the code to Gist which can be added to XCode playground and run. Once you see menu popup, press some keys (preferably arrow keys as they won't close the menu) and observe Response 0
in the console. After that, move cursor inside the menu and press more arrow keys. You should see Response -9874
in the console now.
swift cocoa appkit macos-carbon
This question has an open bounty worth +500
reputation from p0deje ending in 6 days.
This question has not received enough attention.
|
show 3 more comments
up vote
4
down vote
favorite
I'm trying to write a custom NSMenu which will be able to list for key input and intercept the necessary events. This is to provide a simple search-as-you-type functionality for my open source clipboard manager.
It seems like the only way to do this is to install a custom Carbon event handler which will listen for key events and handler them accordingly, but it seems like there is an issue with such a custom handler.
Normally, I can propagate events downwards to other handlers (e.g. system ones) and they should be gracefully handled. This can be done by a simple callback:
let eventHandlerCallback: EventHandlerUPP = { eventHandlerCallRef, eventRef, userData in
let response = CallNextEventHandler(eventHandlerCallRef, eventRef!)
print("Response (response)")
return response
}
This callback works perfectly and prints Response 0
all the time. This response means that the event is handled correctly.
However, things get weird once we send mouse events before keyboard events. In such case, the callback fails and prints Response -9874
. This response means that the event was not handled correctly.
It seems like the event fails to be handled somewhere below my custom view and I don't know where exactly or how to overcome this issue.
To reproduce, I've uploaded the code to Gist which can be added to XCode playground and run. Once you see menu popup, press some keys (preferably arrow keys as they won't close the menu) and observe Response 0
in the console. After that, move cursor inside the menu and press more arrow keys. You should see Response -9874
in the console now.
swift cocoa appkit macos-carbon
This question has an open bounty worth +500
reputation from p0deje ending in 6 days.
This question has not received enough attention.
1
What leads you believe that you have to use a Carbon event handler for this? Have you triedNSEvent.addLocalMonitorForEvents(matching:handler:)
? What else did you consider and discard, and why did you discard it? Also, why are you monitoring key input (other than a keyboard shortcut) from anNSMenu
? Why not some other object, like a controller or custom application class?
– Ken Thomases
Nov 13 at 4:30
I have tried usingNSEvent.addLocalMonitorForEvents(matching:handler:)
but it looks like the menu subsystem doesn't use it at all. I also cannot useNSEvent.addGLobalMonitorForEvents(matching:handler:)
because it doesn't allow to stop event propagation if necessary. Monitoring of key input can be done from anywhere (NSView
in this case), but it doesn't matter since Carbon handlers are installed globally, and it seems like the only way to monitor events and useNSMenu
vs. writing customNSMenu
implementation which can use a normal localNSEvent
monitors or view methods.
– p0deje
Nov 13 at 6:21
Are you sure you need to propagate the event?+
– Aris
Nov 15 at 13:57
Even if I don't explicitly propagate event and let Carbon do it for me, it still fails.
– p0deje
Nov 16 at 6:44
I checked what the -9874 error means. According to the old Carbon Event Manager codes -9874 =eventNotHandledErr
, and this is returned when "This is what you should return from an event handler when your handler has received an event it doesn't currently want to (or isn't able to) handle. If you handle an event, you should return noErr from your event handler." I used to handle and still handle old-style Carbon Events, and is perfectly OK to ignore such an error in some cases. So, what do you exactly mean with "it still fails"?
– jvarela
Nov 19 at 0:55
|
show 3 more comments
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I'm trying to write a custom NSMenu which will be able to list for key input and intercept the necessary events. This is to provide a simple search-as-you-type functionality for my open source clipboard manager.
It seems like the only way to do this is to install a custom Carbon event handler which will listen for key events and handler them accordingly, but it seems like there is an issue with such a custom handler.
Normally, I can propagate events downwards to other handlers (e.g. system ones) and they should be gracefully handled. This can be done by a simple callback:
let eventHandlerCallback: EventHandlerUPP = { eventHandlerCallRef, eventRef, userData in
let response = CallNextEventHandler(eventHandlerCallRef, eventRef!)
print("Response (response)")
return response
}
This callback works perfectly and prints Response 0
all the time. This response means that the event is handled correctly.
However, things get weird once we send mouse events before keyboard events. In such case, the callback fails and prints Response -9874
. This response means that the event was not handled correctly.
It seems like the event fails to be handled somewhere below my custom view and I don't know where exactly or how to overcome this issue.
To reproduce, I've uploaded the code to Gist which can be added to XCode playground and run. Once you see menu popup, press some keys (preferably arrow keys as they won't close the menu) and observe Response 0
in the console. After that, move cursor inside the menu and press more arrow keys. You should see Response -9874
in the console now.
swift cocoa appkit macos-carbon
I'm trying to write a custom NSMenu which will be able to list for key input and intercept the necessary events. This is to provide a simple search-as-you-type functionality for my open source clipboard manager.
It seems like the only way to do this is to install a custom Carbon event handler which will listen for key events and handler them accordingly, but it seems like there is an issue with such a custom handler.
Normally, I can propagate events downwards to other handlers (e.g. system ones) and they should be gracefully handled. This can be done by a simple callback:
let eventHandlerCallback: EventHandlerUPP = { eventHandlerCallRef, eventRef, userData in
let response = CallNextEventHandler(eventHandlerCallRef, eventRef!)
print("Response (response)")
return response
}
This callback works perfectly and prints Response 0
all the time. This response means that the event is handled correctly.
However, things get weird once we send mouse events before keyboard events. In such case, the callback fails and prints Response -9874
. This response means that the event was not handled correctly.
It seems like the event fails to be handled somewhere below my custom view and I don't know where exactly or how to overcome this issue.
To reproduce, I've uploaded the code to Gist which can be added to XCode playground and run. Once you see menu popup, press some keys (preferably arrow keys as they won't close the menu) and observe Response 0
in the console. After that, move cursor inside the menu and press more arrow keys. You should see Response -9874
in the console now.
swift cocoa appkit macos-carbon
swift cocoa appkit macos-carbon
edited Nov 13 at 3:06
rmaddy
235k27306373
235k27306373
asked Nov 13 at 3:06
p0deje
2,8181832
2,8181832
This question has an open bounty worth +500
reputation from p0deje ending in 6 days.
This question has not received enough attention.
This question has an open bounty worth +500
reputation from p0deje ending in 6 days.
This question has not received enough attention.
1
What leads you believe that you have to use a Carbon event handler for this? Have you triedNSEvent.addLocalMonitorForEvents(matching:handler:)
? What else did you consider and discard, and why did you discard it? Also, why are you monitoring key input (other than a keyboard shortcut) from anNSMenu
? Why not some other object, like a controller or custom application class?
– Ken Thomases
Nov 13 at 4:30
I have tried usingNSEvent.addLocalMonitorForEvents(matching:handler:)
but it looks like the menu subsystem doesn't use it at all. I also cannot useNSEvent.addGLobalMonitorForEvents(matching:handler:)
because it doesn't allow to stop event propagation if necessary. Monitoring of key input can be done from anywhere (NSView
in this case), but it doesn't matter since Carbon handlers are installed globally, and it seems like the only way to monitor events and useNSMenu
vs. writing customNSMenu
implementation which can use a normal localNSEvent
monitors or view methods.
– p0deje
Nov 13 at 6:21
Are you sure you need to propagate the event?+
– Aris
Nov 15 at 13:57
Even if I don't explicitly propagate event and let Carbon do it for me, it still fails.
– p0deje
Nov 16 at 6:44
I checked what the -9874 error means. According to the old Carbon Event Manager codes -9874 =eventNotHandledErr
, and this is returned when "This is what you should return from an event handler when your handler has received an event it doesn't currently want to (or isn't able to) handle. If you handle an event, you should return noErr from your event handler." I used to handle and still handle old-style Carbon Events, and is perfectly OK to ignore such an error in some cases. So, what do you exactly mean with "it still fails"?
– jvarela
Nov 19 at 0:55
|
show 3 more comments
1
What leads you believe that you have to use a Carbon event handler for this? Have you triedNSEvent.addLocalMonitorForEvents(matching:handler:)
? What else did you consider and discard, and why did you discard it? Also, why are you monitoring key input (other than a keyboard shortcut) from anNSMenu
? Why not some other object, like a controller or custom application class?
– Ken Thomases
Nov 13 at 4:30
I have tried usingNSEvent.addLocalMonitorForEvents(matching:handler:)
but it looks like the menu subsystem doesn't use it at all. I also cannot useNSEvent.addGLobalMonitorForEvents(matching:handler:)
because it doesn't allow to stop event propagation if necessary. Monitoring of key input can be done from anywhere (NSView
in this case), but it doesn't matter since Carbon handlers are installed globally, and it seems like the only way to monitor events and useNSMenu
vs. writing customNSMenu
implementation which can use a normal localNSEvent
monitors or view methods.
– p0deje
Nov 13 at 6:21
Are you sure you need to propagate the event?+
– Aris
Nov 15 at 13:57
Even if I don't explicitly propagate event and let Carbon do it for me, it still fails.
– p0deje
Nov 16 at 6:44
I checked what the -9874 error means. According to the old Carbon Event Manager codes -9874 =eventNotHandledErr
, and this is returned when "This is what you should return from an event handler when your handler has received an event it doesn't currently want to (or isn't able to) handle. If you handle an event, you should return noErr from your event handler." I used to handle and still handle old-style Carbon Events, and is perfectly OK to ignore such an error in some cases. So, what do you exactly mean with "it still fails"?
– jvarela
Nov 19 at 0:55
1
1
What leads you believe that you have to use a Carbon event handler for this? Have you tried
NSEvent.addLocalMonitorForEvents(matching:handler:)
? What else did you consider and discard, and why did you discard it? Also, why are you monitoring key input (other than a keyboard shortcut) from an NSMenu
? Why not some other object, like a controller or custom application class?– Ken Thomases
Nov 13 at 4:30
What leads you believe that you have to use a Carbon event handler for this? Have you tried
NSEvent.addLocalMonitorForEvents(matching:handler:)
? What else did you consider and discard, and why did you discard it? Also, why are you monitoring key input (other than a keyboard shortcut) from an NSMenu
? Why not some other object, like a controller or custom application class?– Ken Thomases
Nov 13 at 4:30
I have tried using
NSEvent.addLocalMonitorForEvents(matching:handler:)
but it looks like the menu subsystem doesn't use it at all. I also cannot use NSEvent.addGLobalMonitorForEvents(matching:handler:)
because it doesn't allow to stop event propagation if necessary. Monitoring of key input can be done from anywhere (NSView
in this case), but it doesn't matter since Carbon handlers are installed globally, and it seems like the only way to monitor events and use NSMenu
vs. writing custom NSMenu
implementation which can use a normal local NSEvent
monitors or view methods.– p0deje
Nov 13 at 6:21
I have tried using
NSEvent.addLocalMonitorForEvents(matching:handler:)
but it looks like the menu subsystem doesn't use it at all. I also cannot use NSEvent.addGLobalMonitorForEvents(matching:handler:)
because it doesn't allow to stop event propagation if necessary. Monitoring of key input can be done from anywhere (NSView
in this case), but it doesn't matter since Carbon handlers are installed globally, and it seems like the only way to monitor events and use NSMenu
vs. writing custom NSMenu
implementation which can use a normal local NSEvent
monitors or view methods.– p0deje
Nov 13 at 6:21
Are you sure you need to propagate the event?+
– Aris
Nov 15 at 13:57
Are you sure you need to propagate the event?+
– Aris
Nov 15 at 13:57
Even if I don't explicitly propagate event and let Carbon do it for me, it still fails.
– p0deje
Nov 16 at 6:44
Even if I don't explicitly propagate event and let Carbon do it for me, it still fails.
– p0deje
Nov 16 at 6:44
I checked what the -9874 error means. According to the old Carbon Event Manager codes -9874 =
eventNotHandledErr
, and this is returned when "This is what you should return from an event handler when your handler has received an event it doesn't currently want to (or isn't able to) handle. If you handle an event, you should return noErr from your event handler." I used to handle and still handle old-style Carbon Events, and is perfectly OK to ignore such an error in some cases. So, what do you exactly mean with "it still fails"?– jvarela
Nov 19 at 0:55
I checked what the -9874 error means. According to the old Carbon Event Manager codes -9874 =
eventNotHandledErr
, and this is returned when "This is what you should return from an event handler when your handler has received an event it doesn't currently want to (or isn't able to) handle. If you handle an event, you should return noErr from your event handler." I used to handle and still handle old-style Carbon Events, and is perfectly OK to ignore such an error in some cases. So, what do you exactly mean with "it still fails"?– jvarela
Nov 19 at 0:55
|
show 3 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53273191%2fcustom-carbon-key-event-handler-fails-after-mouse-events%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
What leads you believe that you have to use a Carbon event handler for this? Have you tried
NSEvent.addLocalMonitorForEvents(matching:handler:)
? What else did you consider and discard, and why did you discard it? Also, why are you monitoring key input (other than a keyboard shortcut) from anNSMenu
? Why not some other object, like a controller or custom application class?– Ken Thomases
Nov 13 at 4:30
I have tried using
NSEvent.addLocalMonitorForEvents(matching:handler:)
but it looks like the menu subsystem doesn't use it at all. I also cannot useNSEvent.addGLobalMonitorForEvents(matching:handler:)
because it doesn't allow to stop event propagation if necessary. Monitoring of key input can be done from anywhere (NSView
in this case), but it doesn't matter since Carbon handlers are installed globally, and it seems like the only way to monitor events and useNSMenu
vs. writing customNSMenu
implementation which can use a normal localNSEvent
monitors or view methods.– p0deje
Nov 13 at 6:21
Are you sure you need to propagate the event?+
– Aris
Nov 15 at 13:57
Even if I don't explicitly propagate event and let Carbon do it for me, it still fails.
– p0deje
Nov 16 at 6:44
I checked what the -9874 error means. According to the old Carbon Event Manager codes -9874 =
eventNotHandledErr
, and this is returned when "This is what you should return from an event handler when your handler has received an event it doesn't currently want to (or isn't able to) handle. If you handle an event, you should return noErr from your event handler." I used to handle and still handle old-style Carbon Events, and is perfectly OK to ignore such an error in some cases. So, what do you exactly mean with "it still fails"?– jvarela
Nov 19 at 0:55