beeware / toga

A Python native, OS native GUI toolkit.
https://toga.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
4.35k stars 671 forks source link

Develop a HIG-compliant story for GTK menus #874

Open freakboy3742 opened 4 years ago

freakboy3742 commented 4 years ago

Ticket #872 addressed some immediate UX issues with menus under GTK; however, there is a larger UX issue that needs to be addressed.

The GNOME HIG specifies how menus should be used on a GTK app; the current way the GTK backend uses menus violates that specification.

Toga apps don't explicitly define menus so that different HIG guidelines can be incorporated. This allows macOS to display the "quit" option under the application menu, Windows to put "quit" under the File menu... and GTK to have it's own interpretation.

This also extends to user-defined commands; commands are currently grouped, which roughly maps onto top level menu items - but the GNOME HIG will require some re-examination of this.

Specific Gnome HIG references:

We need to develop a consistent HIG-compliant interpretation of Toga commands for the GTK backend.

freakboy3742 commented 4 years ago

An initial proposal:

MuhammadMuradG commented 1 year ago

In regards to the issue title, what the issue context refers to and its conclusion, and the following references, this comment is a trying to take the initial thoughts about this issue to an actual implementation that intend to fix/solve the GTK menu HIG-compliant in Toga.

Dear Toga folks, your thoughts and guidance are appreciated.

Understand the HIG for menus in GTK:

As was mentioned here, the app menus are no longer recommended, look at these reasons, and you should alternatively use Primary and Secondary menus.

The Primary or Secondary menus are putted in the HeaderBar on top-right side of it. The standard items for Primary menu are menu items that relate to an entire application (such as Preferences and About "Name") and note that there is no close/quit item, which is incorporated separately into Header bar. The standard items for Secondary menu are menu items for the current view or content item. For more details about the design see this and this. See this for an example of this design.

Follow this design will raises a little inconsistent in other elements of design. This includes the following:

The answer to the first 4 questions that is HIG-compliant for GTK is to use the navigation techniques and containers to minimize the commands in each view.

If we have a place to reveal commands for users for quick access why we create another place, the ToolBar, to put them. This is my thoughts for the last three questions.

What we have in Toga?

Although Toga follow the old-HIG in its GTK-backend, it has a flexible way to adapt to some extent to any HIG. This is what I will try to do in the next section.

How GTK-backend in Toga can be designed to follow GTK HIG-compliant?

The design will be as following:

At the end and by this we will be able to follow the HIG for GTK menus.

freakboy3742 commented 1 year ago

@MuhammadMouradG Thanks for that excellent summary of the state of GTK/Gnomes HIG - that's incredibly helpful.

Reading through the details about application vs primary vs secondary menus, my immediate impression is that it makes perfect sense to start with... and then goes completely off the rails.

For example, the design mocks of the app menu migration make sense for the examples they've given. I can see how Toga's default menu items like About/Quit would fit into that pattern. The secondary menu sort of makes sense as well- I have questions about where we'd pick icons for secondary menus, but that seems in the realm of a solvable problem.

But then... the examples stop. There's not a single example of how a big application is supposed to use this pattern. The menu items on a contact app are relatively simple - but how does an app like GIMP / Photoshop use this pattern? These are apps that have dozens of menus and submenus. How is that meant to fit into the "single secondary menu" pattern?

And the discussion about why menus are "bad" is just... laughable. "They take up vertical space"... ok... sure... "and they look bad"... Have you considered, maybe, making them look not bad? I've used GUIs for almost 40 years, and the visual appearance of menus isn't something I've ever found myself concerned about. I have, however, consistently found Linux GUI desktops to be a usability nightmare. Menus allow for discoverability of app functionality. If an app has a lot of functionality... there's a lot to discover. This HIG seems to think that discoverability is a bad thing.

But - Toga aims to follow local HIG patterns; whether I agree with them or not, we need to do what we can to adhere to those patterns.

