File indexing completed on 2024-04-28 17:04:31

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 __WINDOW_MANAGER_H__
0024 #define __WINDOW_MANAGER_H__
0025 
0026 // Copied from oxygenwindowmanager.h svnversion: 1137195
0027 
0028 //////////////////////////////////////////////////////////////////////////////
0029 // windowmanager.h
0030 // pass some window mouse press/release/move event actions to window manager
0031 // -------------------
0032 //
0033 // Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
0034 //
0035 // Largely inspired from BeSpin style
0036 // Copyright (C) 2007 Thomas Luebking <thomas.luebking@web.de>
0037 //
0038 // Permission is hereby granted, free of charge, to any person obtaining a copy
0039 // of this software and associated documentation files (the "Software"), to
0040 // deal in the Software without restriction, including without limitation the
0041 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
0042 // sell copies of the Software, and to permit persons to whom the Software is
0043 // furnished to do so, subject to the following conditions:
0044 //
0045 // The above copyright notice and this permission notice shall be included in
0046 // all copies or substantial portions of the Software.
0047 //
0048 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0049 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0050 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0051 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0052 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0053 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0054 // IN THE SOFTWARE.
0055 //////////////////////////////////////////////////////////////////////////////
0056 
0057 #include <QEvent>
0058 #include <QBasicTimer>
0059 #include <QSet>
0060 #include <QString>
0061 #include <QWeakPointer>
0062 #include <QWidget>
0063 
0064 namespace QtCurve {
0065 class WindowManager: public QObject {
0066     Q_OBJECT
0067 public:
0068     explicit WindowManager(QObject*);
0069     // ! initialize
0070     /*! read relevant options from OxygenStyleConfigData */
0071     void initialize(int windowDrag, const QStringList &whiteList=QStringList(),
0072                     const QStringList &blackList=QStringList());
0073     // ! register widget
0074     void registerWidget(QWidget*);
0075     // ! unregister widget
0076     void unregisterWidget(QWidget*);
0077     // ! event filter [reimplemented]
0078     bool eventFilter(QObject*, QEvent*) override;
0079 protected:
0080     // ! timer event,
0081     /*! used to start drag if button is pressed for a long enough time */
0082     void timerEvent(QTimerEvent*) override;
0083     // ! mouse press event
0084     bool mousePressEvent(QObject*, QEvent*);
0085     // ! mouse move event
0086     bool mouseMoveEvent(QObject*, QEvent*);
0087     // ! mouse release event
0088     bool mouseReleaseEvent(QObject*, QEvent*);
0089     // !@name configuration
0090     // @{
0091     // ! enable state
0092     bool
0093     enabled() const
0094     {
0095         return _enabled;
0096     }
0097     // ! enable state
0098     void
0099     setEnabled(bool value)
0100     {
0101         _enabled = value;
0102     }
0103     // ! returns true if window manager is used for moving
0104     bool
0105     useWMMoveResize() const
0106     {
0107         return _useWMMoveResize;
0108     }
0109     // ! drag mode
0110     int
0111     dragMode() const
0112     {
0113         return _dragMode;
0114     }
0115     // ! drag mode
0116     void
0117     setDragMode(int value)
0118     {
0119         _dragMode = value;
0120     }
0121     // ! drag distance (pixels)
0122     void
0123     setDragDistance(int value)
0124     {
0125         _dragDistance = value;
0126     }
0127     // ! drag delay (msec)
0128     void
0129     setDragDelay(int value)
0130     {
0131         _dragDelay = value;
0132     }
0133 
0134     // ! set list of whiteListed widgets
0135     /*!
0136       white list is read from options and is used to adjust
0137       per-app window dragging issues
0138     */
0139     void initializeWhiteList(const QStringList &list);
0140 
0141     // ! set list of blackListed widgets
0142     /*!
0143       black list is read from options and is used to adjust
0144       per-app window dragging issues
0145     */
0146     void initializeBlackList(const QStringList &list);
0147     // @}
0148     // ! returns true if widget is dragable
0149     bool isDragable(QWidget*);
0150     // ! returns true if widget is dragable
0151     bool isBlackListed(QWidget*);
0152     // ! returns true if widget is dragable
0153     bool isWhiteListed(QWidget*) const;
0154     // ! returns true if drag can be started from current widget
0155     bool canDrag(QWidget*);
0156     // ! returns true if drag can be started from current widget and position
0157     /*! child at given position is passed as second argument */
0158     bool canDrag(QWidget*, QWidget*, const QPoint&);
0159     // ! reset drag
0160     void resetDrag();
0161     // ! start drag
0162     void startDrag(QWidget*, const QPoint&);
0163     // ! utility function
0164     bool isDockWidgetTitle(const QWidget*) const;
0165     // !@name lock
0166     // @{
0167     void
0168     setLocked(bool value)
0169     {
0170         _locked = value;
0171     }
0172     // ! lock
0173     bool
0174     isLocked() const
0175     {
0176         return _locked;
0177     }
0178     // @}
0179 private:
0180     // ! enability
0181     bool _enabled;
0182     // ! use WM moveResize
0183     bool _useWMMoveResize;
0184     // ! drag mode
0185     int _dragMode;
0186     // ! drag distance
0187     /*! this is copied from kwin::geometry */
0188     int _dragDistance;
0189     // ! drag delay
0190     /*! this is copied from kwin::geometry */
0191     int _dragDelay;
0192     // ! wrapper for exception id
0193     class ExceptionId: public QPair<QString, QString> {
0194     public:
0195         ExceptionId(const QString &value)
0196         {
0197             const QStringList args(value.split("@"));
0198             if (args.isEmpty()) {
0199                 return;
0200             }
0201             second = args[0].trimmed();
0202             if (args.size() > 1) {
0203                 first = args[1].trimmed();
0204             }
0205         }
0206         const QString&
0207         appName() const
0208         {
0209             return first;
0210         }
0211         const QString&
0212         className() const
0213         {
0214             return second;
0215         }
0216     };
0217     // ! exception set
0218     typedef QSet<ExceptionId> ExceptionSet;
0219     // ! list of white listed special widgets
0220     /*!
0221       it is read from options and is used to adjust
0222       per-app window dragging issues
0223     */
0224     ExceptionSet _whiteList;
0225     // ! list of black listed special widgets
0226     /*!
0227       it is read from options and is used to adjust
0228       per-app window dragging issues
0229     */
0230     ExceptionSet _blackList;
0231     // ! drag point
0232     QPoint _dragPoint;
0233     QPoint _globalDragPoint;
0234     // ! drag timer
0235     QBasicTimer _dragTimer;
0236     // ! target being dragged
0237     /*! QWeakPointer is used in case the target gets deleted while drag
0238       is in progress */
0239     QWeakPointer<QWidget> _target;
0240     // ! true if drag is about to start
0241     bool _dragAboutToStart;
0242     // ! true if drag is in progress
0243     bool _dragInProgress;
0244     // ! true if drag is locked
0245     bool _locked;
0246     // ! cursor override
0247     /*! used to keep track of application cursor being overridden when
0248       dragging in non-WM mode */
0249     bool _cursorOverride;
0250     // ! provide application-wise event filter
0251     /*!
0252       it us used to unlock dragging and make sure event look is properly
0253       restored after a drag has occurred
0254     */
0255     class AppEventFilter: public QObject {
0256     public:
0257         AppEventFilter(WindowManager *parent):
0258             QObject(parent),
0259             _parent(parent)
0260         {
0261         }
0262         bool eventFilter(QObject*, QEvent*) override;
0263     protected:
0264         // ! application-wise event.
0265         /*! needed to catch end of XMoveResize events */
0266         bool appMouseEvent(QObject*, QEvent*);
0267     private:
0268         // ! parent
0269         WindowManager *_parent;
0270     };
0271     // ! application event filter
0272     AppEventFilter *_appEventFilter;
0273     // ! allow access of all private members to the app event filter
0274     friend class AppEventFilter;
0275 };
0276 }
0277 
0278 #endif