use old screen sizes when calculating old window positions on screen size changes

icc-effect-5.14.5
Luboš Luňák 2011-09-30 13:22:39 +02:00
parent 2e7a1bfbf9
commit 40744b6b11
3 changed files with 42 additions and 8 deletions

View File

@ -76,6 +76,7 @@ void Workspace::desktopResized()
rootInfo->setDesktopGeometry(-1, desktop_geometry);
updateClientArea();
saveOldScreenSizes(); // after updateClientArea(), so that one still uses the previous one
#ifdef KWIN_BUILD_SCREENEDGES
m_screenEdge.update(true);
#endif
@ -83,6 +84,15 @@ void Workspace::desktopResized()
compositeResetTimer.start(0);
}
void Workspace::saveOldScreenSizes()
{
oldscreensizes.clear();
for( int i = 0;
i < numScreens();
++i )
oldscreensizes.append( screenGeometry( i ));
}
/*!
Updates the current client areas according to the current clients.
@ -216,7 +226,7 @@ void Workspace::updateClientArea(bool force)
++it)
(*it)->checkWorkspacePosition();
oldrestrictedmovearea.clear(); // reset, for hasPreviousRestrictedMoveAreas()
oldrestrictedmovearea.clear(); // reset, no longer valid or needed
}
kDebug(1212) << "Done.";
@ -341,6 +351,11 @@ QRegion Workspace::restrictedMoveArea(int desktop, StrutAreas areas) const
return region;
}
bool Workspace::inUpdateClientArea() const
{
return !oldrestrictedmovearea.isEmpty();
}
QRegion Workspace::previousRestrictedMoveArea(int desktop, StrutAreas areas) const
{
if (desktop == NETWinInfo::OnAllDesktops || desktop == 0)
@ -352,10 +367,9 @@ QRegion Workspace::previousRestrictedMoveArea(int desktop, StrutAreas areas) con
return region;
}
// This in practice returns true when we are inside Workspace::updateClientArea()
bool Workspace::hasPreviousRestrictedMoveAreas() const
QVector< QRect > Workspace::previousScreenSizes() const
{
return !oldrestrictedmovearea.isEmpty();
return oldscreensizes;
}
/*!
@ -1070,7 +1084,20 @@ void Client::checkWorkspacePosition(QRect oldGeometry, int oldDesktop)
// If the window was touching an edge before but not now move it so it is again.
// Old and new maximums have different starting values so windows on the screen
// edge will move when a new strut is placed on the edge.
const QRect oldScreenArea = workspace()->clientArea(ScreenArea, oldGeometry.center(), oldDesktop);
QRect oldScreenArea;
if( workspace()->inUpdateClientArea()) {
// we need to find the screen area as it was before the change
oldScreenArea = QRect( 0, 0, displayWidth(), displayHeight());
int distance = INT_MAX;
foreach( QRect r, workspace()->previousScreenSizes()) {
int d = r.contains( oldGeometry.center()) ? 0 : ( r.center() - oldGeometry.center()).manhattanLength();
if( d < distance ) {
distance = d;
oldScreenArea = r;
}
}
} else
oldScreenArea = workspace()->clientArea(ScreenArea, oldGeometry.center(), oldDesktop);
int oldTopMax = oldScreenArea.y();
int oldRightMax = oldScreenArea.x() + oldScreenArea.width();
int oldBottomMax = oldScreenArea.y() + oldScreenArea.height();
@ -1084,7 +1111,7 @@ void Client::checkWorkspacePosition(QRect oldGeometry, int oldDesktop)
const QRect newGeomWide = QRect(0, newGeom.y(), displayWidth(), newGeom.height()); // Full screen width
// Get the max strut point for each side where the window is (E.g. Highest point for
// the bottom struts bounded by the window's left and right sides).
if( workspace()->hasPreviousRestrictedMoveAreas()) {
if( workspace()->inUpdateClientArea()) {
// These 4 compute old bounds when the restricted areas themselves changed (Workspace::updateClientArea())
foreach (const QRect & r, workspace()->previousRestrictedMoveArea(oldDesktop, StrutAreaTop).rects()) {
QRect rect = r & oldGeomTall;

View File

@ -462,6 +462,7 @@ void Workspace::init()
// Propagate clients, will really happen at the end of the updates blocker block
updateStackingOrder(true);
saveOldScreenSizes();
updateClientArea();
// NETWM spec says we have to set it to (0,0) if we don't support it

View File

@ -120,8 +120,6 @@ public:
QRect clientArea(clientAreaOption, int screen, int desktop) const;
QRegion restrictedMoveArea(int desktop, StrutAreas areas = StrutAreaAll) const;
QRegion previousRestrictedMoveArea(int desktop, StrutAreas areas = StrutAreaAll) const;
bool hasPreviousRestrictedMoveAreas() const;
/**
* @internal
@ -339,6 +337,12 @@ public:
return activityController_.listActivities(KActivityInfo::Running);
}
// True when performing Workspace::updateClientArea().
// The calls below are valid only in that case.
bool inUpdateClientArea() const;
QRegion previousRestrictedMoveArea(int desktop, StrutAreas areas = StrutAreaAll) const;
QVector< QRect > previousScreenSizes() const;
// Tab box
#ifdef KWIN_BUILD_TABBOX
TabBox::TabBox *tabBox() const;
@ -717,6 +721,7 @@ private:
void blockStackingUpdates(bool block);
void updateToolWindows(bool also_hide);
void fixPositionAfterCrash(Window w, const XWindowAttributes& attr);
void saveOldScreenSizes();
/// This is the right way to create a new client
Client* createClient(Window w, bool is_mapped);
@ -878,6 +883,7 @@ private:
// Array of the previous restricted areas that window cannot be moved into
QVector<StrutRects> oldrestrictedmovearea;
QVector< QVector<QRect> > screenarea; // Array of workareas per xinerama screen for all virtual desktops
QVector< QRect > oldscreensizes; // array of previous sizes of xinerama screens
int set_active_client_recursion;
int block_stacking_updates; // When > 0, stacking updates are temporarily disabled