I can see the argument for dropping the MenuBar in favour of some sort of mapping to Primary/Secondary menus (and a different set of default menu items to match local expectations.

What I don't understand is how multiple user-specified menu groups would be handled. Are there going to be multiple secondary menus? Or one secondary menu that wraps all the "non-app" menus? Is that what "view" is meant to represent? And if there are multiple secondary menus, what provides the icon for those secondary menus?

Dropping Toolbar in favour of header bar options also makes some sense... although I have concerns about available space (which is part of the reason that the HeaderBar approach generally makes no sense to me). If I've got a rich toolbar with lots of icons... and a menu with lots of menu groups... and an app window that includes a document title ... where is all this content meant to fit? How does GTK adapt the header bar to include more content than it has space to render?

In terms of moving this forward - would it be possible to mock up what Toga Tutorial 2 looks like in a "HIG-Compliant" world? Tutorial2 is an example app that contains multiple commands, custom menus, submenus, and a toolbar. It would be very helpful to see what that looks like under this model, and to identify what is missing or ambiguous in mapping to that model.

MuhammadMuradG commented 1 year ago

@freakboy3742 I hard-coded a mock up for Tutorial 2, i.e. write the code in the gtk-backend, to provide a quick response and save my time. The video is here:

https://user-images.githubusercontent.com/50509521/233765567-0b0372e0-6307-4739-b85d-6c6fe43fbc09.mp4

Just some notes:

  1. As I understand, the HIG deal with HeaderBar as a Slide that its content changes depending on the information displayed on the main window. I.e. when we edit text we will find commands that only relates to text editing and the main HeaderBar (that contains the Primary menu) will give us a navigation to this commands and disappear until we finish the edit.
  2. As I understand, the HIG refers to any menu that is not include the app items (Preferences, Keyboard Shortcuts, Help and About application-name) as Secondary Menu.
  3. As I understand, we will always have one Primary menu and one Secondary menu.
  4. We will not have Primary menu and Secondary menu at same time on the same HeaderBar.
  5. None app menus/items could be placed at Primary menu.
  6. My intention by view argument was for implementation considerations, to refer to which HeaderBar we at.
  7. The Secondary menu have (more-options-symbolic) icon and you can add CheckBoxButtons/RadioButtons to it to add some control on the window content also you may do not need to use it.
  8. In the Tutorial we can add Secondary menu in the HeaderBar that appear when we click on the Sub menu command on the top-right corner.
  9. In real application this Sub menu will be for example Edit Text.
  10. As I understand, the HIG emphasis on the design of the application. What I noticed while reading through the HIG is encouraging designers to be careful in choosing places for commands and submenu and are it is important or it just same command in other place. Take a look at screenshots of this carefully designed app, as I think.
  11. As I understand, HeaderBar with alots of items is a bad design of an app. So use multiple HeaderBars each one relate to some functionalities, as example illustrate.
  12. When you use a photo editing application, you are looking for how to do something with an image by this application. It is better for the application to direct you to the command quickly than show you what it can do by interrupts you by its menus.
  13. A final point, I agree with you at some extent and I think MenuBar have an advantages that HeaderBar miss them. See this.
freakboy3742 commented 1 year ago

I've just had a conversation with @KyleRConway at PyCon US, and he had an interesting take - even though the Gnome HIG exists, it's not consistently followed - even inside high profile Gnome/GTK apps. Inkscape and GIMP both are banner apps in the GTK space... and they both have a menu bar.

Kyle pointed me at https://circle.gnome.org - a showcase of HIG-compliant apps; and the interesting property of those apps is that they're all very simple. There's no apps with the sort of complexity that Inkscape or GIMP have on that list.

Based on the conversation I had with Kyle, my impression is that the "best case" HIG interpretation might be something like:

  1. By default, a Toga app doesn't have a menu bar.
  2. We add a Header Bar with Gnome Primary Menu to the Toga GTK app, which includes all the "mandatory" menu items needed by every app - things like About, Help, and Quit.
  3. We map the Toga "app" menu to the Gnome Primary menu, so users can add items to this menu if they want.
  4. We map toolbar items to the header bar as you've done in your demo video
  5. If the user defines any menu items in any other group, we add a menu bar.

Step 5 is the only part that is obviously violating the HIG; but by making it something we only introduce when user commands are actually defined, we are as compliant as we can be within the practical limitations of the HIG itself. Your default "hello world" app will be HIG compliant; and it's only "complex" apps that won't be.

Does that make sense to you?

freakboy3742 commented 1 year ago

Responding to your post directly:

@freakboy3742 I hard-coded a mock up for Tutorial 2, i.e. write the code in the gtk-backend, to provide a quick response and save my time. The video is here:

Thanks for producing that - it's very helpful.

  1. As I understand, the HIG deal with HeaderBar as a Slide that its content changes depending on the information displayed on the main window. I.e. when we edit text we will find commands that only relates to text editing and the main HeaderBar (that contains the Primary menu) will give us a navigation to this commands and disappear until we finish the edit.

Can you provide an example of a "real" app that does this? You've clearly been able to get this to work, but... really? This is considered good UX design?! (That's not a slight on you by the way. This demo is great as a talking point - there's no world in which I would have guessed that sort of UX interaction was intended behavior. I'm just amazed that GTK provides an API that allows that sort of interaction and considers it preferable to a "normal" menu).

