From kde-core-devel Fri Jun 07 01:19:08 2002 From: Kevin Puetz Date: Fri, 07 Jun 2002 01:19:08 +0000 To: kde-core-devel Subject: Re: Kicker Xinerama support X-MARC-Message: https://marc.info/?l=kde-core-devel&m=102341287329820 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--nextPart2127242.g13jEoqQvt" --nextPart2127242.g13jEoqQvt Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8Bit Kevin Puetz wrote: > Kevin Puetz wrote: > > Ok, second cut, all the above bugs are corrected except the lack of > kcontrol configuration. If nobody has any great suggestions, I'm just > going to add a combobox to pick the screen number a panel is on, because I > think trying to represent all the possible locations for Xinerama > placement is just too messy. Better to just drag&drop if you want to see > what you're getting. > > I need to check this on non-Xinerama, and then I'm going to commit if I > don't hear any objections. Oops, I apparently made the diff before, rather than after, fixing a missing semicolon ;-) sorry folks, last time around --nextPart2127242.g13jEoqQvt Content-Type: text/x-diff; name="kicker-xinerama.diff" Content-Transfer-Encoding: 8Bit Content-Disposition: attachment; filename="kicker-xinerama.diff" ? .snprj ? kicker.proj ? core/.container_panel.h.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/07 01:17:36 @@ -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); @@ -171,8 +173,8 @@ PanelContainer::PanelContainer(QWidget * setLineWidth( 0 ); setMargin(0); - connect( UnhideTrigger::the(), SIGNAL(triggerUnhide(UnhideTrigger::Trigger)), - SLOT(unhideTriggered(UnhideTrigger::Trigger)) ); + connect( UnhideTrigger::the(), SIGNAL(triggerUnhide(UnhideTrigger::Trigger,int)), + SLOT(unhideTriggered(UnhideTrigger::Trigger,int)) ); _popupWidgetFilter = new PopupWidgetFilter( this ); connect( _popupWidgetFilter, SIGNAL(popupWidgetHiding()), SLOT(maybeStartAutoHideTimer()) ); @@ -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 ); @@ -448,7 +455,7 @@ void PanelContainer::blockUserInput( boo // are printed! WTF?! This happens if you drag an applet handle outside // the panel and wait for the timeout. I am completely mystified // by this. -void PanelContainer::unhideTriggered( UnhideTrigger::Trigger tr ) +void PanelContainer::unhideTriggered( UnhideTrigger::Trigger tr, int XineramaScreen ) { if( _settings._hideMode == PanelSettings::Manual ) return; @@ -468,6 +475,9 @@ void PanelContainer::unhideTriggered( Un if( !_autoHidden ) return; + if(XineramaScreen != _settings._xineramaScreen) + return; + int x = QCursor::pos().x(); int y = QCursor::pos().y(); int t = geometry().top(); @@ -648,9 +658,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 +688,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; @@ -784,16 +794,15 @@ QPoint PanelContainer::initialLocation( break; } } - 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 +820,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,18 +834,30 @@ 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; // only call KWin::setStrut when the strut is really changed + + //FIXME do not set the strut if we are not actually along the edge of the virtual screen, since + //NETWM has no way to represent the resulting non-rectangular client areas that result in + //an Xinerama environment. Remove these checks once NetWM is smarter NETStrut strut; switch (position()) { - case ::Top: strut.top = geom.y() + h; break; - case ::Bottom: strut.bottom = (r.bottom() - geom.y() - height()) + h + 1; break; - case ::Right: strut.right = (r.right() - geom.x() - width()) + w + 1; break; - case ::Left: strut.left = geom.x() + w; break; + case ::Top: if(geom.top() == r.top()) + strut.top = geom.y() + h; + break; + case ::Bottom: if(geom.bottom() == r.bottom()) + strut.bottom = (r.bottom() - geom.bottom()) + h + 1; + break; + case ::Right: if(geom.right() == r.right()) + strut.right = (r.right() - geom.right()) + w + 1; + break; + case ::Left: if(geom.left() == r.left()) + strut.left = geom.x() + w; + break; } if ( strut.left != _strut.left || @@ -847,12 +868,7 @@ void PanelContainer::updateWindowManager _strut = strut; // kdDebug(1210) << "Panel sets new strut: " << position() << endl; // kdDebug(1210) << strut.top << " " << strut.bottom << " " << strut.right << " " << strut.left << endl; - switch (position()) { - case ::Top: KWin::setStrut( winId(), 0, 0, strut.top, 0 ); break; - case ::Bottom: KWin::setStrut( winId(), 0, 0, 0, strut.bottom); break; - case ::Right: KWin::setStrut( winId(), 0, strut.right, 0, 0 ); break; - case ::Left: KWin::setStrut( winId(), strut.left, 0, 0, 0 ); break; - } + KWin::setStrut( winId(), strut.left, strut.right, strut.top, strut.bottom ); } } @@ -893,14 +909,28 @@ void PanelContainer::animatedHide(bool l if( _userHidden != Unhidden ) newState = Unhidden; else if( left ) - newState = LeftTop; + newState = LeftTop; else newState = RightBottom; QPoint oldpos = pos(); - QPoint newpos = initialGeometry( position(), alignment(), false, newState ).topLeft(); + QRect newextent = initialGeometry( position(), alignment(), xineramaScreen(), false, newState ); + QPoint newpos(newextent.topLeft()); if( newState != Unhidden ) { + /* bail out if we are unable to hide */ + for(int s=0; s < QApplication::desktop()->numScreens(); s++) { + /* don't let it intersect with any screen in the hidden position + * that it doesn't intesect in the shown position. Should prevent + * panels from hiding by sliding onto other screens, while still + * letting them show reveal buttons onscreen */ + if(QApplication::desktop()->screenGeometry(s).intersects(newextent) + && !QApplication::desktop()->screenGeometry(s).intersects(geometry())) { + blockUserInput( false ); + return; + } + } + _userHidden = newState; // So we don't cover the mac-style menubar @@ -970,6 +1000,28 @@ void PanelContainer::autoHide(bool hide) // kdDebug(1210) << "entering autohide for real" << endl; + blockUserInput(true); + + QPoint oldpos = pos(); + QRect newextent = initialGeometry( position(), alignment(), xineramaScreen(), hide, Unhidden ); + QPoint newpos = newextent.topLeft(); + + if ( hide ) { + /* bail out if we are unable to hide */ + + for(int s=0; s < QApplication::desktop()->numScreens(); s++) { + /* don't let it intersect with any screen in the hidden position + * that it doesn't intesect in the shown position. Should prevent + * panels from hiding by sliding onto other screens, while still + * letting them show reveal buttons onscreen */ + if(QApplication::desktop()->screenGeometry(s).intersects(newextent) + && !QApplication::desktop()->screenGeometry(s).intersects(geometry())) { + blockUserInput( false ); + return; + } + } + + } _in_autohide = true; PanelButtonBase::setZoomEnabled(false); @@ -977,11 +1029,6 @@ void PanelContainer::autoHide(bool hide) _autoHidden = hide; UnhideTrigger::the()->setEnabled( _autoHidden ); - blockUserInput(true); - - QPoint oldpos = pos(); - QPoint newpos = initialGeometry( position(), alignment(), hide, Unhidden ).topLeft(); - if( hide ) { // So we don't cover other panels lower(); @@ -1048,18 +1095,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 +1118,7 @@ void PanelContainer::moveMe() maybeStartAutoHideTimer(); } -QRect PanelContainer::workArea() +QRect PanelContainer::workArea(int XineramaScreen) { QValueList list; @@ -1087,7 +1135,10 @@ QRect PanelContainer::workArea() list.append((*it)->winId()); } - return kWinModule->workArea(list); + if(XineramaScreen < 0 || XineramaScreen >= QApplication::desktop()->numScreens()) + /* force invalid screen locations onto the primary screen */ + XineramaScreen = QApplication::desktop()->primaryScreen(); + 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/07 01:17:36 @@ -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; @@ -123,7 +128,7 @@ protected slots: void enableZoomedIcons(); private slots: - void unhideTriggered( UnhideTrigger::Trigger t ); + void unhideTriggered( UnhideTrigger::Trigger t, int XineramaScreen ); void autoHideTimeout(); void hideLeft(); void hideRight(); @@ -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/07 01:17:37 @@ -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) Index: core/unhidetrigger.cpp =================================================================== RCS file: /home/kde/kdebase/kicker/core/unhidetrigger.cpp,v retrieving revision 1.1 diff -u -p -r1.1 unhidetrigger.cpp --- core/unhidetrigger.cpp 2002/02/27 13:31:49 1.1 +++ core/unhidetrigger.cpp 2002/06/07 01:17:37 @@ -36,6 +36,7 @@ UnhideTrigger* UnhideTrigger::the() UnhideTrigger::UnhideTrigger() : _lastTrigger( None ) + , _lastXineramaScreen( -1 ) , enabledCount( 0 ) { _timer = new QTimer( this ); @@ -64,37 +65,42 @@ bool UnhideTrigger::isEnabled() const void UnhideTrigger::pollMouse() { QPoint pos = QCursor::pos(); - QRect r = QApplication::desktop()->geometry(); - if( pos.x() == 0 ) { - if( pos.y() == 0 ) { - emitTrigger( TopLeft ); + for(int s = 0; s < QApplication::desktop()->numScreens(); s++) + { + QRect r = QApplication::desktop()->screenGeometry(s); + if( pos.x() == r.left() ) { + if( pos.y() == r.top() ) { + emitTrigger( TopLeft, s ); + } else if( pos.y() == r.bottom() ) { + emitTrigger( BottomLeft, s ); + } else { + emitTrigger( Left, s ); + } + } else if( pos.x() == r.right() ) { + if( pos.y() == r.top() ) { + emitTrigger( TopRight, s ); + } else if( pos.y() == r.bottom() ) { + emitTrigger( BottomRight ,s ); + } else { + emitTrigger( Right, s ); + } + } else if( pos.y() == r.top() ) { + emitTrigger( Top, s ); } else if( pos.y() == r.bottom() ) { - emitTrigger( BottomLeft ); + emitTrigger( Bottom, s ); } else { - emitTrigger( Left ); + _lastTrigger = None; + _lastXineramaScreen = -1; } - } else if( pos.x() == r.right() ) { - if( pos.y() == 0 ) { - emitTrigger( TopRight ); - } else if( pos.y() == r.bottom() ) { - emitTrigger( BottomRight ); - } else { - emitTrigger( Right ); - } - } else if( pos.y() == 0 ) { - emitTrigger( Top ); - } else if( pos.y() == r.bottom() ) { - emitTrigger( Bottom ); - } else { - _lastTrigger = None; } } -void UnhideTrigger::emitTrigger( Trigger t ) +void UnhideTrigger::emitTrigger( Trigger t, int XineramaScreen ) { - if( _lastTrigger == t ) + if( _lastTrigger == t && _lastXineramaScreen == XineramaScreen) return; _lastTrigger = t; - emit triggerUnhide( t ); + _lastXineramaScreen = XineramaScreen; + emit triggerUnhide( t, XineramaScreen ); } Index: core/unhidetrigger.h =================================================================== RCS file: /home/kde/kdebase/kicker/core/unhidetrigger.h,v retrieving revision 1.1 diff -u -p -r1.1 unhidetrigger.h --- core/unhidetrigger.h 2002/02/27 13:31:49 1.1 +++ core/unhidetrigger.h 2002/06/07 01:17:37 @@ -42,13 +42,14 @@ public: bool isEnabled() const; signals: - void triggerUnhide( UnhideTrigger::Trigger t ); + void triggerUnhide( UnhideTrigger::Trigger t, int XineramaScreen ); private slots: void pollMouse(); private: UnhideTrigger(); - void emitTrigger( Trigger t ); + void emitTrigger( Trigger t , int XineramaScreen); Trigger _lastTrigger; + int _lastXineramaScreen; QTimer *_timer; int enabledCount; }; Index: core/userrectsel.cpp =================================================================== RCS file: /home/kde/kdebase/kicker/core/userrectsel.cpp,v retrieving revision 1.2 diff -u -p -r1.2 userrectsel.cpp --- core/userrectsel.cpp 2002/03/16 06:11:32 1.2 +++ core/userrectsel.cpp 2002/06/07 01:17:37 @@ -66,8 +66,6 @@ void UserRectSel::mouseMoveEvent( QMouse QRect r( rectangles[i] ); int ndiff = (r.center().x() - e->globalPos().x() ) * (r.center().x() - e->globalPos().x() ) + (r.center().y() - e->globalPos().y() ) * (r.center().y() - e->globalPos().y() ); - if ( r.contains( e->globalPos() ) ) - ndiff = 0; if ( diff < 0 || ndiff < diff ) { diff = ndiff; nearest = i; --nextPart2127242.g13jEoqQvt--