Coverage Report

Created: 2025-07-12 07:23

/src/qtbase/src/gui/kernel/qwindowsysteminterface.cpp
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
#include "qwindowsysteminterface.h"
40
#include <qpa/qplatformwindow.h>
41
#include "qwindowsysteminterface_p.h"
42
#include "private/qguiapplication_p.h"
43
#include "private/qevent_p.h"
44
#include "private/qtouchdevice_p.h"
45
#include <QAbstractEventDispatcher>
46
#include <qpa/qplatformintegration.h>
47
#include <qdebug.h>
48
#include "qhighdpiscaling_p.h"
49
50
#include <QtCore/qscopedvaluerollback.h>
51
#include <QtCore/private/qlocking_p.h>
52
53
#if QT_CONFIG(draganddrop)
54
#include <qpa/qplatformdrag.h>
55
#endif
56
57
QT_BEGIN_NAMESPACE
58
59
60
QElapsedTimer QWindowSystemInterfacePrivate::eventTime;
61
bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false;
62
bool QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse = true;
63
QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed;
64
QMutex QWindowSystemInterfacePrivate::flushEventMutex;
65
QAtomicInt QWindowSystemInterfacePrivate::eventAccepted;
66
QWindowSystemEventHandler *QWindowSystemInterfacePrivate::eventHandler;
67
QWindowSystemInterfacePrivate::WindowSystemEventList QWindowSystemInterfacePrivate::windowSystemEventQueue;
68
69
extern QPointer<QWindow> qt_last_mouse_receiver;
70
71
72
// ------------------- QWindowSystemInterfacePrivate -------------------
73
74
/*
75
    Handles a window system event asynchronously by posting the event to Qt Gui.
76
77
    This function posts the event on the window system event queue and wakes the
78
    Gui event dispatcher. Qt Gui will then handle the event asynchonously at a
79
    later point.
80
*/
81
template<>
82
bool QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterface::AsynchronousDelivery>(WindowSystemEvent *ev)
83
0
{
84
0
    windowSystemEventQueue.append(ev);
85
0
    if (QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::qt_qpa_core_dispatcher())
86
0
        dispatcher->wakeUp();
87
0
    return true;
88
0
}
89
90
/*
91
    Handles a window system event synchronously.
92
93
    Qt Gui will process the event immediately. The return value indicates if Qt
94
    accepted the event.
95
96
    If the event is delivered from another thread than the Qt main thread the
97
    window system event queue is flushed, which may deliver other events as
98
    well.
99
*/
100
template<>
101
bool QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterface::SynchronousDelivery>(WindowSystemEvent *ev)
102
0
{
103
0
    bool accepted = true;
104
0
    if (QThread::currentThread() == QGuiApplication::instance()->thread()) {
105
        // Process the event immediately on the current thread and return the accepted state.
106
0
        QGuiApplicationPrivate::processWindowSystemEvent(ev);
107
0
        accepted = ev->eventAccepted;
108
0
        delete ev;
109
0
    } else {
110
        // Post the event on the Qt main thread queue and flush the queue.
111
        // This will wake up the Gui thread which will process the event.
112
        // Return the accepted state for the last event on the queue,
113
        // which is the event posted by this function.
114
0
        handleWindowSystemEvent<QWindowSystemInterface::AsynchronousDelivery>(ev);
115
0
        accepted = QWindowSystemInterface::flushWindowSystemEvents();
116
0
    }
117
0
    return accepted;
118
0
}
119
120
/*
121
    Handles a window system event.
122
123
    By default this function posts the event on the window system event queue and
124
    wakes the Gui event dispatcher. Qt Gui will then handle the event asynchonously
125
    at a later point. The return value is not used in asynchronous mode and will
126
    always be true.
127
128
    In synchronous mode Qt Gui will process the event immediately. The return value
129
    indicates if Qt accepted the event. If the event is delivered from another thread
130
    than the Qt main thread the window system event queue is flushed, which may deliver
131
    other events as well.
132
133
    \sa flushWindowSystemEvents(), setSynchronousWindowSystemEvents()
134
*/
135
template<>
136
bool QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterface::DefaultDelivery>(QWindowSystemInterfacePrivate::WindowSystemEvent *ev)
137
0
{
138
0
    if (synchronousWindowSystemEvents)
139
0
        return handleWindowSystemEvent<QWindowSystemInterface::SynchronousDelivery>(ev);
140
0
    else
141
0
        return handleWindowSystemEvent<QWindowSystemInterface::AsynchronousDelivery>(ev);
142
0
}
143
144
int QWindowSystemInterfacePrivate::windowSystemEventsQueued()
145
0
{
146
0
    return windowSystemEventQueue.count();
147
0
}
148
149
bool QWindowSystemInterfacePrivate::nonUserInputEventsQueued()
150
0
{
151
0
    return windowSystemEventQueue.nonUserInputEventsQueued();
152
0
}
153
154
QWindowSystemInterfacePrivate::WindowSystemEvent * QWindowSystemInterfacePrivate::getWindowSystemEvent()
155
0
{
156
0
    return windowSystemEventQueue.takeFirstOrReturnNull();
157
0
}
158
159
QWindowSystemInterfacePrivate::WindowSystemEvent *QWindowSystemInterfacePrivate::getNonUserInputWindowSystemEvent()
160
0
{
161
0
    return windowSystemEventQueue.takeFirstNonUserInputOrReturnNull();
162
0
}
163
164
QWindowSystemInterfacePrivate::WindowSystemEvent *QWindowSystemInterfacePrivate::peekWindowSystemEvent(EventType t)
165
0
{
166
0
    return windowSystemEventQueue.peekAtFirstOfType(t);
167
0
}
168
169
void QWindowSystemInterfacePrivate::removeWindowSystemEvent(WindowSystemEvent *event)
170
0
{
171
0
    windowSystemEventQueue.remove(event);
172
0
}
173
174
void QWindowSystemInterfacePrivate::installWindowSystemEventHandler(QWindowSystemEventHandler *handler)
175
0
{
176
0
    if (!eventHandler)
177
0
        eventHandler = handler;
178
0
}
179
180
void QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(QWindowSystemEventHandler *handler)
181
0
{
182
0
    if (eventHandler == handler)
183
0
        eventHandler = nullptr;
184
0
}
185
186
QWindowSystemEventHandler::~QWindowSystemEventHandler()
187
0
{
188
0
    QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(this);
189
0
}
190
191
bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
192
0
{
193
0
    QGuiApplicationPrivate::processWindowSystemEvent(e);
194
0
    return true;
195
0
}
196
197
//------------------------------------------------------------
198
//
199
// Callback functions for plugins:
200
//
201
202
#define QT_DEFINE_QPA_EVENT_HANDLER(ReturnType, HandlerName, ...) \
203
    template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::DefaultDelivery>(__VA_ARGS__); \
204
    template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::SynchronousDelivery>(__VA_ARGS__); \
205
    template Q_GUI_EXPORT ReturnType QWindowSystemInterface::HandlerName<QWindowSystemInterface::AsynchronousDelivery>(__VA_ARGS__); \
206
    template<typename Delivery> ReturnType QWindowSystemInterface::HandlerName(__VA_ARGS__)
207
208
/*!
209
    \class QWindowSystemInterface
210
    \since 5.0
211
    \internal
212
    \preliminary
213
    \ingroup qpa
214
    \brief The QWindowSystemInterface provides an event queue for the QPA platform.
215
216
    The platform plugins call the various functions to notify about events. The events are queued
217
    until sendWindowSystemEvents() is called by the event dispatcher.
218
*/
219
220
QT_DEFINE_QPA_EVENT_HANDLER(void, handleEnterEvent, QWindow *window, const QPointF &local, const QPointF &global)
221
0
{
222
0
    if (window) {
223
0
        QWindowSystemInterfacePrivate::EnterEvent *e
224
0
                = new QWindowSystemInterfacePrivate::EnterEvent(window, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window));
225
0
        QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
226
0
    }
227
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleEnterEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, QPointF const&, QPointF const&)
Unexecuted instantiation: void QWindowSystemInterface::handleEnterEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QPointF const&, QPointF const&)
Unexecuted instantiation: void QWindowSystemInterface::handleEnterEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QPointF const&, QPointF const&)
228
229
QT_DEFINE_QPA_EVENT_HANDLER(void, handleLeaveEvent, QWindow *window)
230
0
{
231
0
    QWindowSystemInterfacePrivate::LeaveEvent *e = new QWindowSystemInterfacePrivate::LeaveEvent(window);
232
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
233
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleLeaveEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*)
Unexecuted instantiation: void QWindowSystemInterface::handleLeaveEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*)
Unexecuted instantiation: void QWindowSystemInterface::handleLeaveEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*)
234
235
/*!
236
    This method can be used to ensure leave and enter events are both in queue when moving from
237
    one QWindow to another. This allows QWindow subclasses to check for a queued enter event
238
    when handling the leave event (\c QWindowSystemInterfacePrivate::peekWindowSystemEvent) to
239
    determine where mouse went and act accordingly. E.g. QWidgetWindow needs to know if mouse
240
    cursor moves between windows in same window hierarchy.
241
*/
242
void QWindowSystemInterface::handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local, const QPointF& global)
243
0
{
244
0
    handleLeaveEvent<AsynchronousDelivery>(leave);
245
0
    handleEnterEvent(enter, local, global);
246
0
}
247
248
QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *window, Qt::FocusReason r)
249
0
{
250
0
    QWindowSystemInterfacePrivate::ActivatedWindowEvent *e =
251
0
        new QWindowSystemInterfacePrivate::ActivatedWindowEvent(window, r);
252
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
253
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::DefaultDelivery>(QWindow*, Qt::FocusReason)
Unexecuted instantiation: void QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(QWindow*, Qt::FocusReason)
Unexecuted instantiation: void QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, Qt::FocusReason)
254
255
QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowStates newState, int oldState)
256
0
{
257
0
    Q_ASSERT(window);
258
0
    if (oldState < Qt::WindowNoState)
259
0
        oldState = window->windowStates();
260
261
0
    QWindowSystemInterfacePrivate::WindowStateChangedEvent *e =
262
0
        new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowStates(oldState));
263
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
264
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleWindowStateChanged<QWindowSystemInterface::DefaultDelivery>(QWindow*, QFlags<Qt::WindowState>, int)
Unexecuted instantiation: void QWindowSystemInterface::handleWindowStateChanged<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QFlags<Qt::WindowState>, int)
Unexecuted instantiation: void QWindowSystemInterface::handleWindowStateChanged<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QFlags<Qt::WindowState>, int)
265
266
QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowScreenChanged, QWindow *window, QScreen *screen)
267
0
{
268
269
0
    QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e =
270
0
        new QWindowSystemInterfacePrivate::WindowScreenChangedEvent(window, screen);
271
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
272
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::DefaultDelivery>(QWindow*, QScreen*)
Unexecuted instantiation: void QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QScreen*)
Unexecuted instantiation: void QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QScreen*)
273
274
QT_DEFINE_QPA_EVENT_HANDLER(void, handleSafeAreaMarginsChanged, QWindow *window)
275
0
{
276
0
    QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e =
277
0
        new QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent(window);
278
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
279
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleSafeAreaMarginsChanged<QWindowSystemInterface::DefaultDelivery>(QWindow*)
Unexecuted instantiation: void QWindowSystemInterface::handleSafeAreaMarginsChanged<QWindowSystemInterface::SynchronousDelivery>(QWindow*)
Unexecuted instantiation: void QWindowSystemInterface::handleSafeAreaMarginsChanged<QWindowSystemInterface::AsynchronousDelivery>(QWindow*)
280
281
QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::ApplicationState newState, bool forcePropagate)
282
0
{
283
0
    Q_ASSERT(QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState));
284
0
    QWindowSystemInterfacePrivate::ApplicationStateChangedEvent *e =
285
0
        new QWindowSystemInterfacePrivate::ApplicationStateChangedEvent(newState, forcePropagate);
286
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
287
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleApplicationStateChanged<QWindowSystemInterface::DefaultDelivery>(Qt::ApplicationState, bool)
Unexecuted instantiation: void QWindowSystemInterface::handleApplicationStateChanged<QWindowSystemInterface::SynchronousDelivery>(Qt::ApplicationState, bool)
Unexecuted instantiation: void QWindowSystemInterface::handleApplicationStateChanged<QWindowSystemInterface::AsynchronousDelivery>(Qt::ApplicationState, bool)
288
289
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleApplicationTermination)
290
0
{
291
0
    auto *e = new QWindowSystemInterfacePrivate::WindowSystemEvent(QWindowSystemInterfacePrivate::ApplicationTermination);
292
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
293
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::DefaultDelivery>()
Unexecuted instantiation: bool QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>()
Unexecuted instantiation: bool QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::AsynchronousDelivery>()
294
295
QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry)
296
0
    : WindowSystemEvent(GeometryChange)
297
0
    , window(window)
298
0
    , newGeometry(newGeometry)
299
0
{
300
0
    if (const QPlatformWindow *pw = window->handle()) {
301
0
        const auto nativeGeometry = pw->QPlatformWindow::geometry();
302
0
        requestedGeometry = window->isTopLevel()
303
0
            ? QHighDpi::fromNativePixels(nativeGeometry, window)
304
0
            : QHighDpi::fromNativeLocalPosition(nativeGeometry, window);
305
0
    }
306
0
}
307
308
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
309
0
{
310
0
    Q_ASSERT(window);
311
0
    const auto newRectDi = window->isTopLevel()
312
0
        ? QHighDpi::fromNativePixels(newRect, window)
313
0
        : QHighDpi::fromNativeLocalPosition(newRect, window);
314
0
    auto e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, newRectDi);
315
0
    if (window->handle()) {
316
        // Persist the new geometry so that QWindow::geometry() can be queried in the resize event
317
0
        window->handle()->QPlatformWindow::setGeometry(newRect);
318
        // FIXME: This does not work during platform window creation, where the QWindow does not
319
        // have its handle set up yet. Platforms that deliver events during window creation need
320
        // to handle the persistence manually, e.g. by overriding geometry().
321
0
    }
322
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
323
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::DefaultDelivery>(QWindow*, QRect const&)
Unexecuted instantiation: void QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QRect const&)
Unexecuted instantiation: void QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QRect const&)
324
325
QWindowSystemInterfacePrivate::ExposeEvent::ExposeEvent(QWindow *window, const QRegion &region)
326
0
    : WindowSystemEvent(Expose)
327
0
    , window(window)
328
0
    , isExposed(window && window->handle() ? window->handle()->isExposed() : false)
329
0
    , region(region)
330
0
{
331
0
}
332
333
/*! \internal
334
    Handles an expose event.
335
336
    The platform plugin sends expose events when an area of the window
337
    is invalidated or window exposure changes. \a region is in window
338
    local coordinates. An empty region indicates that the window is
339
    obscured, but note that the exposed property of the QWindow will be set
340
    based on what QPlatformWindow::isExposed() returns at the time of this call,
341
    not based on what the region is. // FIXME: this should probably be fixed.
342
343
    The platform plugin may omit sending expose events (or send obscure
344
    events) for windows that are on screen but where the client area is
345
    completely covered by other windows or otherwise not visible. Expose
346
    event consumers can then use this to disable updates for such windows.
347
    This is required behavior on platforms where OpenGL swapbuffers stops
348
    blocking for obscured windows (like macOS).
349
*/
350
QT_DEFINE_QPA_EVENT_HANDLER(void, handleExposeEvent, QWindow *window, const QRegion &region)
351
0
{
352
0
    QWindowSystemInterfacePrivate::ExposeEvent *e =
353
0
        new QWindowSystemInterfacePrivate::ExposeEvent(window, QHighDpi::fromNativeLocalExposedRegion(region, window));
354
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
355
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, QRegion const&)
Unexecuted instantiation: void QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QRegion const&)
Unexecuted instantiation: void QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QRegion const&)
356
357
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleCloseEvent, QWindow *window)
358
0
{
359
0
    Q_ASSERT(window);
360
0
    auto *event = new QWindowSystemInterfacePrivate::CloseEvent(window);
361
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(event);
362
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*)
Unexecuted instantiation: bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*)
Unexecuted instantiation: bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*)
363
364
/*!
365
366
\a w == 0 means that the event is in global coords only, \a local will be ignored in this case
367
368
*/
369
#if QT_DEPRECATED_SINCE(5, 11)
370
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons b,
371
                                              Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
372
0
{
373
0
    return handleMouseEvent<Delivery>(window, local, global, b, Qt::NoButton, QEvent::None, mods, source);
374
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
375
376
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b,
377
                                              Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
378
0
{
379
0
    return handleMouseEvent<Delivery>(window, timestamp, local, global, b, Qt::NoButton, QEvent::None, mods, source);
380
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, unsigned long, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, unsigned long, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, unsigned long, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
381
382
bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons b,
383
                                                        Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
384
0
{
385
0
    return handleFrameStrutMouseEvent(window, local, global, b, Qt::NoButton, QEvent::None, mods, source);
386
0
}
387
388
bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b,
389
                                                        Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
390
0
{
391
0
    return handleFrameStrutMouseEvent(window, timestamp, local, global, b, Qt::NoButton, QEvent::None, mods, source);
392
0
}
393
#endif // QT_DEPRECATED_SINCE(5, 11)
394
395
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window,
396
                            const QPointF &local, const QPointF &global, Qt::MouseButtons state,
397
                            Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
398
                            Qt::MouseEventSource source)
399
0
{
400
0
    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
401
0
    return handleMouseEvent<Delivery>(window, time, local, global, state, button, type, mods, source);
402
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, Qt::MouseButton, QEvent::Type, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, Qt::MouseButton, QEvent::Type, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, Qt::MouseButton, QEvent::Type, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
403
404
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleMouseEvent, QWindow *window, ulong timestamp,
405
                            const QPointF &local, const QPointF &global, Qt::MouseButtons state,
406
                            Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods,
407
                            Qt::MouseEventSource source)
408
0
{
409
0
    Q_ASSERT_X(type != QEvent::MouseButtonDblClick && type != QEvent::NonClientAreaMouseButtonDblClick,
410
0
               "QWindowSystemInterface::handleMouseEvent",
411
0
               "QTBUG-71263: Native double clicks are not implemented.");
412
0
    auto localPos = QHighDpi::fromNativeLocalPosition(local, window);
413
0
    auto globalPos = QHighDpi::fromNativePixels(global, window);
414
415
0
    QWindowSystemInterfacePrivate::MouseEvent *e =
416
0
        new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, localPos, globalPos,
417
0
                                                      state, mods, button, type, source);
418
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
419
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, unsigned long, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, Qt::MouseButton, QEvent::Type, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, unsigned long, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, Qt::MouseButton, QEvent::Type, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
Unexecuted instantiation: bool QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, unsigned long, QPointF const&, QPointF const&, QFlags<Qt::MouseButton>, Qt::MouseButton, QEvent::Type, QFlags<Qt::KeyboardModifier>, Qt::MouseEventSource)
420
421
bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window,
422
                                                        const QPointF &local, const QPointF &global,
423
                                                        Qt::MouseButtons state,
424
                                                        Qt::MouseButton button, QEvent::Type type,
425
                                                        Qt::KeyboardModifiers mods,
426
                                                        Qt::MouseEventSource source)
427
0
{
428
0
    const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
429
0
    return handleFrameStrutMouseEvent(window, time, local, global, state, button, type, mods, source);
430
0
}
431
432
bool QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *window, ulong timestamp,
433
                                                        const QPointF &local, const QPointF &global,
434
                                                        Qt::MouseButtons state,
435
                                                        Qt::MouseButton button, QEvent::Type type,
436
                                                        Qt::KeyboardModifiers mods,
437
                                                        Qt::MouseEventSource source)
438
0
{
439
0
    auto localPos = QHighDpi::fromNativeLocalPosition(local, window);
440
0
    auto globalPos = QHighDpi::fromNativePixels(global, window);
441
442
0
    QWindowSystemInterfacePrivate::MouseEvent *e =
443
0
            new QWindowSystemInterfacePrivate::MouseEvent(window, timestamp, localPos, globalPos,
444
0
                                                          state, mods, button, type, source, true);
445
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
446
0
}
447
448
bool QWindowSystemInterface::handleShortcutEvent(QWindow *window, ulong timestamp, int keyCode, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode,
449
                                      quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text, bool autorepeat, ushort count)
450
0
{
451
0
#ifndef QT_NO_SHORTCUT
452
0
    if (!window)
453
0
        window = QGuiApplication::focusWindow();
454
455
0
    QShortcutMap &shortcutMap = QGuiApplicationPrivate::instance()->shortcutMap;
456
0
    if (shortcutMap.state() == QKeySequence::NoMatch) {
457
        // Check if the shortcut is overridden by some object in the event delivery path (typically the focus object).
458
        // If so, we should not look up the shortcut in the shortcut map, but instead deliver the event as a regular
459
        // key event, so that the target that accepted the shortcut override event can handle it. Note that we only
460
        // do this if the shortcut map hasn't found a partial shortcut match yet. If it has, the shortcut can not be
461
        // overridden.
462
0
        QWindowSystemInterfacePrivate::KeyEvent *shortcutOverrideEvent = new QWindowSystemInterfacePrivate::KeyEvent(window, timestamp,
463
0
            QEvent::ShortcutOverride, keyCode, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorepeat, count);
464
465
0
        {
466
0
            if (QWindowSystemInterfacePrivate::handleWindowSystemEvent<SynchronousDelivery>(shortcutOverrideEvent))
467
0
                return false;
468
0
        }
469
0
    }
470
471
    // The shortcut event is dispatched as a QShortcutEvent, not a QKeyEvent, but we use
472
    // the QKeyEvent as a container for the various properties that the shortcut map needs
473
    // to inspect to determine if a shortcut matched the keys that were pressed.
474
0
    QKeyEvent keyEvent(QEvent::ShortcutOverride, keyCode, modifiers, nativeScanCode,
475
0
        nativeVirtualKey, nativeModifiers, text, autorepeat, count);
476
477
0
    return shortcutMap.tryShortcut(&keyEvent);
478
#else
479
    Q_UNUSED(window)
480
    Q_UNUSED(timestamp)
481
    Q_UNUSED(keyCode)
482
    Q_UNUSED(modifiers)
483
    Q_UNUSED(nativeScanCode)
484
    Q_UNUSED(nativeVirtualKey)
485
    Q_UNUSED(nativeModifiers)
486
    Q_UNUSED(text)
487
    Q_UNUSED(autorepeat)
488
    Q_UNUSED(count)
489
    return false;
490
#endif
491
0
}
492
493
0
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleKeyEvent, QWindow *window, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) {
494
0
    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
495
0
    return handleKeyEvent<Delivery>(window, time, t, k, mods, text, autorep, count);
496
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, QEvent::Type, int, QFlags<Qt::KeyboardModifier>, QString const&, bool, unsigned short)
Unexecuted instantiation: bool QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QEvent::Type, int, QFlags<Qt::KeyboardModifier>, QString const&, bool, unsigned short)
Unexecuted instantiation: bool QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QEvent::Type, int, QFlags<Qt::KeyboardModifier>, QString const&, bool, unsigned short)
497
498
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleKeyEvent, QWindow *window, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count)
499
0
{
500
#if defined(Q_OS_MACOS)
501
    if (t == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(window, timestamp, k, mods, 0, 0, 0, text, autorep, count))
502
        return true;
503
#endif
504
505
0
    QWindowSystemInterfacePrivate::KeyEvent * e =
506
0
            new QWindowSystemInterfacePrivate::KeyEvent(window, timestamp, t, k, mods, text, autorep, count);
507
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
508
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, unsigned long, QEvent::Type, int, QFlags<Qt::KeyboardModifier>, QString const&, bool, unsigned short)
Unexecuted instantiation: bool QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, unsigned long, QEvent::Type, int, QFlags<Qt::KeyboardModifier>, QString const&, bool, unsigned short)
Unexecuted instantiation: bool QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, unsigned long, QEvent::Type, int, QFlags<Qt::KeyboardModifier>, QString const&, bool, unsigned short)
509
510
bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *window, QEvent::Type type, int key, Qt::KeyboardModifiers modifiers,
511
                                                    quint32 nativeScanCode, quint32 nativeVirtualKey,
512
                                                    quint32 nativeModifiers,
513
                                                    const QString& text, bool autorep,
514
                                                    ushort count, bool tryShortcutOverride)
515
0
{
516
0
    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
517
0
    return handleExtendedKeyEvent(window, time, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers,
518
0
                           text, autorep, count, tryShortcutOverride);
519
0
}
520
521
bool QWindowSystemInterface::handleExtendedKeyEvent(QWindow *window, ulong timestamp, QEvent::Type type, int key,
522
                                                    Qt::KeyboardModifiers modifiers,
523
                                                    quint32 nativeScanCode, quint32 nativeVirtualKey,
524
                                                    quint32 nativeModifiers,
525
                                                    const QString& text, bool autorep,
526
                                                    ushort count, bool tryShortcutOverride)
527
0
{
528
#if defined(Q_OS_MACOS)
529
    if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::handleShortcutEvent(window,
530
            timestamp, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count)) {
531
        return true;
532
    }
533
#else
534
0
    Q_UNUSED(tryShortcutOverride)
535
0
#endif
536
537
0
    QWindowSystemInterfacePrivate::KeyEvent * e =
538
0
            new QWindowSystemInterfacePrivate::KeyEvent(window, timestamp, type, key, modifiers,
539
0
                nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count);
540
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
541
0
}
542
543
QWindowSystemInterfacePrivate::WheelEvent::WheelEvent(QWindow *window, ulong time, const QPointF &local, const QPointF &global, QPoint pixelD,
544
        QPoint angleD, int qt4D, Qt::Orientation qt4O, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase, Qt::MouseEventSource src, bool inverted)
545
0
    : InputEvent(window, time, Wheel, mods), pixelDelta(pixelD), angleDelta(angleD), qt4Delta(qt4D),
546
0
      qt4Orientation(qt4O), localPos(local), globalPos(global), phase(phase), source(src), inverted(inverted)
547
0
{
548
0
}
549
550
#if QT_DEPRECATED_SINCE(5, 10)
551
0
bool QWindowSystemInterface::handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods) {
552
0
    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
553
0
QT_WARNING_PUSH
554
0
QT_WARNING_DISABLE_DEPRECATED
555
0
    return handleWheelEvent(window, time, local, global, d, o, mods);
556
0
QT_WARNING_POP
557
0
}
558
559
bool QWindowSystemInterface::handleWheelEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods)
560
0
{
561
0
    QPoint point = (o == Qt::Vertical) ? QPoint(0, d) : QPoint(d, 0);
562
0
    return handleWheelEvent(window, timestamp, local, global, QPoint(), point, mods);
563
0
}
564
#endif // QT_DEPRECATED_SINCE(5, 10)
565
566
bool QWindowSystemInterface::handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase, Qt::MouseEventSource source)
567
0
{
568
0
    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
569
0
    return handleWheelEvent(window, time, local, global, pixelDelta, angleDelta, mods, phase, source);
570
0
}
571
572
bool QWindowSystemInterface::handleWheelEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods, Qt::ScrollPhase phase,
573
                                              Qt::MouseEventSource source, bool invertedScrolling)
574
0
{
575
    // Qt 4 sends two separate wheel events for horizontal and vertical
576
    // deltas. For Qt 5 we want to send the deltas in one event, but at the
577
    // same time preserve source and behavior compatibility with Qt 4.
578
    //
579
    // In addition high-resolution pixel-based deltas are also supported.
580
    // Platforms that does not support these may pass a null point here.
581
    // Angle deltas must always be sent in addition to pixel deltas.
582
0
    QWindowSystemInterfacePrivate::WheelEvent *e;
583
584
    // Pass Qt::ScrollBegin and Qt::ScrollEnd through
585
    // even if the wheel delta is null.
586
0
    if (angleDelta.isNull() && phase == Qt::ScrollUpdate)
587
0
        return false;
588
589
    // Simple case: vertical deltas only:
590
0
    if (angleDelta.y() != 0 && angleDelta.x() == 0) {
591
0
        e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical,
592
0
                                                          mods, phase, source, invertedScrolling);
593
594
0
        return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
595
0
    }
596
597
    // Simple case: horizontal deltas only:
598
0
    if (angleDelta.y() == 0 && angleDelta.x() != 0) {
599
0
        e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling);
600
0
        return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
601
0
    }
602
603
0
    bool acceptVert;
604
0
    bool acceptHorz;
605
    // Both horizontal and vertical deltas: Send two wheel events.
606
    // The first event contains the Qt 5 pixel and angle delta as points,
607
    // and in addition the Qt 4 compatibility vertical angle delta.
608
0
    e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source, invertedScrolling);
609
0
    acceptVert = QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
610
611
    // The second event contains null pixel and angle points and the
612
    // Qt 4 compatibility horizontal angle delta.
613
0
    e = new QWindowSystemInterfacePrivate::WheelEvent(window, timestamp, QHighDpi::fromNativeLocalPosition(local, window), QHighDpi::fromNativePixels(global, window), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling);
614
0
    acceptHorz = QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
615
0
    return acceptVert || acceptHorz;
616
0
}
617
618
void QWindowSystemInterface::registerTouchDevice(const QTouchDevice *device)
619
0
{
620
0
    QTouchDevicePrivate::registerDevice(device);
621
0
}
622
623
void QWindowSystemInterface::unregisterTouchDevice(const QTouchDevice *device)
624
0
{
625
0
    QTouchDevicePrivate::unregisterDevice(device);
626
0
}
627
628
bool QWindowSystemInterface::isTouchDeviceRegistered(const QTouchDevice *device)
629
0
{
630
0
    return QTouchDevicePrivate::isRegistered(device);
631
0
}
632
633
static int g_nextPointId = 1;
634
635
// map from device-independent point id (arbitrary) to "Qt point" ids
636
static QBasicMutex pointIdMapMutex;
637
typedef QMap<quint64, int> PointIdMap;
638
Q_GLOBAL_STATIC(PointIdMap, g_pointIdMap)
639
640
/*!
641
    \internal
642
    This function maps potentially arbitrary point ids \a pointId in the 32 bit
643
    value space to start from 1 and increase incrementally for each touch point
644
    held down. If all touch points are released it will reset the id back to 1
645
    for the following touch point.
646
647
    We can then assume that the touch points ids will never become too large,
648
    and it will then put the device identifier \a deviceId in the upper 8 bits.
649
    This leaves us with max 255 devices, and 16.7M taps without full release
650
    before we run out of value space.
651
*/
652
static int acquireCombinedPointId(quint8 deviceId, int pointId)
653
0
{
654
0
    const auto locker = qt_scoped_lock(pointIdMapMutex);
655
656
0
    quint64 combinedId64 = (quint64(deviceId) << 32) + pointId;
657
0
    auto it = g_pointIdMap->constFind(combinedId64);
658
0
    int uid;
659
0
    if (it == g_pointIdMap->constEnd()) {
660
0
        uid = g_nextPointId++;
661
0
        g_pointIdMap->insert(combinedId64, uid);
662
0
    } else {
663
0
        uid = *it;
664
0
    }
665
0
    return (deviceId << 24) + uid;
666
0
}
667
668
QList<QTouchEvent::TouchPoint>
669
    QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
670
                                                         const QWindow *window, quint8 deviceId,
671
                                                         QEvent::Type *type)
672
0
{
673
0
    QList<QTouchEvent::TouchPoint> touchPoints;
674
0
    Qt::TouchPointStates states;
675
0
    QTouchEvent::TouchPoint p;
676
677
0
    touchPoints.reserve(points.count());
678
0
    QList<QWindowSystemInterface::TouchPoint>::const_iterator point = points.constBegin();
679
0
    QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd();
680
0
    while (point != end) {
681
0
        p.setId(acquireCombinedPointId(deviceId, point->id));
682
0
        if (point->uniqueId >= 0)
683
0
            p.setUniqueId(point->uniqueId);
684
0
        p.setPressure(point->pressure);
685
0
        p.setRotation(point->rotation);
686
0
        states |= point->state;
687
0
        p.setState(point->state);
688
689
0
        p.setScreenPos(QHighDpi::fromNativePixels(point->area.center(), window));
690
0
        p.setEllipseDiameters(point->area.size());
691
692
        // The local pos and rect are not set, they will be calculated
693
        // when the event gets processed by QGuiApplication.
694
695
0
        p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window));
696
0
        p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window));
697
0
        p.setFlags(point->flags);
698
0
        p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window));
699
700
0
        touchPoints.append(p);
701
0
        ++point;
702
0
    }
703
704
    // Determine the event type based on the combined point states.
705
0
    if (type) {
706
0
        *type = QEvent::TouchUpdate;
707
0
        if (states == Qt::TouchPointPressed)
708
0
            *type = QEvent::TouchBegin;
709
0
        else if (states == Qt::TouchPointReleased)
710
0
            *type = QEvent::TouchEnd;
711
0
    }
712
713
0
    if (states == Qt::TouchPointReleased) {
714
0
        const auto locker = qt_scoped_lock(pointIdMapMutex);
715
716
        // All points on deviceId have been released.
717
        // Remove all points associated with that device from g_pointIdMap.
718
        // (On other devices, some touchpoints might still be pressed.
719
        // But this function is only called with points from one device at a time.)
720
0
        for (auto it = g_pointIdMap->begin(); it != g_pointIdMap->end();) {
721
0
            if (it.key() >> 32 == quint64(deviceId))
722
0
                it = g_pointIdMap->erase(it);
723
0
            else
724
0
                ++it;
725
0
        }
726
0
        if (g_pointIdMap->isEmpty())
727
0
            g_nextPointId = 1;
728
0
    }
729
730
0
    return touchPoints;
731
0
}
732
733
void QWindowSystemInterfacePrivate::clearPointIdMap()
734
0
{
735
0
    const auto locker = qt_scoped_lock(pointIdMapMutex);
736
0
    g_pointIdMap->clear();
737
0
    g_nextPointId = 1;
738
0
}
739
740
QList<QWindowSystemInterface::TouchPoint>
741
    QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
742
                                                       const QWindow *window)
743
0
{
744
0
    QList<QWindowSystemInterface::TouchPoint> newList;
745
0
    newList.reserve(pointList.size());
746
0
    for (const QTouchEvent::TouchPoint &pt : pointList) {
747
0
        QWindowSystemInterface::TouchPoint p;
748
0
        p.id = pt.id();
749
0
        p.flags = pt.flags();
750
0
        p.normalPosition = QHighDpi::toNativeLocalPosition(pt.normalizedPos(), window);
751
0
        QRectF area(QPointF(), pt.ellipseDiameters());
752
0
        area.moveCenter(pt.screenPos());
753
0
        p.area = QHighDpi::toNativePixels(area, window);
754
0
        p.pressure = pt.pressure();
755
0
        p.state = pt.state();
756
0
        p.velocity = QHighDpi::toNativePixels(pt.velocity(), window);
757
0
        p.rawPositions = QHighDpi::toNativePixels(pt.rawScreenPositions(), window);
758
0
        newList.append(p);
759
0
    }
760
0
    return newList;
761
0
}
762
763
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, QTouchDevice *device,
764
                                              const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
765
0
{
766
0
    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
767
0
    return handleTouchEvent<Delivery>(window, time, device, points, mods);
768
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, QTouchDevice*, QList<QWindowSystemInterface::TouchPoint> const&, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QTouchDevice*, QList<QWindowSystemInterface::TouchPoint> const&, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QTouchDevice*, QList<QWindowSystemInterface::TouchPoint> const&, QFlags<Qt::KeyboardModifier>)
769
770
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchEvent, QWindow *window, ulong timestamp, QTouchDevice *device,
771
                                              const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
772
0
{
773
0
    if (!points.size()) // Touch events must have at least one point
774
0
        return false;
775
776
0
    if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices.
777
0
        return false;
778
779
0
    QEvent::Type type;
780
0
    QList<QTouchEvent::TouchPoint> touchPoints =
781
0
            QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, QTouchDevicePrivate::get(device)->id, &type);
782
783
0
    QWindowSystemInterfacePrivate::TouchEvent *e =
784
0
            new QWindowSystemInterfacePrivate::TouchEvent(window, timestamp, type, device, touchPoints, mods);
785
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
786
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, unsigned long, QTouchDevice*, QList<QWindowSystemInterface::TouchPoint> const&, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, unsigned long, QTouchDevice*, QList<QWindowSystemInterface::TouchPoint> const&, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, unsigned long, QTouchDevice*, QList<QWindowSystemInterface::TouchPoint> const&, QFlags<Qt::KeyboardModifier>)
787
788
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, QTouchDevice *device,
789
                                                    Qt::KeyboardModifiers mods)
790
0
{
791
0
    unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
792
0
    return handleTouchCancelEvent<Delivery>(window, time, device, mods);
793
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, QTouchDevice*, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, QTouchDevice*, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, QTouchDevice*, QFlags<Qt::KeyboardModifier>)
794
795
QT_DEFINE_QPA_EVENT_HANDLER(bool, handleTouchCancelEvent, QWindow *window, ulong timestamp, QTouchDevice *device,
796
                                                    Qt::KeyboardModifiers mods)
797
0
{
798
0
    QWindowSystemInterfacePrivate::TouchEvent *e =
799
0
            new QWindowSystemInterfacePrivate::TouchEvent(window, timestamp, QEvent::TouchCancel, device,
800
0
                                                         QList<QTouchEvent::TouchPoint>(), mods);
801
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
802
0
}
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::DefaultDelivery>(QWindow*, unsigned long, QTouchDevice*, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*, unsigned long, QTouchDevice*, QFlags<Qt::KeyboardModifier>)
Unexecuted instantiation: bool QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::AsynchronousDelivery>(QWindow*, unsigned long, QTouchDevice*, QFlags<Qt::KeyboardModifier>)
803
804
/*!
805
    Should be called by the implementation whenever a new screen is added.
806
807
    The first screen added will be the primary screen, used for default-created
808
    windows, GL contexts, and other resources unless otherwise specified.
809
810
    This adds the screen to QGuiApplication::screens(), and emits the
811
    QGuiApplication::screenAdded() signal.
812
813
    The screen should be deleted by calling QWindowSystemInterface::handleScreenRemoved().
814
*/
815
void QWindowSystemInterface::handleScreenAdded(QPlatformScreen *ps, bool isPrimary)
816
0
{
817
0
    QScreen *screen = new QScreen(ps);
818
819
0
    if (isPrimary)
820
0
        QGuiApplicationPrivate::screen_list.prepend(screen);
821
0
    else
822
0
        QGuiApplicationPrivate::screen_list.append(screen);
823
824
0
    QGuiApplicationPrivate::resetCachedDevicePixelRatio();
825
826
0
    emit qGuiApp->screenAdded(screen);
827
828
0
    if (isPrimary)
829
0
        emit qGuiApp->primaryScreenChanged(screen);
830
0
}
831
832
/*!
833
    Should be called by the implementation whenever a screen is removed.
834
835
    This removes the screen from QGuiApplication::screens(), and deletes it.
836
837
    Failing to call this and manually deleting the QPlatformScreen instead may
838
    lead to a crash due to a pure virtual call.
839
*/
840
void QWindowSystemInterface::handleScreenRemoved(QPlatformScreen *platformScreen)
841
0
{
842
    // Important to keep this order since the QSceen doesn't own the platform screen.
843
    // The QScreen destructor will take care changing the primary screen, so no need here.
844
0
    delete platformScreen->screen();
845
0
    delete platformScreen;
846
0
}
847
848
/*!
849
    Should be called whenever the primary screen changes.
850
851
    When the screen specified as primary changes, this method will notify
852
    QGuiApplication and emit the QGuiApplication::primaryScreenChanged signal.
853
 */
854
void QWindowSystemInterface::handlePrimaryScreenChanged(QPlatformScreen *newPrimary)
855
0
{
856
0
    QScreen *newPrimaryScreen = newPrimary->screen();
857
0
    int indexOfScreen = QGuiApplicationPrivate::screen_list.indexOf(newPrimaryScreen);
858
0
    Q_ASSERT(indexOfScreen >= 0);
859
0
    if (indexOfScreen == 0)
860
0
        return;
861
862
0
    QGuiApplicationPrivate::screen_list.swapItemsAt(0, indexOfScreen);
863
0
    emit qGuiApp->primaryScreenChanged(newPrimaryScreen);
864
0
}
865
866
void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::ScreenOrientation orientation)
867
0
{
868
0
    QWindowSystemInterfacePrivate::ScreenOrientationEvent *e =
869
0
            new QWindowSystemInterfacePrivate::ScreenOrientationEvent(screen, orientation);
870
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
871
0
}
872
873
void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry)
874
0
{
875
0
    QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
876
0
        new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft()));
877
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
878
0
}
879
880
void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY)
881
0
{
882
0
    const QDpi effectiveDpi = QPlatformScreen::overrideDpi(QDpi{dpiX, dpiY});
883
0
    auto e = new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, effectiveDpi.first, effectiveDpi.second);
884
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
885
0
}
886
887
void QWindowSystemInterface::handleScreenRefreshRateChange(QScreen *screen, qreal newRefreshRate)
888
0
{
889
0
    QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e =
890
0
            new QWindowSystemInterfacePrivate::ScreenRefreshRateEvent(screen, newRefreshRate);
891
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
892
0
}
893
894
QT_DEFINE_QPA_EVENT_HANDLER(void, handleThemeChange, QWindow *window)
895
0
{
896
0
    QWindowSystemInterfacePrivate::ThemeChangeEvent *e = new QWindowSystemInterfacePrivate::ThemeChangeEvent(window);
897
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e);
898
0
}
Unexecuted instantiation: void QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::DefaultDelivery>(QWindow*)
Unexecuted instantiation: void QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>(QWindow*)
Unexecuted instantiation: void QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::AsynchronousDelivery>(QWindow*)
899
900
#if QT_CONFIG(draganddrop)
901
#if QT_DEPRECATED_SINCE(5, 11)
902
QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *window, const QMimeData *dropData,
903
                                                           const QPoint &p, Qt::DropActions supportedActions)
904
0
{
905
0
    return QGuiApplicationPrivate::processDrag(window, dropData, p, supportedActions,
906
0
                                               QGuiApplication::mouseButtons(),
907
0
                                               QGuiApplication::keyboardModifiers());
908
0
}
909
910
QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *window, const QMimeData *dropData,
911
                                                           const QPoint &p, Qt::DropActions supportedActions)
912
0
{
913
0
    return QGuiApplicationPrivate::processDrop(window, dropData, p, supportedActions,
914
0
                                               QGuiApplication::mouseButtons(),
915
0
                                               QGuiApplication::keyboardModifiers());
916
0
}
917
#endif // QT_DEPRECATED_SINCE(5, 11)
918
/*!
919
    Drag and drop events are sent immediately.
920
921
    ### FIXME? Perhaps DnD API should add some convenience APIs that are more
922
    intuitive for the possible DND operations. Here passing nullptr as drop data is used to
923
    indicate that drop was canceled and QDragLeaveEvent should be sent as a result.
924
*/
925
QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *window, const QMimeData *dropData,
926
                                                           const QPoint &p, Qt::DropActions supportedActions,
927
                                                           Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
928
0
{
929
0
    auto pos = QHighDpi::fromNativeLocalPosition(p, window);
930
0
    return QGuiApplicationPrivate::processDrag(window, dropData, pos, supportedActions, buttons, modifiers);
931
0
}
932
933
QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *window, const QMimeData *dropData,
934
                                                           const QPoint &p, Qt::DropActions supportedActions,
935
                                                           Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
936
0
{
937
0
    auto pos = QHighDpi::fromNativeLocalPosition(p, window);
938
0
    return QGuiApplicationPrivate::processDrop(window, dropData, pos, supportedActions, buttons, modifiers);
939
0
}
940
#endif // QT_CONFIG(draganddrop)
941
942
/*!
943
    \fn static QWindowSystemInterface::handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result)
944
    \brief Passes a native event identified by \a eventType to the \a window.
945
946
    \note This function can only be called from the GUI thread.
947
*/
948
949
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
950
bool QWindowSystemInterface::handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, qintptr *result)
951
#else
952
bool QWindowSystemInterface::handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result)
953
#endif
954
0
{
955
0
    return QGuiApplicationPrivate::processNativeEvent(window, eventType, message, result);
956
0
}
957
958
void QWindowSystemInterface::handleFileOpenEvent(const QString& fileName)
959
0
{
960
0
    QWindowSystemInterfacePrivate::FileOpenEvent e(fileName);
961
0
    QGuiApplicationPrivate::processWindowSystemEvent(&e);
962
0
}
963
964
void QWindowSystemInterface::handleFileOpenEvent(const QUrl &url)
965
0
{
966
0
    QWindowSystemInterfacePrivate::FileOpenEvent e(url);
967
0
    QGuiApplicationPrivate::processWindowSystemEvent(&e);
968
0
}
969
970
void QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(bool v)
971
0
{
972
0
    platformSynthesizesMouse = v;
973
0
}
974
975
bool QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, const QPointF &local, const QPointF &global,
976
                                               int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
977
                                               qreal tangentialPressure, qreal rotation, int z, qint64 uid,
978
                                               Qt::KeyboardModifiers modifiers)
979
0
{
980
0
    QWindowSystemInterfacePrivate::TabletEvent *e =
981
0
        new QWindowSystemInterfacePrivate::TabletEvent(window, timestamp,
982
0
                                                       QHighDpi::fromNativeLocalPosition(local, window),
983
0
                                                       QHighDpi::fromNativePixels(global, window),
984
0
                                                       device, pointerType, buttons, pressure,
985
0
                                                       xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
986
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
987
0
}
988
989
bool QWindowSystemInterface::handleTabletEvent(QWindow *window, const QPointF &local, const QPointF &global,
990
                                               int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, int xTilt, int yTilt,
991
                                               qreal tangentialPressure, qreal rotation, int z, qint64 uid,
992
                                               Qt::KeyboardModifiers modifiers)
993
0
{
994
0
    ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
995
0
    return handleTabletEvent(window, time, local, global, device, pointerType, buttons, pressure,
996
0
                      xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
997
0
}
998
999
#if QT_DEPRECATED_SINCE(5, 10)
1000
void QWindowSystemInterface::handleTabletEvent(QWindow *window, ulong timestamp, bool down, const QPointF &local, const QPointF &global,
1001
                                               int device, int pointerType, qreal pressure, int xTilt, int yTilt,
1002
                                               qreal tangentialPressure, qreal rotation, int z, qint64 uid,
1003
                                               Qt::KeyboardModifiers modifiers)
1004
0
{
1005
0
    handleTabletEvent(window, timestamp, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
1006
0
                      xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
1007
0
}
1008
1009
void QWindowSystemInterface::handleTabletEvent(QWindow *window, bool down, const QPointF &local, const QPointF &global,
1010
                                               int device, int pointerType, qreal pressure, int xTilt, int yTilt,
1011
                                               qreal tangentialPressure, qreal rotation, int z, qint64 uid,
1012
                                               Qt::KeyboardModifiers modifiers)
1013
0
{
1014
0
    handleTabletEvent(window, local, global, device, pointerType, (down ? Qt::LeftButton : Qt::NoButton), pressure,
1015
0
                      xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
1016
0
}
1017
#endif // QT_DEPRECATED_SINCE(5, 10)
1018
1019
bool QWindowSystemInterface::handleTabletEnterProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid)
1020
0
{
1021
0
    QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e =
1022
0
            new QWindowSystemInterfacePrivate::TabletEnterProximityEvent(timestamp, device, pointerType, uid);
1023
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1024
0
}
1025
1026
void QWindowSystemInterface::handleTabletEnterProximityEvent(int device, int pointerType, qint64 uid)
1027
0
{
1028
0
    ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
1029
0
    handleTabletEnterProximityEvent(time, device, pointerType, uid);
1030
0
}
1031
1032
bool QWindowSystemInterface::handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid)
1033
0
{
1034
0
    QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e =
1035
0
            new QWindowSystemInterfacePrivate::TabletLeaveProximityEvent(timestamp, device, pointerType, uid);
1036
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1037
0
}
1038
1039
void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid)
1040
0
{
1041
0
    ulong time = QWindowSystemInterfacePrivate::eventTime.elapsed();
1042
0
    handleTabletLeaveProximityEvent(time, device, pointerType, uid);
1043
0
}
1044
1045
#ifndef QT_NO_GESTURES
1046
bool QWindowSystemInterface::handleGestureEvent(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
1047
                                                QPointF &local, QPointF &global)
1048
0
{
1049
0
    QWindowSystemInterfacePrivate::GestureEvent *e =
1050
0
        new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
1051
0
       return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1052
0
}
1053
1054
bool QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
1055
                                                                qreal value, QPointF &local, QPointF &global)
1056
0
{
1057
0
    QWindowSystemInterfacePrivate::GestureEvent *e =
1058
0
        new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
1059
0
    e->realValue = value;
1060
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1061
0
}
1062
1063
bool QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, QTouchDevice *device, ulong timestamp, Qt::NativeGestureType type,
1064
                                                                         ulong sequenceId, quint64 value, QPointF &local, QPointF &global)
1065
0
{
1066
0
    QWindowSystemInterfacePrivate::GestureEvent *e =
1067
0
        new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, device, local, global);
1068
0
    e->sequenceId = sequenceId;
1069
0
    e->intValue = value;
1070
0
    return QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1071
0
}
1072
#endif // QT_NO_GESTURES
1073
1074
void QWindowSystemInterface::handlePlatformPanelEvent(QWindow *w)
1075
0
{
1076
0
    QWindowSystemInterfacePrivate::PlatformPanelEvent *e =
1077
0
            new QWindowSystemInterfacePrivate::PlatformPanelEvent(w);
1078
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1079
0
}
1080
1081
#ifndef QT_NO_CONTEXTMENU
1082
void QWindowSystemInterface::handleContextMenuEvent(QWindow *window, bool mouseTriggered,
1083
                                                    const QPoint &pos, const QPoint &globalPos,
1084
                                                    Qt::KeyboardModifiers modifiers)
