Allow specifying priority of accelerators compared to handling keys in the focused window
We have had a number of problems related to the accelerators [not] overriding the local key handlers, see at least (but there were plenty of other examples that I couldn't find as easily):
- #14553: Accelerators always have priority in wxGTK, fixed back in 819638a71f (Tweak wxGTK keyboard handling to allow accelerators to work again., 2013-03-21) by making local handler have priority.
- #22404: Accelerators have priority in wxMSW and
MSWShouldPreProcessMessage()must be specifically overridden to allow using the usual editing keys inwxSpinCtrl. - #22625: Accelerators do not have priority in wxGTK.
So the behaviour right now is totally inconsistent between platforms:
- In wxGTK accelerator will always be overridden by a local handler.
- In wxOSX accelerator will always have priority.
- In wxMSW accelerator will have priority by default but it's possible to override this by claiming the key in
MSWShouldPreProcessMessage().
I think we could live with the portable equivalent of the wxMSW API, i.e. we could make all ports behave like wxMSW does and use some new virtual ShouldKeyOverrideAccelerator() which could change this behaviour for individual keys if necessary (and use it for the standard accelerators of the text controls and such, I guess). And I'm relatively confident that it should be possible to implement this in wxGTK, but, as always, I'm less sure about macOS and would appreciate any advice, i.e. is it even possible to override the menu accelerators there? From reading the docs about first responder it looks like it ought to be possible, but a confirmation would be really welcome.
But customizing the logic of such ShouldKeyOverrideAccelerator() would require inheriting from the class, which is not always convenient and, sometimes, not even possible. So it looks like we ought to use an event for this instead. But if we're going to use an event anyhow, it would probably be better to just reuse the existing wxEVT_CHAR_HOOK, i.e. ensure that it is generated before handling accelerators (which already seems to happen in all ports) and that processing a key there prevents the accelerator from triggering (which is not the case in wxOSX). But, unfortunately, using wxEVT_CHAR_HOOK wouldn't allow customizing the logic as easily as overriding a virtual function because you'd have to actually handle the event there, instead of being able to just say "process it as usual without involving the accelerators". And at least in wxMSW it's pretty important to be able to do the latter, as we want to let the native control handle the event instead of processing it ourselves. So it looks like we're also going to need some new field to wxKeyEvent to allow the handler to ask for this to happen, which doesn't really look like a very elegant API...
Would anybody have any better suggestions about what could be done here?
Source: wxWidgets/wxWidgets