Global Menu’s Returning!

Application Menu Plasmoid
Application Menu Plasmoid

With Plasma 5.8 LTS out the door it’s time to look ahead at future Plasma releases. In our first long term support release we introduced “modifier only shortcuts” that allow you to open the application launcher with just the Meta key. Judging from feedback on the Internet this is one of the best features introduced in all of KDE’s history ;) I was quite surprised to find that the global menu is a close second.

Global Menu in Qt 5.7

Since Qt 5.7, thanks to Dmitry Shachnev, QGenericUnixTheme out of the box supports exporting a QMenuBar over DBus and registering it to the com.canonical.AppMenu.Registrar. When I updated to said version I was disappointed that it didn’t “just work”. The reason being that Plasma ships its own Qt Platform Theme that is responsible for enforcing Plasma look and feel settings on Qt applications as well as providing the file dialog. We do this by inheriting from QPlatformTheme which isn’t the aforementioned unix theme, which is private. Since the Plasma-Integration repository is bound to a specific Qt version already anyway, I now use private Qt imports to get hold of the unix theme so we don’t need to re-implement all of that logic, which was the reason I waited for Qt 5.7 for all of this.

What about Wayland?

The global menu infrastructure works by having an application notify a registrar service that it has a menu bar on a certain window accessible on a certain DBus service:

com.canonical.AppMenu.Registrar /com/canonical/AppMenu/Registrar com.canonical.AppMenu.Registrar.RegisterWindow WinId /MenuBar/123
Global Menu on Wayland – the window decoration menu button will also return! Window positioning on Wayland needs to be tweaked a bit ;)
Global Menu on Wayland – the window decoration menu button will also return! Window positioning on Wayland needs to be tweaked a bit ;)

Those of you familar with Wayland might notice that it uses global window IDs, which don’t exist in a Wayland world. That means, no global menu on Wayland, I thought, not without significant re-engineering effort.

Martin Gräßlin then came up with the brilliant idea of writing the DBus service name (it’s omitted in the above call since the registar knows who is calling) and object path onto the windows as properties. This way we don’t need to deal with any window IDs and can even omit the registrar! All we need to do is query the active window for those properties:

_KDE_NET_WM_APPMENU_OBJECT_PATH(STRING) = "/MenuBar/123" 
_KDE_NET_WM_APPMENU_SERVICE_NAME(STRING) = ":1.1337"

On Wayland we then make use of Qt’s Extended Surface protocol which allows you to set arbitrary properties on a window. To my surprise kwin_wayland was engineered in such a way that it works with X clients going through Xwayland with no further adjustment needed!

It works with non-KDE applications, however: VLC player in its full global menu glory!

When we return a new QDBusMenuBar from our platform theme, we then write the properties on the window the menu bar is attached to. This required some changes to Qt code so it actually tells us the window. Unfortunately, we now have to ship a copy of QDBusMenuBar – still better than duplicating everything. I’ve also seen a ticket on Qt’s bug tracker about providing public better access to Qt’s DBus menu implementation. We currently also ship our own system tray implementation for the same reason (and because ours is older but we’d love to get rid of it).

What about non-Qt applications?

Google Chrome sporting a classy decoration menu button
Google Chrome sporting a classy decoration menu button

As you could probably tell by the Registrar service name, this stuff wasn’t invented by us. In theory, any application could export its menu through DBus and both Chrome and Firefox do exactly that. I’ve also seen LibreOffice do it at some point but I couldn’t get it to work and neither could I with Gimp and Inkscape.

They won’t work with this new approach anyway, right? We kept the Registrar but all it now does is write the DBus service name and object path on the window with the ID in the RegisterWindow call. This way we don’t need any special-casing in KWin, even. Unfortunately, this won’t work on Wayland then.

What’s up next?

