Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: rewrite #18

Merged
merged 49 commits into from
Nov 23, 2022
Merged

refactor: rewrite #18

merged 49 commits into from
Nov 23, 2022

Conversation

amrbashir
Copy link
Member

@amrbashir amrbashir commented Oct 6, 2022

This rewrite main goal is to allow modifying the predefined (native) menu items and allow creating the menu item separately from a menu.

  • gtk
  • Windows
  • macOS
  • Error handling
  • Documentation
  • show_context_menu_for_ns_view should take an x and y.

@PerBothner
Copy link

As requested here some niceties of jsMenus and other wishlist items. Note I haven't really looked at Muda or Wry's menu-creating API - currently DomTerm can use the Electron or Qt menus or jsMenus.

  • A way to express multi-key shortcuts. These are common in Emacs. They are also used in the Atom editor - check out the View->Panes submenu. Notice that multi-key shortcuts appear in the menu-item in square brackets as part of the label text like Split Left [Ctrl+K Left], while single-key shortcuts appear right-aligned without the square brackets. This is presumably due to Electron limitations. Note I'm not asking for the menu API to be able to process multikey shortcuts - only that they can be displayed in a non-ugly manner.
  • In DomTerm when using a custom titlebar, the menubar is included in the titlebar (except on macOS with the Electron or Qt front-ends), which saves space. This isn't supported by most toolkits, though it could be simulated with a row of buttons that bring up a popup (context) menu.
  • A nice API to modify menus or generate them on the fly (such as a list of sub-windows). (Electron doesn't seem to have this, except by re-creating the menu(s) from scratch: You can modify or add menuitems, but there doesn't seem to be a way to replace or delete them.)
  • The Electron Menu.buildFromTemplate is nice as it allows me to build the menu in the "renderer" process and send it to the main process by ipc.
  • Potentially it would be nice to include rich text in menu labels, based on HTML or a subset thereof. (jsMenus doesn't currently implement that, but it would be easy to add, as it's all implemented by HTML elements and JavaScript.)

@amrbashir
Copy link
Member Author

  • A way to express multi-key shortcuts. These are common in Emacs. They are also used in the Atom editor - check out the View->Panes submenu. Notice that multi-key shortcuts appear in the menu-item in square brackets as part of the label text like Split Left [Ctrl+K Left], while single-key shortcuts appear right-aligned without the square brackets. This is presumably due to Electron limitations. Note I'm not asking for the menu API to be able to process multikey shortcuts - only that they can be displayed in a non-ugly manner.

I maybe able to do that but I won't include it in this PR

  • In DomTerm when using a custom titlebar, the menubar is included in the titlebar (except on macOS with the Electron or Qt front-ends), which saves space. This isn't supported by most toolkits, though it could be simulated with a row of buttons that bring up a popup (context) menu.

Not sure if I understand this correctly, do you want to display a native menubar when the native titlebar is hiddden?

  • A nice API to modify menus or generate them on the fly (such as a list of sub-windows). (Electron doesn't seem to have this, except by re-creating the menu(s) from scratch: You can modify or add menuitems, but there doesn't seem to be a way to replace or delete them.)

This PR implements all necessary menu modification APIs, append, prepend, insert, append_items, prepend_items, insert_items and remove

  • The Electron Menu.buildFromTemplate is nice as it allows me to build the menu in the "renderer" process and send it to the main process by ipc.

This is out of Tao/Wry/Muda scope, but it is possible that Tauri will provide a JS api for it in the future.

  • Potentially it would be nice to include rich text in menu labels, based on HTML or a subset thereof. (jsMenus doesn't currently implement that, but it would be easy to add, as it's all implemented by HTML elements and JavaScript.)

This is not possible unfortunately, as these are native menus and rendering is done by the OS.

@PerBothner
Copy link

"Not sure if I understand this correctly, do you want to display a native menubar when the native titlebar is hiddden?"

I'd like the ability to embed the menubar into a custom titlebar, as shown below. When space is tight (or depending on user/application preference) the menubar may be replaced by a hamburger menu.

Screenshot from 2022-10-12 11-48-29

@amrbashir
Copy link
Member Author

I don't think that is possible, because the custom titlebar would be in the webview while the menu is in the native window.

For this situation you will have to fallback to a menu implementation in HTML/JS, similar to how VSCode has a native menu when using native title bar and a custom HTML/JS menu when using custom title bar.

@PerBothner
Copy link

"This is not possible unfortunately, as these are native menus and rendering is done by the OS."