It also seems incomplete as a mapping of Tutorial 2. Tutorial 2 has 4 toolbar buttons, but it also has a "Things" submenu that has action 0, 1 and 2, plus a "Commands" menu with actions 4 and 3; and then the submenu that has 5 and 6. This header bar mockup only contains the submenu with 5 and 6. Where would "Things" and "Commands" fit into this mock up? And if "Things" and "Commands" fit where "Sub Menu" is now - is there a second level of nesting needed to place "Sub Menu"?

  1. As I understand, the HIG refers to any menu that is not include the app items (Preferences, Keyboard Shortcuts, Help and About application-name) as Secondary Menu.
  2. As I understand, we will always have one Primary menu and one Secondary menu.
  3. We will not have Primary menu and Secondary menu at same time on the same HeaderBar.

Sure - but that's more a consequence of the "slide" approach, right? You're only looking at one part of the

  1. None app menus/items could be placed at Primary menu.

I'm not sure what you mean by this - what is a "None" app menu/item?

  1. My intention by view argument was for implementation considerations, to refer to which HeaderBar we at.

Sure - but we can't expose a very GTK specific implementation concern to the public API for Toga's commands, unless we can find a meaningful abstraction for what "View" actually means. For example, Command allows for an icon. macOS won't ever use the icon for a menu item, but platforms that use icons will have one available. The idea of "this is a graphical representation for the command" is fairly abstract, and not tied to any specific implementation. What is the analogous interpretation of "view"?

  1. The Secondary menu have (more-options-symbolic) icon and you can add CheckBoxButtons/RadioButtons to it to add some control on the window content also you may do not need to use it.

Good to know that this is an option; but we don't have an API in Toga for this right now.

  1. In the Tutorial we can add Secondary menu in the HeaderBar that appear when we click on the Sub menu command on the top-right corner.
  2. In real application this Sub menu will be for example Edit Text.

As above - I don't think this mapping is correct. SubMenu is a sub menu of a different top level menu. "Command" and "Things" are the top level menus that would appear in the primary menu.

  1. As I understand, the HIG emphasis on the design of the application. What I noticed while reading through the HIG is encouraging designers to be careful in choosing places for commands and submenu and are it is important or it just same command in other place. Take a look at screenshots of this carefully designed app, as I think.

Thanks for that reference. I'm at a slight disadvantage at the moment because I'm at PyCon US and I don't have access to my Linux testing machine, so I can't play with the app myself.

But - based on the screenshots, I genuinely don't know where to start.

  1. The screenshots all show an open project, If I wanted to open a new project, where would I go? What is the analog of the "File / Open" menu?
  2. If I wanted to search and replace text - where's the menu option for that?
  3. If I want to build my project - How do I do that?
  4. If I want to clear all the built artefacts, How do I do that?
  1. As I understand, HeaderBar with alots of items is a bad design of an app. So use multiple HeaderBars each one relate to some functionalities, as example illustrate.
  2. When you use a photo editing application, you are looking for how to do something with an image by this application. It is better for the application to direct you to the command quickly than show you what it can do by interrupts you by its menus.

