Coverage Report

Created: 2025-09-27 07:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qt/qtbase/src/gui/kernel/qwindowsysteminterface_p.h
Line
Count
Source
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>
19
#include "qwindowsysteminterface.h"
20
21
#include <QElapsedTimer>
22
#include <QPointer>
23
#include <QMutex>
24
#include <QList>
25
#include <QWaitCondition>
26
#include <QAtomicInt>
27
#include <QLoggingCategory>
28
29
QT_BEGIN_NAMESPACE
30
31
QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(lcQpaInputDevices, Q_GUI_EXPORT)
32
33
class QWindowSystemEventHandler;
34
35
class Q_GUI_EXPORT QWindowSystemInterfacePrivate {
36
public:
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
0
            : type(t), flags(0), eventAccepted(true) { }
84
0
        virtual ~WindowSystemEvent() { }
85
86
0
        bool synthetic() const  { return flags & Synthetic; }
87
0
        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
0
            : WindowSystemEvent(Close), window(w)
98
0
            { }
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
0
            : WindowSystemEvent(Enter), enter(enter), localPos(local), globalPos(global)
114
0
        { }
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
0
            : WindowSystemEvent(Leave), leave(leave)
124
0
        { }
125
        QPointer<QWindow> leave;
126
    };
127
128
    class FocusWindowEvent : public WindowSystemEvent {
129
    public:
130
        explicit FocusWindowEvent(QWindow *focusedWindow, Qt::FocusReason r)
131
0
            : WindowSystemEvent(FocusWindow), focused(focusedWindow), reason(r)
132
0
        { }
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
0
            : WindowSystemEvent(WindowStateChanged), window(_window), newState(_newState), oldState(_oldState)
141
0
        { }
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
0
            : WindowSystemEvent(WindowScreenChanged), window(w), screen(s)
152
0
        { }
153
154
        QPointer<QWindow> window;
155
        QPointer<QScreen> screen;
156
    };
157
158
    class WindowDevicePixelRatioChangedEvent : public WindowSystemEvent {
159
    public:
160
        WindowDevicePixelRatioChangedEvent(QWindow *w)
161
0
            : WindowSystemEvent(WindowDevicePixelRatioChanged), window(w)
162
0
        { }
163
164
        QPointer<QWindow> window;
165
    };
166
167
    class SafeAreaMarginsChangedEvent : public WindowSystemEvent {
168
    public:
169
        SafeAreaMarginsChangedEvent(QWindow *w)
170
0
            : WindowSystemEvent(SafeAreaMarginsChanged), window(w)
171
0
        { }
172
173
        QPointer<QWindow> window;
174
    };
175
176
    class ApplicationStateChangedEvent : public WindowSystemEvent {
177
    public:
178
        ApplicationStateChangedEvent(Qt::ApplicationState newState, bool forcePropagate = false)
179
0
            : WindowSystemEvent(ApplicationStateChanged), newState(newState), forcePropagate(forcePropagate)
180
0
        { }
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
0
            : WindowSystemEvent(FlushEvents)
190
0
            , flags(f)
191
0
        { }
192
        QEventLoop::ProcessEventsFlags flags;
193
    };
194
195
    class UserEvent : public WindowSystemEvent {
196
    public:
197
        UserEvent(QWindow * w, ulong time, EventType t)
198
0
            : WindowSystemEvent(t), window(w), timestamp(time)
199
0
        {
200
0
            if (!w)
201
0
                flags |= NullWindow;
202
0
        }
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
0
            : 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
0
            : 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
0
            : PointerEvent(w, time, Mouse, mods, device), localPos(local), globalPos(global),
230
0
              buttons(state), source(src), nonClientArea(frame), button(b), buttonType(type),
231
0
              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
0
            : PointerEvent(w, time, Wheel, mods, device), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D),
249
0
              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
0
            : InputEvent(w, time, Key, mods, device), source(nullptr), key(k), unicode(text),
267
0
             repeat(autorep), repeatCount(count), keyType(t),
268
0
             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
0
            : InputEvent(w, time, Key, mods, device), source(nullptr), key(k), unicode(text),
274
0
             repeat(autorep), repeatCount(count), keyType(t),
275
0
             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
0
            : 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
0
            : 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
0
            : 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
0
            : 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
0
            : 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
0
            : 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
0
            :  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
0
            : WindowSystemEvent(FileOpen), url(QUrl::fromLocalFile(fileName))
356
0
        { }
357
        FileOpenEvent(const QUrl &url)
358
0
            : WindowSystemEvent(FileOpen), url(url)
359
0
        { }
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
0
            : PointerEvent(w, time, Tablet, mods, device),
376
0
              buttons(b), local(local), global(global),
377
0
              pressure(pressure), xTilt(xTilt), yTilt(yTilt), tangentialPressure(tpressure),
378
0
              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
0
            : 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
0
            : PointerEvent(nullptr, time, TabletLeaveProximity, Qt::NoModifier, device) { }
403
    };
404
405
    class PlatformPanelEvent : public WindowSystemEvent {
406
    public:
407
        explicit PlatformPanelEvent(QWindow *w)
408
0
            : 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
0
            : WindowSystemEvent(ContextMenu), window(w), mouseTriggered(mouseTriggered), pos(pos),
418
0
              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
0
            : PointerEvent(window, time, Gesture, Qt::NoModifier, dev), type(type), pos(pos), globalPos(globalPos),
433
0
              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
12
        WindowSystemEventList() : impl(), mutex() {}
452
0
        ~WindowSystemEventList() { clear(); }
453
454
        void clear()
455
0
        { const QMutexLocker locker(&mutex); qDeleteAll(impl); impl.clear(); }
456
        void prepend(WindowSystemEvent *e)
457
0
        { const QMutexLocker locker(&mutex); impl.prepend(e); }
458
        WindowSystemEvent *takeFirstOrReturnNull()
459
0
        { const QMutexLocker locker(&mutex); return impl.empty() ? nullptr : impl.takeFirst(); }
460
        WindowSystemEvent *takeFirstNonUserInputOrReturnNull()
461
0
        {
462
0
            const QMutexLocker locker(&mutex);
463
0
            for (int i = 0; i < impl.size(); ++i)
464
0
                if (!(impl.at(i)->type & QWindowSystemInterfacePrivate::UserInputEvent))
465
0
                    return impl.takeAt(i);
466
0
            return nullptr;
467
0
        }
468
        bool nonUserInputEventsQueued()
469
0
        {
470
0
            const QMutexLocker locker(&mutex);
471
0
            for (int i = 0; i < impl.size(); ++i)
472
0
                if (!(impl.at(i)->type & QWindowSystemInterfacePrivate::UserInputEvent))
473
0
                    return true;
474
0
            return false;
475
0
        }
476
        void append(WindowSystemEvent *e)
477
0
        { const QMutexLocker locker(&mutex); impl.append(e); }
478
        qsizetype count() const
479
6
        { const QMutexLocker locker(&mutex); return impl.size(); }
480
        WindowSystemEvent *peekAtFirstOfType(EventType t) const
481
0
        {
482
0
            const QMutexLocker locker(&mutex);
483
0
            for (int i = 0; i < impl.size(); ++i) {
484
0
                if (impl.at(i)->type == t)
485
0
                    return impl.at(i);
486
0
            }
487
0
            return nullptr;
488
0
        }
489
        void remove(const WindowSystemEvent *e)
490
0
        {
491
0
            const QMutexLocker locker(&mutex);
492
0
            for (int i = 0; i < impl.size(); ++i) {
493
0
                if (impl.at(i) == e) {
494
0
                    delete impl.takeAt(i);
495
0
                    break;
496
0
                }
497
0
            }
498
0
        }
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
512
public:
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
0
    {
528
0
        QList<QWindowSystemInterface::TouchPoint> newList;
529
0
        newList.reserve(pointList.size());
530
0
        for (const auto &point : pointList) {
531
0
            newList.append(toNativeTouchPoint(point, window));
532
0
        }
533
0
        return newList;
534
0
    }
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
543
class Q_GUI_EXPORT QWindowSystemEventHandler
544
{
545
public:
546
    virtual ~QWindowSystemEventHandler();
547
    virtual bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *event);
548
};
549
550
QT_END_NAMESPACE
551
552
#endif // QWINDOWSYSTEMINTERFACE_P_H