Esempio n. 1
0
 def __init__(self, parent, menu_registrar, bus):
     global menu_counter
     if not parent.isWindow():
         raise ValueError(
             'You must supply a top level window widget as the parent for an exported menu bar'
         )
     self._blocked = False
     self.is_visible = True
     QMenuBar.__init__(self, parent)
     QMenuBar.setVisible(self, False)
     self.menu_action = MenuBarAction(self)
     self.menu_registrar = menu_registrar
     self.registered_window_id = None
     self.bus = bus
     menu_counter += 1
     import dbus
     from calibre.gui2.dbus_export.menu import DBusMenu
     self.object_path = dbus.ObjectPath('/MenuBar/%d' % menu_counter)
     self.dbus_menu = DBusMenu(self.object_path)
     self.dbus_menu.publish_new_menu(self)
     self.register()
     parent.installEventFilter(self)
     # See https://bugreports.qt-project.org/browse/QTBUG-42281
     if hasattr(parent, 'window_blocked'):
         parent.window_blocked.connect(self._block)
         parent.window_unblocked.connect(self._unblock)
Esempio n. 2
0
 def __init__(self, notifier, **kw):
     global _status_item_menu_count
     self.notifier = notifier
     bus = kw.get('bus')
     if bus is None:
         bus = kw['bus'] = dbus.SessionBus()
     self.name = '%s-%s-%s' % (self.IFACE, os.getpid(), kw.get('num', 1))
     self.dbus_name = BusName(self.name, bus=bus, do_not_queue=True)
     self.app_id = kw.get('app_id') or QApplication.instance().applicationName() or 'unknown_application'
     self.category = kw.get('category') or 'ApplicationStatus'
     self.title = kw.get('title') or self.app_id
     Object.__init__(self, bus, '/' + self.IFACE.split('.')[-1])
     _status_item_menu_count += 1
     self.dbus_menu = DBusMenu('/StatusItemMenu/%d' % _status_item_menu_count, bus=bus, parent=kw.get('parent'))
Esempio n. 3
0
class ExportedMenuBar(QMenuBar):

    def __init__(self, parent, menu_registrar, bus):
        global menu_counter
        if not parent.isWindow():
            raise ValueError('You must supply a top level window widget as the parent for an exported menu bar')
        QMenuBar.__init__(self, parent)
        QMenuBar.setVisible(self, False)
        self.menu_action = MenuBarAction(self)
        self.menu_registrar = menu_registrar
        self.registered_window_id = None
        self.bus = bus
        menu_counter += 1
        import dbus
        from calibre.gui2.dbus_export.menu import DBusMenu
        self.object_path = dbus.ObjectPath('/MenuBar/%d' % menu_counter)
        self.dbus_menu = DBusMenu(self.object_path)
        self.dbus_menu.publish_new_menu(self)
        self.register()
        parent.installEventFilter(self)

    def register(self):
        wid = self.parent().effectiveWinId()
        if wid is not None:
            self.registered_window_id = int(wid)
            args = self.menu_registrar + ('RegisterWindow', 'uo', (self.registered_window_id, self.object_path))
            self.bus.call_blocking(*args)

    def unregister(self):
        if self.registered_window_id is not None:
            args = self.menu_registrar + ('UnregisterWindow', 'u', (self.registered_window_id,))
            self.registered_window_id = None
            self.bus.call_blocking(*args)

    def setVisible(self, visible):
        pass  # no-op

    def isVisible(self):
        return True

    def menuAction(self):
        return self.menu_action

    def eventFilter(self, obj, ev):
        etype = ev.type()
        if etype == QEvent.WinIdChange:
            self.unregister()
            self.register()
        return False
Esempio n. 4
0
 def __init__(self, notifier, **kw):
     global _status_item_menu_count
     self.notifier = notifier
     bus = kw.get('bus')
     if bus is None:
         bus = kw['bus'] = dbus.SessionBus()
     self.name = '%s-%s-%s' % (self.IFACE, os.getpid(), kw.get('num', 1))
     self.dbus_name = BusName(self.name, bus=bus, do_not_queue=True)
     self.app_id = kw.get('app_id') or QApplication.instance().applicationName() or 'unknown_application'
     self.category = kw.get('category') or 'ApplicationStatus'
     self.title = kw.get('title') or self.app_id
     Object.__init__(self, bus, '/' + self.IFACE.split('.')[-1])
     _status_item_menu_count += 1
     self.dbus_menu = DBusMenu('/StatusItemMenu/%d' % _status_item_menu_count, bus=bus, parent=kw.get('parent'))
Esempio n. 5
0
 def __init__(self, parent, menu_registrar, bus):
     global menu_counter
     if not parent.isWindow():
         raise ValueError('You must supply a top level window widget as the parent for an exported menu bar')
     QMenuBar.__init__(self, parent)
     QMenuBar.setVisible(self, False)
     self.menu_action = MenuBarAction(self)
     self.menu_registrar = menu_registrar
     self.registered_window_id = None
     self.bus = bus
     menu_counter += 1
     import dbus
     from calibre.gui2.dbus_export.menu import DBusMenu
     self.object_path = dbus.ObjectPath('/MenuBar/%d' % menu_counter)
     self.dbus_menu = DBusMenu(self.object_path)
     self.dbus_menu.publish_new_menu(self)
     self.register()
     parent.installEventFilter(self)
Esempio n. 6
0
 def __init__(self, parent, menu_registrar, bus):
     global menu_counter
     if not parent.isWindow():
         raise ValueError('You must supply a top level window widget as the parent for an exported menu bar')
     self._blocked = False
     self.is_visible = True
     QMenuBar.__init__(self, parent)
     QMenuBar.setVisible(self, False)
     self.menu_action = MenuBarAction(self)
     self.menu_registrar = menu_registrar
     self.registered_window_id = None
     self.bus = bus
     menu_counter += 1
     import dbus
     from calibre.gui2.dbus_export.menu import DBusMenu
     self.object_path = dbus.ObjectPath('/MenuBar/%d' % menu_counter)
     self.dbus_menu = DBusMenu(self.object_path)
     self.dbus_menu.publish_new_menu(self)
     self.register()
     parent.installEventFilter(self)
     # See https://bugreports.qt-project.org/browse/QTBUG-42281
     if hasattr(parent, 'window_blocked'):
         parent.window_blocked.connect(self._block)
         parent.window_unblocked.connect(self._unblock)
Esempio n. 7
0
class StatusNotifierItemAPI(Object):

    'See http://www.notmart.org/misc/statusnotifieritem/statusnotifieritem.html'

    IFACE = 'org.kde.StatusNotifierItem'

    def __init__(self, notifier, **kw):
        global _status_item_menu_count
        self.notifier = notifier
        bus = kw.get('bus')
        if bus is None:
            bus = kw['bus'] = dbus.SessionBus()
        self.name = '%s-%s-%s' % (self.IFACE, os.getpid(), kw.get('num', 1))
        self.dbus_name = BusName(self.name, bus=bus, do_not_queue=True)
        self.app_id = kw.get('app_id') or QApplication.instance().applicationName() or 'unknown_application'
        self.category = kw.get('category') or 'ApplicationStatus'
        self.title = kw.get('title') or self.app_id
        Object.__init__(self, bus, '/' + self.IFACE.split('.')[-1])
        _status_item_menu_count += 1
        self.dbus_menu = DBusMenu('/StatusItemMenu/%d' % _status_item_menu_count, bus=bus, parent=kw.get('parent'))

    def publish_new_menu(self):
        menu = self.notifier.contextMenu()
        if menu is None:
            menu = QMenu()
        if len(menu.actions()) == 0:
            menu.addAction(self.notifier.icon(), _('Show/hide %s') % self.title, self.notifier.emit_activated)
        # The menu must have at least one entry, namely the show/hide entry.
        # This is necessary as Canonical in their infinite wisdom decided to
        # force all tray icons to show their popup menus when clicked.
        self.dbus_menu.publish_new_menu(menu)

    @dbus_property(IFACE, signature='s')
    def IconName(self):
        return icon_cache().name_for_icon(self.notifier.icon())

    @dbus_property(IFACE, signature='s')
    def IconThemePath(self):
        return icon_cache().icon_theme_path

    @dbus_property(IFACE, signature='a(iiay)')
    def IconPixmap(self):
        return dbus.Array(signature='(iiay)')

    @dbus_property(IFACE, signature='s')
    def OverlayIconName(self):
        return ''

    @dbus_property(IFACE, signature='(sa(iiay)ss)')
    def ToolTip(self):
        # This is ignored on Unity, Canonical believes in user interfaces
        # that are so functionality free that they dont need tooltips
        return self.IconName, self.IconPixmap, self.Title, self.notifier.toolTip()

    @dbus_property(IFACE, signature='a(iiay)')
    def OverlayIconPixmap(self):
        return dbus.Array(signature='(iiay)')

    @dbus_property(IFACE, signature='s')
    def AttentionIconName(self):
        return ''

    @dbus_property(IFACE, signature='a(iiay)')
    def AttentionIconPixmap(self):
        return dbus.Array(signature='(iiay)')

    @dbus_property(IFACE, signature='s')
    def Category(self):
        return self.category

    @dbus_property(IFACE, signature='s')
    def Id(self):
        return self.app_id

    @dbus_property(IFACE, signature='s')
    def Title(self):
        return self.title

    @dbus_property(IFACE, signature='s')
    def Status(self):
        return 'Active' if self.notifier.isVisible() else 'Passive'

    @dbus_property(IFACE, signature='o')
    def Menu(self):
        return dbus.ObjectPath(self.dbus_menu.object_path)

    @dbus_property(IFACE, signature='u')
    def WindowId(self):
        return 0

    @dbus_method(IFACE, in_signature='ii', out_signature='')
    def ContextMenu(self, x, y):
        self.notifier.show_menu.emit(x, y)

    @dbus_method(IFACE, in_signature='ii', out_signature='')
    def Activate(self, x, y):
        self.notifier.activated.emit(QSystemTrayIcon.Trigger)

    @dbus_method(IFACE, in_signature='u', out_signature='')
    def XAyatanaSecondaryActivate(self, timestamp):
        # This is called when the user middle clicks the icon in Unity
        self.notifier.activated.emit(QSystemTrayIcon.MiddleClick)

    @dbus_method(IFACE, in_signature='ii', out_signature='')
    def SecondaryActivate(self, x, y):
        self.notifier.activated.emit(QSystemTrayIcon.MiddleClick)

    @dbus_method(IFACE, in_signature='is', out_signature='')
    def Scroll(self, delta, orientation):
        pass

    @dbus_signal(IFACE, '')
    def NewTitle(self):
        pass

    @dbus_signal(IFACE, '')
    def NewIcon(self):
        pass

    @dbus_signal(IFACE, '')
    def NewAttentionIcon(self):
        pass

    @dbus_signal(IFACE, '')
    def NewOverlayIcon(self):
        pass

    @dbus_signal(IFACE, '')
    def NewToolTip(self):
        pass

    @dbus_signal(IFACE, 's')
    def NewStatus(self, status):
        pass
Esempio n. 8
0
class ExportedMenuBar(QMenuBar):  # {{{

    is_native_menubar = True

    def __init__(self, parent, menu_registrar, bus):
        global menu_counter
        if not parent.isWindow():
            raise ValueError(
                'You must supply a top level window widget as the parent for an exported menu bar'
            )
        self._blocked = False
        self.is_visible = True
        QMenuBar.__init__(self, parent)
        QMenuBar.setVisible(self, False)
        self.menu_action = MenuBarAction(self)
        self.menu_registrar = menu_registrar
        self.registered_window_id = None
        self.bus = bus
        menu_counter += 1
        import dbus
        from calibre.gui2.dbus_export.menu import DBusMenu
        self.object_path = dbus.ObjectPath('/MenuBar/%d' % menu_counter)
        self.dbus_menu = DBusMenu(self.object_path)
        self.dbus_menu.publish_new_menu(self)
        self.register()
        parent.installEventFilter(self)

    def register(self, menu_registrar=None):
        self.menu_registrar = menu_registrar or self.menu_registrar
        wid = self.parent().effectiveWinId()
        if wid is not None:
            self.registered_window_id = int(wid)
            args = self.menu_registrar + ('RegisterWindow', 'uo',
                                          (self.registered_window_id,
                                           self.object_path))
            self.bus.call_blocking(*args)

    def unregister(self):
        if self.registered_window_id is not None:
            args = self.menu_registrar + ('UnregisterWindow', 'u',
                                          (self.registered_window_id, ))
            self.registered_window_id = None
            self.bus.call_blocking(*args)

    def setVisible(self, visible):
        self.is_visible = visible
        self.dbus_menu.set_visible(self.is_visible and not self._blocked)

    def isVisible(self):
        return self.is_visible

    def show(self):
        self.setVisible(True)

    def hide(self):
        self.setVisible(False)

    def menuAction(self):
        return self.menu_action

    def _block(self):
        self._blocked = True
        self.setVisible(self.is_visible)

    def _unblock(self):
        self._blocked = False
        self.setVisible(self.is_visible)

    def eventFilter(self, obj, ev):
        etype = ev.type()
        if etype == QEvent.Type.Show:
            # Hiding a window causes the registrar to auto-unregister it, so we
            # have to re-register it on show events.
            self.register()
        elif etype == QEvent.Type.WinIdChange:
            self.unregister()
            self.register()
        return False
Esempio n. 9
0
class ExportedMenuBar(QMenuBar):  # {{{

    is_native_menubar = True

    def __init__(self, parent, menu_registrar, bus):
        global menu_counter
        if not parent.isWindow():
            raise ValueError('You must supply a top level window widget as the parent for an exported menu bar')
        self._blocked = False
        self.is_visible = True
        QMenuBar.__init__(self, parent)
        QMenuBar.setVisible(self, False)
        self.menu_action = MenuBarAction(self)
        self.menu_registrar = menu_registrar
        self.registered_window_id = None
        self.bus = bus
        menu_counter += 1
        import dbus
        from calibre.gui2.dbus_export.menu import DBusMenu
        self.object_path = dbus.ObjectPath('/MenuBar/%d' % menu_counter)
        self.dbus_menu = DBusMenu(self.object_path)
        self.dbus_menu.publish_new_menu(self)
        self.register()
        parent.installEventFilter(self)
        # See https://bugreports.qt-project.org/browse/QTBUG-42281
        if hasattr(parent, 'window_blocked'):
            parent.window_blocked.connect(self._block)
            parent.window_unblocked.connect(self._unblock)

    def register(self, menu_registrar=None):
        self.menu_registrar = menu_registrar or self.menu_registrar
        wid = self.parent().effectiveWinId()
        if wid is not None:
            self.registered_window_id = int(wid)
            args = self.menu_registrar + ('RegisterWindow', 'uo', (self.registered_window_id, self.object_path))
            self.bus.call_blocking(*args)

    def unregister(self):
        if self.registered_window_id is not None:
            args = self.menu_registrar + ('UnregisterWindow', 'u', (self.registered_window_id,))
            self.registered_window_id = None
            self.bus.call_blocking(*args)

    def setVisible(self, visible):
        self.is_visible = visible
        self.dbus_menu.set_visible(self.is_visible and not self._blocked)

    def isVisible(self):
        return self.is_visible

    def show(self):
        self.setVisible(True)

    def hide(self):
        self.setVisible(False)

    def menuAction(self):
        return self.menu_action

    def _block(self):
        self._blocked = True
        self.setVisible(self.is_visible)

    def _unblock(self):
        self._blocked = False
        self.setVisible(self.is_visible)

    def eventFilter(self, obj, ev):
        etype = ev.type()
        # WindowBlocked and WindowUnblocked aren't delivered to event filters,
        # so we have to rely on co-operation from the mainwindow class
        # See https://bugreports.qt-project.org/browse/QTBUG-42281
        # if etype == QEvent.WindowBlocked:
        #     self._block()
        # elif etype == QEvent.WindowUnblocked:
        #     self._unblock()
        if etype == QEvent.Show:
            # Hiding a window causes the registrar to auto-unregister it, so we
            # have to re-register it on show events.
            self.register()
        elif etype == QEvent.WinIdChange:
            self.unregister()
            self.register()
        return False
