diff --git a/src/abstract_client.cpp b/src/abstract_client.cpp index 7687b5c75b54944516d9a795dacabf96f5cd44f9..fda6f94dd9630213c9fe9b29a4e7007d5e1cd96a 100644 --- a/src/abstract_client.cpp +++ b/src/abstract_client.cpp @@ -260,10 +260,7 @@ void AbstractClient::updateLayer() void AbstractClient::placeIn(const QRect &area) { - // TODO: Get rid of this method eventually. We need to call setGeometryRestore() because - // checkWorkspacePosition() operates on geometryRestore() and because of quick tiling. Placement::self()->place(this, area); - setGeometryRestore(moveResizeGeometry()); } void AbstractClient::invalidateLayer() @@ -3349,8 +3346,10 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, QRect oldClientGe } enum { Left = 0, Top, Right, Bottom }; const int border[4] = { borderLeft(), borderTop(), borderRight(), borderBottom() }; + + QRect newGeom = moveResizeGeometry(); if( !oldGeometry.isValid()) - oldGeometry = moveResizeGeometry(); + oldGeometry = newGeom; if (!oldClientGeometry.isValid()) oldClientGeometry = oldGeometry.adjusted(border[Left], border[Top], -border[Right], -border[Bottom]); if (isFullScreen()) { @@ -3359,7 +3358,6 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, QRect oldClientGe } if (maximizeMode() != MaximizeRestore) { - GeometryUpdatesBlocker block(this); changeMaximize(false, false, true); // adjust size QRect geom = moveResizeGeometry(); const QRect screenArea = workspace()->clientArea(ScreenArea, this, geom.center()); @@ -3390,20 +3388,18 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, QRect oldClientGe // 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. QRect oldScreenArea; + QRect screenArea; if( workspace()->inUpdateClientArea()) { // we need to find the screen area as it was before the change - oldScreenArea = QRect( 0, 0, workspace()->oldDisplayWidth(), workspace()->oldDisplayHeight()); - int distance = INT_MAX; - const auto previousSizes = workspace()->previousScreenSizes(); - for (const QRect &r : previousSizes) { - int d = r.contains( oldGeometry.center()) ? 0 : ( r.center() - oldGeometry.center()).manhattanLength(); - if( d < distance ) { - distance = d; - oldScreenArea = r; - } + oldScreenArea = workspace()->previousScreenSizes().value(output()); + if (oldScreenArea.isNull()) { + oldScreenArea = output()->geometry(); } + screenArea = output()->geometry(); + newGeom.translate(screenArea.topLeft() - oldScreenArea.topLeft()); } else { oldScreenArea = workspace()->clientArea(ScreenArea, kwinApp()->platform()->outputAt(oldGeometry.center()), oldDesktop); + screenArea = workspace()->clientArea(ScreenArea, this, newGeom.center()); } const QRect oldGeomTall = QRect(oldGeometry.x(), oldScreenArea.y(), oldGeometry.width(), oldScreenArea.height()); // Full screen height const QRect oldGeomWide = QRect(oldScreenArea.x(), oldGeometry.y(), oldScreenArea.width(), oldGeometry.height()); // Full screen width @@ -3411,12 +3407,10 @@ void AbstractClient::checkWorkspacePosition(QRect oldGeometry, QRect oldClientGe int oldRightMax = oldScreenArea.x() + oldScreenArea.width(); int oldBottomMax = oldScreenArea.y() + oldScreenArea.height(); int oldLeftMax = oldScreenArea.x(); - const QRect screenArea = workspace()->clientArea(ScreenArea, this, geometryRestore().center()); int topMax = screenArea.y(); int rightMax = screenArea.x() + screenArea.width(); int bottomMax = screenArea.y() + screenArea.height(); int leftMax = screenArea.x(); - QRect newGeom = geometryRestore(); // geometry(); QRect newClientGeom = newGeom.adjusted(border[Left], border[Top], -border[Right], -border[Bottom]); const QRect newGeomTall = QRect(newGeom.x(), screenArea.y(), newGeom.width(), screenArea.height()); // Full screen height const QRect newGeomWide = QRect(screenArea.x(), newGeom.y(), screenArea.width(), newGeom.height()); // Full screen width diff --git a/src/internal_client.cpp b/src/internal_client.cpp index 948f48c9333d4335bfed8bd3124388f3fb922304..43eceef3befdbfdc323d585c4906d23c7ea6375a 100644 --- a/src/internal_client.cpp +++ b/src/internal_client.cpp @@ -58,7 +58,6 @@ InternalClient::InternalClient(QWindow *window) commitGeometry(m_internalWindow->geometry()); updateDecoration(true); moveResize(clientRectToFrameRect(m_internalWindow->geometry())); - setGeometryRestore(moveResizeGeometry()); blockGeometryUpdates(false); m_internalWindow->installEventFilter(this); diff --git a/src/workspace.cpp b/src/workspace.cpp index e4ae1ae18fefb64307825bf3a217483146a7345e..1bc7964f7a5f8a86d1fcf0782d69be81ce8cb81d 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -2091,11 +2091,11 @@ void Workspace::desktopResized() void Workspace::saveOldScreenSizes() { olddisplaysize = m_geometry.size(); - oldscreensizes.clear(); + m_oldScreenGeometries.clear(); const auto outputs = kwinApp()->platform()->enabledOutputs(); for (const AbstractOutput *output : outputs) { - oldscreensizes.append(output->geometry()); + m_oldScreenGeometries.insert(output, output->geometry()); } } @@ -2254,6 +2254,7 @@ void Workspace::updateClientArea() m_workAreas = workAreas; m_screenAreas = screenAreas; + m_inUpdateClientArea = true; m_oldRestrictedAreas = m_restrictedAreas; m_restrictedAreas = restrictedAreas; @@ -2276,6 +2277,7 @@ void Workspace::updateClientArea() } m_oldRestrictedAreas.clear(); // reset, no longer valid or needed + m_inUpdateClientArea = false; } } @@ -2397,7 +2399,7 @@ QRegion Workspace::restrictedMoveArea(const VirtualDesktop *desktop, StrutAreas bool Workspace::inUpdateClientArea() const { - return !m_oldRestrictedAreas.isEmpty(); + return m_inUpdateClientArea; } QRegion Workspace::previousRestrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas) const @@ -2405,9 +2407,9 @@ QRegion Workspace::previousRestrictedMoveArea(const VirtualDesktop *desktop, Str return strutsToRegion(areas, m_oldRestrictedAreas[desktop]); } -QVector< QRect > Workspace::previousScreenSizes() const +QHash Workspace::previousScreenSizes() const { - return oldscreensizes; + return m_oldScreenGeometries; } int Workspace::oldDisplayWidth() const diff --git a/src/workspace.h b/src/workspace.h index 1157ce6dbb5351a68ae3eda12db617aa15458107..8d61a0921b703aacd19ac35ae2e0dfda17b758d2 100644 --- a/src/workspace.h +++ b/src/workspace.h @@ -271,7 +271,7 @@ public: // The calls below are valid only in that case. bool inUpdateClientArea() const; QRegion previousRestrictedMoveArea(const VirtualDesktop *desktop, StrutAreas areas = StrutAreaAll) const; - QVector< QRect > previousScreenSizes() const; + QHash previousScreenSizes() const; int oldDisplayWidth() const; int oldDisplayHeight() const; @@ -670,9 +670,10 @@ private: QHash> m_screenAreas; QRect m_geometry; - QVector< QRect > oldscreensizes; // array of previous sizes of xinerama screens + QHash m_oldScreenGeometries; QSize olddisplaysize; // previous sizes od displayWidth()/displayHeight() QHash m_oldRestrictedAreas; + bool m_inUpdateClientArea = false; int set_active_client_recursion; int block_stacking_updates; // When > 0, stacking updates are temporarily disabled diff --git a/src/x11client.cpp b/src/x11client.cpp index 7b57b09637936b22b523f6e8b8ff8fda93a7bd87..54d6d6481f8fb3bc3d6014edb8cc334fc5b23a40 100644 --- a/src/x11client.cpp +++ b/src/x11client.cpp @@ -3877,7 +3877,6 @@ void X11Client::configureRequest(int value_mask, int rx, int ry, int rw, int rh, } } } - setGeometryRestore(frameGeometry()); // No need to send synthetic configure notify event here, either it's sent together // with geometry change, or there's no need to send it. // Handling of the real ConfigureRequest event forces sending it, as there it's necessary. diff --git a/src/xdgshellclient.cpp b/src/xdgshellclient.cpp index 9e8216a3a0062739c3e229a78fb6cbe11ad471fb..6aab4fc6c6a8ed8ff8d650bc57f375c77e36d961 100644 --- a/src/xdgshellclient.cpp +++ b/src/xdgshellclient.cpp @@ -88,13 +88,6 @@ XdgSurfaceClient::XdgSurfaceClient(XdgSurfaceInterface *shellSurface) m_configureTimer->setSingleShot(true); connect(m_configureTimer, &QTimer::timeout, this, &XdgSurfaceClient::sendConfigure); - - // Unfortunately, AbstractClient::checkWorkspacePosition() operates on the geometry restore - // so we need to initialize it with some reasonable value; otherwise bad things will happen - // when we want to decorate the client or move the client to another screen. This is a hack. - - connect(this, &XdgSurfaceClient::frameGeometryChanged, - this, &XdgSurfaceClient::updateGeometryRestoreHack); } XdgSurfaceClient::~XdgSurfaceClient() @@ -314,23 +307,6 @@ void XdgSurfaceClient::moveResizeInternal(const QRect &rect, MoveResizeMode mode } } -/** - * \internal - * \todo We have to check the current frame geometry in checkWorskpacePosition(). - * - * Sets the geometry restore to the first valid frame geometry. This is a HACK! - * - * Unfortunately, AbstractClient::checkWorkspacePosition() operates on the geometry restore - * rather than the current frame geometry, so we have to ensure that it's initialized with - * some reasonable value even if the client is not maximized or quick tiled. - */ -void XdgSurfaceClient::updateGeometryRestoreHack() -{ - if (geometryRestore().isEmpty() && !frameGeometry().isEmpty()) { - setGeometryRestore(frameGeometry()); - } -} - QRect XdgSurfaceClient::frameRectToBufferRect(const QRect &rect) const { const int left = rect.left() + borderLeft() - m_windowGeometry.left(); @@ -638,10 +614,7 @@ void XdgToplevelClient::updateDecoration(bool check_workspace_pos, bool force) } updateShadow(); if (check_workspace_pos) { - const QRect oldGeometryRestore = geometryRestore(); - setGeometryRestore(frameGeometry()); checkWorkspacePosition(oldFrameGeometry, oldClientGeometry); - setGeometryRestore(oldGeometryRestore); } }