I don't understand how this is even remotely plausible. If I have an image open in Photoshop, the "currently loaded image" has dozens of things that can be done to it. If I select a single element of that image, there are dozens of things I could do that element.

There's a reason Photoshop has rich and deep menus - there's a lot of functionality. Where does that complexity go? The same goes for an IDE. VS Code has Selection, View, Code, Run, Terminal. Each of these menus contains ~10 items, each of which are entirely valid things to do with a project or file at any given time - on top of the "basics" like File, Edit Window and Help which enable you to do basic file, editing, and window control. Even the help menu has 10 different options - because being able to get contextual assistance is important. You can't just sweep this complexity under the rug.

freakboy3742 commented 1 year ago

Another data point about the Gnome HIG and menus: https://fosstodon.org/@doctormo/110243900212689945

freakboy3742 commented 1 year ago

Speaking with @pauloxnet, got a few more data points:

  1. Gnome Text editor was suggested as a good example of a modern compliant app with some complexity
  2. Primary menu has key file commands, maybe some key edit commands, print, preferences, keyboard shortcuts, help, and about.
  3. Quit isn't in the primary menu; Application menu has quit; close window widget is the main "quit" option.
  4. Application menu also has generic application commands (e.g. new window)
  5. App usage of header bar actions should be highly adaptive to window size; on a narrow screen, toolbar icons will often migrate to the bottom of the screen.
  6. The primary menu has a Keyboard Shortcuts option that provides a "cheat sheet" of all keyboard actions.

The suggestion Paulo gave for the mapping was that instead of introducing a menubar for "extra" menus, we could use a toolbar button with a popdown, similar to the "open" option on the top left here:

The contents of the popdown will be a "menu" in the traditional sense.

He also suggested looking into libhandy as a collection of tools for building GNOME HIG compliant apps that are able to adapt to mobile device sizes. It has GI bindings, so we should be able to use it.

MuhammadMuradG commented 1 year ago

Thanks for that amazing information. Also, thanks for @pauloxnet and @KyleRConway for their help.

First of all, sorry for this late response. I was at a slight disadvantage in the last week because I was participating in a volunteering activity in which I have a limited internet connection.

  1. As I understand, the HIG deal with HeaderBar as a Slide that its content changes depending on the information displayed on the main window. I.e. when we edit text we will find commands that only relates to text editing and the main HeaderBar (that contains the Primary menu) will give us a navigation to this commands and disappear until we finish the edit.

Can you provide an example of a "real" app that does this? You've clearly been able to get this to work, but... really? This is considered good UX design?! (That's not a slight on you by the way. This demo is great as a talking point - there's no world in which I would have guessed that sort of UX interaction was intended behavior. I'm just amazed that GTK provides an API that allows that sort of interaction and considers it preferable to a "normal" menu).

I can't say that I am expert UX designer, if you think it is a bad design then I will tend to say that also :smile:. Maybe I was too strict in describing it as a Slide, after some search, I think they don't treat it always as a Slide but whenever this describing fit their needs. So do you think is this description suitable in some circumstances and in other point-of-views in designs? See screenshots of these applications: 1st and 2nd screenshots of this, this and this as examples.

It also seems incomplete as a mapping of Tutorial 2. Tutorial 2 has 4 toolbar buttons, but it also has a "Things" submenu that has action 0, 1 and 2, plus a "Commands" menu with actions 4 and 3; and then the submenu that has 5 and 6. This header bar mockup only contains the submenu with 5 and 6. Where would "Things" and "Commands" fit into this mock up? And if "Things" and "Commands" fit where "Sub Menu" is now - is there a second level of nesting needed to place "Sub Menu"?

