File indexing completed on 2024-05-19 09:28:05
0001 #ifndef oxygenwindowmanager_h 0002 #define oxygenwindowmanager_h 0003 /* 0004 SPDX-FileCopyrightText: 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "oxygen.h" 0009 0010 #include <QEvent> 0011 0012 #include <QBasicTimer> 0013 #include <QObject> 0014 #include <QQuickItem> 0015 #include <QSet> 0016 #include <QString> 0017 #include <QWidget> 0018 0019 namespace Oxygen 0020 { 0021 0022 class WindowManager : public QObject 0023 { 0024 Q_OBJECT 0025 0026 public: 0027 //* constructor 0028 explicit WindowManager(QObject *); 0029 0030 //* initialize 0031 /** read relevant options from config */ 0032 void initialize(void); 0033 0034 //* register widget 0035 void registerWidget(QWidget *); 0036 0037 //* register quick item 0038 void registerQuickItem(QQuickItem *); 0039 0040 //* unregister widget 0041 void unregisterWidget(QWidget *); 0042 0043 //* event filter [reimplemented] 0044 bool eventFilter(QObject *, QEvent *) override; 0045 0046 protected: 0047 //* timer event, 0048 /** used to start drag if button is pressed for a long enough time */ 0049 void timerEvent(QTimerEvent *) override; 0050 0051 private: 0052 //* mouse press event 0053 bool mousePressEvent(QObject *, QEvent *); 0054 0055 //* mouse move event 0056 bool mouseMoveEvent(QObject *, QEvent *); 0057 0058 //* mouse release event 0059 bool mouseReleaseEvent(QObject *, QEvent *); 0060 0061 //*@name configuration 0062 //@{ 0063 0064 //* enable state 0065 bool enabled(void) const 0066 { 0067 return _enabled; 0068 } 0069 0070 //* enable state 0071 void setEnabled(bool value) 0072 { 0073 _enabled = value; 0074 } 0075 0076 //* returns true if window manager is used for moving 0077 bool useWMMoveResize(void) const 0078 { 0079 return _useWMMoveResize; 0080 } 0081 0082 //* use window manager for moving, when available 0083 void setUseWMMoveResize(bool value) 0084 { 0085 _useWMMoveResize = value; 0086 } 0087 0088 //* drag mode 0089 int dragMode(void) const 0090 { 0091 return _dragMode; 0092 } 0093 0094 //* drag mode 0095 void setDragMode(int value) 0096 { 0097 _dragMode = value; 0098 } 0099 0100 //* drag distance (pixels) 0101 void setDragDistance(int value) 0102 { 0103 _dragDistance = value; 0104 } 0105 0106 //* drag delay (msec) 0107 void setDragDelay(int value) 0108 { 0109 _dragDelay = value; 0110 } 0111 0112 //* set list of whiteListed widgets 0113 /** 0114 white list is read from options and is used to adjust 0115 per-app window dragging issues 0116 */ 0117 void initializeWhiteList(); 0118 0119 //* set list of blackListed widgets 0120 /** 0121 black list is read from options and is used to adjust 0122 per-app window dragging issues 0123 */ 0124 void initializeBlackList(void); 0125 0126 //@} 0127 0128 //* returns true if widget is dragable 0129 bool isDragable(QWidget *); 0130 0131 //* returns true if widget is dragable 0132 bool isBlackListed(QWidget *); 0133 0134 //* returns true if widget is dragable 0135 bool isWhiteListed(QWidget *) const; 0136 0137 //* returns true if drag can be started from current widget 0138 bool canDrag(QWidget *); 0139 0140 //* returns true if drag can be started from current widget and position 0141 /** child at given position is passed as second argument */ 0142 bool canDrag(QWidget *, QWidget *, const QPoint &); 0143 0144 //* reset drag 0145 void resetDrag(void); 0146 0147 //* start drag 0148 void startDrag(QWindow *); 0149 0150 //* utility function 0151 bool isDockWidgetTitle(const QWidget *) const; 0152 0153 //*@name lock 0154 //@{ 0155 0156 void setLocked(bool value) 0157 { 0158 _locked = value; 0159 } 0160 0161 //* lock 0162 bool isLocked(void) const 0163 { 0164 return _locked; 0165 } 0166 0167 //@} 0168 0169 //* returns first widget matching given class, or nullptr if none 0170 template<typename T> 0171 T findParent(const QWidget *) const; 0172 0173 //* enability 0174 bool _enabled; 0175 0176 //* use WM moveResize 0177 bool _useWMMoveResize; 0178 0179 //* drag mode 0180 int _dragMode; 0181 0182 //* drag distance 0183 /** this is copied from kwin::geometry */ 0184 int _dragDistance; 0185 0186 //* drag delay 0187 /** this is copied from kwin::geometry */ 0188 int _dragDelay; 0189 0190 //* wrapper for exception id 0191 class ExceptionId : public QPair<QString, QString> 0192 { 0193 public: 0194 //* constructor 0195 explicit ExceptionId(const QString &value) 0196 { 0197 const QStringList args(value.split(QChar::fromLatin1('@'))); 0198 if (args.isEmpty()) 0199 return; 0200 second = args[0].trimmed(); 0201 if (args.size() > 1) 0202 first = args[1].trimmed(); 0203 } 0204 0205 const QString &appName(void) const 0206 { 0207 return first; 0208 } 0209 0210 const QString &className(void) const 0211 { 0212 return second; 0213 } 0214 }; 0215 0216 //* exception set 0217 using ExceptionSet = QSet<ExceptionId>; 0218 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 0226 //* list of black listed special widgets 0227 /** 0228 it is read from options and is used to adjust 0229 per-app window dragging issues 0230 */ 0231 ExceptionSet _blackList; 0232 0233 //* drag point 0234 QPoint _dragPoint; 0235 QPoint _globalDragPoint; 0236 0237 //* drag timer 0238 QBasicTimer _dragTimer; 0239 0240 //* target being dragged 0241 /** Weak pointer is used in case the target gets deleted while drag is in progress */ 0242 WeakPointer<QWidget> _target; 0243 0244 WeakPointer<QQuickItem> _quickTarget; 0245 0246 //* true if drag is about to start 0247 bool _dragAboutToStart; 0248 0249 //* true if drag is in progress 0250 bool _dragInProgress; 0251 0252 //* true if drag is locked 0253 bool _locked; 0254 0255 //* cursor override 0256 /** used to keep track of application cursor being overridden when dragging in non-WM mode */ 0257 bool _cursorOverride; 0258 0259 //* application event filter 0260 QObject *_appEventFilter; 0261 0262 //* allow access of all private members to the app event filter 0263 friend class AppEventFilter; 0264 }; 0265 0266 //____________________________________________________________________ 0267 template<typename T> 0268 T WindowManager::findParent(const QWidget *widget) const 0269 { 0270 if (!widget) 0271 return nullptr; 0272 for (QWidget *parent = widget->parentWidget(); parent; parent = parent->parentWidget()) { 0273 if (T cast = qobject_cast<T>(parent)) 0274 return cast; 0275 } 0276 0277 return nullptr; 0278 } 0279 } 0280 0281 #endif