mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DBus export: Handle restarts of the registry services for the tray icon and window menus
This commit is contained in:
parent
63e446fe19
commit
0893f9bf8c
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import time, sys
|
import time, sys, weakref
|
||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QObject, QMenuBar, QAction, QEvent, QSystemTrayIcon, QApplication, Qt)
|
QObject, QMenuBar, QAction, QEvent, QSystemTrayIcon, QApplication, Qt)
|
||||||
@ -31,7 +31,7 @@ class MenuBarAction(QAction):
|
|||||||
|
|
||||||
menu_counter = 0
|
menu_counter = 0
|
||||||
|
|
||||||
class ExportedMenuBar(QMenuBar):
|
class ExportedMenuBar(QMenuBar): # {{{
|
||||||
|
|
||||||
def __init__(self, parent, menu_registrar, bus):
|
def __init__(self, parent, menu_registrar, bus):
|
||||||
global menu_counter
|
global menu_counter
|
||||||
@ -58,7 +58,8 @@ class ExportedMenuBar(QMenuBar):
|
|||||||
parent.window_blocked.connect(self._block)
|
parent.window_blocked.connect(self._block)
|
||||||
parent.window_unblocked.connect(self._unblock)
|
parent.window_unblocked.connect(self._unblock)
|
||||||
|
|
||||||
def register(self):
|
def register(self, menu_registrar=None):
|
||||||
|
self.menu_registrar = menu_registrar or self.menu_registrar
|
||||||
wid = self.parent().effectiveWinId()
|
wid = self.parent().effectiveWinId()
|
||||||
if wid is not None:
|
if wid is not None:
|
||||||
self.registered_window_id = int(wid)
|
self.registered_window_id = int(wid)
|
||||||
@ -108,6 +109,7 @@ class ExportedMenuBar(QMenuBar):
|
|||||||
self.unregister()
|
self.unregister()
|
||||||
self.register()
|
self.register()
|
||||||
return False
|
return False
|
||||||
|
# }}}
|
||||||
|
|
||||||
class Factory(QObject):
|
class Factory(QObject):
|
||||||
|
|
||||||
@ -127,6 +129,29 @@ class Factory(QObject):
|
|||||||
self.menu_registrar = None
|
self.menu_registrar = None
|
||||||
self.status_notifier = None
|
self.status_notifier = None
|
||||||
self._bus = None
|
self._bus = None
|
||||||
|
self.status_notifiers, self.window_menus = [], []
|
||||||
|
|
||||||
|
def prune_dead_refs(self):
|
||||||
|
self.status_notifiers = [ref for ref in self.status_notifiers if ref() is not None]
|
||||||
|
self.window_menus = [ref for ref in self.window_menus if ref() is not None]
|
||||||
|
|
||||||
|
def window_registrar_changed(self, new_owner):
|
||||||
|
if new_owner:
|
||||||
|
self.menu_registrar = None
|
||||||
|
if self.has_global_menu:
|
||||||
|
for ref in self.window_menus:
|
||||||
|
w = ref()
|
||||||
|
if w is not None:
|
||||||
|
w.register(self.menu_registrar)
|
||||||
|
|
||||||
|
def status_notifier_registrar_changed(self, new_owner):
|
||||||
|
if new_owner:
|
||||||
|
self.status_notifier = None
|
||||||
|
if self.has_status_notifier:
|
||||||
|
for ref in self.status_notifiers:
|
||||||
|
w = ref()
|
||||||
|
if w is not None:
|
||||||
|
self.register_status_notifier(w)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bus(self):
|
def bus(self):
|
||||||
@ -134,6 +159,8 @@ class Factory(QObject):
|
|||||||
try:
|
try:
|
||||||
self._bus = self.dbus.SessionBus()
|
self._bus = self.dbus.SessionBus()
|
||||||
self._bus.call_on_disconnection(self.bus_disconnected)
|
self._bus.call_on_disconnection(self.bus_disconnected)
|
||||||
|
self._bus.watch_name_owner(UNITY_WINDOW_REGISTRAR[0], self.window_registrar_changed)
|
||||||
|
self._bus.watch_name_owner(STATUS_NOTIFIER[0], self.status_notifier_registrar_changed)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
log('Failed to connect to DBUS session bus, with error:', str(err))
|
log('Failed to connect to DBUS session bus, with error:', str(err))
|
||||||
self._bus = False
|
self._bus = False
|
||||||
@ -179,17 +206,25 @@ class Factory(QObject):
|
|||||||
|
|
||||||
def create_window_menubar(self, parent):
|
def create_window_menubar(self, parent):
|
||||||
if not QApplication.instance().testAttribute(Qt.AA_DontUseNativeMenuBar) and self.has_global_menu:
|
if not QApplication.instance().testAttribute(Qt.AA_DontUseNativeMenuBar) and self.has_global_menu:
|
||||||
return ExportedMenuBar(parent, self.menu_registrar, self.bus)
|
ans = ExportedMenuBar(parent, self.menu_registrar, self.bus)
|
||||||
|
self.prune_dead_refs()
|
||||||
|
self.window_menus.append(weakref.ref(ans))
|
||||||
|
return ans
|
||||||
ans = QMenuBar(parent)
|
ans = QMenuBar(parent)
|
||||||
parent.setMenuBar(ans)
|
parent.setMenuBar(ans)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
def register_status_notifier(self, item):
|
||||||
|
args = STATUS_NOTIFIER + ('RegisterStatusNotifierItem', 's', (item.dbus_api.name,))
|
||||||
|
self.bus.call_blocking(*args, timeout=1)
|
||||||
|
|
||||||
def create_system_tray_icon(self, parent=None, title=None, category=None):
|
def create_system_tray_icon(self, parent=None, title=None, category=None):
|
||||||
if self.has_status_notifier:
|
if self.has_status_notifier:
|
||||||
from calibre.gui2.dbus_export.tray import StatusNotifierItem
|
from calibre.gui2.dbus_export.tray import StatusNotifierItem
|
||||||
ans = StatusNotifierItem(parent=parent, title=title, app_id=self.app_id, category=category)
|
ans = StatusNotifierItem(parent=parent, title=title, app_id=self.app_id, category=category)
|
||||||
args = STATUS_NOTIFIER + ('RegisterStatusNotifierItem', 's', (ans.dbus_api.name,))
|
self.register_status_notifier(ans)
|
||||||
self.bus.call_blocking(*args, timeout=1)
|
self.prune_dead_refs()
|
||||||
|
self.status_notifiers.append(weakref.ref(ans))
|
||||||
return ans
|
return ans
|
||||||
if iswindows or isosx:
|
if iswindows or isosx:
|
||||||
return QSystemTrayIcon(parent)
|
return QSystemTrayIcon(parent)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user