My intention was not to produce a complete mapping of Tutorial 2, sorry for missing clarifying this in my comment, my intention was putting the main elements of Tutorial 2 in their positions in the new design. To be honest I was lazy and not sure, sorry for that of course, to put Things and Commands in their appropriate place and instead I placed Sub menu of one of them directly to the Primary menu to draw your attention to the possibility of adding these menus, i.e. Things and Commands, to the Primary menu. Also I was implicitly intended to suggest adding a separator with menu name, like "Things--------------", that contains its sub-menus/items. After your clarifications in your comments, I conclude the last suggestion was a poor especially when we have a lot of elements in the menu.

  1. As I understand, the HIG refers to any menu that is not include the app items (Preferences, Keyboard Shortcuts, Help and About application-name) as Secondary Menu.
  2. As I understand, we will always have one Primary menu and one Secondary menu.
  3. We will not have Primary menu and Secondary menu at same time on the same HeaderBar.

Sure - but that's more a consequence of the "slide" approach, right? You're only looking at one part of the

Yes, this is when we follow the "Slide" approach.

  1. None app menus/items could be placed at Primary menu.

I'm not sure what you mean by this - what is a "None" app menu/item?

Sorry, this is a typo. The correct one is:

5. None app menu items could be placed at Secondary menu.

What I mean by app menu items is the items, like preferences, about and etc, that placed in the Primary menu.

My intention by view argument was for implementation considerations, to refer to which HeaderBar we at.

Sure - but we can't expose a very GTK specific implementation concern to the public API for Toga's commands, unless we can find a meaningful abstraction for what "View" actually means. For example, Command allows for an icon. macOS won't ever use the icon for a menu item, but platforms that use icons will have one available. The idea of "this is a graphical representation for the command" is fairly abstract, and not tied to any specific implementation. What is the analogous interpretation of "view"?

Hmm, well after some thinking, we already have parent argument that maybe used instead of introducing new argument view.

The Secondary menu have (more-options-symbolic) icon and you can add CheckBoxButtons/RadioButtons to it to add some control on the window content also you may do not need to use it.

Good to know that this is an option; but we don't have an API in Toga for this right now.

Yep, we had a talk about this in #1103 and it is in my To-do list.

  1. In the Tutorial we can add Secondary menu in the HeaderBar that appear when we click on the Sub menu command on the top-right corner.
  2. In real application this Sub menu will be for example Edit Text.

As above - I don't think this mapping is correct. SubMenu is a sub menu of a different top level menu. "Command" and "Things" are the top level menus that would appear in the primary menu.

""Command" and "Things" are the top level menus that would appear in the primary menu." Yes, this is what I think and what I was intended to clarify by the demo. Some gnome apps actually do that, for example Gnome Text Editor is using this. look at following screen record. We can also use what @pauloxnet suggest.

https://user-images.githubusercontent.com/50509521/236350740-08495c74-9ea3-4a46-895d-68497f1a1e8b.mp4

  1. As I understand, the HIG emphasis on the design of the application. What I noticed while reading through the HIG is encouraging designers to be careful in choosing places for commands and submenu and are it is important or it just same command in other place. Take a look at screenshots of this carefully designed app, as I think.

Thanks for that reference. I'm at a slight disadvantage at the moment because I'm at PyCon US and I don't have access to my Linux testing machine, so I can't play with the app myself.

But - based on the screenshots, I genuinely don't know where to start.

  1. The screenshots all show an open project, If I wanted to open a new project, where would I go? What is the analog of the "File / Open" menu?
  2. If I wanted to search and replace text - where's the menu option for that?
  3. If I want to build my project - How do I do that?
  4. If I want to clear all the built artifacts, How do I do that?

The following maybe help:

https://user-images.githubusercontent.com/50509521/236349990-b311cb82-22a8-4dbd-a5d4-05cc48769dd2.mp4

  1. As I understand, HeaderBar with a lots of items is a bad design of an app. So use multiple HeaderBars each one relate to some functionalities, as example illustrate.
  2. When you use a photo editing application, you are looking for how to do something with an image by this application. It is better for the application to direct you to the command quickly than show you what it can do by interrupts you by its menus.

