这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@ZIMkaRU
Copy link
Member

@ZIMkaRU ZIMkaRU commented Jan 15, 2025

This PR moves the electron app menu bar to the UI title instead of the electron one so that we can customize the electron menu, as the native electron menu API doesn't provide that. It allows us to build the menu in the UI in one small line with the main app title and typical window buttons (minimize, maximize, and close in the top corner). This is very useful as it saves overall space and at the same time constantly displays the menu and does not require the user to press the Alt key to display it (as practice has shown, because of the last one, many inexperienced users do not even know about the existence of menu functions)


It can be safely merged before the implementation of UI, since the default is still using the native menu (we have a special flag for quick switching after the implementation of UI)


The start example of how the menu should look can be taken from the VSCode view
Screenshot from 2025-01-15 10-55-28

The title should have:

  • on the left side the menu. On the Mac we have to hide the menu in the UI and show native electron menu bar due to some MacOS specifics, it's not possible to have proper menu item control from the UI
  • in the center the main title text
  • on the right the window control buttons (for Mac on the left side)
  • for Mac, hide the whole title in full-screen mode because Mac hides the window control buttons. For this purpose, there are implemented the corresponding listener to be used in the UI

For test and debug purposes a quite simple menu was implemented in the pure html/css and placed into the main index.html
To understand the common logic of implementation look at styles, html and script in this index.html file: https://github.com/ZIMkaRU/bfx-report-ui/blob/feature/add-test-electronjs-menu-to-html/public/index.html
The live beta release can be found here: https://github.com/ZIMkaRU/bfx-report-electron/releases/tag/v4.32.0-beta.10

Debug layout examples:

  • Ununtu:
    • non-maximized window mode:
      1
    • maximized window mode:
      2
  • Windows:
    • non-maximized window mode:
      1
    • maximized window mode:
      2
  • Mac:window.bfxReportElectronApi.setLanguage('en')
    • non-maximized window mode:
      1
    • full-screen mode:
      2
    • native menu and title of the full-screen mode:
      3

Pay attention window control buttons are set over the main window by electronjs and it's not UI implementation. What we can do is enter colors and height for these buttons via the electornjs API. To understand how it works look at this official article https://www.electronjs.org/docs/latest/tutorial/custom-title-bar


API for UI which is provided via context bridge to chromium window object:

// Returns menu data structure to render the menu
window.bfxReportElectronApi.getMenuTemplate()

// Execute menu command using menu item id taken from returned data of getMenuTemplate() method
window.bfxReportElectronApi.execMenuCmd({ id: 'MENU_ITEM_ID_TAKEN_FROM_MENU_DATA_STRUCTURE' })

// Getter for the main menu title which is set in the app
window.bfxReportElectronApi.getTitle()

// Method for adding of a listener to provide state whether the whole menu bar be hidden. The listener returns `args.state`, true if needs to hide the menu bar
window.bfxReportElectronApi.onHideMenuEvent(({ state }) => {})

The method window.bfxReportElectronApi.getMenuTemplate() returns the following data structure on Ubuntu:

{
  "shouldMenuBeHidden": false,
  "menuTemplate": [
    {
      "label": "File",
      "type": "submenu",
      "accelerator": null,
      "enabled": true,
      "visible": true,
      "checked": false,
      "submenu": [
        {
          "label": "Quit",
          "id": "QUIT_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+Q",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        }
      ]
    },
    {
      "label": "Edit",
      "type": "submenu",
      "accelerator": null,
      "enabled": true,
      "visible": true,
      "checked": false,
      "submenu": [
        {
          "label": "Undo",
          "id": "UNDO_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+Z",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Redo",
          "id": "REDO_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+Shift+Z",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Cut",
          "id": "CUT_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+X",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Copy",
          "id": "COPY_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+C",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Paste",
          "id": "PASTE_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+V",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Delete",
          "id": "DELETE_MENU_ITEM",
          "type": "normal",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Select All",
          "id": "SELECT_ALL_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+A",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        }
      ]
    },
    {
      "label": "View",
      "type": "submenu",
      "accelerator": null,
      "enabled": true,
      "visible": true,
      "checked": false,
      "submenu": [
        {
          "label": "Reload",
          "id": "RELOAD_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+R",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Force Reload",
          "id": "FORCE_RELOAD_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+Shift+R",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Toggle Developer Tools",
          "id": "TOGGLE_DEV_TOOLS_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+Shift+I",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Actual Size",
          "id": "RESET_ZOOM_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+0",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Zoom In",
          "id": "ZOOM_IN_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl++",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Zoom Out",
          "id": "ZOOM_OUT_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+-",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Toggle Full Screen",
          "id": "TOGGLE_FULL_SCREEN_MENU_ITEM",
          "type": "normal",
          "accelerator": "F11",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        }
      ]
    },
    {
      "label": "Window",
      "type": "submenu",
      "accelerator": null,
      "enabled": true,
      "visible": true,
      "checked": false,
      "submenu": [
        {
          "label": "Minimize",
          "id": "MINIMIZE_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+M",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Zoom",
          "id": "ZOOM_MENU_ITEM",
          "type": "normal",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Close",
          "id": "CLOSE_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+W",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        }
      ]
    },
    {
      "label": "Tools",
      "type": "submenu",
      "accelerator": null,
      "enabled": true,
      "visible": true,
      "checked": false,
      "submenu": [
        {
          "label": "Data Management",
          "type": "submenu",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": [
            {
              "label": "Export DB",
              "id": "EXPORT_DB_MENU_ITEM",
              "type": "normal",
              "accelerator": "Ctrl+Alt+E",
              "enabled": true,
              "visible": true,
              "checked": false,
              "submenu": null
            },
            {
              "label": "Import DB",
              "id": "IMPORT_DB_MENU_ITEM",
              "type": "normal",
              "accelerator": "Ctrl+Alt+Shift+I",
              "enabled": true,
              "visible": true,
              "checked": false,
              "submenu": null
            },
            {
              "label": "Restore DB",
              "id": "RESTORE_DB_MENU_ITEM",
              "type": "normal",
              "accelerator": "Ctrl+Alt+R",
              "enabled": true,
              "visible": true,
              "checked": false,
              "submenu": null
            },
            {
              "label": "Backup DB",
              "id": "BACKUP_DB_MENU_ITEM",
              "type": "normal",
              "accelerator": "Ctrl+Alt+B",
              "enabled": true,
              "visible": true,
              "checked": false,
              "submenu": null
            },
            {
              "label": "Remove DB",
              "id": "REMOVE_DB_MENU_ITEM",
              "type": "normal",
              "accelerator": "Ctrl+Alt+D",
              "enabled": true,
              "visible": true,
              "checked": false,
              "submenu": null
            },
            {
              "label": "Clear All Data (except user creds)",
              "id": "CLEAR_ALL_DATA_MENU_ITEM",
              "type": "normal",
              "accelerator": "Ctrl+Alt+C",
              "enabled": true,
              "visible": true,
              "checked": false,
              "submenu": null
            }
          ]
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Change Reports Folder",
          "id": "CHANGE_REPORTS_FOLDER_MENU_ITEM",
          "type": "normal",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Change Sync Frequency",
          "id": "CHANGE_SYNC_FREQUENCY_MENU_ITEM",
          "type": "normal",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        }
      ]
    },
    {
      "label": "Help",
      "type": "submenu",
      "accelerator": null,
      "enabled": true,
      "visible": true,
      "checked": false,
      "submenu": [
        {
          "label": "Open new GitHub Issue",
          "id": "REPORT_BUG_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+B",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Check for Updates",
          "id": "CHECK_UPDATE_MENU_ITEM",
          "type": "normal",
          "accelerator": null,
          "enabled": false,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Quit and Install updates",
          "id": "INSTALL_UPDATE_MENU_ITEM",
          "type": "normal",
          "accelerator": null,
          "enabled": true,
          "visible": false,
          "checked": false,
          "submenu": null
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "User Manual",
          "id": "USER_MANUAL_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+H",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "Changelog",
          "id": "SHOW_CHANGE_LOG_MENU_ITEM",
          "type": "normal",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "",
          "type": "separator",
          "accelerator": null,
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        },
        {
          "label": "About Bitfinex Report",
          "id": "ABOUT_MENU_ITEM",
          "type": "normal",
          "accelerator": "Ctrl+O",
          "enabled": true,
          "visible": true,
          "checked": false,
          "submenu": null
        }
      ]
    }
  ]
}

Pay Attention response has shouldMenuBeHidden flag. It's initial state for the menu, should the menu bar be hidden

Also, electronjs provides titlebar-area-height env var to css for getting menu bar height. The example of usage can be found in the above index.html file. CSS should look like this:

:root {
  --fallback-title-bar-height: 40px;
}

#electronMenu {
  min-height: env(titlebar-area-height, var(--fallback-title-bar-height));
}

Get more info here:


Also, this PR updates electron version up to 33.3.1 and makes related changes to be able to add native window controls new BrowserWindow({ titleBarStyle: 'hidden' })
https://www.electronjs.org/docs/latest/tutorial/custom-title-bar


Depends on this PR:

ezewer and others added 30 commits November 13, 2024 16:51
Copy link
Contributor

@ezewer ezewer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

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.

2 participants