File indexing completed on 2024-05-19 13:22:05
0001 #ifndef oxygenblurhelper_h 0002 #define oxygenblurhelper_h 0003 0004 ////////////////////////////////////////////////////////////////////////////// 0005 // oxygenblurhelper.h 0006 // handle regions passed to kwin for blurring 0007 // ------------------- 0008 // 0009 // SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0010 // 0011 // Loosely inspired (and largely rewritten) from BeSpin style 0012 // SPDX-FileCopyrightText: 2007 Thomas Luebking <thomas.luebking@web.de> 0013 // 0014 // SPDX-License-Identifier: MIT 0015 ////////////////////////////////////////////////////////////////////////////// 0016 0017 #include "oxygen.h" 0018 #include "oxygenstylehelper.h" 0019 0020 #include <QBasicTimer> 0021 #include <QHash> 0022 #include <QObject> 0023 #include <QSet> 0024 #include <QTimerEvent> 0025 0026 #include <QDockWidget> 0027 #include <QMenu> 0028 #include <QRegion> 0029 #include <QToolBar> 0030 0031 #if OXYGEN_HAVE_X11 0032 #include <xcb/xcb.h> 0033 #endif 0034 0035 namespace Oxygen 0036 { 0037 class BlurHelper : public QObject 0038 { 0039 Q_OBJECT 0040 0041 public: 0042 //* constructor 0043 BlurHelper(QObject *, StyleHelper &); 0044 0045 //* enable state 0046 void setEnabled(bool value) 0047 { 0048 _enabled = value; 0049 } 0050 0051 //* enabled 0052 bool enabled(void) const 0053 { 0054 return _enabled; 0055 } 0056 0057 //* register widget 0058 void registerWidget(QWidget *); 0059 0060 //* register widget 0061 void unregisterWidget(QWidget *); 0062 0063 //* event filter 0064 bool eventFilter(QObject *, QEvent *) override; 0065 0066 protected: 0067 //* timer event 0068 /** used to perform delayed blur region update of pending widgets */ 0069 void timerEvent(QTimerEvent *event) override 0070 { 0071 if (event->timerId() == _timer.timerId()) { 0072 _timer.stop(); 0073 update(); 0074 } else 0075 QObject::timerEvent(event); 0076 } 0077 0078 private Q_SLOTS: 0079 0080 //* wiget destroyed 0081 void widgetDestroyed(QObject *object) 0082 { 0083 _widgets.remove(object); 0084 } 0085 0086 private: 0087 //* install event filter to object, in a unique way 0088 void addEventFilter(QObject *object) 0089 { 0090 object->removeEventFilter(this); 0091 object->installEventFilter(this); 0092 } 0093 0094 //* get list of blur-behind regions matching a given widget 0095 QRegion blurRegion(QWidget *) const; 0096 0097 //* trim blur region to remove unnecessary areas (recursive) 0098 void trimBlurRegion(QWidget *, QWidget *, QRegion &) const; 0099 0100 //* update blur region for all pending widgets 0101 void update(void) 0102 { 0103 for (const WidgetPointer &widget : std::as_const(_pendingWidgets)) { 0104 if (widget) 0105 update(widget.data()); 0106 } 0107 0108 _pendingWidgets.clear(); 0109 } 0110 0111 //* update blur regions for given widget 0112 void update(QWidget *) const; 0113 0114 //* clear blur regions for given widget 0115 void clear(QWidget *) const; 0116 0117 //* returns true if a given widget is opaque 0118 bool isOpaque(const QWidget *widget) const; 0119 0120 //* true if widget is a transparent window 0121 /** some additional checks are performed to make sure stuff like plasma tooltips 0122 don't get their blur region overwritten */ 0123 bool isTransparent(const QWidget *widget) const; 0124 0125 //* helper 0126 StyleHelper &_helper; 0127 0128 //* enability 0129 bool _enabled; 0130 0131 //* list of widgets for which blur region must be updated 0132 using WidgetPointer = WeakPointer<QWidget>; 0133 using WidgetSet = QHash<QWidget *, WidgetPointer>; 0134 WidgetSet _pendingWidgets; 0135 0136 //* set of registered widgets 0137 QSet<const QObject *> _widgets; 0138 0139 //* delayed update timer 0140 QBasicTimer _timer; 0141 0142 #if OXYGEN_HAVE_X11 0143 //* blur atom 0144 xcb_atom_t _blurAtom; 0145 xcb_atom_t _opaqueAtom; 0146 #endif 0147 }; 0148 } 0149 0150 #endif