File indexing completed on 2024-04-28 05:47:17

0001 /*****************************************************************************
0002  *   Copyright 2010 Craig Drummond <craig.p.drummond@gmail.com>              *
0003  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0004  *                                                                           *
0005  *   This program is free software; you can redistribute it and/or modify    *
0006  *   it under the terms of the GNU Lesser General Public License as          *
0007  *   published by the Free Software Foundation; either version 2.1 of the    *
0008  *   License, or (at your option) version 3, or any later version accepted   *
0009  *   by the membership of KDE e.V. (or its successor approved by the         *
0010  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0011  *   Section 6 of version 3 of the license.                                  *
0012  *                                                                           *
0013  *   This program is distributed in the hope that it will be useful,         *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0016  *   Lesser General Public License for more details.                         *
0017  *                                                                           *
0018  *   You should have received a copy of the GNU Lesser General Public        *
0019  *   License along with this library. If not,                                *
0020  *   see <http://www.gnu.org/licenses/>.                                     *
0021  *****************************************************************************/
0022 
0023 #ifndef blurhelper_h
0024 #define blurhelper_h
0025 
0026 //////////////////////////////////////////////////////////////////////////////
0027 // blurhelper.h
0028 // handle regions passed to kwin for blurring
0029 // -------------------
0030 //
0031 // Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
0032 //
0033 // Loosely inspired (and largely rewritten) from BeSpin style
0034 // Copyright (C) 2007 Thomas Luebking <thomas.luebking@web.de>
0035 //
0036 // Permission is hereby granted, free of charge, to any person obtaining a copy
0037 // of this software and associated documentation files (the "Software"), to
0038 // deal in the Software without restriction, including without limitation the
0039 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
0040 // sell copies of the Software, and to permit persons to whom the Software is
0041 // furnished to do so, subject to the following conditions:
0042 //
0043 // The above copyright notice and this permission notice shall be included in
0044 // all copies or substantial portions of the Software.
0045 //
0046 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0047 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0048 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0049 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0050 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0051 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0052 // IN THE SOFTWARE.
0053 //////////////////////////////////////////////////////////////////////////////
0054 
0055 #include <qtcurve-utils/log.h>
0056 #include "utils.h"
0057 
0058 #include <QPointer>
0059 #include <QHash>
0060 #include <QBasicTimer>
0061 #include <QTimerEvent>
0062 #include <QDockWidget>
0063 #include <QMenu>
0064 #include <QMenuBar>
0065 #include <QRegion>
0066 #include <QToolBar>
0067 
0068 namespace QtCurve {
0069 class BlurHelper: public QObject {
0070     Q_OBJECT
0071 public:
0072     //! constructor
0073     BlurHelper(QObject*);
0074 
0075     //! enable state
0076     void setEnabled(bool value)
0077     {
0078         _enabled = value;
0079     }
0080 
0081     //! enabled
0082     bool enabled() const
0083     {
0084         return _enabled;
0085     }
0086 
0087     //! register widget
0088     void registerWidget(QWidget*);
0089 
0090     //! register widget
0091     void unregisterWidget(QWidget*);
0092 
0093     //! event filter
0094     bool eventFilter(QObject*, QEvent*) override;
0095 
0096 protected:
0097     //! timer event
0098     /*! used to perform delayed blur region update of pending widgets */
0099     void timerEvent(QTimerEvent *event) override
0100     {
0101         if (event->timerId() == _timer.timerId()) {
0102             _timer.stop();
0103             update();
0104         } else {
0105             QObject::timerEvent(event);
0106         }
0107     }
0108 
0109     //! get list of blur-behind regions matching a given widget
0110     QRegion blurRegion(QWidget*) const;
0111 
0112     //! trim blur region to remove unnecessary areas (recursive)
0113     void trimBlurRegion(QWidget*, QWidget*, QRegion&) const;
0114 
0115     //! update blur region for all pending widgets
0116     /*! a timer is used to allow some buffering of the update requests */
0117     void delayedUpdate()
0118     {
0119         if(!_timer.isActive()) {
0120             _timer.start(10, this);
0121         }
0122     }
0123 
0124     //! update blur region for all pending widgets
0125     void update() {
0126         for (const WidgetPointer &widget: const_(_pendingWidgets)) {
0127             if (widget) {
0128                 update(widget.data());
0129             }
0130         }
0131         _pendingWidgets.clear();
0132     }
0133 
0134     //! update blur regions for given widget
0135     void update(QWidget*) const;
0136 
0137     //! clear blur regions for given widget
0138     void clear(WId) const;
0139 
0140     //! returns true if a given widget is opaque
0141     bool isOpaque(const QWidget *widget) const
0142     {
0143         // TODO:
0144         // Figure out what is the right thing to do with Qt::WA_OpaquePaintEvent
0145         return (!widget->isWindow()) &&
0146             ((widget->autoFillBackground() &&
0147               widget->palette().color(widget->backgroundRole()).alpha() ==
0148               0xff) || widget->testAttribute(Qt::WA_OpaquePaintEvent));
0149     }
0150 
0151     //! true if widget is a transparent window
0152     /*! some additional checks are performed to make sure stuff like plasma tooltips
0153       don't get their blur region overwritten */
0154     inline bool isTransparent(const QWidget* widget) const;
0155 
0156 private:
0157     //! enability
0158     bool _enabled;
0159 
0160     //! list of widgets for which blur region must be updated
0161     typedef QPointer<QWidget> WidgetPointer;
0162     typedef QHash<QWidget*, WidgetPointer> WidgetSet;
0163     WidgetSet _pendingWidgets;
0164 
0165     //! delayed update timer
0166     QBasicTimer _timer;
0167 };
0168 
0169 bool
0170 BlurHelper::isTransparent(const QWidget *widget) const
0171 {
0172     return (widget->isWindow() &&
0173             // widgets using qgraphicsview
0174             !(widget->graphicsProxyWidget() ||
0175               widget->inherits("Plasma::Dialog")) &&
0176             // flags and special widgets
0177             (widget->testAttribute(Qt::WA_StyledBackground) ||
0178              qobject_cast<const QMenu*>(widget) ||
0179              // TODO temporary solution only
0180              widget->inherits("QComboBoxPrivateContainer") ||
0181              qobject_cast<const QDockWidget*>(widget) ||
0182              qobject_cast<const QToolBar*>(widget) ||
0183              // konsole (thought that should be handled
0184              // internally by the application
0185              widget->inherits("Konsole::MainWindow")) &&
0186             Utils::hasAlphaChannel(widget));
0187 }
0188 
0189 }
0190 
0191 #endif