[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/KDE/3.5
From:       Luboš Luňák <l.lunak () kde ! org>
Date:       2007-05-30 18:36:48
Message-ID: 1180550208.137638.22413.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 669899 by lunakl:

Backport _NET_DESKTOP_LAYOUT support from trunk. This will allow
mixing kde3/kde4 KWin and also fix #146040.
BUG: 146040



 M  +21 -18    kdebase/kicker/applets/minipager/pagerapplet.cpp  
 M  +2 -0      kdebase/kicker/applets/minipager/pagerapplet.h  
 M  +7 -17     kdebase/kwin/events.cpp  
 M  +17 -9     kdebase/kwin/workspace.cpp  
 M  +2 -2      kdebase/kwin/workspace.h  
 M  +89 -2     kdelibs/kdecore/netwm.cpp  
 M  +23 -0     kdelibs/kdecore/netwm.h  
 M  +21 -1     kdelibs/kdecore/netwm_def.h  
 M  +3 -0      kdelibs/kdecore/netwm_p.h  


--- branches/KDE/3.5/kdebase/kicker/applets/minipager/pagerapplet.cpp #669898:669899
@@ -42,6 +42,7 @@
 #include <kiconloader.h>
 #include <dcopclient.h>
 #include <netwm.h>
+#include <kmanagerselection.h>
 
 #include "global.h"
 #include "kickertip.h"
@@ -83,6 +84,7 @@
                        QWidget *parent, const char *name)
     : KPanelApplet( configFile, type, actions, parent, name ),
       m_layout(0),
+      m_desktopLayoutOwner( NULL ),
       m_shadowEngine(0),
       m_contextMenu(0),
       m_settings( new PagerSettings(sharedConfig()) )
@@ -350,27 +352,28 @@
       return;
     }
 
-    QCString kwin_name;
-    int screen_number = DefaultScreen(qt_xdisplay());
-    if (screen_number == 0)
-        kwin_name = "kwin";
-    else
-        kwin_name.sprintf("kwin-screen-%d", screen_number);
-
-    QCString replyType;
-    QByteArray data, replyData;
-    QDataStream arg(data, IO_WriteOnly);
-    arg << o << x << y;
-    if ( !(kapp->dcopClient()->call( kwin_name, "KWinInterface", \
                "setDesktopLayout(int, int, int)",
-           data, replyType, replyData)))
-    {
-        kdDebug() << "KMiniPager: Call to KWinInterface::setDesktopLayout(int, int, \
                int) failed" << endl;
-        return;
-    }
-
     desktopLayoutOrientation = o;
     desktopLayoutX = x;
     desktopLayoutY = y;
+    if( x == -1 ) // do-the-maths-yourself is encoded as 0 in the wm spec
+        x = 0;
+    if( y == -1 )
+        y = 0;
+    if( m_desktopLayoutOwner == NULL )
+    { // must own manager selection before setting global desktop layout
+        int screen = DefaultScreen( qt_xdisplay());
+        m_desktopLayoutOwner = new KSelectionOwner( QString( \
"_NET_DESKTOP_LAYOUT_S%1" ).arg( screen ).latin1(), +            screen, this );
+        if( !m_desktopLayoutOwner->claim( false ))
+        {
+            delete m_desktopLayoutOwner;
+            m_desktopLayoutOwner = NULL;
+            return;
+        }
+    }
+    NET::Orientation orient = o == Qt::Horizontal ? NET::OrientationHorizontal : \
NET::OrientationVertical; +    NETRootInfo i( qt_xdisplay(), 0 );
+    i.setDesktopLayout( orient, x, y, NET::DesktopLayoutCornerTopLeft );
 }
 
 void KMiniPager::resizeEvent(QResizeEvent*)
--- branches/KDE/3.5/kdebase/kicker/applets/minipager/pagerapplet.h #669898:669899
@@ -40,6 +40,7 @@
 class KProcess;
 class KWinModule;
 class KShadowEngine;
+class KSelectionOwner;
 
 class PagerSettings;
 
