From 4d069cb40691cdeafe7a50945d76f4146c3bdc83 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Fri, 12 Nov 2021 13:17:27 +0000 Subject: [PATCH] Attempting to re-enable Windows "minimize to system tray" support 1. It's not actually hiding the task bar icon currently. 2. As this touched prefs.py I've done a flake8 and mypy cleanup pass too. But some of that will want reviewing later as I noqa'd some things. --- EDMarketConnector.py | 38 ++++++++++++++++----------------- prefs.py | 51 ++++++++++++++++++++++---------------------- requirements.txt | 2 +- setup.py | 1 - 4 files changed, 46 insertions(+), 46 deletions(-) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 24453a47..06fb5bc6 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -9,7 +9,7 @@ import pathlib import queue import re import sys -# import threading +import threading import webbrowser from builtins import object, str from os import chdir, environ @@ -371,7 +371,7 @@ if __name__ == '__main__': # noqa: C901 if TYPE_CHECKING: from logging import TRACE # type: ignore # noqa: F401 # Needed to update mypy import update - # from infi.systray import SysTrayIcon + from infi.systray import SysTrayIcon # isort: on def _(x: str) -> str: @@ -442,16 +442,16 @@ class AppWindow(object): self.prefsdialog = None - # if platform == 'win32': - # from infi.systray import SysTrayIcon + if platform == 'win32': + from infi.systray import SysTrayIcon - # def open_window(systray: 'SysTrayIcon') -> None: - # self.w.deiconify() + def open_window(systray: 'SysTrayIcon') -> None: + 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() + 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) @@ -1663,18 +1663,18 @@ class AppWindow(object): with open(f, 'wb') as h: h.write(str(companion.session.capi_raw_data).encode(encoding='utf-8')) - # def exit_tray(self, systray: 'SysTrayIcon') -> None: - # """Tray icon is shutting down.""" - # exit_thread = threading.Thread(target=self.onexit) - # exit_thread.setDaemon(True) - # exit_thread.start() + def exit_tray(self, systray: 'SysTrayIcon') -> None: + """Tray icon is shutting down.""" + exit_thread = threading.Thread(target=self.onexit) + exit_thread.setDaemon(True) + exit_thread.start() def onexit(self, event=None) -> None: """Application shutdown procedure.""" - # if platform == 'win32': - # shutdown_thread = threading.Thread(target=self.systray.shutdown) - # shutdown_thread.setDaemon(True) - # shutdown_thread.start() + if platform == 'win32': + shutdown_thread = threading.Thread(target=self.systray.shutdown) + shutdown_thread.setDaemon(True) + shutdown_thread.start() config.set_shutdown() # Signal we're in shutdown now. diff --git a/prefs.py b/prefs.py index c403023b..6e06f610 100644 --- a/prefs.py +++ b/prefs.py @@ -5,7 +5,7 @@ import contextlib import logging import tkinter as tk import webbrowser -from os.path import exists, expanduser, expandvars, join, normpath +from os.path import expanduser, expandvars, join, normpath from sys import platform from tkinter import colorchooser as tkColorChooser # type: ignore # noqa: N812 from tkinter import ttk @@ -60,17 +60,17 @@ class PrefsVersion: def __init__(self): return - def stringToSerial(self, versionStr: str) -> int: # noqa: N802 # used in plugins + def stringToSerial(self, version_str: str) -> int: # noqa: N802 # used in plugins """ Convert a version string into a preferences version serial number. If the version string isn't known returns the 'current' (latest) serial number. - :param versionStr: + :param version_str: :return int: """ - if versionStr in self.versions: - return self.versions[versionStr] + if version_str in self.versions: + return self.versions[version_str] return self.versions['current'] @@ -83,7 +83,6 @@ class PrefsVersion: :raises ValueError: on serial number after the current latest :return: bool indicating the answer """ - # config.get('PrefsVersion') is the version preferences we last saved for pv = config.get_int('PrefsVersion') # If no PrefsVersion yet exists then return oldTest @@ -202,6 +201,8 @@ elif platform == 'win32': BrowseCallbackProc = ctypes.WINFUNCTYPE(ctypes.c_int, HWND, ctypes.c_uint, LPARAM, LPARAM) class BROWSEINFO(ctypes.Structure): + """Windows file browser fields.""" + _fields_ = [("hwndOwner", HWND), ("pidlRoot", LPVOID), ("pszDisplayName", LPWSTR), ("lpszTitle", LPCWSTR), ("ulFlags", UINT), ("lpfn", BrowseCallbackProc), ("lParam", LPCWSTR), ("iImage", ctypes.c_int)] @@ -326,7 +327,7 @@ class PreferencesDialog(tk.Toplevel): GetWindowRect(GetParent(self.winfo_id()), position) if CalculatePopupWindowPosition( POINT(parent.winfo_rootx(), parent.winfo_rooty()), - SIZE(position.right - position.left, position.bottom - position.top), + SIZE(position.right - position.left, position.bottom - position.top), # type: ignore 0x10000, None, position ): self.geometry(f"+{position.left}+{position.top}") @@ -422,7 +423,7 @@ class PreferencesDialog(tk.Toplevel): if plugin_frame: notebook.add(plugin_frame, text=plugin.name) - def __setup_config_tab(self, notebook: Notebook) -> None: + def __setup_config_tab(self, notebook: Notebook) -> None: # noqa: CCR001 config_frame = nb.Frame(notebook) config_frame.columnconfigure(1, weight=1) row = AutoInc(start=1) @@ -700,7 +701,7 @@ class PreferencesDialog(tk.Toplevel): # LANG: The system default language choice in Settings > Appearance 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.minimize_system_tray = tk.BooleanVar(value=config.get_bool('minimize_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 = [ @@ -798,7 +799,7 @@ class PreferencesDialog(tk.Toplevel): self.ui_scale.set(config.get_int('ui_scale')) self.uiscale_bar = tk.Scale( appearance_frame, - variable=self.ui_scale, # TODO: intvar, but annotated as DoubleVar + variable=self.ui_scale, # type: ignore # TODO: intvar, but annotated as DoubleVar orient=tk.HORIZONTAL, length=300 * (float(theme.startup_ui_scale) / 100.0 * theme.default_ui_scale), # type: ignore # runtime from_=0, @@ -869,20 +870,20 @@ class PreferencesDialog(tk.Toplevel): ) self.ontop_button.grid(columnspan=3, padx=self.BUTTONX, sticky=tk.W, row=row.get()) # Appearance setting - # if platform == 'win32': - # nb.Checkbutton( - # appearance_frame, - # 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 + if platform == 'win32': + nb.Checkbutton( + appearance_frame, + 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 nb.Label(appearance_frame).grid(sticky=tk.W) # big spacer # LANG: Label for Settings > Appearance tab notebook.add(appearance_frame, text=_('Appearance')) # Tab heading in settings - def __setup_plugin_tab(self, notebook: Notebook) -> None: + def __setup_plugin_tab(self, notebook: Notebook) -> None: # noqa: CCR001 # Plugin settings and info plugins_frame = nb.Frame(notebook) plugins_frame.columnconfigure(0, weight=1) @@ -993,6 +994,7 @@ class PreferencesDialog(tk.Toplevel): self.cmdrchanged_alarm = self.after(1000, self.cmdrchanged) def tabchanged(self, event: tk.Event) -> None: + """Handle preferences active tab changing.""" self.outvarchanged() if platform == 'darwin': # Hack to recompute size so that buttons show up under Mojave @@ -1004,12 +1006,10 @@ class PreferencesDialog(tk.Toplevel): temp.destroy() def outvarchanged(self, event: Optional[tk.Event] = None) -> None: + """Handle Output tab variable changes.""" self.displaypath(self.outdir, self.outdir_entry) self.displaypath(self.logdir, self.logdir_entry) - logdir = self.logdir.get() - logvalid = exists(logdir) if logdir else False - self.out_label['state'] = tk.NORMAL self.out_csv_button['state'] = tk.NORMAL self.out_td_button['state'] = tk.NORMAL @@ -1029,13 +1029,13 @@ class PreferencesDialog(tk.Toplevel): from sys import platform as sys_platform directory = None if sys_platform == 'win32' and current_locale[1] not in ('utf8', 'UTF8', 'utf-8', 'UTF-8'): - def browsecallback(hwnd, uMsg, lParam, lpData): + def browsecallback(hwnd, uMsg, lParam, lpData): # noqa: N803 # Windows API convention # set initial folder if uMsg == BFFM_INITIALIZED and lpData: ctypes.windll.user32.SendMessageW(hwnd, BFFM_SETSELECTION, 1, lpData) return 0 - browseInfo = BROWSEINFO() + browseInfo = BROWSEINFO() # noqa: N806 # Windows convention browseInfo.lpszTitle = title browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI browseInfo.lpfn = BrowseCallbackProc(browsecallback) @@ -1079,7 +1079,7 @@ class PreferencesDialog(tk.Toplevel): display = [] components = normpath(pathvar.get()).split('\\') buf = ctypes.create_unicode_buffer(MAX_PATH) - pidsRes = ctypes.c_int() + pidsRes = ctypes.c_int() # noqa: N806 # Windows convention for i in range(start, len(components)): try: if (not SHGetLocalizedName('\\'.join(components[:i+1]), buf, MAX_PATH, ctypes.byref(pidsRes)) and @@ -1258,7 +1258,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('minimize_system_tray', self.minimize_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]) @@ -1283,6 +1283,7 @@ class PreferencesDialog(tk.Toplevel): if platform == 'darwin': def enableshortcuts(self) -> None: + """Set up macOS preferences shortcut.""" self.apply() # popup System Preferences dialog try: diff --git a/requirements.txt b/requirements.txt index 01e635c5..bcf9b57d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ certifi==2021.10.8 requests==2.26.0 watchdog==2.1.6 # Commented out because this doesn't package well with py2exe -# infi.systray==0.1.12; sys_platform == 'win32' +infi.systray==0.1.12; sys_platform == 'win32' # argh==0.26.2 watchdog dep # pyyaml==5.3.1 watchdog dep semantic-version==2.8.5 diff --git a/setup.py b/setup.py index 372b4477..183a7383 100755 --- a/setup.py +++ b/setup.py @@ -197,7 +197,6 @@ elif sys.platform == 'win32': '_markerlib', 'optparse', 'PIL', - 'pkg_resources', 'simplejson', 'unittest' ],