The Global Shortcut Drama

Whenever it comes to a discussion about the kde4 global shortcuts framework things heat up. Somehow people get really agitated if they learn how it works. Why? I don't know. It's a framework like any other. It has its ups, it has its downs. So lets have look where the problems are.

Using global shortcuts in kde is really simple. Just create action and assign a global shortcuts. Done. The problem - as usual - is in the details.

With kde4 the way global shortcuts work has been overhauled completely. That change was necessary because we wanted to support the mac. At least that's what i remember david saying ... i mean typing once. That was way before my time so let's forget what the reason was and see how it works.

In kde4 only one application listens to global shortcuts: the kdedglobalaccel daemon. As the name implies it is a kded module. This daemon has a list of all active global shortcuts and if one is triggered informs the associated application about that event.

With this setup it is possible to guarantee that no global shortcuts conflicts happen between active kde4 applications. Applications not using our nice little framework are still able to ruin the day but honestly: "who needs them".

But The code goes one step further. This is the point where some say one step to far. If a application is started all its global shortcuts are registered with kdedglobalaccel. We assume this application is named amarok. The daemon saves that information to $KDEHOME/.kde/share/config/kglobalshortcutsrc. If amarok is closed the daemon stops capturing its shortcuts but still remembers it's presence and shortcuts fondly and wait's for its return. While amarok is down another application called khotkeys starts and wants to use one of the shortcuts amarok registered. The daemon politely denies that request because it expects amarok to return soon. This is the most discussed feature ( or bug as some call it ) of the new system.

The upside of the system

  • Which application gets a key sequence no longer depends on which application started first.
  • If you configure a shortcut you can be sure that only this application reacts to the shortcut. You no longer risk a previously unknown application reacting to your key press.

The downside of the design

  • You have to learn and respect the system. Yes i think that's a downside for some of you out there.
  • If the unthinkable happens and the user decides amarok isn't good enough and uses is own player - you know the not invented here syndrom - even if he never starts amarok again it's shortcuts are registered with kdedglobalaccel and stay blocked for other applications until the user intervenes and frees them again.

Call it a bug, call it a feature. That's the current state. If you feel inclined to comment to this post please remember that none of this code was designed or implemented by me. There is no reason to "bark at this tree" to quote thiago. I got my fair share of criticism for my post how i would design a global shortcuts system. I don't like to get blamed for a design i had no speak in.

We haven't talked about the implementation details yet but i think everyone imagines global shortcuts have to have a id. It consist of two strings. An identifier for the component(application) and an identifier for the shortcut. The component is the one you find in KComponentData. The shortcut identifier is specified by the developer. Some applications use the shortcuts untranslated english text like "Reboot without confirmation" and others use a uuid. The important part is that both ids should never be changed. That's why i prefer unreadably ids. People tend to see readable strings as something that is allowed to change or subject to translation. Both are very bad ideas because even if you just fix a typo it becomes a new shortcut for kdedglobalaccel and the old one is left as a ghost holding the key sequence hostage. The 'new' shortcut won't get it.

The one and only problem with the design i see is the part where we remember applications shortcuts even if the application is stopped. But only regarding since uninstalled or never intended to run again application. The uncertainty if the application ever comes back is substituted in some cases with an absolute certainty it won't. KWin for example has a feature called "Window Shortcut" and it's pretty useless to remember that one after the session is down. It's pretty unlikely a window will outlive a kde session. Lubos is not willing to write the code needed to clean up kwins registered global shortcuts on application startup and i think that's correct. This feature is likely to be needed by more applications than kwin so the framework should support it.

To support those session bound global shortcut i have changed kdedglobalaccel not save global shortcuts if their id starts with "session:". The daemon will forget the existence of the shortcut the moment it is stopped.

And to enable the user to clean up the global shortcuts kcm should get a button to trash the configuration of an application, perhaps the option to remove just one shortcut. But of the one shortcut deletion button i am not so certain.

