File indexing completed on 2024-05-19 13:14:11

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0003  * SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #ifndef breezeshadowhelper_h
0009 #define breezeshadowhelper_h
0010 
0011 #include "breezetileset.h"
0012 
0013 #include <KWindowShadow>
0014 
0015 #include <QMap>
0016 #include <QMargins>
0017 #include <QObject>
0018 #include <QPointer>
0019 #include <QSet>
0020 
0021 namespace Breeze
0022 {
0023 //* forward declaration
0024 class Helper;
0025 
0026 struct ShadowParams {
0027     ShadowParams() = default;
0028 
0029     ShadowParams(const QPoint &offset, int radius, qreal opacity)
0030         : offset(offset)
0031         , radius(radius)
0032         , opacity(opacity)
0033     {
0034     }
0035 
0036     QPoint offset;
0037     int radius = 0;
0038     qreal opacity = 0;
0039 
0040     void operator*=(qreal factor)
0041     {
0042         offset *= factor;
0043         radius = qRound(radius * factor);
0044     }
0045 };
0046 
0047 struct CompositeShadowParams {
0048     CompositeShadowParams() = default;
0049 
0050     CompositeShadowParams(const QPoint &offset, const ShadowParams &shadow1, const ShadowParams &shadow2)
0051         : offset(offset)
0052         , shadow1(shadow1)
0053         , shadow2(shadow2)
0054     {
0055     }
0056 
0057     bool isNone() const
0058     {
0059         return qMax(shadow1.radius, shadow2.radius) == 0;
0060     }
0061 
0062     QPoint offset;
0063     ShadowParams shadow1;
0064     ShadowParams shadow2;
0065 
0066     void operator*=(qreal factor)
0067     {
0068         offset *= factor;
0069         shadow1 *= factor;
0070         shadow2 *= factor;
0071     }
0072 };
0073 
0074 //* handle shadow pixmaps passed to window manager via X property
0075 class ShadowHelper : public QObject
0076 {
0077     Q_OBJECT
0078 
0079 public:
0080     //* constructor
0081     ShadowHelper(QObject *, Helper &);
0082 
0083     //* destructor
0084     ~ShadowHelper() override;
0085 
0086     //* shadow params from size enum
0087     static CompositeShadowParams lookupShadowParams(int shadowSizeEnum);
0088 
0089     //* reset
0090     void reset();
0091 
0092     //* load config
0093     void loadConfig();
0094 
0095     //* register widget
0096     bool registerWidget(QWidget *, bool force = false);
0097 
0098     //* unregister widget
0099     void unregisterWidget(QWidget *);
0100 
0101     //* event filter
0102     bool eventFilter(QObject *, QEvent *) override;
0103 
0104     //* shadow tiles
0105     /** is public because it is also needed for mdi windows */
0106     TileSet shadowTiles(QWidget *);
0107 
0108     //* return device pixel ratio for the window containing the widget
0109     static qreal devicePixelRatio(QWidget *);
0110 
0111 protected Q_SLOTS:
0112 
0113     //* unregister widget
0114     void widgetDeleted(QObject *);
0115 
0116     //* unregister window
0117     void windowDeleted(QObject *);
0118 
0119 protected:
0120     //* true if widget is a menu
0121     bool isMenu(QWidget *) const;
0122 
0123     //* true if widget is a tooltip
0124     bool isToolTip(QWidget *) const;
0125 
0126     //* dock widget
0127     bool isDockWidget(QWidget *) const;
0128 
0129     //* toolbar
0130     bool isToolBar(QWidget *) const;
0131 
0132     //* accept widget
0133     bool acceptWidget(QWidget *) const;
0134 
0135     // create shared shadow tiles from tileset
0136     const QVector<KWindowShadowTile::Ptr> &createShadowTiles();
0137 
0138     // create shadow tile from pixmap
0139     KWindowShadowTile::Ptr createTile(const QPixmap &);
0140 
0141     //* installs shadow on given widget in a platform independent way
0142     void installShadows(QWidget *);
0143 
0144     //* uninstalls shadow on given widget in a platform independent way
0145     void uninstallShadows(QWidget *);
0146 
0147     //* gets the shadow margins for the given widget
0148     QMargins shadowMargins(QWidget *) const;
0149 
0150 private:
0151     //* helper
0152     Helper &_helper;
0153 
0154     //* registered widgets
0155     QSet<QWidget *> _widgets;
0156 
0157     //* managed shadows
0158     QMap<QWindow *, KWindowShadow *> _shadows;
0159 
0160     //* tileset
0161     TileSet _shadowTiles;
0162 
0163     //* number of tiles
0164     enum { numTiles = 8 };
0165 
0166     //* shared shadow tiles
0167     QVector<KWindowShadowTile::Ptr> _tiles;
0168 };
0169 
0170 }
0171 
0172 #endif