File indexing completed on 2024-04-28 16:49:17

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