summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qtimer.cpp
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-04-28 12:01:46 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2023-05-04 01:03:52 +0200
commit5c05eb3ea0ebfd8b86f41ae6d0d918fac6414d33 (patch)
tree56c86de9ae5dfed6c937498d0cb97aae7759380b /src/corelib/kernel/qtimer.cpp
parent7d542e1daf09caadf6d3e36c4b09bdf94952c5a1 (diff)
macOS: Don't clam to support action messages from non-Qt menu items
As described in 3bedeb837ef68e0062668406e7662ed9ffc5268a, the way menu items on macOS are typically set up they have an action, e.g. copy:, but no target, and the system then takes care of finding the right target at runtime, starting with the first responder, walking the responder chain, and then moving on to other NSWindows, before ending up in the NSApplication and its delegate. As we (still) don't have a mechanism in Qt to forward generic actions, such as the cut/copy/paste, or selectAll, so we rely on mapping the actions back to QCocoaNSMenuItem that we can trace back to a QPlatformMenuItem that we in turn emit activated() for. Normally this works fine, but in the case where the Qt app is embedded in a native UI, which has its own menu items with cut/copy/paste, we'll get callbacks into QNSView for actions triggered by a generic NSMenuItem. In that case, we need to bail out, but we want to do so in a way that lets AppKit continue to walk the responder chain. This is possible by implementing supplementalTargetForAction:sender:, where we have access to the sender. If sender doesn't match the expected QCocoaNSMenuItem we let AppKit find a better match up the chain. Since the target we return needs to ultimately respond to the selectors and/or forward them, we can't point the target back to ourselves, nor can we point it to the application delegate directly, as the menu items need to be validated in the context of the view, so a new per-view QNSViewMenuHelper class has been added to take the role of forwarding the menu actions. The logic for forwarding the resulting actions to the application delegate has been simplified and hardened a bit as well. A possible scenario with this new approach is that the Qt app has a line edit focused, and the user tries to activate the menu item for Paste, but the item is grayed out because we can not support the action. This is of course confusing for the user, but less so than having an active menu item that then doesn't do anything when activated. Another scenario is that a responder later in the chain does respond to the paste action, and the menu item will end up pasting into something that is not the first responder. This might also be confusing for the user, but it's generally recommended that implementers of actions like paste only allow the action if the view is the first responder, and this is something views have to deal with anyways, so it doesn't change anything that we're now bailing out earlier in not accepting the paste. One benefit of allowing AppKit to find a better target for the action is that if no target is found, and the user presses the key equivalent of the disabled menu item, the key event will be delivered as a normal keyDown to our QNSView, which we do forward, allowing the Qt app to respond to the action, even though the action came from a generic menu item. With our old approach this would not happen, as we would claim to support the action for our QNSView, but then drop it on the floor when AppKit tried to deliver it to us. Change-Id: I609db42df6a107a49e287f435e8808812c83d43e Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/corelib/kernel/qtimer.cpp')
0 files changed, 0 insertions, 0 deletions