MenuBar

In Unity, along the top of the screen should be a menu bar that contains the Ubuntu button, the window menus, the vestigial notification area, and the status menus. These all consist, at the technical level, of Indicators.

Overall rationale

whether-something-appears.jpg

When and where to show the menu bar

The menu bar should appear at the top of every screen, except those screens where a window is currently in full-screen mode.

The menu bars on different displays should not be mirrors, however; opening the “Edit” menu on one should not simultaneously open it on the others.

When a menu is opened by any method that is not a pointing device (for example, by a keyboard shortcut), it should open on whichever display contains the largest proportion of the area of the active window.

Window menus

Rationale

A menu hierarchy is often used to provide access to lesser-used functions — functions that aren’t displayed directly inside a window. Because of its density, a menu hierarchy also often serves as a quick map of what functions are available in a program. For that reason, it includes common functions as well, which also lets it advertise keyboard equivalents to those functions.

There are several ways a menu hierarchy could be presented, each with benefits and drawbacks. For Ubuntu, the best overall presentation is a single menu bar at the top of the screen.

Determining the active window

This algorithm is preliminary and subject to change. The test cases are authoritative.

The active window is not necessarily the focused window.

Consider all the currently open windows that are of of type _NET_WM_WINDOW_TYPE_DESKTOP, _NET_WM_WINDOW_TYPE_NORMAL, or _NET_WM_WINDOW_TYPE_DIALOG. Of these windows, the active window should be whichever of them most recently:

  1. was focused; or
  2. had a child window of _NET_WM_WINDOW_TYPE_UTILITY or _NET_WM_WINDOW_TYPE_TOOLBAR focused.

A “child window” in this sense is one that either:

  1. has WM_TRANSIENT_FOR set to the active window;

  2. has _NET_WM_STATE_SKIP_TASKBAR set;

  3. is of type _NET_WM_WINDOW_TYPE_UTILITY and does not have its own menus.

Test case:

  1. Open two images in Gimp.
  2. Focus image 1; that window’s menus should appear in the menu bar.
  3. Focus the Toolbox; image 1’s menus should remain in the menu bar.
  4. Choose “Edit” > “Fill with FG Color”; image 1 should be filled.

  5. Focus image 2, then the Toolbox, then choose “Edit” > “Fill with BG Color”; image 2 should be filled.

Test case:

  1. Draw a box in Inkscape.
  2. Choose “Object” > “Fill and Stroke”, and tear the “Fill and Stroke” into its own window (if it is not already).

  3. Select the contents of the “Stroke Style” > “Width” field, and choose “Edit” > “Cut”; the field contents should be cut to the clipboard.

Test case:

  1. Launch XChat-Gnome; its menus should appear in the menu bar.
  2. Choose “Edit” > “Preferences”.

  3. Select the contents of the “Real Name” field, and choose “Edit” > “Cut”; the field contents should be cut to the clipboard.