1085
0
{
1086
0
    QWindowSystemInterfacePrivate::ContextMenuEvent *e =
1087
0
            new QWindowSystemInterfacePrivate::ContextMenuEvent(window, mouseTriggered, pos,
1088
0
                                                                globalPos, modifiers);
1089
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1090
0
}
1091
#endif
1092
1093
#if QT_CONFIG(whatsthis)
1094
void QWindowSystemInterface::handleEnterWhatsThisEvent()
1095
0
{
1096
0
    QWindowSystemInterfacePrivate::WindowSystemEvent *e =
1097
0
            new QWindowSystemInterfacePrivate::WindowSystemEvent(QWindowSystemInterfacePrivate::EnterWhatsThisMode);
1098
0
    QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
1099
0
}
1100
#endif
1101
1102
#ifndef QT_NO_DEBUG_STREAM
1103
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPoint &p)
1104
0
{
1105
0
    QDebugStateSaver saver(dbg);
1106
0
    dbg.nospace() << "TouchPoint(" << p.id << " @" << p.area << " normalized " << p.normalPosition
1107
0
                  << " press " << p.pressure << " vel " << p.velocity << " state " << (int)p.state;
1108
0
    return dbg;
1109
0
}
1110
#endif
1111
1112
// ------------------ Event dispatcher functionality ------------------
1113
1114
/*!
1115
    Make Qt Gui process all events on the event queue immediately. Return the
1116
    accepted state for the last event on the queue.
1117
*/
1118
bool QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
1119
0
{
1120
0
    const int count = QWindowSystemInterfacePrivate::windowSystemEventQueue.count();
1121
0
    if (!count)
1122
0
        return false;
1123
0
    if (!QGuiApplication::instance()) {
1124
0
        qWarning().nospace()
1125
0
            << "QWindowSystemInterface::flushWindowSystemEvents() invoked after "
1126
0
               "QGuiApplication destruction, discarding " << count << " events.";
1127
0
        QWindowSystemInterfacePrivate::windowSystemEventQueue.clear();
1128
0
        return false;
1129
0
    }
1130
0
    if (QThread::currentThread() != QGuiApplication::instance()->thread()) {
1131
        // Post a FlushEvents event which will trigger a call back to
1132
        // deferredFlushWindowSystemEvents from the Gui thread.
1133
0
        QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
1134
0
        QWindowSystemInterfacePrivate::FlushEventsEvent *e = new QWindowSystemInterfacePrivate::FlushEventsEvent(flags);
1135
0
        QWindowSystemInterfacePrivate::handleWindowSystemEvent<AsynchronousDelivery>(e);
1136
0
        QWindowSystemInterfacePrivate::eventsFlushed.wait(&QWindowSystemInterfacePrivate::flushEventMutex);
1137
0
    } else {
1138
0
        sendWindowSystemEvents(flags);
1139
0
    }
1140
0
    return QWindowSystemInterfacePrivate::eventAccepted.loadRelaxed() > 0;
1141
0
}
1142
1143
void QWindowSystemInterface::deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
1144
0
{
1145
0
    Q_ASSERT(QThread::currentThread() == QGuiApplication::instance()->thread());
1146
1147
0
    QMutexLocker locker(&QWindowSystemInterfacePrivate::flushEventMutex);
1148
0
    sendWindowSystemEvents(flags);
1149
0
    QWindowSystemInterfacePrivate::eventsFlushed.wakeOne();
1150
0
}
1151
1152
bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
1153
0
{
1154
0
    int nevents = 0;
1155
1156
0
    while (QWindowSystemInterfacePrivate::windowSystemEventsQueued()) {
1157
0
        QWindowSystemInterfacePrivate::WindowSystemEvent *event =
1158
0
                flags & QEventLoop::ExcludeUserInputEvents ?
1159
0
                        QWindowSystemInterfacePrivate::getNonUserInputWindowSystemEvent() :
1160
0
                        QWindowSystemInterfacePrivate::getWindowSystemEvent();
1161
0
        if (!event)
1162
0
            break;
1163
1164
0
        if (QWindowSystemInterfacePrivate::eventHandler) {
1165
0
            if (QWindowSystemInterfacePrivate::eventHandler->sendEvent(event))
1166
0
                nevents++;
1167
0
        } else {
1168
0
            nevents++;
1169
0
            QGuiApplicationPrivate::processWindowSystemEvent(event);
1170
0
        }
1171
1172
        // Record the accepted state for the processed event
1173
        // (excluding flush events). This state can then be
1174
        // returned by flushWindowSystemEvents().
1175
0
        if (event->type != QWindowSystemInterfacePrivate::FlushEvents)
1176
0
            QWindowSystemInterfacePrivate::eventAccepted.storeRelaxed(event->eventAccepted);
1177
1178
0
        delete event;
1179
0
    }
1180
1181
0
    return (nevents > 0);
1182
0
}
1183
1184
void QWindowSystemInterface::setSynchronousWindowSystemEvents(bool enable)
1185
0
{
1186
0
    QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = enable;
1187
0
}
1188
1189
int QWindowSystemInterface::windowSystemEventsQueued()
1190
0
{
1191
0
    return QWindowSystemInterfacePrivate::windowSystemEventsQueued();
1192
0
}
1193
1194
bool QWindowSystemInterface::nonUserInputEventsQueued()
1195
0
{
1196
0
    return QWindowSystemInterfacePrivate::nonUserInputEventsQueued();
1197
0
}
1198
1199
// --------------------- QtTestLib support ---------------------
1200
1201
// The following functions are used by testlib, and need to be synchronous to avoid
1202
// race conditions with plugins delivering native events from secondary threads.
1203
// FIXME: It seems unnecessary to export these wrapper functions, when qtestlib could access
1204
// QWindowSystemInterface directly (by adding dependency to gui-private), see QTBUG-63146.
1205
1206
Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global,
1207
                                      Qt::MouseButtons state, Qt::MouseButton button,
1208
                                      QEvent::Type type, Qt::KeyboardModifiers mods, int timestamp)
1209
0
{
1210
0
    const qreal factor = QHighDpiScaling::factor(window);
1211
0
    QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(window,
1212
0
                timestamp, local * factor, global * factor, state, button, type, mods);
1213
0
}
1214
1215
// Wrapper for compatibility with Qt < 5.11
1216
// ### Qt6: Remove
1217
Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global,
1218
                                      Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp)
1219
0
{
1220
0
    const qreal factor = QHighDpiScaling::factor(window);
1221
0
    QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(window,
1222
0
                timestamp, local * factor, global * factor, b, Qt::NoButton, QEvent::None, mods);
1223
0
}
1224
1225
// Wrapper for compatibility with Qt < 5.6
1226
// ### Qt6: Remove
1227
Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier)
1228
0
{
1229
0
    qt_handleMouseEvent(w, local, global, b, mods, QWindowSystemInterfacePrivate::eventTime.elapsed());
1230
0
}
1231
1232
Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *window, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
1233
0
{
1234
0
    QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>(window, t, k, mods, text, autorep, count);
1235
0
}
1236
1237
Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1)
1238
0
{
1239
0
#ifndef QT_NO_SHORTCUT
1240
1241
    // FIXME: This method should not allow targeting a specific object, but should
1242
    // instead forward the event to a window, which then takes care of normal event
1243
    // propagation. We need to fix a lot of tests before we can refactor this (the
1244
    // window needs to be exposed and active and have a focus object), so we leave
1245
    // it as is for now. See QTBUG-48577.
1246
1247
0
    QGuiApplicationPrivate::modifier_buttons = mods;
1248
1249
0
    QKeyEvent qevent(QEvent::ShortcutOverride, k, mods, text, autorep, count);
1250
0
    qevent.setTimestamp(timestamp);
1251
1252
0
    QShortcutMap &shortcutMap = QGuiApplicationPrivate::instance()->shortcutMap;
1253
0
    if (shortcutMap.state() == QKeySequence::NoMatch) {
1254
        // Try sending as QKeyEvent::ShortcutOverride first
1255
0
        QCoreApplication::sendEvent(o, &qevent);
1256
0
        if (qevent.isAccepted())
1257
0
            return false;
1258
0
    }
1259
1260
    // Then as QShortcutEvent
1261
0
    return shortcutMap.tryShortcut(&qevent);
1262
#else
1263
    Q_UNUSED(o)
1264
    Q_UNUSED(timestamp)
1265
    Q_UNUSED(k)
1266
    Q_UNUSED(mods)
1267
    Q_UNUSED(text)
1268
    Q_UNUSED(autorep)
1269
    Q_UNUSED(count)
1270
    return false;
1271
#endif
1272
0
}
1273
1274
namespace QTest
1275
{
1276
    Q_GUI_EXPORT QTouchDevice * createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen)
1277
0
    {
1278
0
        QTouchDevice *ret = new QTouchDevice();
1279
0
        ret->setType(devType);
1280
0
        QWindowSystemInterface::registerTouchDevice(ret);
1281
0
        return ret;
1282
0
    }
1283
}
1284
1285
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *window, QTouchDevice *device,
1286
                                const QList<QTouchEvent::TouchPoint> &points,
1287
                                Qt::KeyboardModifiers mods = Qt::NoModifier)
1288
0
{
1289
0
    QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window, device,
1290
0
        QWindowSystemInterfacePrivate::toNativeTouchPoints(points, window), mods);
1291
0
}
1292
1293
1294
QT_END_NAMESPACE