File indexing completed on 2024-04-28 05:30:43

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
0006     SPDX-FileCopyrightText: 2018 David Edmundson <davidedmundson@kde.org>
0007     SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0008 
0009     SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #pragma once
0013 
0014 #include "wayland/xdgshell.h"
0015 #include "waylandwindow.h"
0016 
0017 #include <QQueue>
0018 #include <QTimer>
0019 
0020 #include <optional>
0021 
0022 namespace KWin
0023 {
0024 
0025 class AppMenuInterface;
0026 class KillPrompt;
0027 class PlasmaShellSurfaceInterface;
0028 class ServerSideDecorationInterface;
0029 class ServerSideDecorationPaletteInterface;
0030 class XdgToplevelDecorationV1Interface;
0031 class Output;
0032 
0033 class XdgSurfaceConfigure
0034 {
0035 public:
0036     virtual ~XdgSurfaceConfigure()
0037     {
0038     }
0039 
0040     enum ConfigureFlag {
0041         ConfigurePosition = 0x1,
0042     };
0043     Q_DECLARE_FLAGS(ConfigureFlags, ConfigureFlag)
0044 
0045     QRectF bounds;
0046     Gravity gravity;
0047     qreal serial;
0048     ConfigureFlags flags;
0049 };
0050 
0051 class XdgSurfaceWindow : public WaylandWindow
0052 {
0053     Q_OBJECT
0054 
0055 public:
0056     explicit XdgSurfaceWindow(XdgSurfaceInterface *shellSurface);
0057     ~XdgSurfaceWindow() override;
0058 
0059     NET::WindowType windowType() const override;
0060     QRectF frameRectToBufferRect(const QRectF &rect) const override;
0061     void destroyWindow() override;
0062 
0063     void installPlasmaShellSurface(PlasmaShellSurfaceInterface *shellSurface);
0064 
0065 protected:
0066     void moveResizeInternal(const QRectF &rect, MoveResizeMode mode) override;
0067 
0068     virtual XdgSurfaceConfigure *sendRoleConfigure() const = 0;
0069     virtual void handleRoleCommit();
0070     virtual void handleRolePrecommit();
0071     virtual void handleRoleDestroyed();
0072 
0073     XdgSurfaceConfigure *lastAcknowledgedConfigure() const;
0074     void scheduleConfigure();
0075     void sendConfigure();
0076 
0077     QPointer<PlasmaShellSurfaceInterface> m_plasmaShellSurface;
0078 
0079     NET::WindowType m_windowType = NET::Normal;
0080     Gravity m_nextGravity = Gravity::None;
0081 
0082 private:
0083     void handleConfigureAcknowledged(quint32 serial);
0084     void handleCommit();
0085     void handleNextWindowGeometry();
0086     bool haveNextWindowGeometry() const;
0087     void setHaveNextWindowGeometry();
0088     void resetHaveNextWindowGeometry();
0089     void maybeUpdateMoveResizeGeometry(const QRectF &rect);
0090 
0091     XdgSurfaceInterface *m_shellSurface;
0092     QTimer *m_configureTimer;
0093     XdgSurfaceConfigure::ConfigureFlags m_configureFlags;
0094     QQueue<XdgSurfaceConfigure *> m_configureEvents;
0095     std::unique_ptr<XdgSurfaceConfigure> m_lastAcknowledgedConfigure;
0096     std::optional<quint32> m_lastAcknowledgedConfigureSerial;
0097     QRectF m_windowGeometry;
0098     bool m_haveNextWindowGeometry = false;
0099 };
0100 
0101 class XdgToplevelConfigure final : public XdgSurfaceConfigure
0102 {
0103 public:
0104     std::shared_ptr<KDecoration2::Decoration> decoration;
0105     XdgToplevelInterface::States states;
0106 };
0107 
0108 class XdgToplevelWindow final : public XdgSurfaceWindow
0109 {
0110     Q_OBJECT
0111 
0112     enum class PingReason {
0113         CloseWindow,
0114         FocusWindow,
0115     };
0116 
0117     enum class DecorationMode {
0118         None,
0119         Client,
0120         Server,
0121     };
0122 
0123 public:
0124     explicit XdgToplevelWindow(XdgToplevelInterface *shellSurface);
0125     ~XdgToplevelWindow() override;
0126 
0127     XdgToplevelInterface *shellSurface() const;
0128 
0129     MaximizeMode maximizeMode() const override;
0130     MaximizeMode requestedMaximizeMode() const override;
0131     QSizeF minSize() const override;
0132     QSizeF maxSize() const override;
0133     bool isFullScreen() const override;
0134     bool isRequestedFullScreen() const override;
0135     bool isMovableAcrossScreens() const override;
0136     bool isMovable() const override;
0137     bool isResizable() const override;
0138     bool isCloseable() const override;
0139     bool isFullScreenable() const override;
0140     bool isMaximizable() const override;
0141     bool isMinimizable() const override;
0142     bool isPlaceable() const override;
0143     bool isTransient() const override;
0144     bool userCanSetNoBorder() const override;
0145     bool noBorder() const override;
0146     void setNoBorder(bool set) override;
0147     void invalidateDecoration() override;
0148     QString preferredColorScheme() const override;
0149     bool supportsWindowRules() const override;
0150     void applyWindowRules() override;
0151     bool takeFocus() override;
0152     bool wantsInput() const override;
0153     bool dockWantsInput() const override;
0154     void setFullScreen(bool set) override;
0155     void closeWindow() override;
0156     void maximize(MaximizeMode mode) override;
0157 
0158     void installAppMenu(AppMenuInterface *appMenu);
0159     void installServerDecoration(ServerSideDecorationInterface *decoration);
0160     void installPalette(ServerSideDecorationPaletteInterface *palette);
0161     void installXdgDecoration(XdgToplevelDecorationV1Interface *decoration);
0162 
0163 protected:
0164     XdgSurfaceConfigure *sendRoleConfigure() const override;
0165     void handleRoleCommit() override;
0166     void handleRolePrecommit() override;
0167     void handleRoleDestroyed() override;
0168     void doMinimize() override;
0169     void doInteractiveResizeSync(const QRectF &rect) override;
0170     void doSetActive() override;
0171     void doSetFullScreen();
0172     void doSetMaximized();
0173     bool doStartInteractiveMoveResize() override;
0174     void doFinishInteractiveMoveResize() override;
0175     bool acceptsFocus() const override;
0176     void doSetQuickTileMode() override;
0177     void doSetSuspended() override;
0178 
0179 private:
0180     void handleWindowTitleChanged();
0181     void handleWindowClassChanged();
0182     void handleWindowMenuRequested(SeatInterface *seat,
0183                                    const QPoint &surfacePos, quint32 serial);
0184     void handleMoveRequested(SeatInterface *seat, quint32 serial);
0185     void handleResizeRequested(SeatInterface *seat, XdgToplevelInterface::ResizeAnchor anchor, quint32 serial);
0186     void handleStatesAcknowledged(const XdgToplevelInterface::States &states);
0187     void handleMaximizeRequested();
0188     void handleUnmaximizeRequested();
0189     void handleFullscreenRequested(OutputInterface *output);
0190     void handleUnfullscreenRequested();
0191     void handleMinimizeRequested();
0192     void handleTransientForChanged();
0193     void handleForeignTransientForChanged(SurfaceInterface *child);
0194     void handlePingTimeout(quint32 serial);
0195     void handlePingDelayed(quint32 serial);
0196     void handlePongReceived(quint32 serial);
0197     void handleMaximumSizeChanged();
0198     void handleMinimumSizeChanged();
0199     void initialize();
0200     void updateMaximizeMode(MaximizeMode maximizeMode);
0201     void updateFullScreenMode(bool set);
0202     void sendPing(PingReason reason);
0203     MaximizeMode initialMaximizeMode() const;
0204     bool initialFullScreenMode() const;
0205     DecorationMode preferredDecorationMode() const;
0206     void configureDecoration();
0207     void configureXdgDecoration(DecorationMode decorationMode);
0208     void configureServerDecoration(DecorationMode decorationMode);
0209     void clearDecoration();
0210     void updateCapabilities();
0211 
0212     QPointer<AppMenuInterface> m_appMenuInterface;
0213     QPointer<ServerSideDecorationPaletteInterface> m_paletteInterface;
0214     QPointer<ServerSideDecorationInterface> m_serverDecoration;
0215     QPointer<XdgToplevelDecorationV1Interface> m_xdgDecoration;
0216     XdgToplevelInterface *m_shellSurface;
0217     XdgToplevelInterface::States m_nextStates;
0218     XdgToplevelInterface::States m_acknowledgedStates;
0219     XdgToplevelInterface::States m_initialStates;
0220     XdgToplevelInterface::Capabilities m_capabilities;
0221     QMap<quint32, PingReason> m_pings;
0222     MaximizeMode m_maximizeMode = MaximizeRestore;
0223     MaximizeMode m_requestedMaximizeMode = MaximizeRestore;
0224     bool m_isFullScreen = false;
0225     bool m_isRequestedFullScreen = false;
0226     bool m_isInitialized = false;
0227     bool m_userNoBorder = false;
0228     bool m_isTransient = false;
0229     QPointer<Output> m_fullScreenRequestedOutput;
0230     std::shared_ptr<KDecoration2::Decoration> m_nextDecoration;
0231     std::unique_ptr<KillPrompt> m_killPrompt;
0232 };
0233 
0234 class XdgPopupWindow final : public XdgSurfaceWindow
0235 {
0236     Q_OBJECT
0237 
0238 public:
0239     explicit XdgPopupWindow(XdgPopupInterface *shellSurface);
0240     ~XdgPopupWindow() override;
0241 
0242     bool hasPopupGrab() const override;
0243     void popupDone() override;
0244     bool isPopupWindow() const override;
0245     bool isTransient() const override;
0246     bool isResizable() const override;
0247     bool isMovable() const override;
0248     bool isMovableAcrossScreens() const override;
0249     bool hasTransientPlacementHint() const override;
0250     QRectF transientPlacement() const override;
0251     bool isCloseable() const override;
0252     void closeWindow() override;
0253     bool wantsInput() const override;
0254     bool takeFocus() override;
0255 
0256 protected:
0257     bool acceptsFocus() const override;
0258     XdgSurfaceConfigure *sendRoleConfigure() const override;
0259     void handleRoleDestroyed() override;
0260 
0261 private:
0262     void handleGrabRequested(SeatInterface *seat, quint32 serial);
0263     void handleRepositionRequested(quint32 token);
0264     void initialize();
0265     void updateRelativePlacement();
0266     void relayout();
0267 
0268     XdgPopupInterface *m_shellSurface;
0269     bool m_haveExplicitGrab = false;
0270     QRectF m_relativePlacement;
0271 };
0272 
0273 } // namespace KWin
0274 
0275 Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::XdgSurfaceConfigure::ConfigureFlags)