@@ -124,6 +125,7 @@
     int desktopLayoutOrientation;
     int desktopLayoutX;
     int desktopLayoutY;
+    KSelectionOwner* m_desktopLayoutOwner;
 
     KWinModule *m_kwin;
     KShadowEngine* m_shadowEngine;
--- branches/KDE/3.5/kdebase/kwin/events.cpp #669898:669899
@@ -200,10 +200,14 @@
         XUngrabKeyboard( qt_xdisplay(), qt_x_time );
         }
 
-    if ( e->type == PropertyNotify || e->type == ClientMessage ) 
+    if( e->type == PropertyNotify || e->type == ClientMessage )
         {
-        if ( netCheck( e ) )
-            return TRUE;
+        unsigned long dirty[ NETRootInfo::PROPERTIES_SIZE ];
+        rootInfo->event( e, dirty, NETRootInfo::PROPERTIES_SIZE );
+        if( dirty[ NETRootInfo::PROTOCOLS ] & NET::DesktopNames )
+            saveDesktopSettings();
+        if( dirty[ NETRootInfo::PROTOCOLS2 ] & NET::WM2DesktopLayout )
+            updateDesktopLayout();
         }
 
     // events that should be handled before Clients can get them
@@ -491,20 +495,6 @@
         };
     }
 
-/*!
-  Handles client messages sent to the workspace
- */
-bool Workspace::netCheck( XEvent* e )
-    {
-    unsigned int dirty = rootInfo->event( e );
-
-    if ( dirty & NET::DesktopNames )
-        saveDesktopSettings();
-
-    return dirty != 0;
-    }
-
-
 // ****************************************
 // Client
 // ****************************************
--- branches/KDE/3.5/kdebase/kwin/workspace.cpp #669898:669899
@@ -290,6 +290,7 @@
         NET::WM2ExtendedStrut |
         NET::WM2KDETemporaryRules |
         NET::WM2ShowingDesktop |
+        NET::WM2DesktopLayout |
         0
         ,
         NET::ActionMove |
@@ -310,6 +311,7 @@
         protocols, 5, qt_xscreen() );
 
     loadDesktopSettings();
+    updateDesktopLayout();
     // extra NETRootInfo instance in Client mode is needed to get the values of the \
                properties
     NETRootInfo client_info( qt_xdisplay(), NET::ActiveWindow | NET::CurrentDesktop \
);  int initial_desktop;
@@ -1521,25 +1523,31 @@
     updateClientArea();
     }
 
-void Workspace::setDesktopLayout(int o, int x, int y)
+void Workspace::setDesktopLayout( int, int, int )
+    { // DCOP-only, unused
+    }
+
+void Workspace::updateDesktopLayout()
     {
-    layoutOrientation = (Qt::Orientation) o;
-    layoutX = x;
-    layoutY = y;
+    // rootInfo->desktopLayoutCorner(); // I don't find this worth bothering, feel \
free to +    layoutOrientation = ( rootInfo->desktopLayoutOrientation() == \
NET::OrientationHorizontal +        ? Qt::Horizontal : Qt::Vertical );
+    layoutX = rootInfo->desktopLayoutColumnsRows().width();
+    layoutY = rootInfo->desktopLayoutColumnsRows().height();
     }
 
 void Workspace::calcDesktopLayout(int &x, int &y) const
     {
-    x = layoutX;
+    x = layoutX; // <= 0 means compute it from the other and total number of \
desktops  y = layoutY;
-    if ((x == -1) && (y > 0))
+    if((x <= 0) && (y > 0))
        x = (numberOfDesktops()+y-1) / y;
-    else if ((y == -1) && (x > 0))
+    else if((y <=0) && (x > 0))
        y = (numberOfDesktops()+x-1) / x;
 
-    if (x == -1)
+    if(x <=0)
        x = 1;
-    if (y == -1)
+    if (y <= 0)
        y = 1;
     }
 
--- branches/KDE/3.5/kdebase/kwin/workspace.h #669898:669899
@@ -226,7 +226,8 @@
         void circulateDesktopApplications();
 
         QString desktopName( int desk ) const;