I understand - though it is tempting to stick to jsMenus as opposed to native menus. For the record, I see these as the advantages of native menus:

  • On macOS, use the system menubar. I think this is the main advantage of native windows, at least for DomTerm.
  • Menus can stick outside the window boundary - though that can be worked around by using a popup window.
  • Native menu styling - though I'm not sure there is a such a thing (except perhaps on macOS), since there are so many toolkits, that create very different-looking menus.
  • Avoid need for a webview.

@amrbashir
Copy link
Member Author

Js menus are definitely great and they are way more flexible than native ones but each has their tradeoffs that's why I think a combination of both is good.

@PerBothner
Copy link

"I don't think that is possible, because the custom titlebar would be in the webview while the menu is in the native window."

The custom titlebar could have a transparent notch allowing the native menubar to be visible. Or (at some point in the future) use something like the new experimental Windows Controls Overlay API.

"For this situation you will have to fallback to a menu implementation in HTML/JS, similar to how VSCode has a native menu when using native title bar and a custom HTML/JS menu when using custom title bar."

Yes, that is more or less what I do. There is also a hybrid option: custom buttons for the menubar itself, but when you click on one you get a native popup menu.

@amrbashir
Copy link
Member Author

amrbashir commented Oct 12, 2022

The custom titlebar could have a transparent notch allowing the native menubar to be visible. Or (at some point in the future) use something like the new experimental Windows Controls Overlay API.

With a notch in the custom titlebar or with Windows Controls Overlay API (which we haven't implemented yet). It still won't be possible, because both way means the webview starts from 0,0 in the Window and will be above the native menubar so you'd have to make that part transparent either way to show the menu behind it but you still need to a way pass the click to the window rather than the webview which could be tricky and might not be possible at all.

Also note that the Windows Controls Overlay API is just a custom titlebar that mimics the native functionality but is actually drawn manually by the APP using Windows GDI API or similar drawing API while the native menubar is drawn by the OS and if present will be occupy the space above the custom title bar of Windows Controls Overlay API

However the Windows Controls Overlay API might allow to define custom buttons in the titlebar so you could combine that with the hybrid solution you mentiond.

Yes, that is more or less what I do. There is also a hybrid option: custom buttons for the menubar itself, but when you click on one you get a native popup menu.

Yeah that is a viable option also.

@PerBothner
Copy link

"you still need to a way pass the click to the window rather than the webview"

That is why I fiddle with z-order when a menu (using jsMenus) is shown. Specifically, the "master" webview is brought to the front so it can get mouse and keyboard events.

@amrbashir
Copy link
Member Author

this workaround won't work with native menus on Windows at least, that's why I think a custom titlebar should be paired with a custom HTML/JS menu.

@PerBothner
Copy link

I agree for Windows or Linux. On macOS I think it makes sense to use the system menubar even if using a custom titlebar - and in tha case we don't have to worry about embedding the menubar into the titlebar

One advantage of an API like Electron's buildFromTemplate is one can use shared logic for building menus, and use it for both native menus and jsMenus. I currently do that for Electron menus. I hope to do something similar for both Qt and in the future Muda: A utility function to translate a template into a menu structure. Easier for me with Qt because I'm more fluent with C++ than Rust.

@amrbashir
Copy link
Member Author

amrbashir commented Oct 12, 2022

Sounds reasonable, and I already implemented template support using Menu::append_items in this PR. You'd just need a JS representation for it

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
amrbashir and others added 8 commits November 6, 2022 14:13
* partial macOS implementation

* fix context menu examples

* add accelerator support for macOS

* strip ampersands from titles on macOS

* add CMD_OR_CTRL shorthand for modifiers

* implement actions for predefined menu items on macos

* fix examples

* more predefined items

* implement insert for macos

* refactor macOS implementation

* menu state getters and setters on macOS

* implement remove for macOS

* code tweaks

* add show_context_menu_for_nsview for Submenu on macOS

* docs improvements

* allow adding item to the same menu multiple times on macOS

* implement `items` for macOS

* strip only single ampersands from menu titles

* add support for menu item actions on macOS

* add app name to macOS About, Hide, Quit menu items

* add methods to set app window and help menus on macOS

* fix clickable submenu titles on macOS

* refactor submenu for safe reuse on macOS

* fmt & clippy

* few cleanups

* fix docs

* clippy

* fix docs

* cleanup examples

* fix tests
@amrbashir amrbashir linked an issue Nov 11, 2022 that may be closed by this pull request
33 tasks
@amrbashir amrbashir merged commit 812ff0d into master Nov 23, 2022
@amrbashir amrbashir deleted the rewrite branch November 23, 2022 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tracking issue for missing functionality in muda
4 participants