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
This commit is contained in:
Luboš Luňák 2003-10-10 12:58:38 +00:00
parent f89dfaa318
commit 34fa4a4399
7 changed files with 85 additions and 114 deletions

View file

@ -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 )

View file

@ -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 );

View file

@ -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;

View file

@ -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

View file

@ -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();

12
utils.h
View file

@ -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:

View file

@ -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