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 
40 #ifndef QGUIAPPLICATION_P_H
41 #define QGUIAPPLICATION_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include <QtGui/private/qtguiglobal_p.h>
55 #include <QtGui/qguiapplication.h>
56 
57 #include <QtCore/QPointF>
58 #include <QtCore/QSharedPointer>
59 #include <QtCore/private/qcoreapplication_p.h>
60 
61 #include <QtCore/private/qthread_p.h>
62 
63 #include <qpa/qwindowsysteminterface.h>
64 #include <qpa/qwindowsysteminterface_p.h>
65 #include "private/qshortcutmap_p.h"
66 #include <qicon.h>
67 
68 QT_BEGIN_NAMESPACE
69 
70 class QColorTrcLut;
71 class QPlatformIntegration;
72 class QPlatformTheme;
73 class QPlatformDragQtResponse;
74 #if QT_CONFIG(draganddrop)
75 class QDrag;
76 #endif // QT_CONFIG(draganddrop)
77 class QInputDeviceManager;
78 
79 class Q_GUI_EXPORT QGuiApplicationPrivate : public QCoreApplicationPrivate
80 {
81     Q_DECLARE_PUBLIC(QGuiApplication)
82 public:
83     QGuiApplicationPrivate(int &argc, char **argv, int flags);
84     ~QGuiApplicationPrivate();
85 
86     void init();
87 
88     void createPlatformIntegration();
89     void createEventDispatcher() override;
90     void eventDispatcherReady() override;
91 
92     virtual void notifyLayoutDirectionChange();
93     virtual void notifyActiveWindowChange(QWindow *previous);
94 
95 #if QT_CONFIG(commandlineparser)
96     void addQtOptions(QList<QCommandLineOption> *options) override;
97 #endif
98     virtual bool shouldQuit() override;
99 
100     bool shouldQuitInternal(const QWindowList &processedWindows);
101     virtual bool tryCloseAllWindows();
102 
103     static void captureGlobalModifierState(QEvent *e);
104     static Qt::KeyboardModifiers modifier_buttons;
105     static Qt::MouseButtons mouse_buttons;
106 
107     static QPlatformIntegration *platform_integration;
108 
platformIntegration()109     static QPlatformIntegration *platformIntegration()
110     { return platform_integration; }
111 
112     static QPlatformTheme *platform_theme;
113 
platformTheme()114     static QPlatformTheme *platformTheme()
115     { return platform_theme; }
116 
qt_qpa_core_dispatcher()117     static QAbstractEventDispatcher *qt_qpa_core_dispatcher()
118     {
119         if (QCoreApplication::instance())
120             return QCoreApplication::instance()->d_func()->threadData.loadRelaxed()->eventDispatcher.loadRelaxed();
121         else
122             return nullptr;
123     }
124 
125     static void processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e);
126     static void processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e);
127     static void processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e);
128     static void processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e);
129 
130     static void processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e);
131 
132     static void processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e);
133 
134     static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e);
135     static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e);
136 
137     static void processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e);
138     static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e);
139     static void processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e);
140 
141     static void processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e);
142 
143     static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
144 
145     static void processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *e);
146 
147     static void updateFilteredScreenOrientation(QScreen *screen);
148     static void reportScreenOrientationChange(QScreen *screen);
149     static void processScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e);
150     static void processScreenGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e);
151     static void processScreenLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e);
152     static void processScreenRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e);
153     static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce);
154 
155     static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e);
156 
157     static void processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e);
158 
159     static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e);
160     static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e);
161     static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e);
162 
163 #ifndef QT_NO_GESTURES
164     static void processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e);
165 #endif
166 
167     static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e);
168 #ifndef QT_NO_CONTEXTMENU
169     static void processContextMenuEvent(QWindowSystemInterfacePrivate::ContextMenuEvent *e);
170 #endif
171 
172 #if QT_CONFIG(draganddrop)
173     static QPlatformDragQtResponse processDrag(QWindow *w, const QMimeData *dropData,
174                                                const QPoint &p, Qt::DropActions supportedActions,
175                                                Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
176     static QPlatformDropQtResponse processDrop(QWindow *w, const QMimeData *dropData,
177                                                const QPoint &p, Qt::DropActions supportedActions,
178                                                Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
179 #endif
180 
181 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
182     static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, qintptr *result);
183 #else
184     static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, long *result);
185 #endif
186 
187     static bool sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event);
188 
visualAlignment(Qt::LayoutDirection direction,Qt::Alignment alignment)189     static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
190     {
191         if (!(alignment & Qt::AlignHorizontal_Mask))
192             alignment |= Qt::AlignLeft;
193         if (!(alignment & Qt::AlignAbsolute) && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
194             if (direction == Qt::RightToLeft)
195                 alignment ^= (Qt::AlignLeft | Qt::AlignRight);
196             alignment |= Qt::AlignAbsolute;
197         }
198         return alignment;
199     }
200 
201     static void emitLastWindowClosed();
202 
203     QPixmap getPixmapCursor(Qt::CursorShape cshape);
204 
205     void _q_updateFocusObject(QObject *object);
206 
instance()207     static QGuiApplicationPrivate *instance() { return self; }
208 
209     static QIcon *app_icon;
210     static QString *platform_name;
211     static QString *displayName;
212     static QString *desktopFileName;
213 
214     QWindowList modalWindowList;
215     static void showModalWindow(QWindow *window);
216     static void hideModalWindow(QWindow *window);
217     static void updateBlockedStatus(QWindow *window);
218     virtual bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = nullptr) const;
popupActive()219     virtual bool popupActive() { return false; }
220 
221     static ulong mousePressTime;
222     static Qt::MouseButton mousePressButton;
223     static int mousePressX;
224     static int mousePressY;
225     static QPointF lastCursorPosition;
226     static QWindow *currentMouseWindow;
227     static QWindow *currentMousePressWindow;
228     static Qt::ApplicationState applicationState;
229     static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy;
230     static bool highDpiScalingUpdated;
231     static QPointer<QWindow> currentDragWindow;
232 
233     struct TabletPointData {
deviceIdTabletPointData234         TabletPointData(qint64 devId = 0) : deviceId(devId), state(Qt::NoButton), target(nullptr) {}
235         qint64 deviceId;
236         Qt::MouseButtons state;
237         QWindow *target;
238     };
239     static QVector<TabletPointData> tabletDevicePoints;
240     static TabletPointData &tabletDevicePoint(qint64 deviceId);
241 
242 #ifndef QT_NO_CLIPBOARD
243     static QClipboard *qt_clipboard;
244 #endif
245 
246     static QPalette *app_pal;
247 
248     static QWindowList window_list;
249     static QWindow *focus_window;
250 
251 #ifndef QT_NO_CURSOR
252     QList<QCursor> cursor_list;
253 #endif
254     static QList<QScreen *> screen_list;
255 
256     static QFont *app_font;
257 
258     static QString styleOverride;
259     static QStyleHints *styleHints;
260     static bool obey_desktop_settings;
261     QInputMethod *inputMethod;
262 
263     QString firstWindowTitle;
264     QIcon forcedWindowIcon;
265 
266     static QList<QObject *> generic_plugin_list;
267 #ifndef QT_NO_SHORTCUT
268     QShortcutMap shortcutMap;
269 #endif
270 
271 #ifndef QT_NO_SESSIONMANAGER
272     static bool is_fallback_session_management_enabled;
273     QSessionManager *session_manager;
274     bool is_session_restored;
275     bool is_saving_session;
276     void commitData();
277     void saveState();
278 #endif
279 
280     struct ActiveTouchPointsKey {
ActiveTouchPointsKeyActiveTouchPointsKey281         ActiveTouchPointsKey(QTouchDevice *dev, int id) : device(dev), touchPointId(id) { }
282         QTouchDevice *device;
283         int touchPointId;
284     };
285     struct ActiveTouchPointsValue {
286         QPointer<QWindow> window;
287         QPointer<QObject> target;
288         QTouchEvent::TouchPoint touchPoint;
289     };
290     QHash<ActiveTouchPointsKey, ActiveTouchPointsValue> activeTouchPoints;
291     QEvent::Type lastTouchType;
292     struct SynthesizedMouseData {
SynthesizedMouseDataSynthesizedMouseData293         SynthesizedMouseData(const QPointF &p, const QPointF &sp, QWindow *w)
294             : pos(p), screenPos(sp), window(w) { }
295         QPointF pos;
296         QPointF screenPos;
297         QPointer<QWindow> window;
298     };
299     QHash<QWindow *, SynthesizedMouseData> synthesizedMousePoints;
300 
301     static int mouseEventCaps(QMouseEvent *event);
302     static QVector2D mouseEventVelocity(QMouseEvent *event);
303     static void setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity);
304 
305     static Qt::MouseEventSource mouseEventSource(const QMouseEvent *event);
306     static void setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source);
307 
308     static Qt::MouseEventFlags mouseEventFlags(const QMouseEvent *event);
309     static void setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags);
310 
311     static QInputDeviceManager *inputDeviceManager();
312 
313     const QColorTrcLut *colorProfileForA8Text();
314     const QColorTrcLut *colorProfileForA32Text();
315 
316     // hook reimplemented in QApplication to apply the QStyle function on the QIcon
applyQIconStyleHelper(QIcon::Mode,const QPixmap & basePixmap)317     virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
318 
319     virtual void notifyWindowIconChanged();
320 
321     static void applyWindowGeometrySpecificationTo(QWindow *window);
322 
323     static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false);
324 
325     static void resetCachedDevicePixelRatio();
326 
327     static void updatePalette();
328 
329 protected:
330     virtual void notifyThemeChanged();
331 
332     static bool setPalette(const QPalette &palette);
333     virtual QPalette basePalette() const;
334     virtual void handlePaletteChanged(const char *className = nullptr);
335 
336     bool tryCloseRemainingWindows(QWindowList processedWindows);
337 #if QT_CONFIG(draganddrop)
338     virtual void notifyDragStarted(const QDrag *);
339 #endif // QT_CONFIG(draganddrop)
340 
341 private:
342     static void clearPalette();
343 
344     friend class QDragManager;
345 
346     static QGuiApplicationPrivate *self;
347     static QTouchDevice *m_fakeTouchDevice;
348     static int m_fakeMouseSourcePointId;
349     QSharedPointer<QColorTrcLut> m_a8ColorProfile;
350     QSharedPointer<QColorTrcLut> m_a32ColorProfile;
351 
352     bool ownGlobalShareContext;
353 
354     static QInputDeviceManager *m_inputDeviceManager;
355 
356     // Cache the maximum device pixel ratio, to iterate through the screen list
357     // only the first time it's required, or when devices are added or removed.
358     static qreal m_maxDevicePixelRatio;
359 };
360 
361 Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k);
362 
363 Q_GUI_EXPORT bool operator==(const QGuiApplicationPrivate::ActiveTouchPointsKey &a,
364                              const QGuiApplicationPrivate::ActiveTouchPointsKey &b);
365 
366 QT_END_NAMESPACE
367 
368 #endif // QGUIAPPLICATION_P_H
369