-        void setDesktopLayout(int o, int x, int y);
+        virtual void setDesktopLayout(int , int , int );
+        void updateDesktopLayout();
         void setShowingDesktop( bool showing );
         void resetShowingDesktop( bool keep_hidden );
         bool showingDesktop() const;
@@ -388,7 +389,6 @@
 
     protected:
         bool keyPressMouseEmulation( XKeyEvent& ev );
-        bool netCheck( XEvent* e );
 
     private:
         void init();
--- branches/KDE/3.5/kdelibs/kdecore/netwm.cpp #669898:669899
@@ -56,6 +56,7 @@
 static Atom net_supporting_wm_check  = 0;
 static Atom net_virtual_roots        = 0;
 static Atom net_showing_desktop      = 0;
+static Atom net_desktop_layout       = 0;
 
 // root window messages
 static Atom net_close_window         = 0;
@@ -235,7 +236,7 @@
 }
 
 
-static const int netAtomCount = 83;
+static const int netAtomCount = 84;
 static void create_atoms(Display *d) {
     static const char * const names[netAtomCount] =
     {
@@ -252,6 +253,7 @@
 	    "_NET_ACTIVE_WINDOW",
 	    "_NET_WORKAREA",
 	    "_NET_VIRTUAL_ROOTS",
+            "_NET_DESKTOP_LAYOUT",
             "_NET_SHOWING_DESKTOP",
 	    "_NET_CLOSE_WINDOW",
             "_NET_RESTACK_WINDOW",
@@ -346,6 +348,7 @@
 	    &net_active_window,
 	    &net_workarea,
 	    &net_virtual_roots,
+            &net_desktop_layout,
             &net_showing_desktop,
 	    &net_close_window,
             &net_restack_window,
@@ -613,6 +616,9 @@
     p->kde_system_tray_windows = 0;
     p->kde_system_tray_windows_count = 0;
     p->showing_desktop = false;
+    p->desktop_layout_orientation = OrientationHorizontal;
+    p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
+    p->desktop_layout_columns = p->desktop_layout_rows = 0;
     setDefaultProperties();
     if( properties_size > PROPERTIES_SIZE ) {
         fprintf( stderr, "NETRootInfo::NETRootInfo(): properties array too \
large\n"); @@ -624,7 +630,7 @@
     p->properties[ PROTOCOLS ] |= ( Supported | SupportingWMCheck );
     p->client_properties[ PROTOCOLS ] = DesktopNames // the only thing that can be \
changed by clients  | WMPing; // or they can reply to this
-    p->client_properties[ PROTOCOLS2 ] = WM2TakeActivity;
+    p->client_properties[ PROTOCOLS2 ] = WM2TakeActivity | WM2DesktopLayout;
 
     role = WindowManager;
 
@@ -711,6 +717,9 @@
     p->kde_system_tray_windows = 0;
     p->kde_system_tray_windows_count = 0;
     p->showing_desktop = false;
+    p->desktop_layout_orientation = OrientationHorizontal;
+    p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
+    p->desktop_layout_columns = p->desktop_layout_rows = 0;
     setDefaultProperties();
     if( properties_size > 2 ) {
         fprintf( stderr, "NETWinInfo::NETWinInfo(): properties array too large\n");
@@ -769,6 +778,9 @@
     p->kde_system_tray_windows = 0;
     p->kde_system_tray_windows_count = 0;
     p->showing_desktop = false;
+    p->desktop_layout_orientation = OrientationHorizontal;
+    p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
+    p->desktop_layout_columns = p->desktop_layout_rows = 0;
     setDefaultProperties();
     p->client_properties[ PROTOCOLS ] = properties;
     for( int i = 0; i < PROPERTIES_SIZE; ++i )
@@ -873,6 +885,7 @@
 #endif
 
 	setSupported();
+	update(p->client_properties);
     } else {
 
 #ifdef    NETWMDEBUG
@@ -1166,6 +1179,9 @@
     if (p->properties[ PROTOCOLS ] & VirtualRoots)
 	atoms[pnum++] = net_virtual_roots;
 
+    if (p->properties[ PROTOCOLS2 ] & WM2DesktopLayout)
+	atoms[pnum++] = net_desktop_layout;
+
     if (p->properties[ PROTOCOLS ] & CloseWindow)
 	atoms[pnum++] = net_close_window;
 
@@ -1398,6 +1414,9 @@
     else if( atom == net_virtual_roots )
         p->properties[ PROTOCOLS ] |= VirtualRoots;
 
+    else if( atom == net_desktop_layout )
+        p->properties[ PROTOCOLS2 ] |= WM2DesktopLayout;
+
     else if( atom == net_close_window )
         p->properties[ PROTOCOLS ] |= CloseWindow;
 
@@ -1652,6 +1671,29 @@
 }
 
 
+void NETRootInfo::setDesktopLayout(NET::Orientation orientation, int columns, int \
rows, +    NET::DesktopLayoutCorner corner)
+{
+    p->desktop_layout_orientation = orientation;
+    p->desktop_layout_columns = columns;
+    p->desktop_layout_rows = rows;
+    p->desktop_layout_corner = corner;
+
+#ifdef   NETWMDEBUG
+    fprintf(stderr, "NETRootInfo::setDesktopLayout: %d %d %d %d\n",
+	    orientation, columns, rows, corner);
+#endif
+
+    long data[ 4 ];
+    data[ 0 ] = orientation;
+    data[ 1 ] = columns;
+    data[ 2 ] = rows;
+    data[ 3 ] = corner;
+    XChangeProperty(p->display, p->root, net_desktop_layout, XA_CARDINAL, 32,
+		    PropModeReplace, (unsigned char *) &data, 4);
+}
+
+
 void NETRootInfo::setShowingDesktop( bool showing ) {
     if (role == WindowManager) {
 	long d = p->showing_desktop = showing;
@@ -2547,6 +2589,36 @@
 	}
     }
 
+    if (dirty2 & WM2DesktopLayout) {
+        p->desktop_layout_orientation = OrientationHorizontal;
+        p->desktop_layout_corner = DesktopLayoutCornerTopLeft;
+        p->desktop_layout_columns = p->desktop_layout_rows = 0;
+	if (XGetWindowProperty(p->display, p->root, net_desktop_layout,
+			       0, MAX_PROP_SIZE, False, XA_CARDINAL, &type_ret,
+			       &format_ret, &nitems_ret, &unused, &data_ret)
+	    == Success) {
+	    if (type_ret == XA_CARDINAL && format_ret == 32) {
+                long* data = (long*) data_ret;
+                if( nitems_ret >= 4 && data[ 3 ] >= 0 && data[ 3 ] <= 3 )
+                    p->desktop_layout_corner = (NET::DesktopLayoutCorner)data[ 3 ];
+                if( nitems_ret >= 3 ) {
+                    if( data[ 0 ] >= 0 && data[ 0 ] <= 1 )
+                        p->desktop_layout_orientation = (NET::Orientation)data[ 0 ];
+                    p->desktop_layout_columns = data[ 1 ];
+                    p->desktop_layout_rows = data[ 2 ];
+                }
+	    }
+
+#ifdef    NETWMDEBUG
+	    fprintf(stderr, "NETRootInfo::updated: desktop layout updated (%d %d %d %d)\n",
+                p->desktop_layout_orientation, p->desktop_layout_columns,
+                p->desktop_layout_rows, p->desktop_layout_corner );
+#endif
+	    if ( data_ret )
+		XFree(data_ret);
+	}
+    }
+
     if (dirty2 & WM2ShowingDesktop) {
         p->showing_desktop = false;
 	if (XGetWindowProperty(p->display, p->root, net_showing_desktop,
@@ -2702,6 +2774,21 @@
 }
 
 
+NET::Orientation NETRootInfo::desktopLayoutOrientation() const {
+    return p->desktop_layout_orientation;
+}
+
+
+QSize NETRootInfo::desktopLayoutColumnsRows() const {
+    return QSize( p->desktop_layout_columns, p->desktop_layout_rows );
+}
+
+
+NET::DesktopLayoutCorner NETRootInfo::desktopLayoutCorner() const {
+    return p->desktop_layout_corner;
+}
+
+
 int NETRootInfo::numberOfDesktops() const {
     return p->number_of_desktops == 0 ? 1 : p->number_of_desktops;
 }
--- branches/KDE/3.5/kdelibs/kdecore/netwm.h #669898:669899
@@ -373,6 +373,22 @@
     int virtualRootsCount() const;
 
     /**
+       Returns the desktop layout orientation.
+    **/
+    NET::Orientation desktopLayoutOrientation() const;
+
+    /**
+       Returns the desktop layout number of columns and rows. Note that
+       either may be 0 (see _NET_DESKTOP_LAYOUT).
+    **/
+    QSize desktopLayoutColumnsRows() const;
+
+    /**
+       Returns the desktop layout starting corner.
+    **/
+    NET::DesktopLayoutCorner desktopLayoutCorner() const;
+
+    /**
        Returns the number of desktops.
 
        @return the number of desktops
@@ -518,6 +534,13 @@
     void setVirtualRoots(Window *windows, unsigned int count);
     
     /**
+       Sets the desktop layout. This is set by the pager. When setting, the pager \
must +       own the _NET_DESKTOP_LAYOUT_Sn manager selection. See \
_NET_DESKTOP_LAYOUT for details. +    **/
+    void setDesktopLayout(NET::Orientation orientation, int columns, int rows,
+        NET::DesktopLayoutCorner corner);
+
+    /**
      * Sets the _NET_SHOWING_DESKTOP status (whether desktop is being shown).
      * @since 3.5
      */
--- branches/KDE/3.5/kdelibs/kdecore/netwm_def.h #669898:669899
@@ -590,6 +590,7 @@
         @li WM2WindowClass  WM_CLASS
         @li WM2WindowRole   WM_WINDOW_ROLE
         @li WM2ClientMachine WM_CLIENT_MACHINE
+        @li WM2DesktopLayout _NET_DESKTOP_LAYOUT
         
         @since 3.2
 
@@ -608,7 +609,8 @@
         WM2WindowClass         = 1<<10, ///< @since 3.3
         WM2WindowRole          = 1<<11, ///< @since 3.3
         WM2ClientMachine       = 1<<12, ///< @since 3.3
-        WM2ShowingDesktop      = 1<<13  ///< @since 3.5
+        WM2ShowingDesktop      = 1<<13, ///< @since 3.5
+        WM2DesktopLayout       = 1<<15  ///< @since 3.5.8
     };
 
     /**
@@ -632,6 +634,24 @@
     };
     
     /**
+      Orientation.
+    **/
+    enum Orientation {
+        OrientationHorizontal = 0,
+        OrientationVertical = 1
+    };
+    
+    /**
+     Starting corner for desktop layout.
+    **/
+    enum DesktopLayoutCorner {
+        DesktopLayoutCornerTopLeft = 0,
+        DesktopLayoutCornerTopRight = 1,
+        DesktopLayoutCornerBottomLeft = 2,
+        DesktopLayoutCornerBottomRight = 3
+    };
+    
+    /**
      Compares two X timestamps, taking into account wrapping and 64bit \
                architectures.
      Return value is like with strcmp(), 0 for equal, -1 for time1 < time2, 1 for \
time1 > time2.  @since 3.5.3
--- branches/KDE/3.5/kdelibs/kdecore/netwm_p.h #669898:669899
@@ -103,6 +103,9 @@
     unsigned long clients_count, stacking_count, virtual_roots_count,
 	kde_system_tray_windows_count;
     bool showing_desktop;
+    NET::Orientation desktop_layout_orientation;
+    NET::DesktopLayoutCorner desktop_layout_corner;
+    int desktop_layout_columns, desktop_layout_rows;
 
     unsigned long properties[ 5 ];
     unsigned long client_properties[ 5 ]; // properties the client is interested in


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic