From kde-core-devel Wed Jun 05 04:06:39 2002 From: Kevin Puetz Date: Wed, 05 Jun 2002 04:06:39 +0000 To: kde-core-devel Subject: Kicker Xinerama support X-MARC-Message: https://marc.info/?l=kde-core-devel&m=102325015117179 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_P5Y/85IpgWnh+fV" --Boundary-00=_P5Y/85IpgWnh+fV Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8bit Content-Disposition: inline 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. --Boundary-00=_P5Y/85IpgWnh+fV Content-Type: text/x-diff; charset="us-ascii"; name="kicker-xinerama.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kicker-xinerama.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( 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(_position)); c->writeEntry( "Alignment", static_cast(_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 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) --Boundary-00=_P5Y/85IpgWnh+fV--