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