Test case:

  1. Launch IBus, if it is not running already.
  2. Add the “Other - latex” input method to the list, if it is not there already (“IBus Preferences” > “Input Method” > “Select an input method” > “Other” > “latex” > “Add”.

  3. Launch gnome-terminal; its menus should appear in the menu bar.
  4. From the IBus status menu, choose “Other - latex”.
  5. Open the “latex” menu in the palette; gnome-terminal’s menus should remain enabled in the menu bar.

Implementation: The active window is decided by BAMF.

Windows with recognized menus

Where the active window has its own menus in a menu bar in a supported toolkit, these menus should be presented in the menu bar, and the window should not have a menu bar inside it. If the window has more than one menu bar, the first one encountered should be used.

If the application has an application menu, this menu should be presented in the menu bar, before any window menus.

All menus should be presented a consistent distance from each other, regardless of how they were laid out inside the window. For example, the Granule flash-card program has “File”, “CardFile”, and “Deck” menus at the left end of its menu bar, and “Help” at the right end; but with the global menu bar, “Deck” and “Help” should be just as close to each other as the other menus are.

Windows without recognized menus

When the active window does not have its own recognized menus, for visual stability and consistency, the menu bar should still offer a minimal set of menus. (Examples include most current Preferences windows, and applications using unsupported toolkits such as Blender or Fontforge.)

Version 1

The minimal set should consist of these menus:

File
----
  Close

Edit
----
  Undo
  Redo
--------------
  Cut
  Copy
  Paste
  Delete
--------------
  Select All

All these options should always be present, but should be sensitive only if the window uses a supported toolkit and only when they make sense. In particular:

  • “Close” should be sensitive whenever the active window has a close button.
  • “Undo” should be sensitive whenever a control is focused and has had a non-undone action. Choosing it should undo the most recent non-undone action.
  • “Redo” should be sensitive whenever a control is focused and has at least one redoable action. Choosing it should redo the oldest redoable action.
  • “Cut” should be sensitive whenever an editable text field is focused and contains selected text. Choosing it should cut that text to the clipboard.
  • “Copy” should be sensitive whenever text is selected, whether in a text field or list view. Choosing it should copy that text to the clipboard. Selected items of a multi-column list should be copied as lines of tab-delimited text.
  • “Paste” should be sensitive whenever an editable text field is focused and the clipboard contains text. Choosing it should paste the text, replacing any selection.
  • “Delete” should be sensitive whenever an editable text field is focused and any text is selected. Choosing it should delete the selected text.
  • “Select All” should be sensitive whenever the focused element is a text field or a list that allows multiple selection. Choosing it should select all the text, or all the items in the list.

Test case: Copy some text. Open Inkscape. Choose “Edit” > “Find”. In the “Find” window, choose “Edit” > “Paste”. The text you copied should be pasted into the “Find” window.

Version 2

If the window and its parent window both use GTK, and the parent window’s menus contain all of the stock items GTK_STOCK_UNDO, GTK_STOCK_REDO, GTK_STOCK_CUT, GTK_STOCK_COPY, GTK_STOCK_PASTE, GTK_STOCK_DELETE, and GTK_STOCK_SELECT_ALL (even if their text has been changed since), then the menu bar should present the menus of the parent window, all of them insensitive except for those editing items (with text temporarily reset to stock values) when applicable.

Otherwise, the menu bar should present the same minimal set of menus as specified above for a window that does not have a parent window.

The desktop

If Nautilus is running, the desktop should have the same menus as any spatial Nautilus folder, except that:

  • “File” > “Close Parent Folders” and “Close” should not be present

  • “View” > “Reset View to Defaults” should not be present

  • “View” > “Icons”/“List”/“Compact” should not be present

  • “Help” > “Contents” should be replaced with an “Ubuntu Help” item, opening the overall Ubuntu help

  • “Help” > “About” should be replaced with an “About This Computer” item, opening System Monitor.

“Open Parent” should be available as usual, and open the parent folder in a Nautilus window. “Close All Folders” should be available as usual.

Inherited window menus

To minimize effort for programmers and modality for users, it should be easy for all windows in an application to inherit and extend a basic set of menus for that application. For example, someone using a document-editing application should be able to choose “File” > “New Document” or “File” > “Open…” regardless of whether the active window is a document window, the application’s Settings window, or the About window — though in the latter two windows, most other menu items will be insensitive.

This detailed example shows how menus in a fictional mail client, DemoMail, would be shared between mail viewer windows and composition windows. Most simply, both types of window should have a “Help” menu with identical items.

inherited-help.png

A simple tweak would be for the “Help Using DemoMail” item to open different help by default, depending on whether you are in a mail viewer window or a composition window — but that should not require reconstructing the whole menu.

Other menus have more extensive changes: items may be added, made sensitive or insensitive, change in function, or change in both contents and function.

inherited-key.png

inherited-file.png

In the “File” menu, the “New Message” and “Open…” items function identically regardless of what window is focused. But several of the items have different functions, because they operate on the selected message, and in a composition window the selected message is the message you’re composing. The “Reply”/“Follow Up” items also have slightly different text.

inherited-edit.png

Several of the items in the “Edit” menu are insensitive in a viewer window (except when you are filling in a form inside an HTML message). When you are in a composition window, they become sensitive, and most of the other items change function to operate on text inside that window; the “Select” submenu changes to a “Select All” item; the “Paste” item changes to a “Paste” submenu; and a couple of top-level items are added.

inherited-format.png

Most of the “Format” menu items work only in a composition window. If it weren’t for a couple that also apply to reading a message — “Rewrap” and “Text Encoding…” — the entire menu might appear only in composition windows.

inherited-organize.png

The “Organize” menu is the opposite case: most of its items apply in a mail viewer window but not a composition window.

inherited-view.png

Finally, the “View” menu is a mixture of items that apply only to a mail viewer window, items that apply differently in each window, and items that function independently of whichever window is focused.

Unresponsive applications

If the active window belongs to an application that has become unresponsive, the menus should not be openable, and the pointer should appear busy whenever it is over the menu area.

If you want to implement focus-follows-mouse compatibility

When focus-follows-mouse is used, the active window should have the same definition as previously, except with “focused” replaced by “focused by any method other than mousing over it”. (For example, focused by clicking it, by Alt Tabbing to it, or as a result of being next in line when another window closes or minimizes.) This prevents the active window from changing accidentally when someone moves over another window on their way to the menu bar. In this case, whenever the pointer is over the menu bar or any menu bar menus are open, the active window should temporarily appear focused, as a visual indicator of which window the impending menu action applies to.

Handling overlap of window menus and status menus

In the unlikely case that the window menus are so wide that they would overlap the status menus, the window menus should take priority. When the menu bar is navigated with the keyboard, the hidden menus should be accessible as normal, and each menu title should be shown until an item that would overlap it is focused. In all cases, any menu title that is overlapped by a more-recently-focused title should be completely hidden, not partly hidden.

Full-screen windows

  • Opening the app menus when in full screen mode (either by pressing ALT or F10) should cause the top bar to temporally slide down over the top of the full screen application.
  • After the user selects a action from any of the menus, the top bar and associated menus should slide back off the screen.
  • Pressing ALT or F10 a second time should close the menu, and also cause the top bar to slide back off the screen.
  • Pressing ESC should close the menu, and also cause the top bar to slide back off the screen.

Advertising the presence of the menu bar

In some cases, an application developer may want to use menus — or tweak the layout of the window — only if the unified menu bar is available. Examples include preferences windows, dialogs, and Chromium browser windows.

GTK application developers can use this code to detect whether a unified menu bar (or similar menu handler) is in use:

if (gtk_menu_proxy_get() != NULL) {
  ...
}

Qt application developers can use this equivalent code:

if (!QCoreApplication::testAttribute(Qt::AA_DontUseNativeMenuBar)) {
  ...
}

Implementation

Key modules:

  • GtkMenuProxy

  • AppMenuApplet(?)

  • AppMenuIndicator

  • DBusMenu
  • IndicatorProtocol

  • MenuBar (aka uPanel)

  • QTMenuProxy

  • OO.org-specific menu proxy
  • Mozilla/XUL menu proxy
  • Other possible menu proxies (for Java applications, or other toolkits? ie, which SDK can we provide in this case?)

GTK2/GTK3 application integration

gtk-overview.png

gtk-internals.png

  1. Menus will be broadcast to the menu bar by... We can use Parasite to debug troublesome applications.

  2. Applications in Main that use GTK can be listed by ...
  3. Menu bars inside the window can be hidden by ...

Could we share some code with Imendio’s port of GTK to Mac OS X?

XUL application integration

The initial implementation is as a Firefox and Thunderbird extension. Once it has been demonstrated to work well, we will submit it for inclusion in Gecko, so that it also works for Seamonkey and other XUL applications.

Thunderbird’s spinner, which is normally inside the menu bar, should be displayed as if it was positioned at the trailing end of whichever toolbar is topmost.

Apart from that, if there are any items other than menus in a Mozilla toolkit window’s menu bar, the bar should remain visible, but minus the menus themselves. (Test: In an Ubuntu Classic session, customize Thunderbird’s toolbar to add buttons to the right of the menus. Log out, log in to Unity, and launch Thunderbird. The buttons you added should still be visible, but the menus to their left should now be in the global menu bar instead.)

Context menus for menus (such as for bookmarks in Firefox’s Bookmarks menu) should be ignored.

Qt4 application integration

  1. Menus will be broadcast to the menu bar by...
  2. Applications in Main that use Qt4 can be listed by apt-cache rdepends libqt3-mt ... This is imprecise -- it shows lots of libraries etc.

  3. Menu bars inside the window can be hidden by ...

VCL application (LibreOffice) integration

  1. Menus will be broadcast to the menu bar by...
  2. Applications in Main that use VCL are can be listed by apt-cache rdepends openoffice.org-core

  3. Menu bars inside the window can be hidden by ...

Vestigial notification area

The menu bar should contain a notification area equivalent, whitelisted to contain only notification area items inserted by Wine or Java applications, Mumble, Skype, HPLIP, or system-config-printer.

Unlike the previous notification area, this area should not be movable, manually resizable, or removable.

If any application that is not in that whitelist tries to use the notification area, the menu bar should publish as much information as it knows about the connection to a log file.

Custom status menus (application indicators)

Custom status menus are documented on the Application Indicators page.

System status menus (system indicators)

The system status menus should appear, starting from the trailing end of the menu bar, in order from greatest to least likelihood of being there at all. That maximizes the overall probability that a menu on one Ubuntu computer will be in exactly the same place on another Ubuntu computer.

structure-q.png

In Ubuntu 12.10, starting from the trailing end:

System indicator menus — and application indicator menus that have a settings panel as their primary interface — should follow a general pattern that they can be turned on and off using a checkbox in the bottom left corner of the relevant settings panel.

toggling-status-menus.png

Session variations

As described in the individual specifications, each indicator menu may have variations for a guest session, the live session from installation media, the standalone installer session, or the login screen. This involves either omitting the indicator altogether, or omitting any settings item (one of the reasons it is placed last in the menu) and omitting or desensitizing any item that would launch an application. (The variations are implemented as profiles in /usr/share/unity/indicators/.)

Unresolved issues

  • How could a program preserve access to the items in its “Help” menu while a dialog is frontmost?
  • In the absence of access keys, how should the menu bar be accessed with the keyboard? Relatedly, what should Alt Space, Right Arrow do?
  • What happens if access keys in a child window conflict with those in its parent window’s menus? For example, if I have Inkscape’s Find window open and press Alt E, P, should that open the “Edit” menu and choose “Paste”, or should it check the “Search in selection” checkbox and then beep because P isn't a recognized access key?

  • What about tear-off menus, as in emacs22-gtk? Should we still allow them?
  • Window focus must not change while a menu is open.
  • Need to specify menus for when nothing is focused and there is no desktop.

References

* http://design.canonical.com/2010/05/menu-bar/

MenuBar (last edited 2014-02-18 17:17:38 by mpt)