-
-
Notifications
You must be signed in to change notification settings - Fork 674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[cocoa] Keyboard shortcuts: copy, paste, etc #796
Comments
I agreed that cut/copy/paste/paste-special should be "available by default" commands in the same way "About", "Preferences", "Quit" and "Visit homepage" are on "normal" apps; and that these commands should be hooked into text widgets (and anywhere else that makes sense). I also agree these options shouldn't exist on system tray apps. Supporting system tray apps is a long standing feature request (#97). They have completely different UI/UX requirements to a "standard" app - and I'd argue that the way we should accomodate this is a different base class for systray apps. If you're building a systray app, it's not a toga.App with a couple of different flags passed to the constructor - it's a toga.TrayApp (or something similar). We've already got a DocumentApp specifically for this sort of purpose - recognizing that an app that is focused on handling documents is different to an app that provides a control interface. There may even be a need for several different base classes, differentiating between a system tray app that is little more than a menu (e.g., the battery status), and an app that provides a custom window (e.g., Dropbox). This would also allow for the existence of the copy/paste commands, without necessarily adding the command to the menu. |
Yes, I think having a separate base class for system tray apps makes a lot of sense. I have already outlined a rough API and Cocoa implementation for a system tray (icon + menu) but one issue I stumbled upon is the current API for menus and menu items. This also ties in to supporting Copy / Paste commands: Currently, there is
On the Implementation layer, |
@freakboy3742, I have created a sample implementation for catching keyboard commands here. For now, this just subclasses NSApplication and does not add any menubar items. This is the much easier fix since it does not require changing the code to auto enable menubar items. And it will be useful for a future system tray application. If you are happy with this as a temporary solution, I can create a PR. Otherwise, keyboard shortcuts will need to wait until I (or someone else) finds some more time... |
@samschott It sounds like the purpose of Command isn't clear (and that's entirely my fault - we need a lot more documentation, and the existing code has some less-than-ideal implementation details). The idea of Command is to wrap a "thing" that you can do in a GUI. That "thing" can surface in many ways in a GUI - as a menu item, as a toolbar item, or as some other action in a GUI (pressing a button in the normal layout of the app). The key abstraction is that command can be active or inactive - but the active status of the Command should drive the enabled/disabled status of the widgets that expose it. If the command is disabled, then any control activating that action should also be disabled. You shouldn't need to remember that you have to disable both the menu item and the toolbar item. In the current implementation, I've assumed that all commands manifest as a menu item. The intention is to aid discoverability; menus showing that something can be done are a key way for end-users to discover the capabilities of an app. Looking at the Cocoa implementation of Command - there's no default native object; but it will accumulate native objects as the command is deployed (e.g., as a menu, as a toolbar etc). Within this framework, I'd argue that Cut, Copy and Paste are excellent examples of behaviors that should be wrapped as commands, and installed as part of the construction of a toga.App (I'll also note that the current backends all independently define the core application commands like About, Help and Quit; these should be defined at the interface level, since they're common to all apps - only the command grouping and shortcuts are platform specific). They'll acquire their app shortcuts by virtue of being installed as menu items in a standard app; once we start looking at system tray apps, we can investigate the best way to attach those keyboard bindings. Does that make any sense? |
That does clarify the concept of a Command. At the moment they can only be used in the menu bar and toolbar, right? Looking through the docs, I have found no way of attaching a Command to a regular button...
You have also assumed, as far as I can see, that every menu item is a command and therefore omitted a separate API for menu items. This is valid in most cases, but there are some exceptions to this (submenus, 'widgets' such as the help search field on macOS, etc). But this is digressing form the original issue...
Agreed! |
Correct. Chalk this up as one more thing on the "want to add" list :-) More broadly, there's a design pattern that I've used with Tree and Table that I want to use more broadly - the concept of separating the "data" from the underlying widget. In the simple case, you can give a List widget a list of tuples, and it will display them. However, in a more realistic example, the list will be backed by some actual data source, and if that data changes, any visualization of the data should also change. The natural way to store the underlying data might not be a Python list, either - it might be an API call or something similar. Toga handles this with the ListSource API - you can implement the data source however you want, as long as it adheres to the base API; and if the data in the source changes, the widget updates itself. Although I've only implemented this for List, Tree and DetailedList, the same relationship exists on much simpler inputs, too. For example, a text input will usually display some simple name/value; if the underlying name/value changes, then the contents of the text input should change, too. Even a simple Label will sometimes be a reflection of some data state. And in the case of widgets that have "on activation" actions, the enabled/disabled status of the button can be dependent on whether the underlying action is actually possible at any given point in time.
This is technically true, but misses the significance of UI discoverability. My underlying argument is that anything that can be done should be visible in the menu. It should be possible to support submenus by defining commands that have subcommands, or with a sub-grouping That said - I'm willing to entertain the idea that maybe we need to change the Command API to allow for explicit menu creation (and ordering/grouping). However, in any API change, there are 3 key features I want to preserve:
Both of these points are digressions, but hopefully they're digressions that illustrate the underlying idea I'm aiming at, and might provide some guidance about how we can add cut/copy/paste in a way that will fit the overall picture (and possibly even move other pieces of the bigger picture in the right direction). |
Is there any update on this? My app needs copy paste to work, but I'm not sure how to use |
@whateverforever This is a volunteer-driven project; we can't really offer any estimates for when a any given bug will be fixed, or feature implemented, because it's entirely dependent on contributions provided by the community. You're correct in your understanding about using |
Well, but finally, please, where can I find information about how to implement Copy/Paste to |
Expected Behavior
One would typically expect from an app on macOS that common keyboard shortcuts such as CMD+C, CMD+V, etc "just work". However, they don't on widgets such as
TextInput
.Current Behavior
Keyboard events handled by a widget itself do work (e.g., arrow keys in a
TreeView
, backspace in aTextInput
). However, globally defined shortcuts such as copy and paste do not work.Possible fixes
This is typically handled in a NSApplication by adding the respective menu bar items with selectors (e.g.,
SEL('copy:')
for CMD+C). This is what users on macOS expect, but it has two disadvantages:autoenablesItems = True
. In the latter case, they will be automatically enabled/disabled when the action becomes available, e.g., 'Minimise' (CMD+M) will only be enabled when the window supports being minimised. However, settingautoenablesItems = True
means that all user defined items will always be enabled (in the current app implementation).One could intercepting the key events in the NSApplication delegate. This has the disadvantage that the default menu bar items will not be visible unless explicitly added by the user. However, the commands will always work, regardless of the chosen menu bar configuration.
The text was updated successfully, but these errors were encountered: