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)
openSUSE Build Service is sponsored by