1 /*****************************************************************************
2  *   Copyright 2010 Craig Drummond <craig.p.drummond@gmail.com>              *
3  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
4  *                                                                           *
5  *   This program is free software; you can redistribute it and/or modify    *
6  *   it under the terms of the GNU Lesser General Public License as          *
7  *   published by the Free Software Foundation; either version 2.1 of the    *
8  *   License, or (at your option) version 3, or any later version accepted   *
9  *   by the membership of KDE e.V. (or its successor approved by the         *
10  *   membership of KDE e.V.), which shall act as a proxy defined in          *
11  *   Section 6 of version 3 of the license.                                  *
12  *                                                                           *
13  *   This program is distributed in the hope that it will be useful,         *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
16  *   Lesser General Public License for more details.                         *
17  *                                                                           *
18  *   You should have received a copy of the GNU Lesser General Public        *
19  *   License along with this library. If not,                                *
20  *   see <http://www.gnu.org/licenses/>.                                     *
21  *****************************************************************************/
22 
23 #ifndef __WINDOW_MANAGER_H__
24 #define __WINDOW_MANAGER_H__
25 
26 // Copied from oxygenwindowmanager.h svnversion: 1137195
27 
28 //////////////////////////////////////////////////////////////////////////////
29 // windowmanager.h
30 // pass some window mouse press/release/move event actions to window manager
31 // -------------------
32 //
33 // Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
34 //
35 // Largely inspired from BeSpin style
36 // Copyright (C) 2007 Thomas Luebking <thomas.luebking@web.de>
37 //
38 // Permission is hereby granted, free of charge, to any person obtaining a copy
39 // of this software and associated documentation files (the "Software"), to
40 // deal in the Software without restriction, including without limitation the
41 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
42 // sell copies of the Software, and to permit persons to whom the Software is
43 // furnished to do so, subject to the following conditions:
44 //
45 // The above copyright notice and this permission notice shall be included in
46 // all copies or substantial portions of the Software.
47 //
48 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
53 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
54 // IN THE SOFTWARE.
55 //////////////////////////////////////////////////////////////////////////////
56 
57 #include <QEvent>
58 #include <QBasicTimer>
59 #include <QSet>
60 #include <QString>
61 #include <QWeakPointer>
62 #include <QWidget>
63 
64 namespace QtCurve {
65 class WindowManager: public QObject {
66     Q_OBJECT
67 public:
68     explicit WindowManager(QObject*);
69     // ! initialize
70     /*! read relevant options from OxygenStyleConfigData */
71     void initialize(int windowDrag, const QStringList &whiteList=QStringList(),
72                     const QStringList &blackList=QStringList());
73     // ! register widget
74     void registerWidget(QWidget*);
75     // ! unregister widget
76     void unregisterWidget(QWidget*);
77     // ! event filter [reimplemented]
78     bool eventFilter(QObject*, QEvent*) override;
79 protected:
80     // ! timer event,
81     /*! used to start drag if button is pressed for a long enough time */
82     void timerEvent(QTimerEvent*) override;
83     // ! mouse press event
84     bool mousePressEvent(QObject*, QEvent*);
85     // ! mouse move event
86     bool mouseMoveEvent(QObject*, QEvent*);
87     // ! mouse release event
88     bool mouseReleaseEvent(QObject*, QEvent*);
89     // !@name configuration
90     // @{
91     // ! enable state
92     bool
enabled()93     enabled() const
94     {
95         return _enabled;
96     }
97     // ! enable state
98     void
setEnabled(bool value)99     setEnabled(bool value)
100     {
101         _enabled = value;
102     }
103     // ! returns true if window manager is used for moving
104     bool
useWMMoveResize()105     useWMMoveResize() const
106     {
107         return _useWMMoveResize;
108     }
109     // ! drag mode
110     int
dragMode()111     dragMode() const
112     {
113         return _dragMode;
114     }
115     // ! drag mode
116     void
setDragMode(int value)117     setDragMode(int value)
118     {
119         _dragMode = value;
120     }
121     // ! drag distance (pixels)
122     void
setDragDistance(int value)123     setDragDistance(int value)
124     {
125         _dragDistance = value;
126     }
127     // ! drag delay (msec)
128     void
setDragDelay(int value)129     setDragDelay(int value)
130     {
131         _dragDelay = value;
132     }
133 
134     // ! set list of whiteListed widgets
135     /*!
136       white list is read from options and is used to adjust
137       per-app window dragging issues
138     */
139     void initializeWhiteList(const QStringList &list);
140 
141     // ! set list of blackListed widgets
142     /*!
143       black list is read from options and is used to adjust
144       per-app window dragging issues
145     */
146     void initializeBlackList(const QStringList &list);
147     // @}
148     // ! returns true if widget is dragable
149     bool isDragable(QWidget*);
150     // ! returns true if widget is dragable
151     bool isBlackListed(QWidget*);
152     // ! returns true if widget is dragable
153     bool isWhiteListed(QWidget*) const;
154     // ! returns true if drag can be started from current widget
155     bool canDrag(QWidget*);
156     // ! returns true if drag can be started from current widget and position
157     /*! child at given position is passed as second argument */
158     bool canDrag(QWidget*, QWidget*, const QPoint&);
159     // ! reset drag
160     void resetDrag();
161     // ! start drag
162     void startDrag(QWidget*, const QPoint&);
163     // ! utility function
164     bool isDockWidgetTitle(const QWidget*) const;
165     // !@name lock
166     // @{
167     void
setLocked(bool value)168     setLocked(bool value)
169     {
170         _locked = value;
171     }
172     // ! lock
173     bool
isLocked()174     isLocked() const
175     {
176         return _locked;
177     }
178     // @}
179 private:
180     // ! enability
181     bool _enabled;
182     // ! use WM moveResize
183     bool _useWMMoveResize;
184     // ! drag mode
185     int _dragMode;
186     // ! drag distance
187     /*! this is copied from kwin::geometry */
188     int _dragDistance;
189     // ! drag delay
190     /*! this is copied from kwin::geometry */
191     int _dragDelay;
192     // ! wrapper for exception id
193     class ExceptionId: public QPair<QString, QString> {
194     public:
ExceptionId(const QString & value)195         ExceptionId(const QString &value)
196         {
197             const QStringList args(value.split("@"));
198             if (args.isEmpty()) {
199                 return;
200             }
201             second = args[0].trimmed();
202             if (args.size() > 1) {
203                 first = args[1].trimmed();
204             }
205         }
206         const QString&
appName()207         appName() const
208         {
209             return first;
210         }
211         const QString&
className()212         className() const
213         {
214             return second;
215         }
216     };
217     // ! exception set
218     typedef QSet<ExceptionId> ExceptionSet;
219     // ! list of white listed special widgets
220     /*!
221       it is read from options and is used to adjust
222       per-app window dragging issues
223     */
224     ExceptionSet _whiteList;
225     // ! list of black listed special widgets
226     /*!
227       it is read from options and is used to adjust
228       per-app window dragging issues
229     */
230     ExceptionSet _blackList;
231     // ! drag point
232     QPoint _dragPoint;
233     QPoint _globalDragPoint;
234     // ! drag timer
235     QBasicTimer _dragTimer;
236     // ! target being dragged
237     /*! QWeakPointer is used in case the target gets deleted while drag
238       is in progress */
239     QWeakPointer<QWidget> _target;
240     // ! true if drag is about to start
241     bool _dragAboutToStart;
242     // ! true if drag is in progress
243     bool _dragInProgress;
244     // ! true if drag is locked
245     bool _locked;
246     // ! cursor override
247     /*! used to keep track of application cursor being overridden when
248       dragging in non-WM mode */
249     bool _cursorOverride;
250     // ! provide application-wise event filter
251     /*!
252       it us used to unlock dragging and make sure event look is properly
253       restored after a drag has occurred
254     */
255     class AppEventFilter: public QObject {
256     public:
AppEventFilter(WindowManager * parent)257         AppEventFilter(WindowManager *parent):
258             QObject(parent),
259             _parent(parent)
260         {
261         }
262         bool eventFilter(QObject*, QEvent*) override;
263     protected:
264         // ! application-wise event.
265         /*! needed to catch end of XMoveResize events */
266         bool appMouseEvent(QObject*, QEvent*);
267     private:
268         // ! parent
269         WindowManager *_parent;
270     };
271     // ! application event filter
272     AppEventFilter *_appEventFilter;
273     // ! allow access of all private members to the app event filter
274     friend class AppEventFilter;
275 };
276 }
277 
278 #endif
279