diff --git a/abstract_client.h b/abstract_client.h --- a/abstract_client.h +++ b/abstract_client.h @@ -663,8 +663,7 @@ enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet }; void move(int x, int y, ForceGeometry_t force = NormalGeometrySet); void move(const QPoint &p, ForceGeometry_t force = NormalGeometrySet); - virtual void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) = 0; - void resizeWithChecks(const QSize& s, ForceGeometry_t force = NormalGeometrySet); + virtual void resizeWithChecks(const QSize &size, ForceGeometry_t force = NormalGeometrySet) = 0; void keepInArea(QRect area, bool partial = false); virtual QSize minSize() const; virtual QSize maxSize() const; @@ -872,6 +871,14 @@ */ virtual bool supportsWindowRules() const; + /** + * Returns the extents of the server side-decoration. + * + * Note that the returned margins object will have all margins set to 0 if + * the client doesn't have a server side-decoration. + */ + QMargins frameMargins() const; + public Q_SLOTS: virtual void closeWindow() = 0; @@ -1330,11 +1337,6 @@ move(p.x(), p.y(), force); } -inline void AbstractClient::resizeWithChecks(const QSize& s, AbstractClient::ForceGeometry_t force) -{ - resizeWithChecks(s.width(), s.height(), force); -} - inline const QList& AbstractClient::transients() const { return m_transients; diff --git a/abstract_client.cpp b/abstract_client.cpp --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -808,9 +808,12 @@ area.setBottom(qMax(area.bottom() + height() - 100, area.bottom())); } if (!partial) { - // resize to fit into area - if (area.width() < width() || area.height() < height()) - resizeWithChecks(qMin(area.width(), width()), qMin(area.height(), height())); + // Resize to fit into area. + const QSize currentSize = size(); + const QSize clampedSize = currentSize.boundedTo(area.size()); + if (currentSize != clampedSize) { + resizeWithChecks(clampedSize); + } } int tx = x(), ty = y(); if (geometry().right() > area.right() && width() <= area.width()) @@ -2092,4 +2095,9 @@ return true; } +QMargins AbstractClient::frameMargins() const +{ + return QMargins(borderLeft(), borderTop(), borderRight(), borderBottom()); +} + } diff --git a/client.h b/client.h --- a/client.h +++ b/client.h @@ -181,8 +181,7 @@ void plainResize(int w, int h, ForceGeometry_t force = NormalGeometrySet); void plainResize(const QSize& s, ForceGeometry_t force = NormalGeometrySet); /// resizeWithChecks() resizes according to gravity, and checks workarea position - using AbstractClient::resizeWithChecks; - void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override; + void resizeWithChecks(const QSize &size, ForceGeometry_t force = NormalGeometrySet) override; void resizeWithChecks(int w, int h, xcb_gravity_t gravity, ForceGeometry_t force = NormalGeometrySet); void resizeWithChecks(const QSize& s, xcb_gravity_t gravity, ForceGeometry_t force = NormalGeometrySet); QSize sizeForClientSize(const QSize&, Sizemode mode = SizemodeAny, bool noframe = false) const override; @@ -659,9 +658,9 @@ plainResize(s.width(), s.height(), force); } -inline void Client::resizeWithChecks(int w, int h, AbstractClient::ForceGeometry_t force) +inline void Client::resizeWithChecks(const QSize &size, ForceGeometry_t force) { - resizeWithChecks(w, h, XCB_GRAVITY_BIT_FORGET, force); + resizeWithChecks(size, XCB_GRAVITY_BIT_FORGET, force); } inline void Client::resizeWithChecks(const QSize& s, xcb_gravity_t gravity, ForceGeometry_t force) diff --git a/geometry.cpp b/geometry.cpp --- a/geometry.cpp +++ b/geometry.cpp @@ -1932,21 +1932,19 @@ // Such code is wrong and should be changed to handle the case when the window is shaded, // for example using Client::clientSize() - const QMargins frameMargins(borderLeft(), borderTop(), borderRight(), borderBottom()); - QRect geometry = rect; if (shade_geometry_change) ; // nothing else if (isShade()) { if (geometry.height() == borderTop() + borderBottom()) { qCDebug(KWIN_CORE) << "Shaded geometry passed for size:"; } else { - client_size = rect.marginsRemoved(frameMargins).size(); + client_size = rect.marginsRemoved(frameMargins()).size(); geometry.setHeight(borderTop() + borderBottom()); } } else { - client_size = rect.marginsRemoved(frameMargins).size(); + client_size = rect.marginsRemoved(frameMargins()).size(); } if (!areGeometryUpdatesBlocked() && geometry != rules()->checkGeometry(geometry)) { qCDebug(KWIN_CORE) << "forced geometry fail:" << geometry << ":" << rules()->checkGeometry(geometry); diff --git a/internal_client.h b/internal_client.h --- a/internal_client.h +++ b/internal_client.h @@ -57,8 +57,7 @@ bool isInputMethod() const override; bool isOutline() const override; quint32 windowId() const override; - using AbstractClient::resizeWithChecks; - void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override; + void resizeWithChecks(const QSize &size, ForceGeometry_t force = NormalGeometrySet) override; QWindow *internalWindow() const override; bool supportsWindowRules() const override; diff --git a/internal_client.cpp b/internal_client.cpp --- a/internal_client.cpp +++ b/internal_client.cpp @@ -297,21 +297,19 @@ } } -void InternalClient::resizeWithChecks(int w, int h, ForceGeometry_t force) +void InternalClient::resizeWithChecks(const QSize &size, ForceGeometry_t force) { Q_UNUSED(force) + if (!m_internalWindow) { return; } - QRect area = workspace()->clientArea(WorkArea, this); - // don't allow growing larger than workarea - if (w > area.width()) { - w = area.width(); - } - if (h > area.height()) { - h = area.height(); - } - m_internalWindow->setGeometry(QRect(pos() + QPoint(borderLeft(), borderTop()), QSize(w, h) - QSize(borderLeft() + borderRight(), borderTop() + borderBottom()))); + + // Don't allow growing larger than workarea. + const QRect workArea = workspace()->clientArea(WorkArea, this); + const QSize clampedSize = size.boundedTo(workArea.size()); + + m_internalWindow->setGeometry(QRect(pos(), clampedSize) - frameMargins()); } void InternalClient::doResizeSync() diff --git a/shell_client.h b/shell_client.h --- a/shell_client.h +++ b/shell_client.h @@ -105,8 +105,7 @@ bool userCanSetNoBorder() const override; bool wantsInput() const override; bool dockWantsInput() const override; - using AbstractClient::resizeWithChecks; - void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override; + void resizeWithChecks(const QSize &size, ForceGeometry_t force = NormalGeometrySet) override; void setGeometry(const QRect &rect, ForceGeometry_t force = NormalGeometrySet) override; bool hasStrut() const override; diff --git a/shell_client.cpp b/shell_client.cpp --- a/shell_client.cpp +++ b/shell_client.cpp @@ -1259,22 +1259,19 @@ setFullScreen(fullScreen, false); } -void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force) +void ShellClient::resizeWithChecks(const QSize &size, ForceGeometry_t force) { Q_UNUSED(force) - QRect area = workspace()->clientArea(WorkArea, this); - // don't allow growing larger than workarea - if (w > area.width()) { - w = area.width(); - } - if (h > area.height()) { - h = area.height(); - } + + // Don't allow growing larger than workarea. + const QRect workArea = workspace()->clientArea(WorkArea, this); + const QSize clampedSize = size.boundedTo(workArea.size()); + if (m_shellSurface) { - m_shellSurface->requestSize(QSize(w, h)); + m_shellSurface->requestSize(clampedSize); } if (m_xdgShellSurface) { - m_xdgShellSurface->configure(xdgSurfaceStates(), QSize(w, h)); + m_xdgShellSurface->configure(xdgSurfaceStates(), clampedSize); } }