Mac-style menubar for KDE 4 and others

Every two weeks I get a question about the state of (no, not Okteta, he) the port of the Mac-style menubar to KDE 4. Obviously because I once tried to work on it, but then stopped (and nobody took it up).

In the time around the KDE 4.2 release the frequency of this question has risen, including one email from Markus Slopianka, who pointed me to the “Global Menu Bar for GNOME” project, thanks for the hint.

Guess it’s time for me to at least place some information about the state of global menubars for KDE/Qt in a Planet KDE-feeded and googleable document, to have the information flowing and perhaps create some more action somewhere ๐Ÿ™‚ Because myself I won’t work on this anytime soon, given my TODO list and the priorities attached.

Personally I would like it very much if there is a Mac-style global menubar as option also for the FLOSS desktops/shells. One that is supported by all the common FLOSS toolkits, like Qt/KDE Libs, GTK+ (GNOME/XFCE/Mozilla/OOo),
ร‰toilรฉ/GNUstep, Enlightenment Foundation Libraries and maybe more…
Or think of the NextStep-style menu (free floating vertical menu) as alternative option.

I would already be pleased if this works only for the toplevel menu entries, as listed in the menubar, so the submenu popups would be delivered again by the individual toolkit.
Still I could imagine that for menus without any special needs, e.g. custom rendered menu options, also all submenus could be shown by such a “X menu server”. And also the context menus. They are in separate windows anyway, so why not have them displayed by a third party (Another stage would be something like XMLGUI for all toolkits).

The above mentioned project “Global Menu Bar for GNOME” might be good candidate to be the central project to bring this feature into life. Looking at their roadmap it seems they have already reached some useful insights, working code, developers and are open for toolkit-independent solutions.

For KDE support of a Mac-style menubar has always been rather a hack, both in the past (KDE 3) and currently (KDE 4), see below for some detailed explanations. Best would be to put proper support directly into Qt. Like there is a special handling of the menubar for OS X, there could be one for FLOSS desktops/shells/X.org, given some well-defined standard system.

The following passage about the state in Qt/KDE is basically based on input/text from Thomas Lรผbking, of Baghira and Bespin fame, added by me with info of my own stalled try with a KDE 4 port:

KDE 3

On KDE 3, menubars were ripped out of the application window (as supported by KMenuBar) and XEmbedded into a special Kicker panel/applet. The Kicker plugin then acted as a simple WM, monitoring activeWindow changes and selecting the proper menubar in accordance. This has it’s limits:

  • It could not be post-applied (e.g. via a Qt style) to Qt-only programs, as Qt (at least many programs) does not like it too much if you just take away it’s QMainWindow::layout()->menuBar()
  • It can be distracting if remaining part of the program but inside the window of another one. Especially if the program freezes and (from a user point of view) Kicker becomes inresponsive.

Next to the default KDE Kicker applet there was a special variant of the applet provided with the Baghira style.

KDE 4

As a user of the Mac-style menubar I tried to port the Kicker applet to Plasma in time for KDE 4.0. As the support in KWin and KMenuBar in the KDE Libs was already ported (almost no changes needed), I thought this to be easily done.

The Plasma applet was started in playground, almost an 1:1 port of the Kicker applet from KDE 3. I got stuck a little with some XEmbedded problems, then found out that there are other problems, which had also already hit Thomas, who might even have tackled this problem before me, and deeper and harder, as he is in the Qt style business ๐Ÿ™‚ Simply embedding the menubar widget (as X window element) in Plasma is not so straightforward as with Kicker.

Plasma/Oxygen

The core problem is Plasma, or to be more precise, the Oxygen theme, or to be even more preciser…er, the fact that it uses inverted colors by default.
Oxygen – as most styles – at least by default uses dark text on a bright window, but the default Oxygen Plasma theme is pretty much white on black.
Unfortunately the menubars, better the Qt style used for it, don’t know too much about the current Plasma themes colors. So even if you can convince the menubar to paint an X-wise transparent background (removing the backing store usage) you’ll likely end up with painting black text onto a black background….
All in all the menubar, though embedded into a Plasma panel, is not part of the Plasma program, it does not get auto-informed about theme and/or color settings or changes.

