File fusion-icon-tray-fix.patch of Package fusion-icon-qt3
diff -ruN fusion-icon.orig/src/interface_qt3.py fusion-icon/src/interface_qt3.py
--- fusion-icon.orig/src/interface_qt3.py 2007-08-13 02:49:41.000000000 +0400
+++ fusion-icon/src/interface_qt3.py 2011-10-09 16:15:03.913948330 +0400
@@ -3,7 +3,9 @@
import sys
from qt import *
import ctypes as c
+import ctypes.util as cu
from libfusionicon import *
+import time
app = QApplication(sys.argv)
@@ -44,45 +46,47 @@
# Class
class SystrayIcon(QLabel):
- def __init__(self, icon, parent = None, name = "Fusion-Icon"):
- QLabel.__init__(self, parent, name, Qt.WMouseNoMask |\
- Qt.WRepaintNoErase | Qt.WType_TopLevel | Qt.WStyle_Customize |\
+ """ On construction, you have to supply a QPixmap instance holding the
+ application icon. The pixmap should not be bigger than 32x32,
+ preferably 22x22. Currently, no check is made.
+
+ The class can emits two signals:
+ Leftclick on icon: activated()
+ Rightclick on icon: contextMenuRequested(const QPoint&)
+
+ Based on code: (C) 2004 Torsten Marek
+ License: Public domain
+ """
+
+ def __init__(self, icon, parent=None, name=""):
+ QLabel.__init__(self, parent, name, Qt.WMouseNoMask | Qt.WRepaintNoErase |
+ Qt.WType_TopLevel | Qt.WStyle_Customize |
Qt.WStyle_NoBorder | Qt.WStyle_StaysOnTop)
- self.setMinimumSize(22,22);
+
+ self.setMinimumSize(22, 22)
self.setBackgroundMode(Qt.X11ParentRelative)
self.setBackgroundOrigin(QWidget.WindowOrigin)
- libX11 = c.cdll.LoadLibrary("/usr/lib/libX11.so")
- # get all functions, set arguments + return types
- XDefaultScreenOfDisplay = libX11.XDefaultScreenOfDisplay
- XDefaultScreenOfDisplay.argtypes = [c.c_void_p]
- XDefaultScreenOfDisplay.restype = c.c_void_p
-
- XScreenNumberOfScreen = libX11.XScreenNumberOfScreen
- XScreenNumberOfScreen.argtypes = [c.c_void_p]
+ self.libX11 = c.cdll.LoadLibrary(cu.find_library('X11'))
- XInternAtom = libX11.XInternAtom
- XInternAtom.argtypes = [c.c_void_p, c.c_char_p, c.c_int]
-
- XGrabServer = libX11.XGrabServer
- XGrabServer.argtypes = [c.c_void_p]
-
- XGetSelectionOwner = libX11.XGetSelectionOwner
- XGetSelectionOwner.argtypes = [c.c_void_p, c.c_int]
+ # get all functions, set arguments + return types
+ self.XternAtom = self.libX11.XInternAtom
+ self.XternAtom.argtypes = [c.c_void_p, c.c_char_p, c.c_int]
- XSelectInput = libX11.XSelectInput
+ XSelectInput = self.libX11.XSelectInput
XSelectInput.argtypes = [c.c_void_p, c.c_int, c.c_long]
- XUngrabServer = libX11.XUngrabServer
+ XUngrabServer = self.libX11.XUngrabServer
XUngrabServer.argtypes = [c.c_void_p]
- XFlush = libX11.XFlush
+ XFlush = self.libX11.XFlush
XFlush.argtypes = [c.c_void_p]
class data(c.Union):
_fields_ = [("b", c.c_char * 20),
("s", c.c_short * 10),
("l", c.c_long * 5)]
+
class XClientMessageEvent(c.Structure):
_fields_ = [("type", c.c_int),
("serial", c.c_ulong),
@@ -93,30 +97,58 @@
("format", c.c_int),
("data", data)]
- XSendEvent = libX11.XSendEvent
+ time.sleep(1)
+
+ XSendEvent = self.libX11.XSendEvent
XSendEvent.argtypes = [c.c_void_p, c.c_int, c.c_int, c.c_long, c.c_void_p]
- XSync = libX11.XSync
+ XSync = self.libX11.XSync
XSync.argtypes = [c.c_void_p, c.c_int]
+ XChangeProperty = self.libX11.XChangeProperty
+ XChangeProperty.argtypes = [c.c_void_p, c.c_long, c.c_int, c.c_int,
+ c.c_int, c.c_int, c.c_char_p, c.c_int]
+
dpy = int(qt_xdisplay())
+ trayWin = self.winId()
+
+ x = 0
+ while True:
+ managerWin = self.locateTray(dpy)
+ if managerWin: break
+ x += 1
+ if x > 10: break
+ time.sleep(2.0)
+
+
+ # Make sure KDE puts the icon in the system tray
+ class data2(c.Union):
+ _fields_ = [("i", c.c_int, 32),
+ ("s", c.c_char * 4)]
+
+ k = data2()
+ k.i = 1
+ pk = c.cast(c.pointer(k), c.c_char_p)
+
+ r = self.XternAtom(dpy, "KWM_DOCKWINDOW", 0)
+ XChangeProperty(dpy, trayWin, r, r, 32, 0, pk, 1)
+
+ r = self.XternAtom(dpy, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", 0)
+ XChangeProperty(dpy, trayWin, r, 33, 32, 0, pk, 1)
- iscreen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(dpy))
- # get systray window (holds _NET_SYSTEM_TRAY_S<screen> atom)
- selectionAtom = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S%i" % iscreen, 0)
- XGrabServer(dpy)
- managerWin = XGetSelectionOwner(dpy, selectionAtom)
if managerWin != 0:
# set StructureNotifyMask (1L << 17)
XSelectInput(dpy, managerWin, 1L << 17)
- XUngrabServer(dpy)
+
+ #XUngrabServer(dpy)
XFlush(dpy)
+
if managerWin != 0:
# send "SYSTEM_TRAY_OPCODE_REQUEST_DOCK to managerWin
k = data()
k.l = (0, # CurrentTime
0, # REQUEST_DOCK
- self.winId(), # window ID
+ trayWin, # window ID
0, # empty
0) # empty
ev = XClientMessageEvent(33, #type: ClientMessage
@@ -124,24 +156,54 @@
0, # send_event
dpy, # display
managerWin, # systray manager
- XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", 0), 32, k)
+ self.XternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", 0), # message type
+ 32, # format
+ k) # message data
XSendEvent(dpy, managerWin, 0, 0, c.addressof(ev))
XSync(dpy, 0)
+
self.setPixmap(QPixmap(sys.path[0] + '/../icons/hicolor/22x22/apps/fusion-icon.png'))
self.setAlignment(Qt.AlignHCenter)
+
QToolTip.add(self, "Compiz Fusion Icon")
+
+
+ def locateTray(self, dpy):
+ # get systray window (holds _NET_SYSTEM_TRAY_S<screen> atom)
+ self.XScreenNumberOfScreen = self.libX11.XScreenNumberOfScreen
+ self.XScreenNumberOfScreen.argtypes = [c.c_void_p]
+
+ XDefaultScreenOfDisplay = self.libX11.XDefaultScreenOfDisplay
+ XDefaultScreenOfDisplay.argtypes = [c.c_void_p]
+ XDefaultScreenOfDisplay.restype = c.c_void_p
+
+ XGetSelectionOwner = self.libX11.XGetSelectionOwner
+ XGetSelectionOwner.argtypes = [c.c_void_p, c.c_int]
+
+ XGrabServer = self.libX11.XGrabServer
+ XGrabServer.argtypes = [c.c_void_p]
+
+ iscreen = self.XScreenNumberOfScreen(XDefaultScreenOfDisplay(dpy))
+ selectionAtom = self.XternAtom(dpy, "_NET_SYSTEM_TRAY_S%i" % iscreen, 0)
+ #XGrabServer(dpy)
+
+ managerWin = XGetSelectionOwner(dpy, selectionAtom)
+ return managerWin
+
def mousePressEvent(self, e):
if e.button() == Qt.RightButton:
id = contextMenu.exec_loop(e.globalPos())
if id == menuSettings:
subprocess.Popen(['ccsm'])
- elif id == menuEmerald:
- subprocess.Popen(['emerald-theme-manager'])
+ elif is_installed('emerald'):
+ if id == menuEmerald:
+ subprocess.Popen(['emerald-theme-manager'])
elif id == menuReload:
print '* reloading window manager...'
start_wm()
+
#Menus
managerMenu = QPopupMenu()
optionsMenu = QPopupMenu()
@@ -212,15 +274,16 @@
if not is_installed('emerald'):
actionEmeraldWD.setEnabled(False)
if not is_installed('gtk-window-decorator'):
- actionGTKWD.setVisible(False)
+ actionGTKWD.setEnabled(False)
if not is_installed('kde-window-decorator'):
- actionKDEWD.setVisible(False)
+ actionKDEWD.setEnabled(False)
groupWD.addTo(decoratorMenu)
# Main Menu
contextMenu = QPopupMenu()
menuSettings = contextMenu.insertItem("Settings Manager")
-menuEmerald = contextMenu.insertItem("Emerald Theme Manager")
+if is_installed('emerald'):
+ menuEmerald = contextMenu.insertItem("Emerald Theme Manager")
contextMenu.insertSeparator()
menuReload = contextMenu.insertItem("Reload Window Manager")
menuManager = contextMenu.insertItem("Select Window Manager", managerMenu)