From b377199119e339921b1b995638809b5ee1ce1f48 Mon Sep 17 00:00:00 2001 From: Sayak Mukhopadhyay Date: Mon, 26 Apr 2021 15:36:43 +0530 Subject: [PATCH] Changed logic to handle minimize too system tray --- EDMarketConnector.py | 68 +++++++++++++++----------------------------- L10n/en.template | 2 +- prefs.py | 8 +++--- 3 files changed, 28 insertions(+), 50 deletions(-) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 2ea6f372..6d90e03f 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -9,6 +9,7 @@ import locale import pathlib import re import sys +import threading import webbrowser from builtins import object, str from os import chdir, environ @@ -331,28 +332,15 @@ class AppWindow(object): self.prefsdialog = None if platform == 'win32': - import threading from infi.systray import SysTrayIcon - self.only_tray_close = 0 # This is kind of a hack. - # When the tray icon is double click to reopen the EDMC window, I want the tray icon to disappear. To do - # that I have to call the `shutdown()` method of the systray object. Calling the shutdown method triggers - # the method associated with `on_quit` twice, once for WM_DESTROY and again for WM_CLOSE. This is not the - # case when the application is exited by clicking on `Quit` in the tray menu. So, to handle this, we are - # creating this class variable and setting it to 2 when `Open` is called from the tray menu (either by - # clicking open or by double clicking the icon) and decrementing it by 1 when the tray shutdown is triggered - def open_window(systray) -> None: - self.only_tray_close = 2 - # Shutdown needs to happen in a separate thread to prevent joining with itself - shutdown_thread = threading.Thread(target=systray.shutdown) - shutdown_thread.setDaemon(True) - shutdown_thread.start() self.w.deiconify() menu_options = (("Open", None, open_window),) # Method associated with on_quit is called whenever the systray is closing self.systray = SysTrayIcon("EDMarketConnector.ico", applongname, menu_options, on_quit=self.exit_tray) + self.systray.start() plug.load_plugins(master) @@ -1395,35 +1383,20 @@ class AppWindow(object): logger.debug('"other" exception', exc_info=e) self.status['text'] = str(e) - def onexit(self, event=None) -> None: - """Application shutdown procedure.""" - if platform == 'win32': - value = bool(config.get_int('close_system_tray')) - # When exit is called, either exit application or minimize to system tray - if value: - self.w.withdraw() - self.systray.start() - - else: - self.exit() - - else: - self.exit() - def exit_tray(self, systray) -> None: """Tray icon is shutting down.""" - import threading - # Hack to see if the tray shutdown has been called by calling quit or calling shutdown - if self.only_tray_close > 0: - self.only_tray_close -= 1 + exit_thread = threading.Thread(target=self.onexit) + exit_thread.setDaemon(True) + exit_thread.start() - else: - exit_thread = threading.Thread(target=self.exit) - exit_thread.setDaemon(True) - exit_thread.start() + def onexit(self, event=None) -> None: + """Application shutdown procedure.""" + value = config.get_bool('minimize_system_tray') + if platform == 'win32' and value is not None and value: + shutdown_thread = threading.Thread(target=self.systray.shutdown) + shutdown_thread.setDaemon(True) + shutdown_thread.start() - def exit(self) -> None: - """Actual application shutdown.""" config.set_shutdown() # Signal we're in shutdown now. # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 @@ -1490,12 +1463,17 @@ class AppWindow(object): self.drag_offset = (None, None) def oniconify(self, event=None) -> None: - """Handle iconification of the application.""" - self.w.overrideredirect(0) # Can't iconize while overrideredirect - self.w.iconify() - self.w.update_idletasks() # Size and windows styles get recalculated here - self.w.wait_visibility() # Need main window to be re-created before returning - theme.active = None # So theme will be re-applied on map + """Handle minimization of the application.""" + value = config.get_bool('minimize_system_tray') + if platform == 'win32' and value is not None and value: + self.w.withdraw() + + else: + self.w.overrideredirect(0) # Can't iconize while overrideredirect + self.w.iconify() + self.w.update_idletasks() # Size and windows styles get recalculated here + self.w.wait_visibility() # Need main window to be re-created before returning + theme.active = None # So theme will be re-applied on map # TODO: Confirm this is unused and remove. def onmap(self, event=None) -> None: diff --git a/L10n/en.template b/L10n/en.template index 3bb2865d..c7379ba7 100644 --- a/L10n/en.template +++ b/L10n/en.template @@ -20,7 +20,7 @@ "Always on top" = "Always on top"; /* Appearance setting. [EDMarketConnector.py] */ -"Close to system tray" = "Close to system tray"; +"Minimize to system tray" = "Minimize to system tray"; /* CQC rank. [stats.py] */ "Amateur" = "Amateur"; diff --git a/prefs.py b/prefs.py index 929ddc0c..119b727f 100644 --- a/prefs.py +++ b/prefs.py @@ -636,7 +636,7 @@ class PreferencesDialog(tk.Toplevel): # Appearance theme and language setting self.lang = tk.StringVar(value=self.languages.get(config.get_str('language'), _('Default'))) self.always_ontop = tk.BooleanVar(value=bool(config.get_int('always_ontop'))) - self.close_system_tray = tk.BooleanVar(value=config.get_bool('close_system_tray')) + self.minimize_system_tray = tk.BooleanVar(value=config.get_bool('minimize_system_tray')) self.theme = tk.IntVar(value=config.get_int('theme')) self.theme_colors = [config.get_str('dark_text'), config.get_str('dark_highlight')] self.theme_prompts = [ @@ -795,8 +795,8 @@ class PreferencesDialog(tk.Toplevel): if platform == 'win32': nb.Checkbutton( appearance_frame, - text=_('Close to system tray'), - variable=self.close_system_tray, + text=_('Minimize to system tray'), + variable=self.minimize_system_tray, command=self.themevarchanged ).grid(columnspan=3, padx=self.BUTTONX, sticky=tk.W, row=row.get()) # Appearance setting @@ -1172,7 +1172,7 @@ class PreferencesDialog(tk.Toplevel): config.set('ui_scale', self.ui_scale.get()) config.set('ui_transparency', self.transparency.get()) config.set('always_ontop', self.always_ontop.get()) - config.set('close_system_tray', self.close_system_tray.get()) + config.set('minimize_system_tray', self.minimize_system_tray.get()) config.set('theme', self.theme.get()) config.set('dark_text', self.theme_colors[0]) config.set('dark_highlight', self.theme_colors[1])