@Aaron and the plasma team. I have not forgotten about our discussion and will come back if i have time to work on plasmas ... beefs ... with the global shortcuts code.

Mike

PS: I think we have to improve KActions documentation rapidly. Especially in the global shortcuts context. I hope to trigger something in the next week but i think this will be hopefully a community task.

PPS: I'm interested in discussions related to global shortcuts. I'm willing to help people use the system. I'm not willing to read mails and posts telling me in to many words that the system sucks and you are unable to use it without telling what you want to do. Just explain what you want to do. More than one sentence. Show some use cases and we can talk and find a solution.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Thanks for working

Thanks for working on it. According to me why cant there be a simple condition in kdedglobalaccel that if the window is present use the set of keys for that purpose and if the window is not present allow access to khotkeys. Now as a practical user if i use a global shortcut i would prefer not to use it for other application shortcuts. For E.g. if i use amarok and if i close it i will not use win + e for the next song because in most practical cases i would use that key stroke to open a home folder. now is it not possible for the kdedglobalaccel to check if the application is running or not? These are just my comments.

The point of storing the configuration

As the original perpetrator, I'll give you the rationale for persisting the settings: If there is a clash (two apps using the same shortcut) something *has* to happen, and the idea was to avoid user interaction. So the first app to register a shortcut can keep it, even across sessions so things don't change behind the scenes. If you really want a certain shortcut in app X you can still configure it that way. By default, however, the first application to use a global shortcut can keep it. Hence the need to store the configuration. This has the side benefit of having a list of all global shortcuts which can be used to show and configure them in a KControl module. Note that this may be achieved in other ways and with different semantics of who gets a shortcut, too.

thanks for working on

thanks for working on this.

the assumption that shortcuts actually outlive the application is simply incorrect and applications like plasma (highly dynamic, shifting components during a session), kwin (highly dynamic, shifting between sessions) and media players (same keyboard controls should work with whatever the "active" media player is, which can change during the session) show this to be true.

not harrassing users at runtime with dialogs is ok; centrally coordinating shortcuts is great ...

it's just, as you note, in the configuration storage that things go awry with this setup. thankfully it's pretty evident that the configuration strategy can be altered without giving up the rest of the benefits.

in plasma we are currently simply managing the shortcuts on our own as plasma knows when a shortcut makes sense and when it doesn't. i'm happy with that scenario as it is quite straightforward given how plasma apps work. we register a shortcut when the widget is created and unregister it when it goes away ... as long as that's kosher with the design of the global shortcuts, i don't see any particular need for change for plasma at this point. just don't complain when we "work around" the configuration system. it is precisely the behaviour we want, regardless of where the code lives.

But, would not it be better

But, would not it be better if applications will have no global hotkeys of they own at all, that is, for registration of their hotkeys they will open some kcontrol module with, maybe, a list of d-bus calls they could handle? And it is the same control for all of them. That is, technically it is only khotkeys, it owns all globals, but with, maybe, better user interface.

Seems a bit crazy.

Surely the best solution is to let apps register any global shortcuts they want, and then when an ambiguous one is pressed just pop up a dialog box saying something like:
"This global short-cut (Ctrl-Shift-I) is used by more than one application. Please resolve this conflict.

Amarok:   [Shortcut widget]
Kopete:    [Shortcut widget]

[ ]  Use both shortcuts

[OK] [Cancel]"
And then disable OK until the conflict is resolved (either by clearing/changing the shortcuts or saying that they should use them both - this might be useful in some situations). This seems like a much more sensible solution if you ask me and it doesn't sound like it would be too hard to implement. The only persistent data you need is which keys should use all short-cuts assigned to them, and that doesn't depend on the applications installed.

Hi Mike, I'm afraid I am very

Hi Mike,

I'm afraid I am very clueless about shortcuts, global and otherwise, so perhaps, since you seem to have given the issue a lot of thought, you'll be able to enlighten me about a specific question: what is the *point* of persisting global shortcut registration between sessions? Shouldn't the registrations be cleared when the session starts?

Thanks.

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.