I don't understand how this is even remotely plausible. If I have an image open in Photoshop, the "currently loaded image" has dozens of things that can be done to it. If I select a single element of that image, there are dozens of things I could do that element.

There's a reason Photoshop has rich and deep menus - there's a lot of functionality. Where does that complexity go? The same goes for an IDE. VS Code has Selection, View, Code, Run, Terminal. Each of these menus contains ~10 items, each of which are entirely valid things to do with a project or file at any given time - on top of the "basics" like File, Edit Window and Help which enable you to do basic file, editing, and window control. Even the help menu has 10 different options - because being able to get contextual assistance is important. You can't just sweep this complexity under the rug.

Directing the user to a command is not opposite to introducing a lot of functionality or rich menus; it is just about how the things will be organized, where will be putted and, the new one, when will appear. Always, we will do one thing in a given time, so, if there is a possibility that some elements will not be useful in current view, then hiding them will be a good thing. For example, in first screen record when we click on the "View" sub menu the other elements of "Primary menu" disappear until you click on back button, this disappearing give you the ability to focus on the current available options after you decided choosing "View" sub menu, instead of a nested stacked sub menus, shown below. Another example in screenshots of this.

nested menus

In fact, MacOs and Windows have similar to this by deactivating these commands. In Gnome, as I understand, they have chosen to make these commands disappear.

MuhammadMuradG commented 1 year ago

Now, what do you think about the suitable place to add user defined menus:

  1. In the Primary menu?
  2. As @pauloxnet suggest, button in the HeaderBar with a popdown?
  3. Let the user to choose between the two options?
freakboy3742 commented 1 year ago

I can't say that I am expert UX designer, if you think it is a bad design then I will tend to say that also 😄. Maybe I was too strict in describing it as a Slide, after some search, I think they don't treat it always as a Slide but whenever this describing fit their needs. So do you think is this description suitable in some circumstances and in other point-of-views in designs? See screenshots of these applications: 1st and 2nd screenshots of this, this and this as examples.

So - my impression from those examples is that the Slide is serving a different purpose entirely - It's not a "menu navigation" analog, but a contextual switch for the entire application. I'm not convinced it's a good match for what we need here. It seems a much closer match for a top-level navigation widget, rather than a layer of the menuing system.

Directing the user to a command is not opposite to introducing a lot of functionality or rich menus; it is just about how the things will be organized, where will be putted and, the new one, when will appear. Always, we will do one thing in a given time, so, if there is a possibility that some elements will not be useful in current view, then hiding them will be a good thing.

I disagree philosophically - I'd argue that having menu items visible (but disabled) at all time is a key feature of discoverability. Being able to see that "Do X" is a feature in a menu leads to the question "what do I need to activate/select to be able to perform that function". That opportunity doesn't exist if the menu item is invisible until some magical context is activated.

However, I also acknowledge that GTK/Gnome doesn't seem to agree with this analysis. The aim of Toga is to produce UIs that adhere to local UX conventions, regardless of whether I (or anyone else) agrees with them.

The problem that then emerges is that actual GTK developers don't seem to agree either - see comments like this one on Mastodon from an Inkscape maintainer. That leaves a framework like Toga (which is trying to abstract the behavior) in an awkward position.

freakboy3742 commented 1 year ago

Now, what do you think about the suitable place to add user defined menus:

  1. In the Primary menu?
  2. As @pauloxnet suggest, button in the HeaderBar with a popdown?
  3. Let the user to choose between the two options?

IMHO (2) is probably the best we're going to be able to do. The mapping is obvious and relatively straightforward once the "default" app/primary menu items are sorted out. All abstractions are leaky; all we can aim for is an abstraction that is vaguely watertight. :-)

I don't think we want to get into providing user-switchable options, if only because it will make the implementation needlessly complex.

MuhammadMuradG commented 1 year ago

I created a PR #1931 for addressing implementing what we had discussed, please take a quick look on its description if it is possible.