Introduce the client geometry in Toplevel

In most cases, we don't need to react to client geometry changes, but in
code that deals with server-side window decorations, we need to react to
client geometry changes. The problem is that frame and client geometry
updates are not correlated even though there is a connection between the
frame geometry and the client geometry.

This change introduces the client geometry in the Toplevel class in order
to allow monitoring client geometry updates from DecoratedClientImpl.
remotes/origin/work/gitignore
Vlad Zahorodnii 6 years ago committed by Vlad Zahorodnii
parent 68ec39f433
commit cc3eb54b32
  1. 6
      abstract_client.cpp
  2. 2
      abstract_client.h
  3. 5
      deleted.cpp
  4. 1
      deleted.h
  5. 1
      events.cpp
  6. 14
      internal_client.cpp
  7. 2
      internal_client.h
  8. 1
      toplevel.cpp
  9. 21
      toplevel.h
  10. 5
      unmanaged.cpp
  11. 1
      unmanaged.h
  12. 10
      x11client.cpp
  13. 7
      x11client.h
  14. 36
      xdgshellclient.cpp
  15. 2
      xdgshellclient.h

@ -1984,10 +1984,16 @@ QRect AbstractClient::frameGeometryBeforeUpdateBlocking() const
return m_frameGeometryBeforeUpdateBlocking;
}
QRect AbstractClient::clientGeometryBeforeUpdateBlocking() const
{
return m_clientGeometryBeforeUpdateBlocking;
}
void AbstractClient::updateGeometryBeforeUpdateBlocking()
{
m_bufferGeometryBeforeUpdateBlocking = bufferGeometry();
m_frameGeometryBeforeUpdateBlocking = frameGeometry();
m_clientGeometryBeforeUpdateBlocking = clientGeometry();
}
void AbstractClient::doMove(int, int)

