Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowsysteminterface_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3#ifndef QWINDOWSYSTEMINTERFACE_P_H
4#define QWINDOWSYSTEMINTERFACE_P_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include <QtGui/private/qevent_p.h>
18#include <QtGui/private/qtguiglobal_p.h>
20
21#include <QElapsedTimer>
22#include <QPointer>
23#include <QMutex>
24#include <QList>
25#include <QWaitCondition>
26#include <QAtomicInt>
27#include <QLoggingCategory>
28
30
31QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(lcQpaInputDevices, Q_GUI_EXPORT)
32
33class QWindowSystemEventHandler;
34
36public:
37 enum EventType {
38 UserInputEvent = 0x100,
39 Close = UserInputEvent | 0x01,
40 GeometryChange = 0x02,
41 Enter = UserInputEvent | 0x03,
42 Leave = UserInputEvent | 0x04,
43 FocusWindow = 0x05,
44 WindowStateChanged = 0x06,
45 Mouse = UserInputEvent | 0x07,
46 Wheel = UserInputEvent | 0x09,
47 Key = UserInputEvent | 0x0a,
48 Touch = UserInputEvent | 0x0b,
49 ScreenOrientation = 0x0c,
50 ScreenGeometry = 0x0d,
51 ScreenAvailableGeometry = 0x0e,
52 ScreenLogicalDotsPerInch = 0x0f,
53 ScreenRefreshRate = 0x10,
54 ThemeChange = 0x11,
55 Expose = 0x12,
56 FileOpen = UserInputEvent | 0x13,
57 Tablet = UserInputEvent | 0x14,
58 TabletEnterProximity = UserInputEvent | 0x15,
59 TabletLeaveProximity = UserInputEvent | 0x16,
60 PlatformPanel = UserInputEvent | 0x17,
61 ContextMenu = UserInputEvent | 0x18,
62 EnterWhatsThisMode = UserInputEvent | 0x19,
63#ifndef QT_NO_GESTURES
64 Gesture = UserInputEvent | 0x1a,
65#endif
66 ApplicationStateChanged = 0x19,
67 FlushEvents = 0x20,
68 WindowScreenChanged = 0x21,
69 SafeAreaMarginsChanged = 0x22,
70 ApplicationTermination = 0x23,
71 Paint = 0x24,
72 WindowDevicePixelRatioChanged = 0x25,
73 };
74
75 class WindowSystemEvent {
76 public:
77 enum {
78 Synthetic = 0x1,
79 NullWindow = 0x2
80 };
81
82 explicit WindowSystemEvent(EventType t)
83 : type(t), flags(0), eventAccepted(true) { }
84 virtual ~WindowSystemEvent() { }
85
86 bool synthetic() const { return flags & Synthetic; }
87 bool nullWindow() const { return flags & NullWindow; }
88
89 EventType type;
90 int flags;
91 bool eventAccepted;
92 };
93
94 class CloseEvent : public WindowSystemEvent {
95 public:
96 explicit CloseEvent(QWindow *w)
97 : WindowSystemEvent(Close), window(w)
98 { }
99 QPointer<QWindow> window;
100 };
101
102 class GeometryChangeEvent : public WindowSystemEvent {
103 public:
104 GeometryChangeEvent(QWindow *window, QRect requestedGeometry, QRect newGeometry);
105 QPointer<QWindow> window;
106 QRect requestedGeometry;
107 QRect newGeometry;
108 };
109
110 class EnterEvent : public WindowSystemEvent {
111 public:
112 explicit EnterEvent(QWindow *enter, const QPointF &local, const QPointF &global)
113 : WindowSystemEvent(Enter), enter(enter), localPos(local), globalPos(global)
114 { }
115 QPointer<QWindow> enter;
116 const QPointF localPos;
117 const QPointF globalPos;
118 };
119
120 class LeaveEvent : public WindowSystemEvent {
121 public:
122 explicit LeaveEvent(QWindow *leave)
123 : WindowSystemEvent(Leave), leave(leave)
124 { }
125 QPointer<QWindow> leave;
126 };
127
128 class FocusWindowEvent : public WindowSystemEvent {
129 public:
130 explicit FocusWindowEvent(QWindow *focusedWindow, Qt::FocusReason r)
131 : WindowSystemEvent(FocusWindow), focused(focusedWindow), reason(r)
132 { }
133 QPointer<QWindow> focused;
134 Qt::FocusReason reason;
135 };
136
137 class WindowStateChangedEvent : public WindowSystemEvent {
138 public:
139 WindowStateChangedEvent(QWindow *_window, Qt::WindowStates _newState, Qt::WindowStates _oldState)
140 : WindowSystemEvent(WindowStateChanged), window(_window), newState(_newState), oldState(_oldState)
141 { }
142
143 QPointer<QWindow> window;
144 Qt::WindowStates newState;
145 Qt::WindowStates oldState;
146 };
147
148 class WindowScreenChangedEvent : public WindowSystemEvent {
149 public:
150 WindowScreenChangedEvent(QWindow *w, QScreen *s)
151 : WindowSystemEvent(WindowScreenChanged), window(w), screen(s)
152 { }
153
154 QPointer<QWindow> window;
155 QPointer<QScreen> screen;
156 };
157
158 class WindowDevicePixelRatioChangedEvent : public WindowSystemEvent {
159 public:
160 WindowDevicePixelRatioChangedEvent(QWindow *w)
161 : WindowSystemEvent(WindowDevicePixelRatioChanged), window(w)
162 { }
163
164 QPointer<QWindow> window;
165 };
166
167 class SafeAreaMarginsChangedEvent : public WindowSystemEvent {
168 public:
169 SafeAreaMarginsChangedEvent(QWindow *w)
170 : WindowSystemEvent(SafeAreaMarginsChanged), window(w)
171 { }
172
173 QPointer<QWindow> window;
174 };
175
176 class ApplicationStateChangedEvent : public WindowSystemEvent {
177 public:
178 ApplicationStateChangedEvent(Qt::ApplicationState newState, bool forcePropagate = false)
179 : WindowSystemEvent(ApplicationStateChanged), newState(newState), forcePropagate(forcePropagate)
180 { }
181
182 Qt::ApplicationState newState;
183 bool forcePropagate;
184 };
185
186 class FlushEventsEvent : public WindowSystemEvent {
187 public:
188 FlushEventsEvent(QEventLoop::ProcessEventsFlags f = QEventLoop::AllEvents)
189 : WindowSystemEvent(FlushEvents)
190 , flags(f)
191 { }
192 QEventLoop::ProcessEventsFlags flags;
193 };
194
195 class UserEvent : public WindowSystemEvent {
196 public:
197 UserEvent(QWindow * w, ulong time, EventType t)
198 : WindowSystemEvent(t), window(w), timestamp(time)
199 {
200 if (!w)
201 flags |= NullWindow;
202 }
203 QPointer<QWindow> window;
204 unsigned long timestamp;
205 };
206
207 class InputEvent: public UserEvent {
208 public:
209 InputEvent(QWindow *w, ulong time, EventType t, Qt::KeyboardModifiers mods, const QInputDevice *dev)
210 : UserEvent(w, time, t), modifiers(mods), device(dev) {}
211 Qt::KeyboardModifiers modifiers;
212 const QInputDevice *device;
213 };
214
215 class PointerEvent : public InputEvent {
216 public:
217 PointerEvent(QWindow * w, ulong time, EventType t, Qt::KeyboardModifiers mods, const QPointingDevice *device)
218 : InputEvent(w, time, t, mods, device) {}
219 };
220
221 class MouseEvent : public PointerEvent {
222 public:
223 MouseEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global,
224 Qt::MouseButtons state, Qt::KeyboardModifiers mods,
225 Qt::MouseButton b, QEvent::Type type,
226 Qt::MouseEventSource src = Qt::MouseEventNotSynthesized, bool frame = false,
227 const QPointingDevice *device = QPointingDevice::primaryPointingDevice(),
228 int evPtId = -1)
229 : PointerEvent(w, time, Mouse, mods, device), localPos(local), globalPos(global),
230 buttons(state), source(src), nonClientArea(frame), button(b), buttonType(type),
231 eventPointId(evPtId) { }
232
233 QPointF localPos;
234 QPointF globalPos;
235 Qt::MouseButtons buttons;
236 Qt::MouseEventSource source;
237 bool nonClientArea;
238 Qt::MouseButton button;
239 QEvent::Type buttonType;
240 int eventPointId; // from the original device if synth-mouse, otherwise -1
241 };
242
243 class WheelEvent : public PointerEvent {
244 public:
245 WheelEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global, QPoint pixelD, QPoint angleD, int qt4D, Qt::Orientation qt4O,
246 Qt::KeyboardModifiers mods, Qt::ScrollPhase phase = Qt::NoScrollPhase, Qt::MouseEventSource src = Qt::MouseEventNotSynthesized,
247 bool inverted = false, const QPointingDevice *device = QPointingDevice::primaryPointingDevice())
248 : PointerEvent(w, time, Wheel, mods, device), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D),
249 qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase), source(src), inverted(inverted) { }
250 QPoint pixelDelta;
251 QPoint angleDelta;
252 int qt4Delta;
253 Qt::Orientation qt4Orientation;
254 QPointF localPos;
255 QPointF globalPos;
256 Qt::ScrollPhase phase;
257 Qt::MouseEventSource source;
258 bool inverted;
259 };
260
261 class KeyEvent : public InputEvent {
262 public:
263 KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods,
264 const QString & text = QString(), bool autorep = false, ushort count = 1,
265 const QInputDevice *device = QInputDevice::primaryKeyboard())
266 : InputEvent(w, time, Key, mods, device), source(nullptr), key(k), unicode(text),
267 repeat(autorep), repeatCount(count), keyType(t),
268 nativeScanCode(0), nativeVirtualKey(0), nativeModifiers(0) { }
269 KeyEvent(QWindow *w, ulong time, QEvent::Type t, int k, Qt::KeyboardModifiers mods,
270 quint32 nativeSC, quint32 nativeVK, quint32 nativeMods,
271 const QString & text = QString(), bool autorep = false, ushort count = 1,
272 const QInputDevice *device = QInputDevice::primaryKeyboard())
273 : InputEvent(w, time, Key, mods, device), source(nullptr), key(k), unicode(text),
274 repeat(autorep), repeatCount(count), keyType(t),
275 nativeScanCode(nativeSC), nativeVirtualKey(nativeVK), nativeModifiers(nativeMods) { }
276 const QInputDevice *source;
277 int key;
278 QString unicode;
279 bool repeat;
280 ushort repeatCount;
281 QEvent::Type keyType;
282 quint32 nativeScanCode;
283 quint32 nativeVirtualKey;
284 quint32 nativeModifiers;
285 };
286
287 class TouchEvent : public PointerEvent {
288 public:
289 TouchEvent(QWindow *w, ulong time, QEvent::Type t, const QPointingDevice *device,
290 const QList<QEventPoint> &p, Qt::KeyboardModifiers mods)
291 : PointerEvent(w, time, Touch, mods, device), points(p), touchType(t) { }
292 QList<QEventPoint> points;
293 QEvent::Type touchType;
294 };
295
296 class ScreenOrientationEvent : public WindowSystemEvent {
297 public:
298 ScreenOrientationEvent(QScreen *s, Qt::ScreenOrientation o)
299 : WindowSystemEvent(ScreenOrientation), screen(s), orientation(o) { }
300 QPointer<QScreen> screen;
301 Qt::ScreenOrientation orientation;
302 };
303
304 class ScreenGeometryEvent : public WindowSystemEvent {
305 public:
306 ScreenGeometryEvent(QScreen *s, const QRect &g, const QRect &ag)
307 : WindowSystemEvent(ScreenGeometry), screen(s), geometry(g), availableGeometry(ag) { }
308 QPointer<QScreen> screen;
309 QRect geometry;
310 QRect availableGeometry;
311 };
312
313 class ScreenLogicalDotsPerInchEvent : public WindowSystemEvent {
314 public:
315 ScreenLogicalDotsPerInchEvent(QScreen *s, qreal dx, qreal dy)
316 : WindowSystemEvent(ScreenLogicalDotsPerInch), screen(s), dpiX(dx), dpiY(dy) { }
317 QPointer<QScreen> screen;
318 qreal dpiX;
319 qreal dpiY;
320 };
321
322 class ScreenRefreshRateEvent : public WindowSystemEvent {
323 public:
324 ScreenRefreshRateEvent(QScreen *s, qreal r)
325 : WindowSystemEvent(ScreenRefreshRate), screen(s), rate(r) { }
326 QPointer<QScreen> screen;
327 qreal rate;
328 };
329
330 class ThemeChangeEvent : public WindowSystemEvent {
331 public:
332 explicit ThemeChangeEvent()
333 : WindowSystemEvent(ThemeChange) { }
334 };
335
336 class ExposeEvent : public WindowSystemEvent {
337 public:
338 ExposeEvent(QWindow *window, const QRegion &region);
339 QPointer<QWindow> window;
340 bool isExposed;
341 QRegion region;
342 };
343
344 class PaintEvent : public WindowSystemEvent {
345 public:
346 PaintEvent(QWindow *window, const QRegion &region)
347 : WindowSystemEvent(Paint), window(window), region(region) {}
348 QPointer<QWindow> window;
349 QRegion region;
350 };
351
352 class FileOpenEvent : public WindowSystemEvent {
353 public:
354 FileOpenEvent(const QString& fileName)
355 : WindowSystemEvent(FileOpen), url(QUrl::fromLocalFile(fileName))
356 { }
357 FileOpenEvent(const QUrl &url)
358 : WindowSystemEvent(FileOpen), url(url)
359 { }
360 QUrl url;
361 };
362
363 class Q_GUI_EXPORT TabletEvent : public PointerEvent {
364 public:
365 // TODO take QPointingDevice* instead of types and IDs
366 static void handleTabletEvent(QWindow *w, const QPointF &local, const QPointF &global,
367 int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, qreal xTilt, qreal yTilt,
368 qreal tangentialPressure, qreal rotation, int z, qint64 uid,
369 Qt::KeyboardModifiers modifiers = Qt::NoModifier);
370 static void setPlatformSynthesizesMouse(bool v);
371
372 TabletEvent(QWindow *w, ulong time, const QPointF &local, const QPointF &global,
373 const QPointingDevice *device, Qt::MouseButtons b, qreal pressure, qreal xTilt, qreal yTilt, qreal tpressure,
374 qreal rotation, int z, Qt::KeyboardModifiers mods)
375 : PointerEvent(w, time, Tablet, mods, device),
376 buttons(b), local(local), global(global),
377 pressure(pressure), xTilt(xTilt), yTilt(yTilt), tangentialPressure(tpressure),
378 rotation(rotation), z(z) { }
379 Qt::MouseButtons buttons;
380 QPointF local;
381 QPointF global;
382 qreal pressure;
383 qreal xTilt;
384 qreal yTilt;
385 qreal tangentialPressure;
386 qreal rotation;
387 int z;
388 static bool platformSynthesizesMouse;
389 };
390
391 class TabletEnterProximityEvent : public PointerEvent {
392 public:
393 // TODO store more info: position and whatever else we can get on most platforms
394 TabletEnterProximityEvent(ulong time, const QPointingDevice *device)
395 : PointerEvent(nullptr, time, TabletEnterProximity, Qt::NoModifier, device) { }
396 };
397
398 class TabletLeaveProximityEvent : public PointerEvent {
399 public:
400 // TODO store more info: position and whatever else we can get on most platforms
401 TabletLeaveProximityEvent(ulong time, const QPointingDevice *device)
402 : PointerEvent(nullptr, time, TabletLeaveProximity, Qt::NoModifier, device) { }
403 };
404
405 class PlatformPanelEvent : public WindowSystemEvent {
406 public:
407 explicit PlatformPanelEvent(QWindow *w)
408 : WindowSystemEvent(PlatformPanel), window(w) { }
409 QPointer<QWindow> window;
410 };
411
412#ifndef QT_NO_CONTEXTMENU
413 class ContextMenuEvent : public WindowSystemEvent {
414 public:
415 explicit ContextMenuEvent(QWindow *w, bool mouseTriggered, const QPoint &pos,
416 const QPoint &globalPos, Qt::KeyboardModifiers modifiers)
417 : WindowSystemEvent(ContextMenu), window(w), mouseTriggered(mouseTriggered), pos(pos),
418 globalPos(globalPos), modifiers(modifiers) { }
419 QPointer<QWindow> window;
420 bool mouseTriggered;
421 QPoint pos; // Only valid if triggered by mouse
422 QPoint globalPos; // Only valid if triggered by mouse
423 Qt::KeyboardModifiers modifiers;
424 };
425#endif
426
427#ifndef QT_NO_GESTURES
428 class GestureEvent : public PointerEvent {
429 public:
430 GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, const QPointingDevice *dev,
431 int fingerCount, QPointF pos, QPointF globalPos, qreal realValue, QPointF delta)
432 : PointerEvent(window, time, Gesture, Qt::NoModifier, dev), type(type), pos(pos), globalPos(globalPos),
433 delta(delta), fingerCount(fingerCount), realValue(realValue), sequenceId(0), intValue(0) { }
434 Qt::NativeGestureType type;
435 QPointF pos;
436 QPointF globalPos;
437 QPointF delta;
438 int fingerCount;
439 // Mac
440 qreal realValue;
441 // Windows
442 ulong sequenceId;
443 quint64 intValue;
444 };
445#endif
446
447 class WindowSystemEventList {
448 QList<WindowSystemEvent *> impl;
449 mutable QMutex mutex;
450 public:
451 WindowSystemEventList() : impl(), mutex() {}
452 ~WindowSystemEventList() { clear(); }
453
454 void clear()
455 { const QMutexLocker locker(&mutex); qDeleteAll(impl); impl.clear(); }
456 void prepend(WindowSystemEvent *e)
457 { const QMutexLocker locker(&mutex); impl.prepend(e); }
458 WindowSystemEvent *takeFirstOrReturnNull()
459 { const QMutexLocker locker(&mutex); return impl.empty() ? nullptr : impl.takeFirst(); }
460 WindowSystemEvent *takeFirstNonUserInputOrReturnNull()
461 {
462 const QMutexLocker locker(&mutex);
463 for (int i = 0; i < impl.size(); ++i)
464 if (!(impl.at(i)->type & QWindowSystemInterfacePrivate::UserInputEvent))
465 return impl.takeAt(i);
466 return nullptr;
467 }
468 bool nonUserInputEventsQueued()
469 {
470 const QMutexLocker locker(&mutex);
471 for (int i = 0; i < impl.size(); ++i)
472 if (!(impl.at(i)->type & QWindowSystemInterfacePrivate::UserInputEvent))
473 return true;
474 return false;
475 }
476 void append(WindowSystemEvent *e)
477 { const QMutexLocker locker(&mutex); impl.append(e); }
478 qsizetype count() const
479 { const QMutexLocker locker(&mutex); return impl.size(); }
480 WindowSystemEvent *peekAtFirstOfType(EventType t) const
481 {
482 const QMutexLocker locker(&mutex);
483 for (int i = 0; i < impl.size(); ++i) {
484 if (impl.at(i)->type == t)
485 return impl.at(i);
486 }
487 return nullptr;
488 }
489 void remove(const WindowSystemEvent *e)
490 {
491 const QMutexLocker locker(&mutex);
492 for (int i = 0; i < impl.size(); ++i) {
493 if (impl.at(i) == e) {
494 delete impl.takeAt(i);
495 break;
496 }
497 }
498 }
499 private:
500 Q_DISABLE_COPY_MOVE(WindowSystemEventList)
501 };
502
503 static WindowSystemEventList windowSystemEventQueue;
504
505 static qsizetype windowSystemEventsQueued();
506 static bool nonUserInputEventsQueued();
507 static WindowSystemEvent *getWindowSystemEvent();
508 static WindowSystemEvent *getNonUserInputWindowSystemEvent();
509 static WindowSystemEvent *peekWindowSystemEvent(EventType t);
510 static void removeWindowSystemEvent(WindowSystemEvent *event);
511
512public:
513 static QElapsedTimer eventTime;
514 static bool synchronousWindowSystemEvents;
515 static bool platformFiltersEvents;
516
517 static QWaitCondition eventsFlushed;
518 static QMutex flushEventMutex;
519 static QAtomicInt eventAccepted;
520
521 static QList<QEventPoint>
522 fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
523 const QWindow *window, QEvent::Type *type = nullptr);
524 template<class EventPointList>
525 static QList<QWindowSystemInterface::TouchPoint>
526 toNativeTouchPoints(const EventPointList &pointList, const QWindow *window)
527 {
528 QList<QWindowSystemInterface::TouchPoint> newList;
529 newList.reserve(pointList.size());
530 for (const auto &point : pointList) {
531 newList.append(toNativeTouchPoint(point, window));
532 }
533 return newList;
534 }
535 static QWindowSystemInterface::TouchPoint
536 toNativeTouchPoint(const QEventPoint &point, const QWindow *window);
537
538 static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
539 static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);
540 static QWindowSystemEventHandler *eventHandler;
541};
542
544{
545public:
546 virtual ~QWindowSystemEventHandler();
547 virtual bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *event);
548};
549
550QT_END_NAMESPACE
551
552#endif // QWINDOWSYSTEMINTERFACE_P_H
The QInputDevice class describes a device from which a QInputEvent originates.