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

List:       kde-core-devel
Subject:    Kicker Xinerama support
From:       Kevin Puetz <puetzk () iastate ! edu>
Date:       2002-06-05 4:06:39
[Download RAW message or body]

The attached patch provides at least the beginnings of real Xinerama support 
for kicker placement. It allows the user to drag&drop the panel along any 
edge of any monitor, saves/restores panel placement correctly, and prevents 
panels from spanning across multiple screens. 

Just posting a rough-cut for comments (espescially any suggestions on how to 
do a kcontrol UI for placing the panel). I haven't got any great ideas 
here... maybe just a combobox to pick the screen number, but that seems 
cryptic (and the useability team just did such a nice job with that dialog). 
Showing multiple pickers (for each monitor) is another possibility, but also 
not a great one since there could be a heck of a lot of them.

also, which Kicker classes have to stay BC? I hope not PanelContainer (it's 
header is not shipped, so I went ahead and assumed not).

Known bugs:
	Category 1: panels along the edges of physical screens, but logically in the 
middle
		Kwin seems to mess up window placement with these around (it won't let you 
drag windows past them). 
		Autohiding - autohidden panels in this position are basically impossible to 
open, since the electric borders aren't there to trigger it. Since they look 
stupid anyway (they slide oddly from one screen to the other, where they show 
but are dead) I need to disable autohide for these positions.

	Switching - it doesn't correctly force taskbars assigned to screens greated 
than the available number back onto an existing one. So reconfiguration is 
bad until I fix that.

It should work on non-Xinerama systems as well, though I haven't tested that 
yet :-)

If anybody with an unusual Xinerama setup would like to take a look, be my 
guest. Any bug reports I haven't listed above are also welcome.
["kicker-xinerama.diff" (text/x-diff)]

? .snprj
? kicker.proj
? core/.container_panel.cpp.swp
? core/.container_panel.h.swp
? core/.containerarea.cpp.swp
Index: core/container_panel.cpp
===================================================================
RCS file: /home/kde/kdebase/kicker/core/container_panel.cpp,v
retrieving revision 1.57
diff -u -p -r1.57 container_panel.cpp
--- core/container_panel.cpp	2002/06/02 23:55:10	1.57
+++ core/container_panel.cpp	2002/06/05 03:48:45
@@ -78,11 +78,11 @@ PanelSettings::PanelSettings()
     _size              = Normal;
     _customSize        = 58;
 
-    // For now, we barely support xinerama.  Let's just stick to the U-L head and \
that's it. +    // Basic Xinerama support - position itself on the U-L head, along \
the bottom  if (QApplication::desktop()->isVirtualDesktop()) {
-        int screen = QApplication::desktop()->screenNumber(QPoint(0,0));
-        _sizePercentage = \
                100*QApplication::desktop()->screenGeometry(screen).width() / 
-                   QApplication::desktop()->width();
+        _xineramaScreen = QApplication::desktop()->screenNumber(QPoint(0,0));
+    } else {
+        _xineramaScreen = -1;
     }
 }
 
@@ -92,6 +92,7 @@ void PanelSettings::readConfig( KConfig 
                          c->readNumEntry(  "Position",               _position));
     _alignment         = static_cast<Alignment>(
                          c->readNumEntry(  "Alignment",              _alignment));
+    _xineramaScreen    = c->readNumEntry(  "XineramaScreen",         \
                _xineramaScreen);
     _HBwidth           = c->readNumEntry(  "HideButtonSize",         _HBwidth);
     _showLeftHB        = c->readBoolEntry( "ShowLeftHideButton",     _showLeftHB);
     _showRightHB       = c->readBoolEntry( "ShowRightHideButton",    _showRightHB);
