kwin/src/xdgshellwindow.h

277 lines
9.3 KiB
C
Raw Normal View History

2020-08-02 22:22:19 +00:00
/*
KWin - the KDE window manager
This file is part of the KDE project.
2020-08-02 22:22:19 +00:00
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
SPDX-FileCopyrightText: 2018 David Edmundson <davidedmundson@kde.org>
SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
2020-08-02 22:22:19 +00:00
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "wayland/xdgshell_interface.h"
#include "waylandwindow.h"
#include <QQueue>
#include <QTimer>
#include <optional>
namespace KWaylandServer
{
class AppMenuInterface;
class PlasmaShellSurfaceInterface;
class ServerSideDecorationInterface;
class ServerSideDecorationPaletteInterface;
class XdgToplevelDecorationV1Interface;
}
namespace KWin
{
class Output;
class XdgSurfaceConfigure
{
public:
virtual ~XdgSurfaceConfigure()
{
}
Rework async geometry updates Window management features were written with synchronous geometry updates in mind. Currently, this poses a big problem on Wayland because geometry updates are done in asynchronous fashion there. At the moment, geometry is updated in a so called pseudo-asynchronous fashion, meaning that the frame geometry will be reset to the old value once geometry updates are unblocked. The main drawback of this approach is that it is too error prone, the data flow is hard to comprehend, etc. It is worth noting that there is already a machinery to perform async geometry which is used during interactive move/resize operations. This change extends the move/resize geometry usage beyond interactive move/resize to make asynchronous geometry updates less error prone and easier to comprehend. With the proposed solution, all geometry updates must be done on the move/resize geometry first. After that, the new geometry is passed on to the Client-specific implementation of moveResizeInternal(). To be more specific, the frameGeometry() returns the current frame geometry, it is primarily useful only to the scene. If you want to move or resize a window, you need to use moveResizeGeometry() because it corresponds to the last requested frame geometry. It is worth noting that the moveResizeGeometry() returns the desired bounding geometry. The client may commit the xdg_toplevel surface with a slightly smaller window geometry, for example to enforce a specific aspect ratio. The client is not allowed to resize beyond the size as indicated in moveResizeGeometry(). The data flow is very simple: moveResize() updates the move/resize geometry and calls the client-specific implementation of the moveResizeInternal() method. Based on whether a configure event is needed, moveResizeInternal() will update the frameGeometry() either immediately or after the client commits a new buffer. Unfortunately, both the compositor and xdg-shell clients try to update the window geometry. It means that it's possible to have conflicts between the two. With this change, the compositor's move resize geometry will be synced only if there are no pending configure events, meaning that the user doesn't try to resize the window.
2021-04-30 18:26:09 +00:00
enum ConfigureFlag {
ConfigurePosition = 0x1,
};
Rework async geometry updates Window management features were written with synchronous geometry updates in mind. Currently, this poses a big problem on Wayland because geometry updates are done in asynchronous fashion there. At the moment, geometry is updated in a so called pseudo-asynchronous fashion, meaning that the frame geometry will be reset to the old value once geometry updates are unblocked. The main drawback of this approach is that it is too error prone, the data flow is hard to comprehend, etc. It is worth noting that there is already a machinery to perform async geometry which is used during interactive move/resize operations. This change extends the move/resize geometry usage beyond interactive move/resize to make asynchronous geometry updates less error prone and easier to comprehend. With the proposed solution, all geometry updates must be done on the move/resize geometry first. After that, the new geometry is passed on to the Client-specific implementation of moveResizeInternal(). To be more specific, the frameGeometry() returns the current frame geometry, it is primarily useful only to the scene. If you want to move or resize a window, you need to use moveResizeGeometry() because it corresponds to the last requested frame geometry. It is worth noting that the moveResizeGeometry() returns the desired bounding geometry. The client may commit the xdg_toplevel surface with a slightly smaller window geometry, for example to enforce a specific aspect ratio. The client is not allowed to resize beyond the size as indicated in moveResizeGeometry(). The data flow is very simple: moveResize() updates the move/resize geometry and calls the client-specific implementation of the moveResizeInternal() method. Based on whether a configure event is needed, moveResizeInternal() will update the frameGeometry() either immediately or after the client commits a new buffer. Unfortunately, both the compositor and xdg-shell clients try to update the window geometry. It means that it's possible to have conflicts between the two. With this change, the compositor's move resize geometry will be synced only if there are no pending configure events, meaning that the user doesn't try to resize the window.
2021-04-30 18:26:09 +00:00
Q_DECLARE_FLAGS(ConfigureFlags, ConfigureFlag)
QRectF bounds;
Gravity gravity;
qreal serial;
Rework async geometry updates Window management features were written with synchronous geometry updates in mind. Currently, this poses a big problem on Wayland because geometry updates are done in asynchronous fashion there. At the moment, geometry is updated in a so called pseudo-asynchronous fashion, meaning that the frame geometry will be reset to the old value once geometry updates are unblocked. The main drawback of this approach is that it is too error prone, the data flow is hard to comprehend, etc. It is worth noting that there is already a machinery to perform async geometry which is used during interactive move/resize operations. This change extends the move/resize geometry usage beyond interactive move/resize to make asynchronous geometry updates less error prone and easier to comprehend. With the proposed solution, all geometry updates must be done on the move/resize geometry first. After that, the new geometry is passed on to the Client-specific implementation of moveResizeInternal(). To be more specific, the frameGeometry() returns the current frame geometry, it is primarily useful only to the scene. If you want to move or resize a window, you need to use moveResizeGeometry() because it corresponds to the last requested frame geometry. It is worth noting that the moveResizeGeometry() returns the desired bounding geometry. The client may commit the xdg_toplevel surface with a slightly smaller window geometry, for example to enforce a specific aspect ratio. The client is not allowed to resize beyond the size as indicated in moveResizeGeometry(). The data flow is very simple: moveResize() updates the move/resize geometry and calls the client-specific implementation of the moveResizeInternal() method. Based on whether a configure event is needed, moveResizeInternal() will update the frameGeometry() either immediately or after the client commits a new buffer. Unfortunately, both the compositor and xdg-shell clients try to update the window geometry. It means that it's possible to have conflicts between the two. With this change, the compositor's move resize geometry will be synced only if there are no pending configure events, meaning that the user doesn't try to resize the window.
2021-04-30 18:26:09 +00:00
ConfigureFlags flags;
};
2019-01-28 00:28:48 +00:00
class XdgSurfaceWindow : public WaylandWindow
{
Q_OBJECT
public:
explicit XdgSurfaceWindow(KWaylandServer::XdgSurfaceInterface *shellSurface);
~XdgSurfaceWindow() override;
NET::WindowType windowType(bool direct = false) const override;
QRectF frameRectToBufferRect(const QRectF &rect) const override;
void destroyWindow() override;
void installPlasmaShellSurface(KWaylandServer::PlasmaShellSurfaceInterface *shellSurface);
protected:
void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override;
virtual XdgSurfaceConfigure *sendRoleConfigure() const = 0;
virtual void handleRoleCommit();
wayland: Properly handle async xdg-decoration updates Currently, if a window switches between SSD and CSD, it is possible to encounter a "corrupted" state where the server-side decoration is wrapped around the window while it still has the client-side decoration. The xdg-decoration protocol fixes this problem by saying that decoration updates are bound to xdg_surface configure events. At the moment, kwin sort of applies decoration updates immediately. With this change, decoration updates will be done according to the spec. If the compositor wants to create a decoration, it will send a configure event and apply the decoration when the configure event is acked by the client. In order to send the configure event with a good window geometry size, kwin will create the decoration to query the border size but not assign it to the client yet. As is, KDecoration api doesn't make querying the border size ahead of time easy. The decoration plugin can assign arbitrary border sizes to windows as it pleases it. We could change that, but it effectively means starting KDecoration3 and setting existing window deco ecosystem around kwin on fire the second time, that's off the table. If the compositor wants to remove the decoration, it will send a configure event. When the configure event is acked and the surface is committed, the window decoration will be destroyed. Sync'ing decoration updates to configure events ensures that we cannot end up with having both client-side and server-side decoration. It also helps us to fix a bunch of geometry related issues caused by creating and destroying the decoration without any surface buffer attached yet. BUG: 445259
2021-01-27 15:35:13 +00:00
virtual void handleRolePrecommit();
virtual void handleRoleDestroyed();
XdgSurfaceConfigure *lastAcknowledgedConfigure() const;
Rework async geometry updates Window management features were written with synchronous geometry updates in mind. Currently, this poses a big problem on Wayland because geometry updates are done in asynchronous fashion there. At the moment, geometry is updated in a so called pseudo-asynchronous fashion, meaning that the frame geometry will be reset to the old value once geometry updates are unblocked. The main drawback of this approach is that it is too error prone, the data flow is hard to comprehend, etc. It is worth noting that there is already a machinery to perform async geometry which is used during interactive move/resize operations. This change extends the move/resize geometry usage beyond interactive move/resize to make asynchronous geometry updates less error prone and easier to comprehend. With the proposed solution, all geometry updates must be done on the move/resize geometry first. After that, the new geometry is passed on to the Client-specific implementation of moveResizeInternal(). To be more specific, the frameGeometry() returns the current frame geometry, it is primarily useful only to the scene. If you want to move or resize a window, you need to use moveResizeGeometry() because it corresponds to the last requested frame geometry. It is worth noting that the moveResizeGeometry() returns the desired bounding geometry. The client may commit the xdg_toplevel surface with a slightly smaller window geometry, for example to enforce a specific aspect ratio. The client is not allowed to resize beyond the size as indicated in moveResizeGeometry(). The data flow is very simple: moveResize() updates the move/resize geometry and calls the client-specific implementation of the moveResizeInternal() method. Based on whether a configure event is needed, moveResizeInternal() will update the frameGeometry() either immediately or after the client commits a new buffer. Unfortunately, both the compositor and xdg-shell clients try to update the window geometry. It means that it's possible to have conflicts between the two. With this change, the compositor's move resize geometry will be synced only if there are no pending configure events, meaning that the user doesn't try to resize the window.
2021-04-30 18:26:09 +00:00
void scheduleConfigure();
void sendConfigure();
QPointer<KWaylandServer::PlasmaShellSurfaceInterface> m_plasmaShellSurface;
NET::WindowType m_windowType = NET::Normal;
Gravity m_nextGravity = Gravity::None;
private:
void handleConfigureAcknowledged(quint32 serial);
void handleCommit();
void handleNextWindowGeometry();
bool haveNextWindowGeometry() const;
void setHaveNextWindowGeometry();
void resetHaveNextWindowGeometry();
void maybeUpdateMoveResizeGeometry(const QRectF &rect);
KWaylandServer::XdgSurfaceInterface *m_shellSurface;
QTimer *m_configureTimer;
Rework async geometry updates Window management features were written with synchronous geometry updates in mind. Currently, this poses a big problem on Wayland because geometry updates are done in asynchronous fashion there. At the moment, geometry is updated in a so called pseudo-asynchronous fashion, meaning that the frame geometry will be reset to the old value once geometry updates are unblocked. The main drawback of this approach is that it is too error prone, the data flow is hard to comprehend, etc. It is worth noting that there is already a machinery to perform async geometry which is used during interactive move/resize operations. This change extends the move/resize geometry usage beyond interactive move/resize to make asynchronous geometry updates less error prone and easier to comprehend. With the proposed solution, all geometry updates must be done on the move/resize geometry first. After that, the new geometry is passed on to the Client-specific implementation of moveResizeInternal(). To be more specific, the frameGeometry() returns the current frame geometry, it is primarily useful only to the scene. If you want to move or resize a window, you need to use moveResizeGeometry() because it corresponds to the last requested frame geometry. It is worth noting that the moveResizeGeometry() returns the desired bounding geometry. The client may commit the xdg_toplevel surface with a slightly smaller window geometry, for example to enforce a specific aspect ratio. The client is not allowed to resize beyond the size as indicated in moveResizeGeometry(). The data flow is very simple: moveResize() updates the move/resize geometry and calls the client-specific implementation of the moveResizeInternal() method. Based on whether a configure event is needed, moveResizeInternal() will update the frameGeometry() either immediately or after the client commits a new buffer. Unfortunately, both the compositor and xdg-shell clients try to update the window geometry. It means that it's possible to have conflicts between the two. With this change, the compositor's move resize geometry will be synced only if there are no pending configure events, meaning that the user doesn't try to resize the window.
2021-04-30 18:26:09 +00:00
XdgSurfaceConfigure::ConfigureFlags m_configureFlags;
QQueue<XdgSurfaceConfigure *> m_configureEvents;
std::unique_ptr<XdgSurfaceConfigure> m_lastAcknowledgedConfigure;
std::optional<quint32> m_lastAcknowledgedConfigureSerial;
QRectF m_windowGeometry;
bool m_haveNextWindowGeometry = false;
};
class XdgToplevelConfigure final : public XdgSurfaceConfigure
{
public:
std::shared_ptr<KDecoration2::Decoration> decoration;
KWaylandServer::XdgToplevelInterface::States states;
};
class XdgToplevelWindow final : public XdgSurfaceWindow
{
Q_OBJECT
2021-03-14 17:06:22 +00:00
enum class PingReason {
CloseWindow,
FocusWindow,
};
wayland: Properly handle async xdg-decoration updates Currently, if a window switches between SSD and CSD, it is possible to encounter a "corrupted" state where the server-side decoration is wrapped around the window while it still has the client-side decoration. The xdg-decoration protocol fixes this problem by saying that decoration updates are bound to xdg_surface configure events. At the moment, kwin sort of applies decoration updates immediately. With this change, decoration updates will be done according to the spec. If the compositor wants to create a decoration, it will send a configure event and apply the decoration when the configure event is acked by the client. In order to send the configure event with a good window geometry size, kwin will create the decoration to query the border size but not assign it to the client yet. As is, KDecoration api doesn't make querying the border size ahead of time easy. The decoration plugin can assign arbitrary border sizes to windows as it pleases it. We could change that, but it effectively means starting KDecoration3 and setting existing window deco ecosystem around kwin on fire the second time, that's off the table. If the compositor wants to remove the decoration, it will send a configure event. When the configure event is acked and the surface is committed, the window decoration will be destroyed. Sync'ing decoration updates to configure events ensures that we cannot end up with having both client-side and server-side decoration. It also helps us to fix a bunch of geometry related issues caused by creating and destroying the decoration without any surface buffer attached yet. BUG: 445259
2021-01-27 15:35:13 +00:00
enum class DecorationMode {
None,
Client,
Server,
};
public:
explicit XdgToplevelWindow(KWaylandServer::XdgToplevelInterface *shellSurface);
~XdgToplevelWindow() override;
KWaylandServer::XdgToplevelInterface *shellSurface() const;
MaximizeMode maximizeMode() const override;
MaximizeMode requestedMaximizeMode() const override;
QSizeF minSize() const override;
QSizeF maxSize() const override;
bool isFullScreen() const override;
bool isRequestedFullScreen() const override;
bool isMovableAcrossScreens() const override;
bool isMovable() const override;
bool isResizable() const override;
bool isCloseable() const override;
bool isFullScreenable() const override;
bool isMaximizable() const override;
bool isMinimizable() const override;
bool isPlaceable() const override;
bool isTransient() const override;
bool userCanSetFullScreen() const override;
bool userCanSetNoBorder() const override;
bool noBorder() const override;
void setNoBorder(bool set) override;
void invalidateDecoration() override;
QString preferredColorScheme() const override;
bool supportsWindowRules() const override;
void applyWindowRules() override;
bool takeFocus() override;
bool wantsInput() const override;
bool dockWantsInput() const override;
void setFullScreen(bool set, bool user) override;
void closeWindow() override;
void maximize(MaximizeMode mode) override;
void installAppMenu(KWaylandServer::AppMenuInterface *appMenu);
void installServerDecoration(KWaylandServer::ServerSideDecorationInterface *decoration);
void installPalette(KWaylandServer::ServerSideDecorationPaletteInterface *palette);
void installXdgDecoration(KWaylandServer::XdgToplevelDecorationV1Interface *decoration);
protected:
XdgSurfaceConfigure *sendRoleConfigure() const override;
void handleRoleCommit() override;
wayland: Properly handle async xdg-decoration updates Currently, if a window switches between SSD and CSD, it is possible to encounter a "corrupted" state where the server-side decoration is wrapped around the window while it still has the client-side decoration. The xdg-decoration protocol fixes this problem by saying that decoration updates are bound to xdg_surface configure events. At the moment, kwin sort of applies decoration updates immediately. With this change, decoration updates will be done according to the spec. If the compositor wants to create a decoration, it will send a configure event and apply the decoration when the configure event is acked by the client. In order to send the configure event with a good window geometry size, kwin will create the decoration to query the border size but not assign it to the client yet. As is, KDecoration api doesn't make querying the border size ahead of time easy. The decoration plugin can assign arbitrary border sizes to windows as it pleases it. We could change that, but it effectively means starting KDecoration3 and setting existing window deco ecosystem around kwin on fire the second time, that's off the table. If the compositor wants to remove the decoration, it will send a configure event. When the configure event is acked and the surface is committed, the window decoration will be destroyed. Sync'ing decoration updates to configure events ensures that we cannot end up with having both client-side and server-side decoration. It also helps us to fix a bunch of geometry related issues caused by creating and destroying the decoration without any surface buffer attached yet. BUG: 445259
2021-01-27 15:35:13 +00:00
void handleRolePrecommit() override;
void handleRoleDestroyed() override;
void doMinimize() override;
void doInteractiveResizeSync(const QRectF &rect) override;
void doSetActive() override;
void doSetFullScreen();
void doSetMaximized();
bool doStartInteractiveMoveResize() override;
void doFinishInteractiveMoveResize() override;
bool acceptsFocus() const override;
Layer layerForDock() const override;
void doSetQuickTileMode() override;
private:
void handleWindowTitleChanged();
void handleWindowClassChanged();
void handleWindowMenuRequested(KWaylandServer::SeatInterface *seat,
const QPoint &surfacePos, quint32 serial);
void handleMoveRequested(KWaylandServer::SeatInterface *seat, quint32 serial);
void handleResizeRequested(KWaylandServer::SeatInterface *seat, KWaylandServer::XdgToplevelInterface::ResizeAnchor anchor, quint32 serial);
void handleStatesAcknowledged(const KWaylandServer::XdgToplevelInterface::States &states);
void handleMaximizeRequested();
void handleUnmaximizeRequested();
void handleFullscreenRequested(KWaylandServer::OutputInterface *output);
void handleUnfullscreenRequested();
void handleMinimizeRequested();
void handleTransientForChanged();
void handleForeignTransientForChanged(KWaylandServer::SurfaceInterface *child);
void handlePingTimeout(quint32 serial);
void handlePingDelayed(quint32 serial);
void handlePongReceived(quint32 serial);
void handleMaximumSizeChanged();
void handleMinimumSizeChanged();
void initialize();
2018-10-05 14:36:02 +00:00
void updateMaximizeMode(MaximizeMode maximizeMode);
void updateFullScreenMode(bool set);
void sendPing(PingReason reason);
MaximizeMode initialMaximizeMode() const;
bool initialFullScreenMode() const;
wayland: Properly handle async xdg-decoration updates Currently, if a window switches between SSD and CSD, it is possible to encounter a "corrupted" state where the server-side decoration is wrapped around the window while it still has the client-side decoration. The xdg-decoration protocol fixes this problem by saying that decoration updates are bound to xdg_surface configure events. At the moment, kwin sort of applies decoration updates immediately. With this change, decoration updates will be done according to the spec. If the compositor wants to create a decoration, it will send a configure event and apply the decoration when the configure event is acked by the client. In order to send the configure event with a good window geometry size, kwin will create the decoration to query the border size but not assign it to the client yet. As is, KDecoration api doesn't make querying the border size ahead of time easy. The decoration plugin can assign arbitrary border sizes to windows as it pleases it. We could change that, but it effectively means starting KDecoration3 and setting existing window deco ecosystem around kwin on fire the second time, that's off the table. If the compositor wants to remove the decoration, it will send a configure event. When the configure event is acked and the surface is committed, the window decoration will be destroyed. Sync'ing decoration updates to configure events ensures that we cannot end up with having both client-side and server-side decoration. It also helps us to fix a bunch of geometry related issues caused by creating and destroying the decoration without any surface buffer attached yet. BUG: 445259
2021-01-27 15:35:13 +00:00
DecorationMode preferredDecorationMode() const;
void configureDecoration();
void configureXdgDecoration(DecorationMode decorationMode);
void configureServerDecoration(DecorationMode decorationMode);
void clearDecoration();
void updateCapabilities();
2018-10-05 14:36:02 +00:00
QPointer<KWaylandServer::AppMenuInterface> m_appMenuInterface;
QPointer<KWaylandServer::ServerSideDecorationPaletteInterface> m_paletteInterface;
QPointer<KWaylandServer::ServerSideDecorationInterface> m_serverDecoration;
QPointer<KWaylandServer::XdgToplevelDecorationV1Interface> m_xdgDecoration;
KWaylandServer::XdgToplevelInterface *m_shellSurface;
KWaylandServer::XdgToplevelInterface::States m_nextStates;
KWaylandServer::XdgToplevelInterface::States m_acknowledgedStates;
KWaylandServer::XdgToplevelInterface::States m_initialStates;
KWaylandServer::XdgToplevelInterface::Capabilities m_capabilities;
QMap<quint32, PingReason> m_pings;
MaximizeMode m_maximizeMode = MaximizeRestore;
MaximizeMode m_requestedMaximizeMode = MaximizeRestore;
bool m_isFullScreen = false;
bool m_isRequestedFullScreen = false;
bool m_isInitialized = false;
bool m_userNoBorder = false;
bool m_isTransient = false;
QPointer<Output> m_fullScreenRequestedOutput;
std::shared_ptr<KDecoration2::Decoration> m_nextDecoration;
};
class XdgPopupWindow final : public XdgSurfaceWindow
{
Q_OBJECT
public:
explicit XdgPopupWindow(KWaylandServer::XdgPopupInterface *shellSurface);
~XdgPopupWindow() override;
bool hasPopupGrab() const override;
void popupDone() override;
bool isPopupWindow() const override;
bool isTransient() const override;
bool isResizable() const override;
bool isMovable() const override;
bool isMovableAcrossScreens() const override;
bool hasTransientPlacementHint() const override;
QRectF transientPlacement(const QRectF &bounds) const override;
bool isCloseable() const override;
void closeWindow() override;
bool wantsInput() const override;
bool takeFocus() override;
protected:
bool acceptsFocus() const override;
XdgSurfaceConfigure *sendRoleConfigure() const override;
void handleRoleDestroyed() override;
private:
void handleGrabRequested(KWaylandServer::SeatInterface *seat, quint32 serial);
2021-01-06 01:08:25 +00:00
void handleRepositionRequested(quint32 token);
void initialize();
2021-01-06 01:08:25 +00:00
void relayout();
2021-02-01 07:59:02 +00:00
void updateReactive();
KWaylandServer::XdgPopupInterface *m_shellSurface;
bool m_haveExplicitGrab = false;
};
} // namespace KWin
Rework async geometry updates Window management features were written with synchronous geometry updates in mind. Currently, this poses a big problem on Wayland because geometry updates are done in asynchronous fashion there. At the moment, geometry is updated in a so called pseudo-asynchronous fashion, meaning that the frame geometry will be reset to the old value once geometry updates are unblocked. The main drawback of this approach is that it is too error prone, the data flow is hard to comprehend, etc. It is worth noting that there is already a machinery to perform async geometry which is used during interactive move/resize operations. This change extends the move/resize geometry usage beyond interactive move/resize to make asynchronous geometry updates less error prone and easier to comprehend. With the proposed solution, all geometry updates must be done on the move/resize geometry first. After that, the new geometry is passed on to the Client-specific implementation of moveResizeInternal(). To be more specific, the frameGeometry() returns the current frame geometry, it is primarily useful only to the scene. If you want to move or resize a window, you need to use moveResizeGeometry() because it corresponds to the last requested frame geometry. It is worth noting that the moveResizeGeometry() returns the desired bounding geometry. The client may commit the xdg_toplevel surface with a slightly smaller window geometry, for example to enforce a specific aspect ratio. The client is not allowed to resize beyond the size as indicated in moveResizeGeometry(). The data flow is very simple: moveResize() updates the move/resize geometry and calls the client-specific implementation of the moveResizeInternal() method. Based on whether a configure event is needed, moveResizeInternal() will update the frameGeometry() either immediately or after the client commits a new buffer. Unfortunately, both the compositor and xdg-shell clients try to update the window geometry. It means that it's possible to have conflicts between the two. With this change, the compositor's move resize geometry will be synced only if there are no pending configure events, meaning that the user doesn't try to resize the window.
2021-04-30 18:26:09 +00:00
Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::XdgSurfaceConfigure::ConfigureFlags)