Esempio n. 10
0
class StatusNotifierItemAPI(Object):

    'See http://www.notmart.org/misc/statusnotifieritem/statusnotifieritem.html'

    IFACE = 'org.kde.StatusNotifierItem'

    def __init__(self, notifier, **kw):
        global _status_item_menu_count
        self.notifier = notifier
        bus = kw.get('bus')
        if bus is None:
            bus = kw['bus'] = dbus.SessionBus()
        self.name = '%s-%s-%s' % (self.IFACE, os.getpid(), kw.get('num', 1))
        self.dbus_name = BusName(self.name, bus=bus, do_not_queue=True)
        self.app_id = kw.get('app_id') or QApplication.instance().applicationName() or 'unknown_application'
        self.category = kw.get('category') or 'ApplicationStatus'
        self.title = kw.get('title') or self.app_id
        Object.__init__(self, bus, '/' + self.IFACE.split('.')[-1])
        _status_item_menu_count += 1
        self.dbus_menu = DBusMenu('/StatusItemMenu/%d' % _status_item_menu_count, bus=bus, parent=kw.get('parent'))

    def publish_new_menu(self):
        menu = self.notifier.contextMenu()
        if menu is None:
            menu = QMenu()
        if len(menu.actions()) == 0:
            menu.addAction(self.notifier.icon(), _('Show/hide %s') % self.title, self.notifier.emit_activated)
        # The menu must have at least one entry, namely the show/hide entry.
        # This is necessary as Canonical in their infinite wisdom decided to
        # force all tray icons to show their popup menus when clicked.
        self.dbus_menu.publish_new_menu(menu)

    @dbus_property(IFACE, signature='s')
    def IconName(self):
        return icon_cache().name_for_icon(self.notifier.icon())

    @dbus_property(IFACE, signature='s')
    def IconThemePath(self):
        return icon_cache().icon_theme_path

    @dbus_property(IFACE, signature='a(iiay)')
    def IconPixmap(self):
        return dbus.Array(signature='(iiay)')

    @dbus_property(IFACE, signature='s')
    def OverlayIconName(self):
        return ''

    @dbus_property(IFACE, signature='(sa(iiay)ss)')
    def ToolTip(self):
        # This is ignored on Unity, Canonical believes in user interfaces
        # that are so functionality free that they dont need tooltips
        return self.IconName, self.IconPixmap, self.Title, self.notifier.toolTip()

    @dbus_property(IFACE, signature='a(iiay)')
    def OverlayIconPixmap(self):
        return dbus.Array(signature='(iiay)')

    @dbus_property(IFACE, signature='s')
    def AttentionIconName(self):
        return ''

    @dbus_property(IFACE, signature='a(iiay)')
    def AttentionIconPixmap(self):
        return dbus.Array(signature='(iiay)')

    @dbus_property(IFACE, signature='s')
    def Category(self):
        return self.category

    @dbus_property(IFACE, signature='s')
    def Id(self):
        return self.app_id

    @dbus_property(IFACE, signature='s')
    def Title(self):
        return self.title

    @dbus_property(IFACE, signature='s')
    def Status(self):
        return 'Active' if self.notifier.isVisible() else 'Passive'

    @dbus_property(IFACE, signature='o')
    def Menu(self):
        return dbus.ObjectPath(self.dbus_menu.object_path)

    @dbus_property(IFACE, signature='u')
    def WindowId(self):
        return 0

    @dbus_method(IFACE, in_signature='ii', out_signature='')
    def ContextMenu(self, x, y):
        self.notifier.show_menu.emit(x, y)

    @dbus_method(IFACE, in_signature='ii', out_signature='')
    def Activate(self, x, y):
        self.notifier.activated.emit(QSystemTrayIcon.Trigger)

    @dbus_method(IFACE, in_signature='u', out_signature='')
    def XAyatanaSecondaryActivate(self, timestamp):
        # This is called when the user middle clicks the icon in Unity
        self.notifier.activated.emit(QSystemTrayIcon.MiddleClick)

    @dbus_method(IFACE, in_signature='ii', out_signature='')
    def SecondaryActivate(self, x, y):
        self.notifier.activated.emit(QSystemTrayIcon.MiddleClick)

    @dbus_method(IFACE, in_signature='is', out_signature='')
    def Scroll(self, delta, orientation):
        pass

    @dbus_signal(IFACE, '')
    def NewTitle(self):
        pass

    @dbus_signal(IFACE, '')
    def NewIcon(self):
        pass

    @dbus_signal(IFACE, '')
    def NewAttentionIcon(self):
        pass

    @dbus_signal(IFACE, '')
    def NewOverlayIcon(self):
        pass

    @dbus_signal(IFACE, '')
    def NewToolTip(self):
        pass

    @dbus_signal(IFACE, 's')
    def NewStatus(self, status):
        pass