XBar

The XBar is developed by Thomas as part of the Bespin style. It uses a client/server approach to the Mac-style menubar. Currently it’s only used by the Bespin Style to post apply clients to Qt4 based programs. The only currently existing server is a Plasmoid, also part of the Bespin project.

For the client/server approach D-Bus is used as IPC for a most simple protocol. This resolves from the color issues and also allows to “do stuff” with the visual menubar (such as manipulating the string of the first entry or inject pseudo entries without having to fear side effects). Thomas chose D-Bus as it’s fast, reliable, tested … and the default IPC used by KDE and Qt ๐Ÿ˜‰

How it works

The server (aka the XBar plasmoid) registers itself as org.kde.XBar to the D-Bus session bus.
It provides functions to

  • add/remove complete menubars alongside a unique id
  • add/remove/change menu entries (for that unique id)
  • change the unique id (that’s e.g. the original menubars mainwindow which could change due to reparenting)
  • focus change requests (whether a client want’s its menubar to be visible now)
  • be informed that a popup actually appeared (this is technical, to allow visual status updates)

The clients (aka Bespin styled menubars) register as org.kde.XBar-<PID> to provide a central hook for an internal dispatcher (i.e. you can have as many menubars per program as ever you want).
They provide functions to

  • activate/deactivate the global menu usage (i.e. (un)hide the internal menubar)
  • open/close the popup for some menubar index
  • get notified that a menubar index was hovered (so they can decide to open the attached popup, depending on whether another popup is already open)
  • (raise the attached window – that’s rather a gimmick, you can change the current XBar menubar by mousewheeling and some XBar setup provides functions to do stuff with the window like raising/closing it ect.)

Processing

Right after starting up, the server calls all clients for activation. If they’re interested, they’ll register themselves to the server and hide the internal menubar.
When the server dies, it calls all clients for deactivation. (Both functions can of course be used w/o the server, e.g. by a simple bash script that allows you to click a window to toogle the global menu usage on or off).

As soon as a client starts it looks for an existing server and activates itself registers to the server and hides the internal menubar.
When the client dies, it unregisters from the server.
(In case a client segfaults, the server has a timer triggered cleanup routine that removes bodies every few seconds, so the user will usually not be confused with inoperative menubars)

Together the whole thing works “automagically” – you don’t have to change settings or so. Just add the server plasmoid and the global menus will start working. Remove it, and you return to the common MS-style menubars.

With the registration, the client sends the server a stringlist containing the strings for the cliented menubar. If in case of e.g. Kate the menubar is initially more or less empty and then gets and changes items later on, the server just gets the updates and repaints.

Whenever a cliented window gets activated, it requests it’s menu to be shown by the server. If it falls inactive, it tells the server to unset the menubar (i.e. it’s no more interested in its menu being shown)

The server implements a (in case of Plasma QGraphics-) widget that acts more or less like a simple menubar. (I.e. it holds a list of items, calculates their positions, watches mouse position changes, thus triggers hover events, etc.)
When the user selects an item and presses the lmb, the server sends a request to the current client to popup (or down – NOTICE: this should be changed to just one trigger notification) the attached client. The client then pops up (or down) the popup at the position demanded by the server and informs the server which popup is now open (for visual status updates).
The server also informs the client whenever the hovered item changes and this way allow it to change the currently open popup (popup sliding).

Implementation specifics:

  • The server currently uses QStyle to paint the items, but nothing would prevent us from e.g. making use of plasma theme elements.
  • The post-applied proxy-menubar implementation in Bespin has it’s drawbacks:
    • It’s pretty much a giant hack, as taking away or even just hiding the menubar isn’t very much appreciated by Qt
    • It’s not perfect and i’m not sure whether every issue (see below) can be addressed this way

What does not work (yet…)

Keyboard usage:
Using menu shortcuts will open the popups inside the window.
On the other hand, if you open a popup with the mouse, you cannot change to open popup with the left/right arrow keys. (Thomas simply was never interested in neither).

Closing the initially opened popup by clicking the “not-window” (aka. the desktop or other windows) if you change the open popup (even forth and back) “click-to-close” works as expected (some mouse grabbing issue)

Icons and non-label actions in the menubar:
Icons aren’t important, but Thomas doesn’t know what to do e.g. with Konqueror’s throbber (aside especially this thing being hardly more than annoying).

General Drawbacks

  • Links D-Bus for every program
  • Sometimes (with opera?) there can be a slight delay when changing the active window leading to the “no active menubar” content being displayed for a moment and thus flicker.

End of Thomas’ text. Thanks for this deep insight, Thomas. ๐Ÿ™‚

See here a screenshot of Bespin and the XBar in action (warning, fancy styling for having some fun when creating this post):
XBar from Bespin
Really, this is not my own desktop setup. Proof: I am still with good old KDE 3.5 ๐Ÿ™‚ How can I? KDE 3.5 works great, even if some have forgotten this. Never change a running system without strong needs. Still I see myself for going for KDE 4.3, given that all my little KDE 3 applets I am so used to (like the Khalkhi applet, oh, and the Mac-style menubar) have been ported until then.):

26 thoughts on “Mac-style menubar for KDE 4 and others

  1. Hi,

    You could set the styleSheet for the QMenuBar (KMenuMar) you have embedded into the plasma widget and change the colours that way.

    Since the applet itself reacts to theme changes, you can listen to the signal for that and then change the style accordingly.

    Cheerio!

  2. I like the D-Bus approach, and rather than being implemented in the style, I suppose it can be implemented in Qt/KDELIBS,right ? (and in GTK ?). Being a huge fan of the MacOS style menu as well, I have considered in the past to help having some sort of spec so that it would work cross-desktop… only to realize that I didn’t have time for this… all I can offer is testing, and I am going to see if I can test the bespin theme ๐Ÿ™‚

  3. In a broader project it probably makes sense to not only implement the Mac-style menubar, but also a Mac-like application activation model. The Mac, as opposed to Windows (hence the name), separates application from visible windows. If you close the last window of an application, the application still remains active, and can be reactivated any time with alt-tab.

    Implementing this properly might require some additions to the window management protocol. Focus needs to stay with the application, so that keyboard shortcuts keep working.

    Great project, if you can get Gtk and Open Office on board.

  4. I was wondering if I could get the wallpaper. It’s really adorable and I would like it as my wallpaper. Can you give me the link or something?

  5. I’m waiting for the MacOS-menubar on KDE with bated breath. I got hooked on the concept on OS X (even though at first I absolutely hated it. After few months of usage, I realized that I live the idea and the implementation).

    Hell, if you asked me, the MacOS-menubar would be the default in KDE :)!

  6. I’ve been wondering about this for a long time. I really love this feature! Hope it will work for all graphical toolkits, as some apps I need use gtk ๐Ÿ˜ฆ

  7. I have a problem, we had a Mac OSX setup in a KDE3 desktop. We copied .kde/ to .kde4/ and now none of the KDE applications have any menus at all.

    When picking the first two options in KDE 3.5.10, the file that is changed is ~/.kde/share/config/kdesktoprc but when a user picks that third option (Mac OS-style) that file ~/.kde/share/config/kdesktoprc is not affected at all.

    What do we need to edit or erase so that the KDE4 apps have menus in KDE 4.2? Currently the KDE apps ahve no menus at all ๐Ÿ˜ฆ

  8. Alright, seems good that I posted this, there have never been that many visitors to this blog, looks like people are really interested in this ๐Ÿ™‚ Thanks for your commments.

    @Ivan: Yes, things could be hacked together that way in the styles (knowing about the color of the panel and the menustyle used). But a better than nothing working interim solution (KDE-only) keeps from solving things correctly, no? ๐Ÿ™‚

    @Matthias: Yes, the part of me striving for perfect solutions agrees. Then I learned for myself the hard way that one step completed after the other makes sure at least some steps are done. Still this aspect should be hold in the view when working on a global menubar, sure, good idea.

    @Lin: Somewhere on kde-look.org. I searched for “pink” ๐Ÿ˜‰ Here it is: http://www.kde-look.org/content/show.php/Sugarcoma+Bunny?content=35736

    @lefty.crupps: Should be in the file ‘kdeglobals’ in the group ‘KDE’ the key ‘macStyle’. Set it to false or remove it (default is false).
    You can use
    kwriteconfig --file kdeglobals --group KDE --key macStyle --type bool false
    on the commandline to do so (or just
    kwriteconfig --key macStyle --type bool false
    using defaults).

  9. Excellent, thank you. I had looked in that file but didn’t see anything that I thought was related — obviously I was wrong ๐Ÿ™‚

    We just tested the full command
    —-
    kwriteconfig –file kdeglobals –group KDE –key macStyle –type bool false
    —-
    and it didn’t seem to do anything. When we manually edited the file ~/.kde4/share/config/kdeglobals and replaced true with false and relogged in, everything worked as expected.

    Personally I dislike this style of menu bar, as my mouse has to travel far every time I want to use the menus and they change for each app meaning I have to ‘activate’ the app to use its menus, but it looks like some people do like it.

    Good luck in the reimplementation for the amazing KDE4 series, and again — Thanks a lot for the fix!!

  10. @lefty.crupps: He, I extra tested this here before and it works ๐Ÿ™‚
    Perhaps you did call the command as root and not as the user? Because then you changed the system-wide file kdeglobals ๐Ÿ™‚

    Just try
    kreadconfig --file kdeglobals --group KDE --key macStyle
    both as user and as root and compare the output, please.

  11. So the only reason you gave up on your port is the color issue with the Oxygen Plasma theme? Sounds pretty weak considering there are themes like Aya where that’s a non-issue.

  12. you do realize that it would be beyond trivial to create a containment specifically for this that used the system colours and otherwise emulate the widget style settings so that the plasma theme chosen and the menu bar didn’t collide visually, right?

    plasma is flexible. stop thinking in terms of inflexible monoliths.

  13. @Kevin: Don’t say “sounds pretty weak” to someone who has at least tried to work at something he was no expert in (X embedding, Plasma), honey ๐Ÿ˜‰ Aya and friends may be a solution, but are you willing to be the one to make all the users understand this limitation (I am not)? And it would make a single-click setup more difficult.

    @Aaron: Beyond trivial perhaps for you ๐Ÿ™‚ Then, while this flexibleness of Plasma is great I would prefer it if the global menubar works with all the Plasma containments and styles.

    All in all, hacking around a hack (which the KDE Mac-style menubar is) is not the way to go, if it is up to me ๐Ÿ™‚ At that point I would spent my (free) time rather on solving things at the right level. So thanks for the pointers to possible solutions, but sadly they do not please me. ๐Ÿ™‚

  14. It’s good to know that not only the Gnome community are making effort to implement Global Menu. I hope you guys will collaborate towards realizing this very beautiful feature. I can’t wait to use it. Good luck and thank you!

  15. A year after your blog entry ๐Ÿ™‚ I would like to play the devil’s advocate here, after having spent the last four weeks mainly using a MacBook for development (I had hardly ever used a Mac before). I used to be impressed by the Mac global menu bar – not least because it saves screen real estate. Having used it for a month now, I am starting to feel differently.

    Firstly, although the global menu may be faster to hit, the frequency with which the menu at the top doesn’t belong to the application I thought it did rather cancels out that gain for me. (The Mac makes this worse by decoupling applications from windows, so that the menu may belong to an app you just minimised or a window you just closed.)

    The second point is that having the menu bar far away form the application tends to break my thought process, as clicking on a menu entry forces me to move my gaze away from what I am doing.

    The third point is: what does Fitt’s law say about how long it takes to get your mouse *back* from a global menu to your application, as opposed to getting it back from a local menu to your application?

    Keep up the good work though, I thoroughly approve of having a global menu available for people who like it.

  16. Hi,

    10 years have passed,

    Plasma 4 has gone

    Is it possible to bring the Mac Style Menu Bar to Plasma 5

    somehow?

    • It’s available now by the name “Global menu” as applet.Not using myself, so just know it exists (and GTK developers seem to have troubles support it, but works good enough with Qt-based apps)

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.