From 81be3f2cf993f3b19c5f6ac152c231d147dbcace Mon Sep 17 00:00:00 2001 From: June Tate-Gans Date: Sat, 8 May 2021 19:23:14 -0500 Subject: [PATCH] main: Migrate to the Application model We weren't registering with dbus or the session manager before, so migrating to Application as our base really really helps with duplicate launches. --- g13gui/g13gui/app.py | 60 ++++++++++++++++++++++++++++++++ g13gui/g13gui/main.py | 20 ++++------- g13gui/g13gui/ui/appindicator.py | 24 ++++++------- g13gui/g13gui/ui/mainwindow.py | 45 +++++++++++++----------- 4 files changed, 101 insertions(+), 48 deletions(-) create mode 100644 g13gui/g13gui/app.py diff --git a/g13gui/g13gui/app.py b/g13gui/g13gui/app.py new file mode 100644 index 0000000..46227f9 --- /dev/null +++ b/g13gui/g13gui/app.py @@ -0,0 +1,60 @@ +import signal + +from g13gui.model.prefsstore import PreferencesStore +from g13gui.g13.manager import DeviceManager +from g13gui.ui.appindicator import AppIndicator +from g13gui.ui.mainwindow import MainWindow + +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +gi.require_version('GLib', '2.0') +gi.require_version('GnomeDesktop', '3.0') + +from gi.repository import Gtk, GLib, Gio + + +class Application(Gtk.Application): + def __init__(self): + Gtk.Application.__init__( + self, + application_id='com.theonelab.g13.G13Configurator') + + GLib.set_application_name('G13 Configurator') + + self._prefs = None + self._indicator = None + self._dm = None + self._mainwindow = None + + def do_startup(self): + Gtk.Application.do_startup(self) + signal.signal(signal.SIGINT, signal.SIG_DFL) + + action = Gio.SimpleAction.new('quit') + action.connect('activate', lambda *x: self.quit()) + self.add_action(action) + self.add_accelerator('q', 'app.quit') + + def do_activate(self): + if not self._prefs: + self._prefs = PreferencesStore.getPrefs() + if not self._indicator: + self._indicator = AppIndicator(self, self._prefs) + if not self._dm: + self._dm = DeviceManager(self._prefs) + self._dm.start() + if not self._mainwindow: + self._mainwindow = MainWindow(self, self._prefs) + if self._prefs.showWindowOnStart: + self.showMainWindow() + + def showMainWindow(self): + self._mainwindow.present() + + def do_shutdown(self): + if self._mainwindow: + self._mainwindow.destroy() + if self._dm: + self._dm.shutdown() + Gtk.Application.do_shutdown(self) diff --git a/g13gui/g13gui/main.py b/g13gui/g13gui/main.py index de0ac7b..8e94181 100644 --- a/g13gui/g13gui/main.py +++ b/g13gui/g13gui/main.py @@ -1,22 +1,14 @@ #!/usr/bin/python -import gi +import sys -import g13gui.ui as ui -from g13gui.model.prefsstore import PreferencesStore -from g13gui.g13.manager import Manager +from dbus.mainloop.glib import DBusGMainLoop -gi.require_version('Gtk', '3.0') -from gi.repository import Gtk, Gdk, GObject +from g13gui.app import Application if __name__ == '__main__': - Gdk.threads_init() + DBusGMainLoop(set_as_default=True) - prefs = PreferencesStore.getPrefs() - manager = Manager(prefs) - manager.start() - - indicator = ui.AppIndicator(prefs) - - Gtk.main() + app = Application() + app.run(sys.argv) diff --git a/g13gui/g13gui/ui/appindicator.py b/g13gui/g13gui/ui/appindicator.py index e0dd10e..7839cc4 100644 --- a/g13gui/g13gui/ui/appindicator.py +++ b/g13gui/g13gui/ui/appindicator.py @@ -12,25 +12,24 @@ from gi.repository import AppIndicator3 as indicator class AppIndicator(GtkObserver): - def __init__(self, prefs): + def __init__(self, app, prefs): GtkObserver.__init__(self) + self._app = app + self._prefs = prefs + self._initIndicator() - self._prefs = prefs - self._mainWindow = None self._menu = Gtk.Menu() self._menuItems = [] self._indicator.set_menu(self._menu) + self._rebuilding = False self._prefs.registerObserver(self, {'selectedProfile'}) self.changeTrigger(self.onSelectedProfileChanged, keys={'selectedProfile'}) - if self._prefs.showWindowOnStart: - self.showMainWindow(None) - self._rebuildMenu() def _initIndicator(self): @@ -75,20 +74,17 @@ class AppIndicator(GtkObserver): self._attachMenuItem(sep) quitItem = Gtk.MenuItem('Quit') + quitItem.connect('activate', self.onQuit) self._attachMenuItem(quitItem) - quitItem.connect('activate', Gtk.main_quit) self._menu.show_all() self._rebuilding = False - def onMainWindowHidden(self, win): - del self._mainWindow - self._mainWindow = None - def showMainWindow(self, menuItem): - self._mainWindow = MainWindow(self._prefs) - self._mainWindow.connect('hide', self.onMainWindowHidden) - self._mainWindow.show_all() + self._app.showMainWindow() + + def onQuit(self, menuItem): + self._app.do_shutdown() def changeProfile(self, menuItem): self._prefs.setSelectedProfile(menuItem.get_label()) diff --git a/g13gui/g13gui/ui/mainwindow.py b/g13gui/g13gui/ui/mainwindow.py index c18998e..b304b05 100644 --- a/g13gui/g13gui/ui/mainwindow.py +++ b/g13gui/g13gui/ui/mainwindow.py @@ -1,29 +1,32 @@ -#!/usr/bin/python - -import gi import threading -import g13gui.ui as ui - +from g13gui.ui.profilecombobox import ProfileComboBox +from g13gui.ui.profilepopover import ProfilePopover +from g13gui.ui.profilepopover import ProfilePopoverMode +from g13gui.ui.g13button import G13Button from g13gui.observer.gtkobserver import GtkObserver from g13gui.model.prefsstore import PreferencesStore +import gi gi.require_version('Gtk', '3.0') gi.require_version('Gdk', '3.0') from gi.repository import Gtk, Gdk, GObject -class MainWindow(Gtk.Window, GtkObserver): - def __init__(self, prefs): - Gtk.Window.__init__(self) +class MainWindow(Gtk.ApplicationWindow, GtkObserver): + def __init__(self, app, prefs, **kwargs): + Gtk.ApplicationWindow.__init__( + self, + default_width=640, + default_height=480, + window_position=Gtk.WindowPosition.NONE, + name='g13configurator', + icon_name='g13configurator', + application=app, + **kwargs) GtkObserver.__init__(self) - self.set_default_size(640, 480) - geometry = Gdk.Geometry() - geometry.max_width = 640 - geometry.max_height = 480 - self.set_geometry_hints(None, geometry, Gdk.WindowHints.MAX_SIZE) - + self._app = app self._prefs = prefs self._prefs.registerObserver(self, 'selectedProfile') self._prefs.selectedProfile().registerObserver(self) @@ -46,6 +49,8 @@ class MainWindow(Gtk.Window, GtkObserver): self.setupG13ButtonGrid() + self.show_all() + def _updateProfileRegistration(self): self._lastProfileName.removeObserver(self) self._lastProfileName = self._prefs.selectedProfile() @@ -66,22 +71,22 @@ class MainWindow(Gtk.Window, GtkObserver): self._headerBar.set_title("G13 Configurator") self._headerBar.set_show_close_button(True) - self._profileComboBox = ui.ProfileComboBox(self._prefs) + self._profileComboBox = ProfileComboBox(self._prefs) self._headerBar.add(self._profileComboBox) addProfileButton = Gtk.MenuButton.new() addProfileButton.add(Gtk.Image.new_from_icon_name( "document-new-symbolic", 1)) - addProfilePopover = ui.ProfilePopover(self._prefs, - mode=ui.ProfilePopoverMode.ADD) + addProfilePopover = ProfilePopover(self._prefs, + mode=ProfilePopoverMode.ADD) addProfileButton.set_popover(addProfilePopover) self._headerBar.add(addProfileButton) editProfileButton = Gtk.MenuButton.new() editProfileButton.add( Gtk.Image.new_from_icon_name('document-edit-symbolic', 1)) - editProfilePopover = ui.ProfilePopover(self._prefs, - mode=ui.ProfilePopoverMode.EDIT) + editProfilePopover = ProfilePopover(self._prefs, + mode=ProfilePopoverMode.EDIT) editProfileButton.set_popover(editProfilePopover) self._headerBar.add(editProfileButton) @@ -146,6 +151,6 @@ class MainWindow(Gtk.Window, GtkObserver): return button def newG13Button(self, name): - button = ui.G13Button(self._prefs, name) + button = G13Button(self._prefs, name) self._g13Buttons[name] = button return button