From d74c8aba1aa4c0e9e271fe021d371a1026050e0b Mon Sep 17 00:00:00 2001 From: kramo Date: Wed, 10 Jul 2024 21:56:02 +0200 Subject: [PATCH] Use menu bar on macOS --- .github/workflows/ci.yml | 2 +- cartridges/main.py | 76 ++++++++++++++++++++++++++++++++++++++-- cartridges/window.py | 3 ++ 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99bf575..106ae92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,7 @@ jobs: - name: Install Dependencies run: | brew install meson pygobject3 libadwaita adwaita-icon-theme desktop-file-utils pyinstaller pillow - pip3 install --break-system-packages requests PyYAML + pip3 install --break-system-packages requests PyYAML pyobjc - name: Meson Build run: | diff --git a/cartridges/main.py b/cartridges/main.py index cc2f480..4d8096b 100644 --- a/cartridges/main.py +++ b/cartridges/main.py @@ -58,6 +58,71 @@ from cartridges.utils.run_executable import run_executable from cartridges.window import CartridgesWindow +if sys.platform == "darwin": + from AppKit import NSApp, NSApplication, NSMenu, NSMenuItem # type: ignore + + from Foundation import NSObject # type: ignore + from PyObjCTools import AppHelper + + class ApplicationDelegate(NSObject): # type: ignore + def applicationDidFinishLaunching_(self, *_args: Any) -> None: + main_menu = NSApp.mainMenu() + + show_hidden_menu_item = ( + NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( + "Show Hidden", "hidden:", "h" + ) + ) + + view_menu = NSMenu.alloc().init() + view_menu.addItem_(show_hidden_menu_item) + + view_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( + "View", None, "" + ) + view_menu_item.setSubmenu_(view_menu) + main_menu.addItem_(view_menu_item) + + windows_menu = NSMenu.alloc().init() + + windows_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( + "Window", None, "" + ) + windows_menu_item.setSubmenu_(windows_menu) + main_menu.addItem_(windows_menu_item) + + NSApp.setWindowsMenu_(windows_menu) + + keyboard_shortcuts_menu_item = ( + NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( + "Keyboard Shortcuts", "shortcuts:", "?" + ) + ) + + help_menu = NSMenu.alloc().init() + help_menu.addItem_(keyboard_shortcuts_menu_item) + + help_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_( + "Help", None, "" + ) + help_menu_item.setSubmenu_(help_menu) + main_menu.addItem_(help_menu_item) + + NSApp.setHelpMenu_(help_menu) + + def hidden_(self, *_args: Any) -> None: + if not shared.win: + return + + shared.win.on_show_hidden_action() + + def shortcuts_(self, *_args: Any) -> None: + if (not shared.win) or (not (overlay := shared.win.get_help_overlay())): + return + + overlay.present() + + class CartridgesApplication(Adw.Application): state = shared.AppState.DEFAULT win: CartridgesWindow @@ -87,8 +152,15 @@ class CartridgesApplication(Adw.Application): self.add_main_option_entries((search, launch)) - if sys.platform == "darwin" and (settings := Gtk.Settings.get_default()): - settings.props.gtk_decoration_layout = "close,minimize,maximize:" + if sys.platform == "darwin": + if settings := Gtk.Settings.get_default(): + settings.props.gtk_decoration_layout = "close,minimize,maximize:" + + def setup_app_delegate() -> None: + NSApp.setDelegate_(ApplicationDelegate.alloc().init()) # type: ignore + AppHelper.runEventLoop() # type: ignore + + GLib.Thread.new(None, setup_app_delegate) def do_activate(self) -> None: # pylint: disable=arguments-differ """Called on app creation""" diff --git a/cartridges/window.py b/cartridges/window.py index fc1070b..040dad5 100644 --- a/cartridges/window.py +++ b/cartridges/window.py @@ -450,6 +450,9 @@ class CartridgesWindow(Adw.ApplicationWindow): self.navigation_view.pop_to_page(self.library_page) def on_show_hidden_action(self, *_args: Any) -> None: + if self.navigation_view.get_visible_page() == self.hidden_library_page: + return + self.navigation_view.push(self.hidden_library_page) def on_sort_action(self, action: Gio.SimpleAction, state: GLib.Variant) -> None: