1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QGUIAPPLICATION_P_H
5#define QGUIAPPLICATION_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/private/qtguiglobal_p.h>
19#include <QtGui/qguiapplication.h>
20#include <QtGui/qicon.h>
21
22#include <QtCore/QHash>
23#include <QtCore/QPointF>
24#include <QtCore/private/qcoreapplication_p.h>
25
26#include <QtCore/qnativeinterface.h>
27#include <QtCore/private/qnativeinterface_p.h>
28#include <QtCore/private/qnumeric_p.h>
29#include <QtCore/private/qthread_p.h>
30
31#include <qpa/qwindowsysteminterface.h>
32#include <qpa/qwindowsysteminterface_p.h>
33#if QT_CONFIG(shortcut)
34# include "private/qshortcutmap_p.h"
35#endif
36
37#include <memory>
38
39QT_BEGIN_NAMESPACE
40
41class QColorTrcLut;
42class QPlatformIntegration;
43class QPlatformTheme;
44class QPlatformDragQtResponse;
45#if QT_CONFIG(draganddrop)
46class QDrag;
47#endif // QT_CONFIG(draganddrop)
48class QInputDeviceManager;
49#ifndef QT_NO_ACTION
50class QActionPrivate;
51#endif
52#if QT_CONFIG(shortcut)
53class QShortcutPrivate;
54#endif
55
56class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate
57{
58 Q_DECLARE_PUBLIC(QGuiApplication)
59public:
60 QGuiApplicationPrivate(int &argc, char **argv);
61 ~QGuiApplicationPrivate();
62
63 void init();
64
65 void createPlatformIntegration();
66 void createEventDispatcher() override;
67 void eventDispatcherReady() override;
68
69 virtual void notifyLayoutDirectionChange();
70 virtual void notifyActiveWindowChange(QWindow *previous);
71
72#if QT_CONFIG(commandlineparser)
73 void addQtOptions(QList<QCommandLineOption> *options) override;
74#endif
75 bool canQuitAutomatically() override;
76 void quit() override;
77
78 void maybeLastWindowClosed();
79 bool lastWindowClosed() const;
80 static bool quitOnLastWindowClosed;
81
82 static void captureGlobalModifierState(QEvent *e);
83 static Qt::KeyboardModifiers modifier_buttons;
84 static Qt::MouseButtons mouse_buttons;
85
86 static QPlatformIntegration *platform_integration;
87
88 static QPlatformIntegration *platformIntegration()
89 { return platform_integration; }
90
91 static QPlatformTheme *platform_theme;
92
93 static QPlatformTheme *platformTheme()
94 { return platform_theme; }
95
96 static QAbstractEventDispatcher *qt_qpa_core_dispatcher()
97 {
98 if (QCoreApplication::instance())
99 return QCoreApplication::instance()->d_func()->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
100 else
101 return nullptr;
102 }
103
104 static void processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e);
105 static void processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e);
106 static void processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e);
107 static void processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e);
108
109 static void processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e);
110
111 static void processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e);
112
113 static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e);
114 static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e);
115
116 static void processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e);
117 static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e);
118 static void processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e);
119 static void processWindowDevicePixelRatioChangedEvent(QWindowSystemInterfacePrivate::WindowDevicePixelRatioChangedEvent *e);
120
121 static void processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e);
122
123 static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
124
125 static void processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
126
127 static void updateFilteredScreenOrientation(QScreen *screen);
128 static void processScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e);
129 static void processScreenGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
130 static void processScreenLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e);
131 static void processScreenRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e);
132 static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce);
133
134 static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e);
135 static void processPaintEvent(QWindowSystemInterfacePrivate::PaintEvent *e);
136
137 static void processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e);
138
139 static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e);
140 static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e);
141 static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e);
142
143#ifndef QT_NO_GESTURES
144 static void processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e);
145#endif
146
147 static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e);
148#ifndef QT_NO_CONTEXTMENU
149 static void processContextMenuEvent(QWindowSystemInterfacePrivate::ContextMenuEvent *e);
150#endif
151
152#if QT_CONFIG(draganddrop)
153 static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData,
154 const QPoint &p, Qt::DropActions supportedActions,
155 Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
156 static QPlatformDropQtResponse processDrop(QWindow *w, const QMimeData *dropData,
157 const QPoint &p, Qt::DropActions supportedActions,
158 Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
159#endif
160
161 static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, qintptr *result);
162
163 static bool sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event);
164
165 static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
166 {
167 if (!(alignment & Qt::AlignHorizontal_Mask))
168 alignment |= Qt::AlignLeft;
169 if (!(alignment & Qt::AlignAbsolute) && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
170 if (direction == Qt::RightToLeft)
171 alignment ^= (Qt::AlignLeft | Qt::AlignRight);
172 alignment |= Qt::AlignAbsolute;
173 }
174 return alignment;
175 }
176
177 QPixmap getPixmapCursor(Qt::CursorShape cshape);
178
179 void _q_updateFocusObject(QObject *object);
180
181 static QGuiApplicationPrivate *instance() { return self; }
182
183 static QIcon *app_icon;
184 static QString *platform_name;
185 static QString *displayName;
186 static QString *desktopFileName;
187
188 QWindowList modalWindowList;
189 static void showModalWindow(QWindow *window);
190 static void hideModalWindow(QWindow *window);
191 static void updateBlockedStatus(QWindow *window);
192
193 virtual Qt::WindowModality defaultModality() const;
194 virtual bool windowNeverBlocked(QWindow *window) const;
195 bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = nullptr) const;
196 virtual bool popupActive() { return false; }
197 virtual bool closeAllPopups() { return false; }
198
199 static Qt::MouseButton mousePressButton;
200 static struct QLastCursorPosition {
201 constexpr inline QLastCursorPosition() noexcept : thePoint(qt_inf(), qt_inf()) {}
202 constexpr inline Q_IMPLICIT QLastCursorPosition(QPointF p) noexcept : thePoint(p) {}
203 constexpr inline Q_IMPLICIT operator QPointF() const noexcept { return thePoint; }
204 constexpr inline qreal x() const noexcept{ return thePoint.x(); }
205 constexpr inline qreal y() const noexcept{ return thePoint.y(); }
206 Q_GUI_EXPORT QPoint toPoint() const noexcept;
207
208 constexpr void reset() noexcept { *this = QLastCursorPosition{}; }
209
210 // QGuiApplicationPrivate::lastCursorPosition is used for mouse-move detection
211 // but even QPointF's qFuzzCompare on doubles is too precise, and causes move-noise
212 // e.g. on macOS (see QTBUG-111170). So we specialize the equality operators here
213 // to use single-point precision.
214 friend constexpr bool operator==(const QLastCursorPosition &p1, const QPointF &p2) noexcept
215 {
216 return qFuzzyCompare(p1: float(p1.x()), p2: float(p2.x()))
217 && qFuzzyCompare(p1: float(p1.y()), p2: float(p2.y()));
218 }
219 friend constexpr bool operator!=(const QLastCursorPosition &p1, const QPointF &p2) noexcept
220 {
221 return !(p1 == p2);
222 }
223 friend constexpr bool operator==(const QPointF &p1, const QLastCursorPosition &p2) noexcept
224 {
225 return p2 == p1;
226 }
227 friend constexpr bool operator!=(const QPointF &p1, const QLastCursorPosition &p2) noexcept
228 {
229 return !(p2 == p1);
230 }
231
232 private:
233 QPointF thePoint;
234 } lastCursorPosition;
235 static QWindow *currentMouseWindow;
236 static QWindow *currentMousePressWindow;
237 static Qt::ApplicationState applicationState;
238 static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy;
239 static QPointer<QWindow> currentDragWindow;
240
241 // TODO remove this: QPointingDevice can store what we need directly
242 struct TabletPointData {
243 TabletPointData(qint64 devId = 0) : deviceId(devId), state(Qt::NoButton), target(nullptr) {}
244 qint64 deviceId;
245 Qt::MouseButtons state;
246 QWindow *target;
247 };
248 static QList<TabletPointData> tabletDevicePoints;
249 static TabletPointData &tabletDevicePoint(qint64 deviceId);
250
251#ifndef QT_NO_CLIPBOARD
252 static QClipboard *qt_clipboard;
253#endif
254
255 static QPalette *app_pal;
256
257 static QWindowList window_list;
258 static QWindow *focus_window;
259
260#ifndef QT_NO_CURSOR
261 QList<QCursor> cursor_list;
262#endif
263 static QList<QScreen *> screen_list;
264
265 static QFont *app_font;
266
267 static QString styleOverride;
268 static QStyleHints *styleHints;
269 static bool obey_desktop_settings;
270 QInputMethod *inputMethod;
271
272 QString firstWindowTitle;
273 QIcon forcedWindowIcon;
274
275 static QList<QObject *> generic_plugin_list;
276#if QT_CONFIG(shortcut)
277 QShortcutMap shortcutMap;
278#endif
279
280#ifndef QT_NO_SESSIONMANAGER
281 QSessionManager *session_manager;
282 bool is_session_restored;
283 bool is_saving_session;
284 void commitData();
285 void saveState();
286#endif
287
288 QEvent::Type lastTouchType;
289 struct SynthesizedMouseData {
290 SynthesizedMouseData(const QPointF &p, const QPointF &sp, QWindow *w)
291 : pos(p), screenPos(sp), window(w) { }
292 QPointF pos;
293 QPointF screenPos;
294 QPointer<QWindow> window;
295 };
296 QHash<QWindow *, SynthesizedMouseData> synthesizedMousePoints;
297
298 static QInputDeviceManager *inputDeviceManager();
299
300 const QColorTrcLut *colorProfileForA8Text();
301 const QColorTrcLut *colorProfileForA32Text();
302
303 // hook reimplemented in QApplication to apply the QStyle function on the QIcon
304 virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
305
306 virtual void notifyWindowIconChanged();
307
308 static void applyWindowGeometrySpecificationTo(QWindow *window);
309
310 static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false);
311
312 static void resetCachedDevicePixelRatio();
313
314#ifndef QT_NO_ACTION
315 virtual QActionPrivate *createActionPrivate() const;
316#endif
317#ifndef QT_NO_SHORTCUT
318 virtual QShortcutPrivate *createShortcutPrivate() const;
319#endif
320
321 static void updatePalette();
322
323 static Qt::ColorScheme colorScheme();
324
325protected:
326 virtual void handleThemeChanged();
327
328 static bool setPalette(const QPalette &palette);
329 virtual QPalette basePalette() const;
330 virtual void handlePaletteChanged(const char *className = nullptr);
331
332#if QT_CONFIG(draganddrop)
333 virtual void notifyDragStarted(const QDrag *);
334#endif // QT_CONFIG(draganddrop)
335
336private:
337 static void clearPalette();
338
339 friend class QDragManager;
340
341 static QGuiApplicationPrivate *self;
342 static int m_fakeMouseSourcePointId;
343#ifdef Q_OS_WIN
344 std::shared_ptr<QColorTrcLut> m_a8ColorProfile;
345#endif
346 std::shared_ptr<QColorTrcLut> m_a32ColorProfile;
347
348 bool ownGlobalShareContext;
349
350 static QInputDeviceManager *m_inputDeviceManager;
351
352 // Cache the maximum device pixel ratio, to iterate through the screen list
353 // only the first time it's required, or when devices are added or removed.
354 static qreal m_maxDevicePixelRatio;
355};
356
357// ----------------- QNativeInterface -----------------
358
359class QWindowsMimeConverter;
360
361namespace QNativeInterface::Private {
362
363#if defined(Q_OS_WIN) || defined(Q_QDOC)
364
365
366struct Q_GUI_EXPORT QWindowsApplication
367{
368 QT_DECLARE_NATIVE_INTERFACE(QWindowsApplication, 1, QGuiApplication)
369
370 enum WindowActivationBehavior {
371 DefaultActivateWindow,
372 AlwaysActivateWindow
373 };
374
375 enum TouchWindowTouchType {
376 NormalTouch = 0x00000000,
377 FineTouch = 0x00000001,
378 WantPalmTouch = 0x00000002
379 };
380
381 Q_DECLARE_FLAGS(TouchWindowTouchTypes, TouchWindowTouchType)
382
383 enum DarkModeHandlingFlag {
384 DarkModeWindowFrames = 0x1,
385 DarkModeStyle = 0x2
386 };
387
388 Q_DECLARE_FLAGS(DarkModeHandling, DarkModeHandlingFlag)
389
390 virtual void setTouchWindowTouchType(TouchWindowTouchTypes type) = 0;
391 virtual TouchWindowTouchTypes touchWindowTouchType() const = 0;
392
393 virtual WindowActivationBehavior windowActivationBehavior() const = 0;
394 virtual void setWindowActivationBehavior(WindowActivationBehavior behavior) = 0;
395
396 virtual void setHasBorderInFullScreenDefault(bool border) = 0;
397
398 virtual bool isTabletMode() const = 0;
399
400 virtual bool isWinTabEnabled() const = 0;
401 virtual bool setWinTabEnabled(bool enabled) = 0;
402
403 virtual bool isDarkMode() const = 0;
404
405 virtual DarkModeHandling darkModeHandling() const = 0;
406 virtual void setDarkModeHandling(DarkModeHandling handling) = 0;
407
408 virtual void registerMime(QWindowsMimeConverter *mime) = 0;
409 virtual void unregisterMime(QWindowsMimeConverter *mime) = 0;
410
411 virtual int registerMimeType(const QString &mime) = 0;
412
413 virtual HWND createMessageWindow(const QString &classNameTemplate,
414 const QString &windowName,
415 QFunctionPointer eventProc = nullptr) const = 0;
416
417 virtual bool asyncExpose() const = 0; // internal, used by Active Qt
418 virtual void setAsyncExpose(bool value) = 0;
419
420 virtual QVariant gpu() const = 0; // internal, used by qtdiag
421 virtual QVariant gpuList() const = 0;
422
423 virtual void populateLightSystemPalette(QPalette &pal) const = 0;
424};
425#endif // Q_OS_WIN
426
427} // QNativeInterface::Private
428
429#if defined(Q_OS_WIN)
430Q_DECLARE_OPERATORS_FOR_FLAGS(QNativeInterface::Private::QWindowsApplication::TouchWindowTouchTypes)
431Q_DECLARE_OPERATORS_FOR_FLAGS(QNativeInterface::Private::QWindowsApplication::DarkModeHandling)
432#endif
433
434QT_END_NAMESPACE
435
436#endif // QGUIAPPLICATION_P_H
437

source code of qtbase/src/gui/kernel/qguiapplication_p.h