@ -1040,6 +1040,7 @@ protected:
void setPendingGeometryUpdate(PendingGeometry_t update);
QRect bufferGeometryBeforeUpdateBlocking() const;
QRect frameGeometryBeforeUpdateBlocking() const;
QRect clientGeometryBeforeUpdateBlocking() const;
void updateGeometryBeforeUpdateBlocking();
/**
* Schedules a repaint for the visibleRect before and after a
@ -1270,6 +1271,7 @@ private:
QRect m_visibleRectBeforeGeometryUpdate;
QRect m_bufferGeometryBeforeUpdateBlocking;
QRect m_frameGeometryBeforeUpdateBlocking;
QRect m_clientGeometryBeforeUpdateBlocking;
QRect m_virtualKeyboardGeometry;
QRect m_keyboardGeometryRestore;
QRect m_maximizeGeometryRestore;

@ -206,11 +206,6 @@ QPoint Deleted::clientPos() const
return contentsRect.topLeft();
}
QSize Deleted::clientSize() const
{
return contentsRect.size();
}
void Deleted::debug(QDebug& stream) const
{
stream << "\'ID:" << window() << "\' (deleted)";

@ -51,7 +51,6 @@ public:
QStringList activities() const override;
QVector<VirtualDesktop *> desktops() const override;
QPoint clientPos() const override;
QSize clientSize() const override;
QPoint clientContentPos() const override {
return m_contentPos;
}

@ -1294,6 +1294,7 @@ void Unmanaged::configureNotifyEvent(xcb_configure_notify_event_t *e)
if (newgeom != m_frameGeometry) {
addWorkspaceRepaint(visibleRect()); // damage old area
QRect old = m_frameGeometry;
m_clientGeometry = newgeom;
m_frameGeometry = newgeom;
emit frameGeometryChanged(this, old); // update shadow region
addRepaintFull();

@ -38,7 +38,6 @@ namespace KWin
InternalClient::InternalClient(QWindow *window)
: m_internalWindow(window)
, m_clientSize(window->size())
, m_windowId(window->winId())
, m_internalWindowFlags(window->flags())
{
@ -139,11 +138,6 @@ QPoint InternalClient::clientContentPos() const
return -1 * clientPos();
}
QSize InternalClient::clientSize() const
{
return m_clientSize;
}
QSize InternalClient::minSize() const
{
return m_internalWindow->minimumSize();
@ -334,7 +328,7 @@ void InternalClient::setFrameGeometry(const QRect &rect, ForceGeometry_t force)
const QRect newClientGeometry = frameRectToClientRect(rect);
if (m_clientSize == newClientGeometry.size()) {
if (clientSize() == newClientGeometry.size()) {
commitGeometry(rect);
} else {
requestGeometry(rect);
@ -530,13 +524,15 @@ void InternalClient::commitGeometry(const QRect &rect)
return;
}
m_clientGeometry = frameRectToClientRect(rect);
m_frameGeometry = rect;
m_clientSize = frameRectToClientRect(frameGeometry()).size();
addWorkspaceRepaint(visibleRect());
syncGeometryToInternalWindow();
if (clientGeometryBeforeUpdateBlocking() != clientGeometry()) {
emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking());
}
if (frameGeometryBeforeUpdateBlocking() != frameGeometry()) {
emit frameGeometryChanged(this, frameGeometryBeforeUpdateBlocking());
}

@ -42,7 +42,6 @@ public:
QString captionNormal() const override;
QString captionSuffix() const override;
QPoint clientContentPos() const override;
QSize clientSize() const override;
QSize minSize() const override;
QSize maxSize() const override;
void debug(QDebug &stream) const override;
@ -101,7 +100,6 @@ private:
void updateInternalWindowGeometry();
QWindow *m_internalWindow = nullptr;
QSize m_clientSize = QSize(0, 0);
QString m_captionNormal;
QString m_captionSuffix;
double m_opacity = 1.0;

@ -92,6 +92,7 @@ void Toplevel::copyToDeleted(Toplevel* c)
{
m_internalId = c->internalId();
m_frameGeometry = c->m_frameGeometry;
m_clientGeometry = c->m_clientGeometry;
m_visual = c->m_visual;
bit_depth = c->bit_depth;
info = c->info;

@ -327,6 +327,10 @@ public:
* server-side and client-side drop shadows, etc.
*/
QRect frameGeometry() const;
/**
* Returns the geometry of the client window, in global screen coordinates.
*/
QRect clientGeometry() const;
/**
* Returns the extents of the server-side decoration.
*
@ -372,7 +376,7 @@ public:
* The default implementation is a 1:1 mapping meaning the frame is part of the content.
*/
virtual QPoint clientContentPos() const;
virtual QSize clientSize() const = 0;
QSize clientSize() const;
/**
* Returns a rectangle that the window occupies on the screen, including drop-shadows.
*/
@ -657,6 +661,10 @@ Q_SIGNALS:
* This signal is emitted when the Toplevel's frame geometry changes.
*/
void frameGeometryChanged(KWin::Toplevel *toplevel, const QRect &oldGeometry);
/**
* This signal is emitted when the Toplevel's client geometry has changed.
*/
void clientGeometryChanged(KWin::Toplevel *toplevel, const QRect &oldGeometry);
protected Q_SLOTS:
/**
@ -705,6 +713,7 @@ protected:
void deleteEffectWindow();
void setDepth(int depth);
QRect m_frameGeometry;
QRect m_clientGeometry;
xcb_visualid_t m_visual;
int bit_depth;
NETWinInfo* info;
@ -754,6 +763,16 @@ inline void Toplevel::setWindowHandles(xcb_window_t w)
m_client.reset(w, false);
}
inline QRect Toplevel::clientGeometry() const
{
return m_clientGeometry;
}
inline QSize Toplevel::clientSize() const
{
return m_clientGeometry.size();
}
inline QRect Toplevel::frameGeometry() const
{
return m_frameGeometry;

@ -152,11 +152,6 @@ QPoint Unmanaged::clientPos() const
return QPoint(0, 0); // unmanaged windows don't have decorations
}
QSize Unmanaged::clientSize() const
{
return size();
}
QRect Unmanaged::transparentRect() const
{
return QRect(clientPos(), clientSize());

@ -43,7 +43,6 @@ public:
QStringList activities() const override;
QVector<VirtualDesktop *> desktops() const override;
QPoint clientPos() const override;
QSize clientSize() const override;
QRect transparentRect() const override;
Layer layer() const override {
return UnmanagedLayer;

@ -160,6 +160,7 @@ X11Client::X11Client()
//client constructed be connected to the workspace wrapper
m_frameGeometry = QRect(0, 0, 100, 100); // So that decorations don't start with size being (0,0)
m_clientGeometry = QRect(0, 0, 100, 100);
connect(clientMachine(), &ClientMachine::localhostChanged, this, &X11Client::updateCaption);
connect(options, &Options::condensedTitleChanged, this, &X11Client::updateCaption);
@ -2898,6 +2899,9 @@ void X11Client::move(int x, int y, ForceGeometry_t force)
screens()->setCurrent(this);
workspace()->updateStackingOrder();
// client itself is not damaged
if (clientGeometryBeforeUpdateBlocking() != clientGeometry()) {
emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking());
}
if (frameGeometryBeforeUpdateBlocking() != frameGeometry()) {
emit frameGeometryChanged(this, frameGeometryBeforeUpdateBlocking());
}
@ -4190,6 +4194,9 @@ void X11Client::setFrameGeometry(const QRect &rect, ForceGeometry_t force)
if (bufferGeometryBeforeUpdateBlocking().size() != m_bufferGeometry.size()) {
discardWindowPixmap();
}
if (clientGeometryBeforeUpdateBlocking() != m_clientGeometry) {
emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking());
}
if (frameGeometryBeforeUpdateBlocking() != m_frameGeometry) {
emit frameGeometryChanged(this, frameGeometryBeforeUpdateBlocking());
}
@ -4247,6 +4254,9 @@ void X11Client::plainResize(int w, int h, ForceGeometry_t force)
if (bufferGeometryBeforeUpdateBlocking().size() != m_bufferGeometry.size()) {
discardWindowPixmap();
}
if (clientGeometryBeforeUpdateBlocking() != clientGeometry()) {
emit clientGeometryChanged(this, clientGeometryBeforeUpdateBlocking());
}
if (frameGeometryBeforeUpdateBlocking() != frameGeometry()) {
emit frameGeometryChanged(this, frameGeometryBeforeUpdateBlocking());
}

@ -123,7 +123,6 @@ public:
QSize minSize() const override;
QSize maxSize() const override;
QSize basicUnit() const;
QSize clientSize() const override;
QPoint inputPos() const { return input_offset; } // Inside of geometry()
bool windowEvent(xcb_generic_event_t *e);
@ -508,7 +507,6 @@ private:
MaximizeMode max_mode;
QRect m_bufferGeometry = QRect(0, 0, 100, 100);
QRect m_clientGeometry = QRect(0, 0, 100, 100);
QRect geom_fs_restore;
xcb_colormap_t m_colormap;
QString cap_normal, cap_iconic, cap_suffix;
@ -624,11 +622,6 @@ inline bool X11Client::isManaged() const
return m_managed;
}
inline QSize X11Client::clientSize() const
{
return m_clientGeometry.size();
}
inline void X11Client::plainResize(const QSize& s, ForceGeometry_t force)
{
plainResize(s.width(), s.height(), force);

@ -49,6 +49,12 @@ using namespace KWaylandServer;
namespace KWin
{
enum XdgSurfaceGeometryType {
XdgSurfaceGeometryClient = 0x1,
XdgSurfaceGeometryFrame = 0x2,
XdgSurfaceGeometryBuffer = 0x4,
};
XdgSurfaceClient::XdgSurfaceClient(XdgSurfaceInterface *shellSurface)
: WaylandClient(shellSurface->surface())
, m_shellSurface(shellSurface)
@ -156,11 +162,6 @@ QRect XdgSurfaceClient::clientGeometry() const
return m_clientGeometry;
}
QSize XdgSurfaceClient::clientSize() const
{
return m_clientGeometry.size();
}
QMatrix4x4 XdgSurfaceClient::inputTransformation() const
{
QMatrix4x4 transformation;
@ -437,20 +438,39 @@ void XdgSurfaceClient::requestGeometry(const QRect &rect)
void XdgSurfaceClient::updateGeometry(const QRect &rect)
{
const QRect oldClientGeometry = m_clientGeometry;
const QRect oldFrameGeometry = m_frameGeometry;
const QRect oldBufferGeometry = m_bufferGeometry;
m_clientGeometry = frameRectToClientRect(rect);
m_frameGeometry = rect;
m_bufferGeometry = frameRectToBufferRect(rect);
m_clientGeometry = frameRectToClientRect(rect);
if (oldFrameGeometry == m_frameGeometry) {
uint changedGeometries = 0;
if (m_clientGeometry != oldClientGeometry) {
changedGeometries |= XdgSurfaceGeometryClient;
}
if (m_frameGeometry != oldFrameGeometry) {
changedGeometries |= XdgSurfaceGeometryFrame;
}
if (m_bufferGeometry != oldBufferGeometry) {
changedGeometries |= XdgSurfaceGeometryBuffer;
}
if (!changedGeometries) {
return;
}
updateWindowRules(Rules::Position | Rules::Size);
updateGeometryBeforeUpdateBlocking();
emit frameGeometryChanged(this, oldFrameGeometry);
if (changedGeometries & XdgSurfaceGeometryClient) {
emit clientGeometryChanged(this, oldClientGeometry);
}
if (changedGeometries & XdgSurfaceGeometryFrame) {
emit frameGeometryChanged(this, oldFrameGeometry);
}
emit geometryShapeChanged(this, oldFrameGeometry);
addRepaintDuringGeometryUpdates();

@ -66,7 +66,6 @@ public:
QRect inputGeometry() const override;
QRect bufferGeometry() const override;
QSize clientSize() const override;
QMatrix4x4 inputTransformation() const override;
void setFrameGeometry(const QRect &rect, ForceGeometry_t force = NormalGeometrySet) override;
using AbstractClient::move;
@ -122,7 +121,6 @@ private:
QRect m_requestedFrameGeometry;
QRect m_bufferGeometry;
QRect m_requestedClientGeometry;
QRect m_clientGeometry;
bool m_isClosing = false;
bool m_isHidden = false;
bool m_haveNextWindowGeometry = false;

Loading…
Cancel
Save