File indexing completed on 2024-04-28 16:55:00

0001 /*
0002     SPDX-FileCopyrightText: 2013 Marco Martin <mart@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <Plasma/Theme>
0010 #include <QPointer>
0011 #include <QTimer>
0012 #ifdef HAVE_X11
0013 #include <QWindow> // For WId
0014 #endif
0015 
0016 #include <PlasmaQuick/ConfigView>
0017 #include <PlasmaQuick/ContainmentView>
0018 
0019 class ShellCorona;
0020 
0021 namespace KWayland
0022 {
0023 namespace Client
0024 {
0025 class PlasmaShellSurface;
0026 }
0027 }
0028 
0029 class PanelView : public PlasmaQuick::ContainmentView
0030 
0031 {
0032     Q_OBJECT
0033     /**
0034      * Alignment of the panel: when not fullsize it can be aligned at left,
0035      * right or center of the screen (left and right work as top/bottom
0036      * too for vertical panels)
0037      */
0038     Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
0039 
0040     /**
0041      * how much the panel is moved from the left/right/center anchor point
0042      */
0043     Q_PROPERTY(int offset READ offset WRITE setOffset NOTIFY offsetChanged)
0044 
0045     /**
0046      * Height of horizontal panels or width of vertical panels, set by the user.
0047      */
0048     Q_PROPERTY(int thickness READ thickness WRITE setThickness NOTIFY thicknessChanged)
0049 
0050     /**
0051      * Preferred (natural) width of horizontal panels or height of vertical
0052      * panels, given its current thickness and content.  When the panel is
0053      * constrained by other factors such as minimumLength, maximumLength or
0054      * screen size, its reported length may differ from an actual width or
0055      * height.
0056      */
0057     Q_PROPERTY(int length READ length WRITE setLength NOTIFY lengthChanged)
0058 
0059     /**
0060      * if the panel resizes itself, never resize more than that
0061      */
0062     Q_PROPERTY(int maximumLength READ maximumLength WRITE setMaximumLength NOTIFY maximumLengthChanged)
0063 
0064     /**
0065      * if the panel resizes itself, never resize less than that
0066      */
0067     Q_PROPERTY(int minimumLength READ minimumLength WRITE setMinimumLength NOTIFY minimumLengthChanged)
0068 
0069     /**
0070      * how much the panel is distant for the screen edge: used by the panel controller to drag it around
0071      */
0072     Q_PROPERTY(int distance READ distance WRITE setDistance NOTIFY distanceChanged)
0073 
0074     /**
0075      * support NoBackground in order to disable blur/contrast effects and remove
0076      * the panel shadows
0077      * @since 5.9
0078      */
0079     Q_PROPERTY(Plasma::Types::BackgroundHints backgroundHints WRITE setBackgroundHints READ backgroundHints NOTIFY backgroundHintsChanged)
0080 
0081     /**
0082      * The borders that should have a shadow
0083      * @since 5.7
0084      */
0085     Q_PROPERTY(Plasma::FrameSvg::EnabledBorders enabledBorders READ enabledBorders NOTIFY enabledBordersChanged)
0086 
0087     /**
0088      * information about the screen in which the panel is in
0089      */
0090     Q_PROPERTY(QScreen *screenToFollow READ screenToFollow WRITE setScreenToFollow NOTIFY screenToFollowChanged)
0091 
0092     /**
0093      *  how the panel behaves, visible, autohide etc.
0094      */
0095     Q_PROPERTY(VisibilityMode visibilityMode READ visibilityMode WRITE setVisibilityMode NOTIFY visibilityModeChanged)
0096 
0097     /**
0098      *  Property that determines how a panel's opacity behaves.
0099      *
0100      * @see OpacityMode
0101      */
0102     Q_PROPERTY(OpacityMode opacityMode READ opacityMode WRITE setOpacityMode NOTIFY opacityModeChanged)
0103 
0104     /**
0105      *  Property that determines whether adaptive opacity is used.
0106      */
0107     Q_PROPERTY(bool adaptiveOpacityEnabled READ adaptiveOpacityEnabled NOTIFY adaptiveOpacityEnabledChanged)
0108 
0109     /**
0110      * Property that determines whether the panel is currently floating or not
0111      * @since 5.25
0112      */
0113     Q_PROPERTY(int floating READ floating WRITE setFloating NOTIFY floatingChanged)
0114 
0115     /**
0116      * The minimum thickness in pixels that the panel can have.
0117      * @since 5.27
0118      */
0119     Q_PROPERTY(int minThickness READ minThickness NOTIFY minThicknessChanged)
0120 
0121 public:
0122     enum VisibilityMode {
0123         NormalPanel = 0, /** default, always visible panel, the windowmanager reserves a places for it */
0124         AutoHide, /**the panel will be shownn only if the mouse cursor is on screen edges */
0125         LetWindowsCover, /** always visible, windows will go over the panel, no area reserved */
0126         WindowsGoBelow, /** always visible, windows will go under the panel, no area reserved */
0127     };
0128     Q_ENUM(VisibilityMode)
0129 
0130     /** Enumeration of possible opacity modes. */
0131     enum OpacityMode {
0132         Adaptive = 0, /** The panel will change opacity depending on the presence of a maximized window */
0133         Opaque, /** The panel will always be opaque */
0134         Translucent /** The panel will always be translucent */
0135     };
0136     Q_ENUM(OpacityMode)
0137 
0138     explicit PanelView(ShellCorona *corona, QScreen *targetScreen = nullptr, QWindow *parent = nullptr);
0139     ~PanelView() override;
0140 
0141     KConfigGroup config() const override;
0142     KConfigGroup configDefaults() const;
0143 
0144     Q_INVOKABLE QString fileFromPackage(const QString &key, const QString &fileName);
0145     Q_INVOKABLE void maximize();
0146 
0147     Qt::Alignment alignment() const;
0148     void setAlignment(Qt::Alignment alignment);
0149 
0150     int offset() const;
0151     void setOffset(int offset);
0152 
0153     int thickness() const;
0154     void setThickness(int thickness);
0155     int totalThickness() const;
0156 
0157     int length() const;
0158     void setLength(int value);
0159 
0160     int maximumLength() const;
0161     void setMaximumLength(int length);
0162 
0163     int minimumLength() const;
0164     void setMinimumLength(int length);
0165 
0166     int distance() const;
0167     void setDistance(int dist);
0168 
0169     bool floating() const;
0170     void setFloating(bool floating);
0171 
0172     int minThickness() const;
0173 
0174     Plasma::Types::BackgroundHints backgroundHints() const;
0175     void setBackgroundHints(Plasma::Types::BackgroundHints hint);
0176 
0177     Plasma::FrameSvg::EnabledBorders enabledBorders() const;
0178 
0179     VisibilityMode visibilityMode() const;
0180     void setVisibilityMode(PanelView::VisibilityMode mode);
0181 
0182     PanelView::OpacityMode opacityMode() const;
0183     bool adaptiveOpacityEnabled();
0184     void setOpacityMode(PanelView::OpacityMode mode);
0185     void updateAdaptiveOpacityEnabled();
0186 
0187     /**
0188      * @returns the geometry of the panel given a distance
0189      */
0190     Q_INVOKABLE QRect geometryByDistance(int distance) const;
0191 
0192     /* Both Shared with script/panel.cpp */
0193     static KConfigGroup panelConfig(ShellCorona *corona, Plasma::Containment *containment, QScreen *screen);
0194     static KConfigGroup panelConfigDefaults(ShellCorona *corona, Plasma::Containment *containment, QScreen *screen);
0195 
0196     void updateStruts();
0197 
0198     /*This is different from screen() as is always there, even if the window is
0199       temporarily outside the screen or if is hidden: only plasmashell will ever
0200       change this property, unlike QWindow::screen()*/
0201     void setScreenToFollow(QScreen *screen);
0202     QScreen *screenToFollow() const;
0203 
0204 protected:
0205     void resizeEvent(QResizeEvent *ev) override;
0206     void showEvent(QShowEvent *event) override;
0207     void moveEvent(QMoveEvent *ev) override;
0208     void keyPressEvent(QKeyEvent *event) override;
0209     bool event(QEvent *e) override;
0210 
0211 Q_SIGNALS:
0212     void alignmentChanged();
0213     void offsetChanged();
0214     void screenGeometryChanged();
0215     void thicknessChanged();
0216     void lengthChanged();
0217     void maximumLengthChanged();
0218     void minimumLengthChanged();
0219     void distanceChanged();
0220     void backgroundHintsChanged();
0221     void enabledBordersChanged();
0222     void floatingChanged();
0223     void minThicknessChanged();
0224 
0225     // QWindow does not have a property for screen. Adding this property requires re-implementing the signal
0226     void screenToFollowChanged(QScreen *screen);
0227     void visibilityModeChanged();
0228     void opacityModeChanged();
0229     void adaptiveOpacityEnabledChanged();
0230 
0231 protected Q_SLOTS:
0232     /**
0233      * It will be called when the configuration is requested
0234      */
0235     void showConfigurationInterface(Plasma::Applet *applet) override;
0236 
0237 private Q_SLOTS:
0238     void positionPanel();
0239     void restore();
0240     void setAutoHideEnabled(bool autoHideEnabled);
0241     void showTemporarily();
0242     void refreshContainment();
0243     void refreshStatus(Plasma::Types::ItemStatus);
0244     void restoreAutoHide();
0245     void screenDestroyed(QObject *screen);
0246     void adaptToScreen();
0247     void handleQmlStatusChange(QQmlComponent::Status status);
0248     void updateMask();
0249     void updateEnabledBorders();
0250     void updatePadding();
0251     void updateFloating();
0252     void updateShadows();
0253 
0254 private:
0255     int readConfigValueWithFallBack(const QString &key, int defaultValue);
0256     void resizePanel();
0257     void integrateScreen();
0258     bool containmentContainsPosition(const QPointF &point) const;
0259     QPointF positionAdjustedForContainment(const QPointF &point) const;
0260     void setupWaylandIntegration();
0261     void visibilityModeToWayland();
0262     bool edgeActivated() const;
0263     bool canSetStrut() const;
0264 
0265     int m_offset;
0266     int m_maxLength;
0267     int m_minLength;
0268     int m_contentLength;
0269     int m_distance;
0270     int m_thickness;
0271     int m_bottomPadding;
0272     int m_topPadding;
0273     int m_leftPadding;
0274     int m_rightPadding;
0275     int m_bottomFloatingPadding;
0276     int m_topFloatingPadding;
0277     int m_leftFloatingPadding;
0278     int m_rightFloatingPadding;
0279     int m_minDrawingWidth;
0280     int m_minDrawingHeight;
0281     bool m_initCompleted;
0282     bool m_floating;
0283     bool m_containsMouse = false;
0284     bool m_fakeEventPending = false;
0285     Qt::Alignment m_alignment;
0286     QPointer<PlasmaQuick::ConfigView> m_panelConfigView;
0287     ShellCorona *m_corona;
0288     QTimer m_strutsTimer;
0289     VisibilityMode m_visibilityMode;
0290     OpacityMode m_opacityMode;
0291     Plasma::Theme m_theme;
0292     QTimer m_unhideTimer;
0293     Plasma::Types::BackgroundHints m_backgroundHints;
0294     Plasma::FrameSvg::EnabledBorders m_enabledBorders = Plasma::FrameSvg::AllBorders;
0295     KWayland::Client::PlasmaShellSurface *m_shellSurface;
0296     QPointer<QScreen> m_lastScreen;
0297     QPointer<QScreen> m_screenToFollow;
0298     QMetaObject::Connection m_transientWindowVisibleWatcher;
0299 
0300     static const int STRUTSTIMERDELAY = 200;
0301 };