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