From 34fa4a43999571070647a9a101d6bdc51442c229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Fri, 10 Oct 2003 12:58:38 +0000 Subject: [PATCH] Cleanup of Xinerama handling. I don't claim I actually fixed something, but at least now the code doesn't look like uncommented random something. And who knows, maybe I even fixed it ;). CCMAIL: staikos@kde.org What the hell does "Show unmanaged windows on:" mean in the kcm dialog? svn path=/trunk/kdebase/kwin/; revision=257723 --- client.cpp | 2 +- client.h | 2 +- geometry.cpp | 109 ++++++++++++++------------------------------------ manage.cpp | 14 +++---- placement.cpp | 46 ++++++++++++++------- utils.h | 12 ++++++ workspace.h | 14 +------ 7 files changed, 85 insertions(+), 114 deletions(-) diff --git a/client.cpp b/client.cpp index 92f78aca9e..94e75640be 100644 --- a/client.cpp +++ b/client.cpp @@ -1534,7 +1534,7 @@ NET::WindowType Client::windowType( bool strict, int supported_types ) const // if it's as wide as the screen, not very high and has its upper-left // corner a bit above the screen's upper-left cornet, it's a topmenu if( x() == 0 && y() < 0 && y() > -10 && height() < 100 - && abs( width() - workspace()->geometry().width()) < 10 ) + && abs( width() - workspace()->clientArea( FullArea, this ).width()) < 10 ) wt = NET::TopMenu; } if( wt == NET::Unknown ) diff --git a/client.h b/client.h index 63b261a9c0..40992292c1 100644 --- a/client.h +++ b/client.h @@ -323,7 +323,7 @@ class Client : public QObject, public KDecorationDefines void fetchName(); void fetchIconicName(); - void updateWorkareaDiffs( const QRect& area = QRect()); + void updateWorkareaDiffs(); void checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area ); static int computeWorkareaDiff( int left, int right, int a_left, int a_right ); void configureRequest( int value_mask, int rx, int ry, int rw, int rh, int gravity = 0 ); diff --git a/geometry.cpp b/geometry.cpp index 3904df4c73..bf9776e30b 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -36,28 +36,6 @@ namespace KWinInternal // Workspace //******************************************** -/*! - Returns the workspace's geometry - - \sa clientArea() - */ -QRect Workspace::geometry() const - { - if ( root == qt_xrootwin() ) - return QRect( QPoint(0, 0), QApplication::desktop()->size() ); - else - { - // todo caching, keep track of configure notify etc. - QRect r; - XWindowAttributes attr; - if (XGetWindowAttributes(qt_xdisplay(), root, &attr)) - { - r.setRect(0, 0, attr.width, attr.height ); - } - return r; - } - } - /*! Resizes the workspace after an XRANDR screen size change */ @@ -147,9 +125,9 @@ void Workspace::updateClientArea() \sa geometry() */ -QRect Workspace::clientArea(clientAreaOption opt, const QPoint& p, int desktop ) const +QRect Workspace::clientArea( clientAreaOption opt, const QPoint& p, int desktop ) const { - if( desktop == NETWinInfo::OnAllDesktops ) + if( desktop == NETWinInfo::OnAllDesktops || desktop == 0 ) desktop = currentDesktop(); QRect rect = QApplication::desktop()->geometry(); QDesktopWidget *desktopwidget = KApplication::desktop(); @@ -157,6 +135,7 @@ QRect Workspace::clientArea(clientAreaOption opt, const QPoint& p, int desktop ) switch (opt) { case MaximizeArea: + case MaximizeFullArea: if (options->xineramaMaximizeEnabled) rect = desktopwidget->screenGeometry(desktopwidget->screenNumber(p)); break; @@ -168,44 +147,23 @@ QRect Workspace::clientArea(clientAreaOption opt, const QPoint& p, int desktop ) if (options->xineramaMovementEnabled) rect = desktopwidget->screenGeometry(desktopwidget->screenNumber(p)); break; + case WorkArea: + case FullArea: + break; // nothing + case ScreenArea: + rect = desktopwidget->screenGeometry(desktopwidget->screenNumber(p)); + break; } - if (workarea[ desktop ].isNull()) + if( workarea[ desktop ].isNull() || opt == FullArea || opt == MaximizeFullArea || opt == ScreenArea ) return rect; return workarea[ desktop ].intersect(rect); } -QRect Workspace::clientArea(clientAreaOption opt, const QPoint& p) const +QRect Workspace::clientArea( clientAreaOption opt, const Client* c ) const { - return clientArea( opt, p, currentDesktop()); - } - -QRect Workspace::clientArea(const QPoint& p, int desktop) const - { - if( desktop == NETWinInfo::OnAllDesktops ) - desktop = currentDesktop(); - - QRect rect; - if (options->xineramaPlacementEnabled) - { - int screenNum = QApplication::desktop()->screenNumber(p); - rect = QApplication::desktop()->screenGeometry(screenNum); - } - else - { - rect = QApplication::desktop()->geometry(); - } - - if (workarea[ desktop ].isNull()) - return rect; - - return workarea[ desktop ].intersect(rect); - } - -QRect Workspace::clientArea(const QPoint& p) const - { - return clientArea( p, currentDesktop()); + return clientArea( opt, c->geometry().center(), c->desktop()); } /*! @@ -407,12 +365,9 @@ QRect Client::adjustedClientArea( const QRect& area ) const // updates differences to workarea edges for all directions -// area_ is workarea for this Client (optimization - given only if already known) -void Client::updateWorkareaDiffs( const QRect& area_ ) +void Client::updateWorkareaDiffs() { - QRect area = area_; - if( !area.isValid()) // default arg - area = workspace()->clientArea( geometry().center(), desktop()); + QRect area = workspace()->clientArea( WorkArea, this ); QRect geom = geometry(); workarea_diff_x = computeWorkareaDiff( geom.left(), geom.right(), area.left(), area.right()); workarea_diff_y = computeWorkareaDiff( geom.top(), geom.bottom(), area.top(), area.bottom()); @@ -452,8 +407,7 @@ void Client::checkWorkspacePosition() if( isFullScreen()) { - QRect area = workspace()->geometry(); - // TODO XINERAMA only one xinerama screen + QRect area = workspace()->clientArea( MaximizeFullArea, this ); if( geometry() != area ) setGeometry( area ); return; @@ -465,16 +419,16 @@ void Client::checkWorkspacePosition() if( isTopMenu()) { if( workspace()->managingTopMenus()) - { // XINERAMA + { QRect area; - ClientList mainclients = mainClients(); - if( mainclients.count() == 1 ) - area = kapp->desktop()->screenGeometry( mainclients.first()->geometry().center()); - else - area = kapp->desktop()->geometry(); // desktop menu ? - area.setHeight( workspace()->topMenuHeight()); + ClientList mainclients = mainClients(); + if( mainclients.count() == 1 ) + area = workspace()->clientArea( MaximizeFullArea, mainclients.first()); + else + area = workspace()->clientArea( MaximizeFullArea, QPoint( 0, 0 ), desktop()); + area.setHeight( workspace()->topMenuHeight()); // kdDebug() << "TOPMENU size adjust: " << area << ":" << this << endl; - setGeometry( area ); + setGeometry( area ); } NETStrut strut = info->strut(); int top = workspace()->managingTopMenus() ? workspace()->topMenuHeight() : 0; @@ -493,10 +447,9 @@ void Client::checkWorkspacePosition() if( !isShade()) // TODO { - QRect area = workspace()->clientArea( geometry().center(), desktop()); int old_diff_x = workarea_diff_x; int old_diff_y = workarea_diff_y; - updateWorkareaDiffs( area ); + updateWorkareaDiffs(); // this can be true only if this window was mapped before KWin // was started - in such case, don't adjust position to workarea, @@ -506,6 +459,7 @@ void Client::checkWorkspacePosition() if( workspace()->initializing()) return; + QRect area = workspace()->clientArea( WorkArea, this ); QRect new_geom = geometry(); QRect tmp_rect_x( new_geom.left(), 0, new_geom.width(), 0 ); QRect tmp_area_x( area.left(), 0, area.width(), 0 ); @@ -525,7 +479,7 @@ void Client::checkWorkspacePosition() } if( final_geom != geometry() ) setGeometry( final_geom ); - // updateWorkareaDiffs( area ); done already by setGeometry() + // updateWorkareaDiffs(); done already by setGeometry() } } @@ -920,7 +874,7 @@ void Client::resizeWithChecks( int w, int h, ForceGeometry_t force ) { int newx = x(); int newy = y(); - QRect area = workspace()->clientArea( geometry().center(), desktop()); + QRect area = workspace()->clientArea( WorkArea, this ); // don't allow growing larger than workarea if( w > area.width()) w = area.width(); @@ -1200,7 +1154,7 @@ void Client::changeMaximize( bool vertical, bool horizontal, bool adjust ) if( decoration != NULL ) // decorations may turn off some borders when maximized decoration->borders( border_left, border_right, border_top, border_bottom ); - QRect clientArea = workspace()->clientArea(geometry().center()); + QRect clientArea = workspace()->clientArea( MaximizeArea, this ); switch (max_mode) { @@ -1342,8 +1296,7 @@ void Client::setFullScreen( bool set, bool user ) info->setState( isFullScreen() ? NET::FullScreen : 0, NET::FullScreen ); updateDecoration( false, false, true ); // delayed deletion of decoration if( isFullScreen()) - setGeometry( workspace()->geometry()); - // XINERAMA only on one screen + setGeometry( workspace()->clientArea( MaximizeFullArea, this )); else { if( maximizeMode() != MaximizeRestore ) @@ -1353,7 +1306,7 @@ void Client::setFullScreen( bool set, bool user ) // TODO isShaded() ? else { // does this ever happen? - setGeometry( workspace()->clientArea( Workspace::MaximizeArea, geometry().center(), desktop())); + setGeometry( workspace()->clientArea( MaximizeArea, this )); } } } @@ -1507,7 +1460,7 @@ void Client::handleMoveResize( int x, int y, int x_root, int y_root ) setShade( ShadeNone ); QPoint globalPos( x_root, y_root ); - QRect desktopArea = workspace()->clientArea( globalPos ); + QRect desktopArea = workspace()->clientArea( WorkArea, globalPos, desktop()); QPoint p = globalPos + invertedMoveOffset; diff --git a/manage.cpp b/manage.cpp index e86902d203..5f06285845 100644 --- a/manage.cpp +++ b/manage.cpp @@ -199,22 +199,22 @@ bool Client::manage( Window w, bool isMapped ) if ( session ) geom = session->geometry; - QRect area = workspace()->clientArea( geom.center(), desktop()); + QRect area = workspace()->clientArea( PlacementArea, geom.center(), desktop()); - - if (( geom.size() == workspace()->geometry().size()) // XINERAMA TODO check also size of the screen + // if it's noborder window, and has size of one screen or the whole desktop geometry, it's fullscreen hack + if( ( geom.size() == workspace()->clientArea( FullArea, geom.center(), desktop()).size() + || geom.size() == workspace()->clientArea( ScreenArea, geom.center(), desktop()).size()) && noBorder() && !isUserNoBorder() && isFullScreenable()) { fullscreen_mode = FullScreenHack; - // TODO XINERAMA show fullscreen on only one xinerama screen - geom.moveTopLeft( QPoint( 0, 0 )); // in case they try to make it fullscreen, but misplace (#55290) + geom = workspace()->clientArea( MaximizeFullArea, geom.center(), desktop()); placementDone = true; } if ( isDesktop() ) { // desktops are treated slightly special - geom = workspace()->geometry(); + geom = workspace()->clientArea( FullArea, geom.center(), desktop()); placementDone = true; } @@ -484,7 +484,7 @@ bool Client::manage( Window w, bool isMapped ) user_time = qt_x_time - 1000000 + 10; } - updateWorkareaDiffs( area ); + updateWorkareaDiffs(); // sendSyntheticConfigureNotify(); done when setting mapping state diff --git a/placement.cpp b/placement.cpp index ff4ca4b8e7..a9f46e26b8 100644 --- a/placement.cpp +++ b/placement.cpp @@ -71,7 +71,7 @@ void Placement::placeAtRandom(Client* c) static int py = 2 * step; int tx,ty; - const QRect maxRect = m_WorkspacePtr->clientArea(Workspace::PlacementArea); // TODO use desktop number + const QRect maxRect = m_WorkspacePtr->clientArea( PlacementArea, c ); if (px < maxRect.x()) px = maxRect.x(); @@ -129,7 +129,7 @@ void Placement::placeSmart(Client* c) int basket; //temp holder // get the maximum allowed windows space - const QRect maxRect = m_WorkspacePtr->clientArea(Workspace::PlacementArea); + const QRect maxRect = m_WorkspacePtr->clientArea( PlacementArea, c ); int x = maxRect.left(), y = maxRect.top(); x_optimal = x; y_optimal = y; @@ -293,7 +293,7 @@ void Placement::placeCascaded (Client* c, bool re_init) // get the maximum allowed windows space and desk's origin // (CT 20Nov1999 - is this common to all desktops?) - QRect maxRect = m_WorkspacePtr->clientArea(Workspace::PlacementArea); + QRect maxRect = m_WorkspacePtr->clientArea( PlacementArea, c ); // initialize often used vars: width and height of c; we gain speed const int ch = c->height(); @@ -369,7 +369,7 @@ void Placement::placeCentered (Client* c) // get the maximum allowed windows space and desk's origin // (CT 20Nov1999 - is this common to all desktops?) - const QRect maxRect = m_WorkspacePtr->clientArea(Workspace::PlacementArea); + const QRect maxRect = m_WorkspacePtr->clientArea( PlacementArea, c ); const int xp = maxRect.left() + (maxRect.width() - c->width()) / 2; const int yp = maxRect.top() + (maxRect.height() - c->height()) / 2; @@ -385,7 +385,7 @@ void Placement::placeZeroCornered(Client* c) { // get the maximum allowed windows space and desk's origin // (CT 20Nov1999 - is this common to all desktops?) - const QRect maxRect = m_WorkspacePtr->clientArea(Workspace::PlacementArea); + const QRect maxRect = m_WorkspacePtr->clientArea( PlacementArea, c ); // place the window c->move(QPoint(maxRect.left(), maxRect.top())); @@ -503,7 +503,9 @@ void Client::growHorizontal() if( geometry().size() == adjsize && geom.size() != adjsize && xSizeHint.width_inc > 1 ) // take care of size increments { int newright = workspace()->packPositionRight( this, geom.right() + xSizeHint.width_inc - 1, true ); - if( workspace()->clientArea( Workspace::MovementArea, geometry().center(), desktop()).right() >= newright ) + // check that it hasn't grown outside of the area, due to size increments + if( workspace()->clientArea( MovementArea, + QPoint(( x() + newright ) / 2, geometry().center().y()), desktop()).right() >= newright ) geom.setRight( newright ); } geom.setSize( adjustedSize( geom.size())); @@ -541,7 +543,9 @@ void Client::growVertical() if( geometry().size() == adjsize && geom.size() != adjsize && xSizeHint.height_inc > 1 ) // take care of size increments { int newbottom = workspace()->packPositionDown( this, geom.bottom() + xSizeHint.height_inc - 1, true ); - if( workspace()->clientArea( Workspace::MovementArea, geometry().center(), desktop()).bottom() >= newbottom ) + // check that it hasn't grown outside of the area, due to size increments + if( workspace()->clientArea( MovementArea, + QPoint( geometry().center().x(), ( y() + newbottom ) / 2 ), desktop()).bottom() >= newbottom ) geom.setBottom( newbottom ); } geom.setSize( adjustedSize( geom.size())); @@ -568,8 +572,11 @@ void Client::shrinkVertical() int Workspace::packPositionLeft( const Client* cl, int oldx, bool left_edge ) const { - int newx = clientArea( MovementArea, cl->geometry().center(), cl->desktop()).left(); - if( oldx < newx ) + int newx = clientArea( MovementArea, cl ).left(); + if( oldx <= newx ) // try another Xinerama screen + newx = clientArea( MovementArea, + QPoint( cl->geometry().left() - 1, cl->geometry().center().y()), cl->desktop()).left(); + if( oldx <= newx ) return oldx; for( ClientList::ConstIterator it = clients.begin(); it != clients.end(); @@ -588,8 +595,11 @@ int Workspace::packPositionLeft( const Client* cl, int oldx, bool left_edge ) co int Workspace::packPositionRight( const Client* cl, int oldx, bool right_edge ) const { - int newx = clientArea( MovementArea, cl->geometry().center(), cl->desktop()).right(); - if( oldx > newx ) + int newx = clientArea( MovementArea, cl ).right(); + if( oldx >= newx ) // try another Xinerama screen + newx = clientArea( MovementArea, + QPoint( cl->geometry().right() + 1, cl->geometry().center().y()), cl->desktop()).right(); + if( oldx >= newx ) return oldx; for( ClientList::ConstIterator it = clients.begin(); it != clients.end(); @@ -608,8 +618,11 @@ int Workspace::packPositionRight( const Client* cl, int oldx, bool right_edge ) int Workspace::packPositionUp( const Client* cl, int oldy, bool top_edge ) const { - int newy = clientArea( MovementArea, cl->geometry().center(), cl->desktop()).top(); - if( oldy < newy ) + int newy = clientArea( MovementArea, cl ).top(); + if( oldy <= newy ) // try another Xinerama screen + newy = clientArea( MovementArea, + QPoint( cl->geometry().center().x(), cl->geometry().top() - 1 ), cl->desktop()).top(); + if( oldy <= newy ) return oldy; for( ClientList::ConstIterator it = clients.begin(); it != clients.end(); @@ -628,8 +641,11 @@ int Workspace::packPositionUp( const Client* cl, int oldy, bool top_edge ) const int Workspace::packPositionDown( const Client* cl, int oldy, bool bottom_edge ) const { - int newy = clientArea( MovementArea, cl->geometry().center(), cl->desktop()).bottom(); - if( oldy > newy ) + int newy = clientArea( MovementArea, cl ).bottom(); + if( oldy >= newy ) // try another Xinerama screen + newy = clientArea( MovementArea, + QPoint( cl->geometry().center().x(), cl->geometry().bottom() + 1 ), cl->desktop()).bottom(); + if( oldy >= newy ) return oldy; for( ClientList::ConstIterator it = clients.begin(); it != clients.end(); diff --git a/utils.h b/utils.h index 08363c4d0b..b8faa45efa 100644 --- a/utils.h +++ b/utils.h @@ -75,6 +75,18 @@ enum allowed_t { Allowed }; // some enums to have more readable code, instead of using bools enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet }; +// Areas, mostly related to Xinerama +enum clientAreaOption + { + PlacementArea, // geometry where a window will be initially placed after being mapped + MovementArea, // ??? window movement snapping area? + MaximizeArea, // geometry to which a window will be maximized + MaximizeFullArea, // like MaximizeArea, but ignore struts - used e.g. for fullscreening + WorkArea, // whole workarea (all screens together) + FullArea, // whole area (all screens together), ignore struts + ScreenArea // one whole screen, ignore struts + }; + class Shape { public: diff --git a/workspace.h b/workspace.h index 622dfddc66..1dc5293c39 100644 --- a/workspace.h +++ b/workspace.h @@ -84,18 +84,8 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine void addGroup( Group* group, allowed_t ); void removeGroup( Group* group, allowed_t ); - QRect geometry() const; - - enum clientAreaOption { PlacementArea, MovementArea, MaximizeArea }; - - - // default is MaximizeArea - QRect clientArea(clientAreaOption, const QPoint& p, int desktop) const; - QRect clientArea(const QPoint& p, int desktop) const; - // KDE4 remove the following 3 methods - inline QRect clientArea(clientAreaOption opt) const { return clientArea(opt, QCursor::pos()); } - QRect clientArea(clientAreaOption, const QPoint& p) const; - QRect clientArea(const QPoint& p) const; + QRect clientArea( clientAreaOption, const QPoint& p, int desktop ) const; + QRect clientArea( clientAreaOption, const Client* c ) const; /** * @internal