@@ -130,6 +131,7 @@ void PanelSettings::readConfig( KConfig 
 void PanelSettings::writeConfig( KConfig *c ) {
     c->writeEntry( "Position", static_cast<int>(_position));
     c->writeEntry( "Alignment", static_cast<int>(_alignment));
+    c->writeEntry( "XineramaScreen",         _xineramaScreen);
     c->writeEntry( "HideButtonSize",         _HBwidth);
     c->writeEntry( "ShowLeftHideButton",     _showLeftHB);
     c->writeEntry( "ShowRightHideButton",    _showRightHB);
@@ -252,9 +254,9 @@ void PanelContainer::writeConfig( KConfi
     _settings.writeConfig( config );
 }
 
-void PanelContainer::arrange( Position p, Alignment a )
+void PanelContainer::arrange( Position p, Alignment a, int XineramaScreen )
 {
-    if ( p == _settings._position && a == _settings._alignment )
+    if ( p == _settings._position && a == _settings._alignment && XineramaScreen == \
_settings._xineramaScreen)  return;
 
     if ( p != _settings._position ) {
@@ -267,6 +269,11 @@ void PanelContainer::arrange( Position p
 	emit alignmentChange( a );
     }
 
+   if( XineramaScreen != _settings._xineramaScreen ) {
+	_settings._xineramaScreen = XineramaScreen;
+	emit xineramaScreenChange( XineramaScreen );
+    }
+
     updateLayout();
     writeConfig();
 }
@@ -334,7 +341,7 @@ void PanelContainer::hideRight()
 
 void PanelContainer::resetLayout()
 {
-    QRect g = initialGeometry( position(), alignment(), autoHidden(), userHidden() \
); +    QRect g = initialGeometry( position(), alignment(), xineramaScreen(), \
autoHidden(), userHidden() );  
     setGeometry( g );
 
@@ -648,9 +655,9 @@ bool PanelContainer::eventFilter( QObjec
     return false;
 }
 
-QSize PanelContainer::initialSize( Position p )
+QSize PanelContainer::initialSize( Position p, int XineramaScreen )
 {
-    QRect a = workArea();
+    QRect a = workArea(XineramaScreen);
 
 //    kdDebug(1210) << "     Work Area: (" << a.topLeft().x() << ", " << \
a.topLeft().y() << ") to ("  //                                 << \
a.bottomRight().x() << ", " << a.bottomRight().y() << ")" << endl; @@ -678,9 +685,9 \
@@ QSize PanelContainer::initialSize( Posit  return QSize( width, height );
 }
 
-QPoint PanelContainer::initialLocation( Position p, Alignment a, QSize s, bool \
autohidden, UserHidden userHidden ) +QPoint PanelContainer::initialLocation( Position \
p, Alignment a, int XineramaScreen, QSize s, bool autohidden, UserHidden userHidden ) \
                {
-    QRect area = workArea();
+    QRect area = workArea(XineramaScreen);
 
     int left;
     int top;
@@ -788,12 +795,12 @@ QPoint PanelContainer::initialLocation( 
     return QPoint( left, top );
 }
 
-QRect PanelContainer::initialGeometry( Position p, Alignment a, bool autoHidden, \
UserHidden userHidden ) +QRect PanelContainer::initialGeometry( Position p, Alignment \
a, int XineramaScreen, bool autoHidden, UserHidden userHidden )  {
 //    kdDebug(1210) << "   Computing geometry for " << name() << endl;
 
-    QSize size = initialSize( p );
-    QPoint point = initialLocation( p, a, size, autoHidden, userHidden );
+    QSize size = initialSize( p, XineramaScreen );
+    QPoint point = initialLocation( p, a, XineramaScreen, size, autoHidden, \
userHidden );  
 //    kdDebug(1210) << "     Size: " << size.width() << " x " << size.height() << \
endl;  //    kdDebug(1210) << "     Pos: (" << point.x() << ", " << point.y() << ")" \
<< endl; @@ -811,7 +818,7 @@ void PanelContainer::updateLayout()
 void PanelContainer::strutChanged()
 {
 //    kdDebug(1210) << "PanelContainer::strutChanged()" << endl;
-    if ( initialGeometry( position(), alignment(), autoHidden(), userHidden() ) != \
geometry() ) { +    if ( initialGeometry( position(), alignment(), xineramaScreen(), \
autoHidden(), userHidden() ) != geometry() ) {  updateLayout();
     }
 }
@@ -825,7 +832,7 @@ void PanelContainer::updateWindowManager
 
     QRect r(QApplication::desktop()->geometry());
 
-    QRect geom = initialGeometry( position(), alignment() );
+    QRect geom = initialGeometry( position(), alignment(), xineramaScreen() );
 
     if( userHidden() || _settings._hideMode != PanelSettings::Manual )
 	w = h = 0;
@@ -898,7 +905,7 @@ void PanelContainer::animatedHide(bool l
         newState = RightBottom;
 
     QPoint oldpos = pos();
-    QPoint newpos = initialGeometry( position(), alignment(), false, newState \
).topLeft(); +    QPoint newpos = initialGeometry( position(), alignment(), \
xineramaScreen(), false, newState ).topLeft();  
     if( newState != Unhidden ) {
 	_userHidden = newState;
@@ -980,7 +987,7 @@ void PanelContainer::autoHide(bool hide)
     blockUserInput(true);
 
     QPoint oldpos = pos();
-    QPoint newpos = initialGeometry( position(), alignment(), hide, Unhidden \
).topLeft(); +    QPoint newpos = initialGeometry( position(), alignment(), \
xineramaScreen(), hide, Unhidden ).topLeft();  
     if( hide ) {
 	// So we don't cover other panels
@@ -1048,18 +1055,19 @@ void PanelContainer::moveMe()
 
     Position  positions[]  = { ::Left, ::Right, ::Top, ::Bottom };
     Alignment alignments[] = { ::LeftTop, ::Center, ::RightBottom };
-    for( int i = 0; i < 4; i++ ) {
-        for( int j = 0; j < 3; j++ ) {
-            rects.append( initialGeometry( positions[i], alignments[j] ) );
+    for(int s = 0; s < QApplication::desktop()->numScreens(); s++) {
+        for( int i = 0; i < 4; i++ ) {
+            for( int j = 0; j < 3; j++ ) {
+                rects.append( initialGeometry( positions[i], alignments[j], s ) );
+            }
         }
     }
 
     int rect = UserRectSel::select(rects, position());
-    Position p = (Position)(rect / 3);
+    int XineramaScreen = rect / 12;
+    Position p = (Position)((rect / 3) % 4);
     Alignment a = (Alignment)(rect % 3);
-    setPosition( p );
-    setAlignment( a );
-    updateLayout();
+    arrange(p, a, XineramaScreen);
 
     _is_lmb_down = false;
 
@@ -1070,7 +1078,7 @@ void PanelContainer::moveMe()
     maybeStartAutoHideTimer();
 }
 
-QRect PanelContainer::workArea()
+QRect PanelContainer::workArea(int XineramaScreen)
 {
     QValueList<WId> list;
 
@@ -1087,7 +1095,7 @@ QRect PanelContainer::workArea()
 	list.append((*it)->winId());
     }
 
-    return kWinModule->workArea(list);
+    return kWinModule->workArea(list).intersect(QApplication::desktop()->screenGeometry(XineramaScreen));
  }
 
 PopupWidgetFilter::PopupWidgetFilter( QObject *parent )
Index: core/container_panel.h
===================================================================
RCS file: /home/kde/kdebase/kicker/core/container_panel.h,v
retrieving revision 1.26
diff -u -p -r1.26 container_panel.h
--- core/container_panel.h	2002/06/02 23:55:10	1.26
+++ core/container_panel.h	2002/06/05 03:48:46
@@ -51,6 +51,7 @@ public:
     // Configuration settings
     Position  _position;
     Alignment _alignment;
+		int       _xineramaScreen;
     int       _HBwidth;
     bool      _showLeftHB;
     bool      _showRightHB;
@@ -76,17 +77,20 @@ public:
     virtual ~PanelContainer();
 
     Position position() const { return _settings._position; }
-    void setPosition(Position p) { arrange( p, alignment() ); }
+    void setPosition(Position p) { arrange( p, alignment(), xineramaScreen() ); }
 
+    int xineramaScreen() const { return _settings._xineramaScreen; }
+    void setXineramaScreen(int screen) { arrange(position(),alignment(), screen); }
+
     virtual void setSize(Size size, int customSize = 0);
     Size size() const;
     int customSize() const;
 
     Alignment alignment() const { return _settings._alignment; }
-    void setAlignment(Alignment a) { arrange( position(), a ); }
+    void setAlignment(Alignment a) { arrange( position(), a, xineramaScreen() ); }
 
     enum UserHidden{ Unhidden, LeftTop, RightBottom };
-    QRect initialGeometry( Position p, Alignment a, bool autoHidden = false, \
UserHidden userHidden = Unhidden ); +    QRect initialGeometry( Position p, Alignment \
a, int XineramaScreen, bool autoHidden = false, UserHidden userHidden = Unhidden );  
     virtual QSize sizeHint( Position p, QSize maxSize );
     bool eventFilter( QObject *, QEvent * );
@@ -101,10 +105,11 @@ public:
 signals:
     void positionChange( Position pos );
     void alignmentChange( Alignment a );
+    void xineramaScreenChange ( int XineramaScreen );
     void sizeChange( int size, int customSize );
 
 protected:
-    void arrange( Position p, Alignment a );
+    void arrange( Position p, Alignment a, int XineramaScreen );
     void setMainWidget( QWidget* widget );
     virtual PanelSettings defaultSettings();
     bool autoHidden() const { return _autoHidden; };
@@ -112,7 +117,7 @@ protected:
     Orientation orientation() const;
     virtual void resetLayout();
     virtual bool vetoAutoHide() { return false; }
-    QRect workArea();
+    QRect workArea(int XineramaScreen);
 
     static KWinModule* kWinModule;
 
@@ -137,8 +142,8 @@ private slots:
     void stopAutoHideTimer();
 
 private:
-    QSize initialSize( Position p );
-    QPoint initialLocation( Position p, Alignment a, QSize s,
+    QSize initialSize( Position p, int XineramaScreen );
+    QPoint initialLocation( Position p, Alignment a, int XineramaScreen, QSize s,
          bool autohidden = false, UserHidden userHidden = Unhidden );
 
     PanelSettings    _settings;
Index: core/containerarea.cpp
===================================================================
RCS file: /home/kde/kdebase/kicker/core/containerarea.cpp,v
retrieving revision 1.122
diff -u -p -r1.122 containerarea.cpp
--- core/containerarea.cpp	2002/05/26 22:47:06	1.122
+++ core/containerarea.cpp	2002/06/05 03:48:46
@@ -114,7 +114,7 @@ void ContainerArea::defaultContainerConf
     containers.append( new KMenuButtonContainer( viewport() ) );
     containers.append( new DesktopButtonContainer( viewport() ) );
 
-    QRect r = panel->initialGeometry( panel->position(), panel->alignment() );
+    QRect r = panel->initialGeometry( panel->position(), panel->alignment(), \
panel->xineramaScreen() );  
     int dsize;
     if (orientation() == Horizontal)



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

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