From 15f69b8fa3de505b39e3e43dee3c7c3a3f72930b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 12 Jul 2019 13:43:48 +0530 Subject: [PATCH] Clean up usage of app uids on windows --- src/calibre/gui2/__init__.py | 31 +++++++++-------------------- src/calibre/gui2/main.py | 11 +++------- src/calibre/gui2/tweak_book/main.py | 12 +++-------- src/calibre/gui2/viewer/main.py | 9 ++------- 4 files changed, 17 insertions(+), 46 deletions(-) diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 4346657c3f..e656ca1386 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -812,7 +812,13 @@ class Application(QApplication): shutdown_signal_received = pyqtSignal() - def __init__(self, args, force_calibre_style=False, override_program_name=None, headless=False, color_prefs=gprefs): + def __init__(self, args, force_calibre_style=False, override_program_name=None, headless=False, color_prefs=gprefs, windows_app_uid=None): + if iswindows: + self.windows_app_uid = None + if windows_app_uid: + windows_app_uid = unicode_type(windows_app_uid) + if set_app_uid(windows_app_uid): + self.windows_app_uid = windows_app_uid self.file_event_hook = None if isfrozen and QT_VERSION <= 0x050700 and 'wayland' in os.environ.get('QT_QPA_PLATFORM', ''): os.environ['QT_QPA_PLATFORM'] = 'xcb' @@ -1343,25 +1349,6 @@ empty_model = QStringListModel(['']) empty_index = empty_model.index(0) -def get_app_uid(): - import ctypes - from ctypes import wintypes - lpBuffer = wintypes.LPWSTR() - try: - AppUserModelID = ctypes.windll.shell32.GetCurrentProcessExplicitAppUserModelID - except Exception: # Vista has no app uids - return - AppUserModelID.argtypes = [wintypes.LPWSTR] - AppUserModelID.restype = wintypes.HRESULT - try: - AppUserModelID(ctypes.cast(ctypes.byref(lpBuffer), wintypes.LPWSTR)) - except Exception: - return - appid = lpBuffer.value - ctypes.windll.ole32.CoTaskMemFree(lpBuffer) - return appid - - def set_app_uid(val): import ctypes from ctypes import wintypes @@ -1380,5 +1367,5 @@ def set_app_uid(val): def add_to_recent_docs(path): - app_id = get_app_uid() - plugins['winutil'][0].add_to_recent_docs(unicode_type(path), app_id) + app = QApplication.instance() + plugins['winutil'][0].add_to_recent_docs(unicode_type(path), app.windows_app_uid) diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index aeffaa283a..3d13ab7b34 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -20,7 +20,7 @@ from calibre.constants import ( ) from calibre.gui2 import ( Application, choose_dir, error_dialog, gprefs, initialize_file_icon_provider, - question_dialog, set_app_uid, setup_gui_option_parser + question_dialog, setup_gui_option_parser ) from calibre.gui2.main_window import option_parser as _option_parser from calibre.gui2.splash_screen import SplashScreen @@ -111,7 +111,8 @@ def init_qt(args): prefs.set('library_path', os.path.abspath(libpath)) prints('Using library at', prefs['library_path']) override = 'calibre-gui' if islinux else None - app = Application(args, override_program_name=override) + app = Application(args, override_program_name=override, windows_app_uid=MAIN_APP_UID) + app.file_event_hook = EventAccumulator() try: is_x11 = app.platformName() == 'xcb' @@ -519,12 +520,6 @@ def main(args=sys.argv): gui_debug = args[1] args = ['calibre'] - if iswindows: - # Ensure that all ebook editor instances are grouped together in the task - # bar. This prevents them from being grouped with viewer process when - # launched from within calibre, as both use calibre-parallel.exe - set_app_uid(MAIN_APP_UID) - try: app, opts, args = init_qt(args) except AbortInit: diff --git a/src/calibre/gui2/tweak_book/main.py b/src/calibre/gui2/tweak_book/main.py index 7a419e3a94..9accee3af3 100644 --- a/src/calibre/gui2/tweak_book/main.py +++ b/src/calibre/gui2/tweak_book/main.py @@ -9,9 +9,9 @@ import time from PyQt5.Qt import QIcon -from calibre.constants import EDITOR_APP_UID, islinux, iswindows +from calibre.constants import EDITOR_APP_UID, islinux from calibre.gui2 import ( - Application, decouple, set_app_uid, set_gui_prefs, setup_gui_option_parser + Application, decouple, set_gui_prefs, setup_gui_option_parser ) from calibre.ptempfile import reset_base_dir from calibre.utils.config import OptionParser @@ -53,12 +53,6 @@ def _run(args, notify=None): os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() - if iswindows: - # Ensure that all ebook editor instances are grouped together in the task - # bar. This prevents them from being grouped with viewer process when - # launched from within calibre, as both use calibre-parallel.exe - set_app_uid(EDITOR_APP_UID) - # The following two lines are needed to prevent circular imports causing # errors during initialization of plugins that use the polish container # infrastructure. @@ -70,7 +64,7 @@ def _run(args, notify=None): opts, args = parser.parse_args(args) decouple('edit-book-'), set_gui_prefs(tprefs) override = 'calibre-edit-book' if islinux else None - app = Application(args, override_program_name=override, color_prefs=tprefs) + app = Application(args, override_program_name=override, color_prefs=tprefs, windows_app_uid=EDITOR_APP_UID) app.file_event_hook = EventAccumulator() app.load_builtin_fonts() app.setWindowIcon(QIcon(I('tweak.png'))) diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 7d8b9bc6a5..f28e2d3d74 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -23,7 +23,7 @@ from calibre.customize.ui import available_input_formats from calibre.ebooks.oeb.iterator.book import EbookIterator from calibre.gui2 import ( Application, add_to_recent_docs, choose_files, error_dialog, info_dialog, - open_url, set_app_uid, setup_gui_option_parser + open_url, setup_gui_option_parser ) from calibre.gui2.viewer.toc import TOC from calibre.gui2.viewer.ui import Main as MainWindow @@ -1309,11 +1309,6 @@ def main(args=sys.argv): # Ensure viewer can continue to function if GUI is closed os.environ.pop('CALIBRE_WORKER_TEMP_DIR', None) reset_base_dir() - if iswindows: - # Ensure that all ebook editor instances are grouped together in the task - # bar. This prevents them from being grouped with viewer process when - # launched from within calibre, as both use calibre-parallel.exe - set_app_uid(VIEWER_APP_UID) parser = option_parser() opts, args = parser.parse_args(args) @@ -1326,7 +1321,7 @@ def main(args=sys.argv): listener = None override = 'calibre-ebook-viewer' if islinux else None acc = EventAccumulator() - app = Application(args, override_program_name=override, color_prefs=vprefs) + app = Application(args, override_program_name=override, color_prefs=vprefs, windows_app_uid=VIEWER_APP_UID) app.file_event_hook = acc app.load_builtin_fonts() app.setWindowIcon(QIcon(I('viewer.png')))