From 9c55c01767081f9da886cf7b2ea866ca6f515012 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 14 Jul 2020 15:00:29 +0300 Subject: [PATCH] Introduce a signal that notifies about new buffer geometry The new signal can be useful if one wants to watch a toplevel for buffer geometry updates. This can be especially useful for input related code because the position of the upper left corner of the main surface is used to compute the input transformation matrix. --- abstract_client.cpp | 1 + internal_client.cpp | 3 +++ toplevel.h | 4 ++++ x11client.cpp | 9 +++++++++ xdgshellclient.cpp | 3 +++ 5 files changed, 20 insertions(+) diff --git a/abstract_client.cpp b/abstract_client.cpp index 8d2a8ea7d8..4f40703301 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -908,6 +908,7 @@ void AbstractClient::move(int x, int y, ForceGeometry_t force) screens()->setCurrent(this); workspace()->updateStackingOrder(); // client itself is not damaged + emit bufferGeometryChanged(this, bufferGeometryBeforeUpdateBlocking()); emit frameGeometryChanged(this, frameGeometryBeforeUpdateBlocking()); addRepaintDuringGeometryUpdates(); updateGeometryBeforeUpdateBlocking(); diff --git a/internal_client.cpp b/internal_client.cpp index 9e9e27c3e8..91c0e0adcc 100644 --- a/internal_client.cpp +++ b/internal_client.cpp @@ -531,6 +531,9 @@ void InternalClient::commitGeometry(const QRect &rect) addWorkspaceRepaint(visibleRect()); syncGeometryToInternalWindow(); + if (bufferGeometryBeforeUpdateBlocking() != bufferGeometry()) { + emit bufferGeometryChanged(this, bufferGeometryBeforeUpdateBlocking()); + } if (clientGeometryBeforeUpdateBlocking() != clientGeometry()) { emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking()); } diff --git a/toplevel.h b/toplevel.h index a21e84a89e..5d564594e4 100644 --- a/toplevel.h +++ b/toplevel.h @@ -657,6 +657,10 @@ Q_SIGNALS: */ void shadowChanged(); + /** + * This signal is emitted when the Toplevel's buffer geometry changes. + */ + void bufferGeometryChanged(KWin::Toplevel *toplevel, const QRect &oldGeometry); /** * This signal is emitted when the Toplevel's frame geometry changes. */ diff --git a/x11client.cpp b/x11client.cpp index 59e2f39852..bb389e4b37 100644 --- a/x11client.cpp +++ b/x11client.cpp @@ -2902,6 +2902,9 @@ void X11Client::move(int x, int y, ForceGeometry_t force) screens()->setCurrent(this); workspace()->updateStackingOrder(); // client itself is not damaged + if (bufferGeometryBeforeUpdateBlocking() != bufferGeometry()) { + emit bufferGeometryChanged(this, bufferGeometryBeforeUpdateBlocking()); + } if (clientGeometryBeforeUpdateBlocking() != clientGeometry()) { emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking()); } @@ -4197,6 +4200,9 @@ void X11Client::setFrameGeometry(const QRect &rect, ForceGeometry_t force) if (bufferGeometryBeforeUpdateBlocking().size() != m_bufferGeometry.size()) { discardWindowPixmap(); } + if (bufferGeometryBeforeUpdateBlocking() != m_bufferGeometry) { + emit bufferGeometryChanged(this, bufferGeometryBeforeUpdateBlocking()); + } if (clientGeometryBeforeUpdateBlocking() != m_clientGeometry) { emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking()); } @@ -4257,6 +4263,9 @@ void X11Client::plainResize(int w, int h, ForceGeometry_t force) if (bufferGeometryBeforeUpdateBlocking().size() != m_bufferGeometry.size()) { discardWindowPixmap(); } + if (bufferGeometryBeforeUpdateBlocking() != bufferGeometry()) { + emit bufferGeometryChanged(this, bufferGeometryBeforeUpdateBlocking()); + } if (clientGeometryBeforeUpdateBlocking() != clientGeometry()) { emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking()); } diff --git a/xdgshellclient.cpp b/xdgshellclient.cpp index 5ca01e3074..5922a6d2c1 100644 --- a/xdgshellclient.cpp +++ b/xdgshellclient.cpp @@ -463,6 +463,9 @@ void XdgSurfaceClient::updateGeometry(const QRect &rect) updateWindowRules(Rules::Position | Rules::Size); updateGeometryBeforeUpdateBlocking(); + if (changedGeometries & XdgSurfaceGeometryBuffer) { + emit bufferGeometryChanged(this, oldBufferGeometry); + } if (changedGeometries & XdgSurfaceGeometryClient) { emit clientGeometryChanged(this, oldClientGeometry); }