Coverage Report

Created: 2025-07-23 08:13

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