The last bit in this feature frenzy is the application menu KRunner plugin, aka “Unity HUD”. It allows you to search through a potentially complex menu structure of an application using KRunner. Back in Plasma 4 I stopped remembering shortcuts just used it to find all actions I needed.

One issue I came across is that for the application menu runner to work, an application would need to export its menu. However, non-KDE applications like VLC player and Firefox hide their menu bars in this case. This means you cannot really use the application menu runner when you don’t want a global menu or window decoration menu button. I don’t know how to proceed here…

My initial plan was to have three options in Applicaton Behavior settings, Menu “in application” (the default with no global menu service running), “window decoration button” and “in a widget”. Theoretically you could use the window decoration and global menu applet simultaneously, though.

Another obstacle is keyboard activation. When you press Alt+F it would open the “File” menu. With global menu or decoration button I found no way of implementing this. There’s a “request activaton” signal but I never saw anybody actually emit it. What I could perhaps do is add another “modifier only shortcut” when just pressing Alt which then passes focus to and/or opens the menu. Do you know how Unity handles this?

If you like what you saw and want to help make this happen, especially if you have answers to my above questions, be sure to ping me in #plasma on Freenode IRC!

30 thoughts on “Global Menu’s Returning!”

  1. I won’t be able to talk about the internals of it but it seems they do what you said, “What I could perhaps do is add another ‘modifier only shortcut’ when just pressing Alt which then passes focus to and/or opens the menu.” I say this because, in Unity (w/menus at windows decorations at least), if you hit and quickly release Alt it shows HUD but, if you only hold Alt, it will show the menu in decoration (and hide it on release). That is, maybe Unity “passes focus to and/or opens the menu” on ALT keypress, so being able to take a letter for shortcut (like Alt+f), or showing HUD on Alt keyup.

    A view I have for “window decoration button”, also applicable to “in a widget” is:

    * Just toggle menu open/closed on Alt keypress, leaving it open when so, then user could use mouse if he wants to, for example. If he holds Alt and type a key, menu is open and triggers that shortcut. But a search field could be somewhere around (I guess focused — or typing blinking cursor could simply be right before the first item, indicating you could type there) to filter items, like, say, typing “print” would slim the list down to “Print” and “Print preview” (“Printer setup” and whatever else it has). It sort of IS a HUD but visually in context, the window (again, for “window decoration button” — for “in a widget” it’d simply feel like HUD).

    * Also, get the window decoration menu’s first level in line instead of column. It’d feel more natural, specially to muscle memory (e.g. Considering a top panel w/global menu and a maximized window, Help menu item would be around the same place being it “in application” or in “window decoration button” or “in a widget”).

    I could do a mockup if you’d like to me to be more clear about these.

  2. Thanks! I’ve always used the global menu bar in KDE 4 on my laptop and I’m going to use it again on my current laptop. The smaller screen, its location below the natural line of sight and the less precise input device make the global menu attractive. Quite a few people I’ve talked to also like to use global menu on laptops and the regular kind on desktops.

  3. Next step should be to allow us to close menu with Meta key.
    Right now it can only be opened with it.

    1. That was recently addressed and will work in the upcoming Plasma 5.8.3 release in conjunction with a patch that will be part of KDE Frameworks 5.28

  4. Is it possible or not to place menu in titlebar like in Ubuntu. (Not only one button, but whole menu) ?

  5. Just a thought about global menu not working with gimp : it may need an environment variable to work :
    UBUNTU_MENUPROXY=1
    (usually used with a 0 value to disable global menu using gimp in a “multiple windows” arrangement)

    1. Thanks. That didn’t work for me, though, perhaps I’m missing a package but I don’t know which.
      When I start LibreOffice with SAL_USE_VCLPLUGIN=gtk it hides its menu bar and instead uses GMenuModel on DBus (interestingly, they use the same approach of writing the DBus service and path on the window) but that doesn’t work with our menu unfortunately.

  6. Great work! One question: will menus remain as qwidgets or they’ll be converted as plain plasma widgets? Thanks

    1. The menus are regular widgets QMenus. We might go crazy design-wise once the infrastructure works but as of now I want to get it working the way it used to first.

      The top menu bar is implemented as a Plasma widget that can be placed anywhere, though, which then also spawns QMenus for the submenus.

      1. “We might go crazy design-wise once the infrastructure works”
        Would my design above be possible? What do you think of implementing it as the behaviour for “window decoration button” and plasmoid (“in a widget”)?

      2. Ok. I asked this for visual consistency. The kde4 version was useful but a bit ugly. Full plasma will be awesome. Good work.

    1. I looked into QMenuModel a while ago but I don’t think this is an option. We would pull in GMenuModel for this and just using the DBus interface directly doesn’t work because the interface is deemed non-stable.

      Also, Qt now supports global DBusMenu out of the box, which is the way of least resistance. And, of course, why stick with something that works if you can just invent something new…

  7. hello,
    good that we have global menu again, I have a question, it will also include buttons to maximize, minimize and close as unity and Mac or single global menu?

  8. > Theoretically you could use the window decoration and global menu applet simultaneously, though.

    This please!

    I already wished for this in Plasma(1) times, but there it wasn’t easily possible. So if this is now possible please make this option available.

    And yay for global menus comming back!

  9. I’m so glad to see this. I hope it comes quickly. :)

    Personally, I’d really love it if the menu could be integrated into each window’s titlebar, in the same way that Unity does it. That is, the titlebar displays the window title, but when you mouse over it (or hold Alt), the titlebar changes to display the menu instead.

    Having a button in the titlebar which shows a pop-up menu when clicked (as described in this blog post) is an acceptable alternative, but the Unity way is nicer in my opinion. I prefer it because it looks and functions in the same way as the regular menu (laid out horizontally, in the same area, easily visible while holding Alt), but saves pixels.

    Thanks for the good work.

  10. How did you get Qt5 applications to export their menus? I’m the author of qmenu_hud [1] and can’t get it to work with current Qt5 on Arch Linux. Previously it was working fine with appmenu-qt5 but since some Qt releases nothing is exported. I removed appemenu-qt5 as i heard it interfers with the builtin functionality, but still no luck.

    How do i trigger QGenericUnixTheme? I don’t run Plasma or Kwin, just Awesome WM with some KDE applications.

    [1] https://github.com/tetzank/qmenu_hud

    1. I hoped for it to work out of the box with Qt 5.7 but even when not loading Plasma’s platform theme it wouldn’t work here for some reason. I didn’t figure out what it was, though, and for Plasma’s platform theme I added a copy of QDBusMenuBar to make it work.

      Perhaps have a look at Qt’s global menu code or contact the original author of that: https://codereview.qt-project.org/#/c/146234/

  11. I can’t wait to get this feature and to go off gnome-based DEs. This is the only feature I miss in KDE. And it is really deserves respect that KDE-devs pay attention to this feature unlike gnome-devs don’t want to integrate to their DEs (Cinnamon, Gnome-shell etc.). It think there are many laptop users and global menu helps to save vertical space on the small laptop display.

    Thank you very much!

  12. Well this is fantastic, but on mac we have the java applications, like android studio and eclipse that have the menus “working globally”, this kde plasma’s global menu will do the same thing or will be impossible? I think that feature should be provide, because today the android development on small screen is horrible and this should help and please the small screens users, and attract developers to use kde plasma as main environment on linux world.

    1. Given how horribly Java applications integrate into Plasma right now I don’t have any hopes for that…

  13. Happy Arch Linux KDE user!
    I’m writing to ask you if we may except global menu compatibility for GTK apps at all from your perspective.
    Also, how do I get an app icon and name next to a global menu like in MacOS?
    I found that necessary to compose my desktop and meet my aesthetic requirements. :)

    Best regards!

Leave a Reply

Your email address will not be published. Required fields are marked *