QtBase  v6.3.1
qguiapplication.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qguiapplication.h"
42 
43 #include "private/qguiapplication_p.h"
44 #include "private/qabstractfileiconprovider_p.h"
45 #include <qpa/qplatformintegrationfactory_p.h>
46 #include "private/qevent_p.h"
47 #include "private/qeventpoint_p.h"
48 #include "qfont.h"
49 #include "qpointingdevice.h"
50 #include <qpa/qplatformfontdatabase.h>
51 #include <qpa/qplatformwindow.h>
52 #include <qpa/qplatformnativeinterface.h>
53 #include <qpa/qplatformtheme.h>
54 #include <qpa/qplatformintegration.h>
55 
56 #include <QtCore/QAbstractEventDispatcher>
57 #include <QtCore/QStandardPaths>
58 #include <QtCore/QVariant>
59 #include <QtCore/private/qcoreapplication_p.h>
60 #include <QtCore/private/qabstracteventdispatcher_p.h>
61 #include <QtCore/qmutex.h>
62 #include <QtCore/private/qthread_p.h>
63 #include <QtCore/private/qlocking_p.h>
64 #include <QtCore/private/qflatmap_p.h>
65 #include <QtCore/qdir.h>
66 #include <QtCore/qlibraryinfo.h>
67 #include <QtCore/private/qnumeric_p.h>
68 #include <QtDebug>
69 #ifndef QT_NO_ACCESSIBILITY
70 #include "qaccessible.h"
71 #endif
72 #include <qpalette.h>
73 #include <qscreen.h>
74 #include "qsessionmanager.h"
75 #include <private/qcolortrclut_p.h>
76 #include <private/qscreen_p.h>
77 
78 #include <QtGui/qgenericpluginfactory.h>
79 #include <QtGui/qstylehints.h>
80 #include <QtGui/qinputmethod.h>
81 #include <QtGui/qpixmapcache.h>
82 #include <qpa/qplatforminputcontext.h>
83 #include <qpa/qplatforminputcontext_p.h>
84 
85 #include <qpa/qwindowsysteminterface.h>
86 #include <qpa/qwindowsysteminterface_p.h>
87 #include "private/qwindow_p.h"
88 #include "private/qcursor_p.h"
89 #include "private/qopenglcontext_p.h"
90 #include "private/qinputdevicemanager_p.h"
91 #include "private/qinputmethod_p.h"
92 #include "private/qpointingdevice_p.h"
93 
94 #include <qpa/qplatformthemefactory_p.h>
95 
96 #if QT_CONFIG(draganddrop)
97 #include <qpa/qplatformdrag.h>
98 #include <private/qdnd_p.h>
99 #endif
100 
101 #ifndef QT_NO_CURSOR
102 #include <qpa/qplatformcursor.h>
103 #endif
104 
105 #include <QtGui/QPixmap>
106 
107 #ifndef QT_NO_CLIPBOARD
108 #include <QtGui/QClipboard>
109 #endif
110 
111 #if QT_CONFIG(library)
112 #include <QtCore/QLibrary>
113 #endif
114 
115 #if defined(Q_OS_MAC)
116 # include "private/qcore_mac_p.h"
117 #elif defined(Q_OS_WIN)
118 # include <QtCore/qt_windows.h>
119 # include <QtCore/QLibraryInfo>
120 #endif // Q_OS_WIN
121 
122 #ifdef Q_OS_WASM
123 #include <emscripten.h>
124 #endif
125 
126 #include <qtgui_tracepoints_p.h>
127 
128 #include <ctype.h>
129 #include <limits>
130 
132 
133 // Helper macro for static functions to check on the existence of the application class.
134 #define CHECK_QAPP_INSTANCE(...) \
135  if (Q_LIKELY(QCoreApplication::instance())) { \
136  } else { \
137  qWarning("Must construct a QGuiApplication first."); \
138  return __VA_ARGS__; \
139  }
140 
141 Q_CORE_EXPORT void qt_call_post_routines();
142 Q_GUI_EXPORT bool qt_is_tty_app = false;
143 
146 
147 QGuiApplicationPrivate::QLastCursorPosition QGuiApplicationPrivate::lastCursorPosition;
148 
150 
152 
154 
157 
159 
161 
164 
166 
168 {
170 };
171 
172 static unsigned applicationResourceFlags = 0;
173 
175 
179 
180 QPalette *QGuiApplicationPrivate::app_pal = nullptr; // default application palette
181 
183 
184 static int mouseDoubleClickDistance = 0;
185 static int touchDoubleTapDistance = 0;
186 
188 
189 static Qt::LayoutDirection layout_direction = Qt::LayoutDirectionAuto;
190 static Qt::LayoutDirection effective_layout_direction = Qt::LeftToRight;
191 static bool force_reverse = false;
192 
193 QGuiApplicationPrivate *QGuiApplicationPrivate::self = nullptr;
194 int QGuiApplicationPrivate::m_fakeMouseSourcePointId = -1;
195 
196 #ifndef QT_NO_CLIPBOARD
198 #endif
199 
201 
204 
205 static QBasicMutex applicationFontMutex;
209 
210 QInputDeviceManager *QGuiApplicationPrivate::m_inputDeviceManager = nullptr;
211 
212 qreal QGuiApplicationPrivate::m_maxDevicePixelRatio = 0.0;
213 
214 static qreal fontSmoothingGamma = 1.7;
215 
217 
218 extern void qRegisterGuiVariant();
219 #if QT_CONFIG(animation)
220 extern void qRegisterGuiGetInterpolator();
221 #endif
222 
223 static bool qt_detectRTLLanguage()
224 {
225  return force_reverse ^
226  (QGuiApplication::tr("QT_LAYOUT_DIRECTION",
227  "Translate this string to the string 'LTR' in left-to-right"
228  " languages or to 'RTL' in right-to-left languages (such as Hebrew"
229  " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
230 }
231 
232 static void initFontUnlocked()
233 {
236  if (const QFont *font = theme->font(QPlatformTheme::SystemFont))
238  }
241  new QFont(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFont());
242 }
243 
244 static inline void clearFontUnlocked()
245 {
248 }
249 
250 static void initThemeHints()
251 {
254 }
255 
256 static bool checkNeedPortalSupport()
257 {
258 #if QT_CONFIG(dbus)
259  return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty() || qEnvironmentVariableIsSet("SNAP");
260 #else
261  return false;
262 #endif // QT_CONFIG(dbus)
263 }
264 
265 // Using aggregate initialization instead of ctor so we can have a POD global static
266 #define Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER { Qt::TopLeftCorner, -1, -1, -1, -1 }
267 
268 // Geometry specification for top level windows following the convention of the
269 // -geometry command line arguments in X11 (see XParseGeometry).
271 {
273  void applyTo(QWindow *window) const;
274 
276  int xOffset;
277  int yOffset;
278  int width;
279  int height;
280 };
281 
282 // Parse a token of a X11 geometry specification "200x100+10-20".
283 static inline int nextGeometryToken(const QByteArray &a, int &pos, char *op)
284 {
285  *op = 0;
286  const int size = a.size();
287  if (pos >= size)
288  return -1;
289 
290  *op = a.at(pos);
291  if (*op == '+' || *op == '-' || *op == 'x')
292  pos++;
293  else if (isdigit(*op))
294  *op = 'x'; // If it starts with a digit, it is supposed to be a width specification.
295  else
296  return -1;
297 
298  const int numberPos = pos;
299  for ( ; pos < size && isdigit(a.at(pos)); ++pos) ;
300 
301  bool ok;
302  const int result = a.mid(numberPos, pos - numberPos).toInt(&ok);
303  return ok ? result : -1;
304 }
305 
307 {
309  int pos = 0;
310  for (int i = 0; i < 4; ++i) {
311  char op;
312  const int value = nextGeometryToken(a, pos, &op);
313  if (value < 0)
314  break;
315  switch (op) {
316  case 'x':
317  (result.width >= 0 ? result.height : result.width) = value;
318  break;
319  case '+':
320  case '-':
321  if (result.xOffset >= 0) {
322  result.yOffset = value;
323  if (op == '-')
325  } else {
326  result.xOffset = value;
327  if (op == '-')
328  result.corner = Qt::TopRightCorner;
329  }
330  }
331  }
332  return result;
333 }
334 
336 {
337  QRect windowGeometry = window->frameGeometry();
338  QSize size = windowGeometry.size();
339  if (width >= 0 || height >= 0) {
340  const QSize windowMinimumSize = window->minimumSize();
341  const QSize windowMaximumSize = window->maximumSize();
342  if (width >= 0)
343  size.setWidth(qBound(windowMinimumSize.width(), width, windowMaximumSize.width()));
344  if (height >= 0)
345  size.setHeight(qBound(windowMinimumSize.height(), height, windowMaximumSize.height()));
346  window->resize(size);
347  }
348  if (xOffset >= 0 || yOffset >= 0) {
349  const QRect availableGeometry = window->screen()->virtualGeometry();
350  QPoint topLeft = windowGeometry.topLeft();
351  if (xOffset >= 0) {
353  xOffset :
354  qMax(availableGeometry.right() - size.width() - xOffset, availableGeometry.left()));
355  }
356  if (yOffset >= 0) {
358  yOffset :
359  qMax(availableGeometry.bottom() - size.height() - yOffset, availableGeometry.top()));
360  }
361  window->setFramePosition(topLeft);
362  }
363 }
364 
366 
651 #ifdef Q_QDOC
652 QGuiApplication::QGuiApplication(int &argc, char **argv)
653 #else
654 QGuiApplication::QGuiApplication(int &argc, char **argv, int flags)
655 #endif
656  : QCoreApplication(*new QGuiApplicationPrivate(argc, argv, flags))
657 {
658  d_func()->init();
659 
661 }
662 
668 {
669 }
670 
675 {
676  Q_D(QGuiApplication);
677 
679 
680  d->eventDispatcher->closingDown();
681  d->eventDispatcher = nullptr;
682 
683 #ifndef QT_NO_CLIPBOARD
686 #endif
687 
688 #ifndef QT_NO_SESSIONMANAGER
689  delete d->session_manager;
690  d->session_manager = nullptr;
691 #endif //QT_NO_SESSIONMANAGER
692 
693  QGuiApplicationPrivate::clearPalette();
695 
696 #ifndef QT_NO_CURSOR
697  d->cursor_list.clear();
698 #endif
699 
706  delete QGuiApplicationPrivate::m_inputDeviceManager;
707  QGuiApplicationPrivate::m_inputDeviceManager = nullptr;
717 }
718 
720  : QCoreApplicationPrivate(argc, argv, flags),
721  inputMethod(nullptr),
722  lastTouchType(QEvent::TouchEnd),
723  ownGlobalShareContext(false)
724 {
725  self = this;
727 #ifndef QT_NO_SESSIONMANAGER
728  is_session_restored = false;
729  is_saving_session = false;
730 #endif
731 }
732 
746 {
749  if (qGuiApp) {
752 
754  emit qGuiApp->applicationDisplayNameChanged();
755  }
756  } else if (name != *QGuiApplicationPrivate::displayName) {
758  if (qGuiApp)
759  emit qGuiApp->applicationDisplayNameChanged();
760  }
761 }
762 
764 {
766 }
767 
785 {
789 }
790 
792 {
794 }
795 
811 {
812  CHECK_QAPP_INSTANCE(nullptr)
813  if (QGuiApplicationPrivate::self->modalWindowList.isEmpty())
814  return nullptr;
815  return QGuiApplicationPrivate::self->modalWindowList.first();
816 }
817 
818 static void updateBlockedStatusRecursion(QWindow *window, bool shouldBeBlocked)
819 {
821  if (p->blockedByModalWindow != shouldBeBlocked) {
822  p->blockedByModalWindow = shouldBeBlocked;
825  for (QObject *c : window->children()) {
826  if (c->isWindowType())
827  updateBlockedStatusRecursion(static_cast<QWindow *>(c), shouldBeBlocked);
828  }
829  }
830 }
831 
833 {
834  bool shouldBeBlocked = false;
835  const bool popupType = (window->type() == Qt::ToolTip) || (window->type() == Qt::Popup);
836  if (!popupType && !self->modalWindowList.isEmpty())
837  shouldBeBlocked = self->isWindowBlocked(window);
838  updateBlockedStatusRecursion(window, shouldBeBlocked);
839 }
840 
841 // Return whether the window needs to be notified about window blocked events.
842 // As opposed to QGuiApplication::topLevelWindows(), embedded windows are
843 // included in this list (QTBUG-18099).
844 static inline bool needsWindowBlockedEvent(const QWindow *w)
845 {
846  return w->isTopLevel() && w->type() != Qt::Desktop;
847 }
848 
850 {
851  self->modalWindowList.prepend(modal);
852 
853  // Send leave for currently entered window if it should be blocked
855  bool shouldBeBlocked = self->isWindowBlocked(currentMouseWindow);
856  if (shouldBeBlocked) {
857  // Remove the new window from modalWindowList temporarily so leave can go through
858  self->modalWindowList.removeFirst();
861  currentMouseWindow = nullptr;
862  self->modalWindowList.prepend(modal);
863  }
864  }
865 
867  if (needsWindowBlockedEvent(window) && !window->d_func()->blockedByModalWindow)
869  }
870 
871  updateBlockedStatus(modal);
872 }
873 
875 {
876  self->modalWindowList.removeAll(window);
877 
879  if (needsWindowBlockedEvent(window) && window->d_func()->blockedByModalWindow)
881  }
882 }
883 
884 /*
885  Returns \c true if \a window is blocked by a modal window. If \a
886  blockingWindow is non-zero, *blockingWindow will be set to the blocking
887  window (or to zero if \a window is not blocked).
888 */
890 {
891  QWindow *unused = nullptr;
892  if (!blockingWindow)
893  blockingWindow = &unused;
894 
895  if (modalWindowList.isEmpty()) {
896  *blockingWindow = nullptr;
897  return false;
898  }
899 
900  for (int i = 0; i < modalWindowList.count(); ++i) {
901  QWindow *modalWindow = modalWindowList.at(i);
902 
903  // A window is not blocked by another modal window if the two are
904  // the same, or if the window is a child of the modal window.
905  if (window == modalWindow || modalWindow->isAncestorOf(window, QWindow::IncludeTransients)) {
906  *blockingWindow = nullptr;
907  return false;
908  }
909 
910  Qt::WindowModality windowModality = modalWindow->modality();
911  switch (windowModality) {
913  {
914  if (modalWindow != window) {
915  *blockingWindow = modalWindow;
916  return true;
917  }
918  break;
919  }
920  case Qt::WindowModal:
921  {
922  QWindow *w = window;
923  do {
924  QWindow *m = modalWindow;
925  do {
926  if (m == w) {
927  *blockingWindow = m;
928  return true;
929  }
930  QWindow *p = m->parent();
931  if (!p)
932  p = m->transientParent();
933  m = p;
934  } while (m);
935  QWindow *p = w->parent();
936  if (!p)
937  p = w->transientParent();
938  w = p;
939  } while (w);
940  break;
941  }
942  default:
943  Q_ASSERT_X(false, "QGuiApplication", "internal error, a modal widget cannot be modeless");
944  break;
945  }
946  }
947  *blockingWindow = nullptr;
948  return false;
949 }
950 
956 {
958 }
959 
983 {
984  if (focusWindow())
985  return focusWindow()->focusObject();
986  return nullptr;
987 }
988 
999 {
1001 }
1002 
1011 {
1014  for (int i = 0; i < list.size(); ++i) {
1015  QWindow *window = list.at(i);
1016  if (!window->isTopLevel())
1017  continue;
1018 
1019  // Desktop windows are special, as each individual desktop window
1020  // will report that it's a top level window, but we don't want to
1021  // include them in the application wide list of top level windows.
1022  if (window->type() == Qt::Desktop)
1023  continue;
1024 
1025  // Windows embedded in native windows do not have QWindow parents,
1026  // but they are not true top level windows, so do not include them.
1027  if (window->handle() && window->handle()->isEmbedded())
1028  continue;
1029 
1031  }
1032 
1033  return topLevelWindows;
1034 }
1035 
1037 {
1039  return nullptr;
1041 }
1042 
1048 {
1050 }
1051 
1064 {
1065  QVarLengthArray<const QScreen *, 8> visitedScreens;
1066  for (const QScreen *screen : QGuiApplication::screens()) {
1067  if (visitedScreens.contains(screen))
1068  continue;
1069 
1070  // The virtual siblings include the screen itself, so iterate directly
1071  for (QScreen *sibling : screen->virtualSiblings()) {
1072  if (sibling->geometry().contains(point))
1073  return sibling;
1074 
1075  visitedScreens.append(sibling);
1076  }
1077  }
1078 
1079  return nullptr;
1080 }
1081 
1126 {
1127  if (!qFuzzyIsNull(QGuiApplicationPrivate::m_maxDevicePixelRatio))
1128  return QGuiApplicationPrivate::m_maxDevicePixelRatio;
1129 
1130  QGuiApplicationPrivate::m_maxDevicePixelRatio = 1.0; // make sure we never return 0.
1132  QGuiApplicationPrivate::m_maxDevicePixelRatio = qMax(QGuiApplicationPrivate::m_maxDevicePixelRatio, screen->devicePixelRatio());
1133 
1134  return QGuiApplicationPrivate::m_maxDevicePixelRatio;
1135 }
1136 
1138 {
1139  m_maxDevicePixelRatio = 0.0;
1140 }
1141 
1146 {
1147  if (QScreen *windowScreen = screenAt(pos)) {
1148  const QPoint devicePosition = QHighDpi::toNativePixels(pos, windowScreen);
1149  return windowScreen->handle()->topLevelAt(devicePosition);
1150  }
1151  return nullptr;
1152 }
1153 
1188 {
1191 }
1192 
1193 Q_LOGGING_CATEGORY(lcQpaPluginLoading, "qt.qpa.plugin");
1194 Q_LOGGING_CATEGORY(lcQpaTheme, "qt.qpa.theme");
1195 Q_LOGGING_CATEGORY(lcPtrDispatch, "qt.pointer.dispatch");
1196 
1197 static void init_platform(const QString &pluginNamesWithArguments, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv)
1198 {
1199  qCDebug(lcQpaPluginLoading) << "init_platform called with"
1200  << "pluginNamesWithArguments" << pluginNamesWithArguments
1201  << "platformPluginPath" << platformPluginPath
1202  << "platformThemeName" << platformThemeName;
1203 
1204  QStringList plugins = pluginNamesWithArguments.split(QLatin1Char(';'), Qt::SkipEmptyParts);
1205  QStringList platformArguments;
1206  QStringList availablePlugins = QPlatformIntegrationFactory::keys(platformPluginPath);
1207  for (const auto &pluginArgument : plugins) {
1208  // Split into platform name and arguments
1209  QStringList arguments = pluginArgument.split(QLatin1Char(':'), Qt::SkipEmptyParts);
1210  if (arguments.isEmpty())
1211  continue;
1212  const QString name = arguments.takeFirst().toLower();
1213  QString argumentsKey = name;
1214  if (name.isEmpty())
1215  continue;
1216  argumentsKey[0] = argumentsKey.at(0).toUpper();
1218 
1219  qCDebug(lcQpaPluginLoading) << "Attempting to load Qt platform plugin" << name << "with arguments" << arguments;
1220 
1221  // Create the platform integration.
1224  if (availablePlugins.contains(name)) {
1225  qCInfo(lcQpaPluginLoading).nospace().noquote()
1226  << "Could not load the Qt platform plugin \"" << name << "\" in \""
1227  << QDir::toNativeSeparators(platformPluginPath) << "\" even though it was found.";
1228  } else {
1229  qCWarning(lcQpaPluginLoading).nospace().noquote()
1230  << "Could not find the Qt platform plugin \"" << name << "\" in \""
1231  << QDir::toNativeSeparators(platformPluginPath) << "\"";
1232  }
1233  } else {
1234  qCDebug(lcQpaPluginLoading) << "Successfully loaded Qt platform plugin" << name;
1236  platformArguments = arguments;
1237  break;
1238  }
1239  }
1240 
1242  QString fatalMessage = QStringLiteral("This application failed to start because no Qt platform plugin could be initialized. "
1243  "Reinstalling the application may fix this problem.\n");
1244 
1245  if (!availablePlugins.isEmpty())
1246  fatalMessage += QStringLiteral("\nAvailable platform plugins are: %1.\n").arg(availablePlugins.join(QLatin1String(", ")));
1247 
1248 #if defined(Q_OS_WIN)
1249  // Windows: Display message box unless it is a console application
1250  // or debug build showing an assert box.
1251  if (!QLibraryInfo::isDebugBuild() && !GetConsoleWindow())
1252  MessageBox(0, (LPCTSTR)fatalMessage.utf16(), (LPCTSTR)(QCoreApplication::applicationName().utf16()), MB_OK | MB_ICONERROR);
1253 #endif // Q_OS_WIN
1254  qFatal("%s", qPrintable(fatalMessage));
1255 
1256  return;
1257  }
1258 
1259  // Create the platform theme:
1260 
1261  // 1) Fetch the platform name from the environment if present.
1262  QStringList themeNames;
1263  if (!platformThemeName.isEmpty()) {
1264  qCDebug(lcQpaTheme) << "Adding" << platformThemeName << "from environment to list of theme names";
1265  themeNames.append(platformThemeName);
1266  }
1267 
1268  // 2) Special case - check whether it's a flatpak or snap app to use xdg-desktop-portal platform theme for portals support
1269  if (checkNeedPortalSupport()) {
1270  qCDebug(lcQpaTheme) << "Adding xdgdesktopportal to list of theme names";
1271  themeNames.append(QStringLiteral("xdgdesktopportal"));
1272  }
1273 
1274  // 3) Ask the platform integration for a list of theme names
1275  const auto platformIntegrationThemeNames = QGuiApplicationPrivate::platform_integration->themeNames();
1276  qCDebug(lcQpaTheme) << "Adding platform integration's theme names to list of theme names:" << platformIntegrationThemeNames;
1277  themeNames += platformIntegrationThemeNames;
1278  // 4) Look for a theme plugin.
1279  for (const QString &themeName : qAsConst(themeNames)) {
1280  qCDebug(lcQpaTheme) << "Attempting to create platform theme" << themeName << "via QPlatformThemeFactory::create";
1283  qCDebug(lcQpaTheme) << "Successfully created platform theme" << themeName;
1284  break;
1285  }
1286  }
1287 
1288  // 5) If no theme plugin was found ask the platform integration to
1289  // create a theme
1291  for (const QString &themeName : qAsConst(themeNames)) {
1292  qCDebug(lcQpaTheme) << "Attempting to create platform theme" << themeName << "via createPlatformTheme";
1295  qCDebug(lcQpaTheme) << "Successfully created platform theme" << themeName;
1296  break;
1297  }
1298  }
1299  // No error message; not having a theme plugin is allowed.
1300  }
1301 
1302  // 6) Fall back on the built-in "null" platform theme.
1304  qCDebug(lcQpaTheme) << "Failed to create platform theme; using \"null\" platform theme";
1306  }
1307 
1308 #ifndef QT_NO_PROPERTIES
1309  // Set arguments as dynamic properties on the native interface as
1310  // boolean 'foo' or strings: 'foo=bar'
1311  if (!platformArguments.isEmpty()) {
1312  if (QObject *nativeInterface = QGuiApplicationPrivate::platform_integration->nativeInterface()) {
1313  for (const QString &argument : qAsConst(platformArguments)) {
1314  const int equalsPos = argument.indexOf(QLatin1Char('='));
1315  const QByteArray name =
1316  equalsPos != -1 ? argument.left(equalsPos).toUtf8() : argument.toUtf8();
1317  const QVariant value =
1318  equalsPos != -1 ? QVariant(argument.mid(equalsPos + 1)) : QVariant(true);
1319  nativeInterface->setProperty(name.constData(), value);
1320  }
1321  }
1322  }
1323 #endif
1324 
1325  const auto platformIntegration = QGuiApplicationPrivate::platformIntegration();
1326  fontSmoothingGamma = platformIntegration->styleHint(QPlatformIntegration::FontSmoothingGamma).toReal();
1328  !platformIntegration->styleHint(QPlatformIntegration::ShowShortcutsInContextMenus).toBool());
1329 }
1330 
1331 static void init_plugins(const QList<QByteArray> &pluginList)
1332 {
1333  for (int i = 0; i < pluginList.count(); ++i) {
1334  QByteArray pluginSpec = pluginList.at(i);
1335  int colonPos = pluginSpec.indexOf(':');
1336  QObject *plugin;
1337  if (colonPos < 0)
1339  else
1340  plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
1341  QLatin1String(pluginSpec.mid(colonPos+1)));
1342  if (plugin)
1344  else
1345  qWarning("No such plugin for spec \"%s\"", pluginSpec.constData());
1346  }
1347 }
1348 
1349 #if QT_CONFIG(commandlineparser)
1350 void QGuiApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options)
1351 {
1352  QCoreApplicationPrivate::addQtOptions(options);
1353 
1354 #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
1355  const QByteArray sessionType = qgetenv("XDG_SESSION_TYPE");
1356  const bool x11 = sessionType == "x11";
1357  // Technically the x11 aliases are only available if platformName is "xcb", but we can't know that here.
1358 #else
1359  const bool x11 = false;
1360 #endif
1361 
1362  options->append(QCommandLineOption(QStringLiteral("platform"),
1363  QGuiApplication::tr("QPA plugin. See QGuiApplication documentation for available options for each plugin."), QStringLiteral("platformName[:options]")));
1364  options->append(QCommandLineOption(QStringLiteral("platformpluginpath"),
1365  QGuiApplication::tr("Path to the platform plugins."), QStringLiteral("path")));
1366  options->append(QCommandLineOption(QStringLiteral("platformtheme"),
1367  QGuiApplication::tr("Platform theme."), QStringLiteral("theme")));
1368  options->append(QCommandLineOption(QStringLiteral("plugin"),
1369  QGuiApplication::tr("Additional plugins to load, can be specified multiple times."), QStringLiteral("plugin")));
1370  options->append(QCommandLineOption(QStringLiteral("qwindowgeometry"),
1371  QGuiApplication::tr("Window geometry for the main window, using the X11-syntax, like 100x100+50+50."), QStringLiteral("geometry")));
1372  options->append(QCommandLineOption(QStringLiteral("qwindowicon"),
1373  QGuiApplication::tr("Default window icon."), QStringLiteral("icon")));
1374  options->append(QCommandLineOption(QStringLiteral("qwindowtitle"),
1375  QGuiApplication::tr("Title of the first window."), QStringLiteral("title")));
1376  options->append(QCommandLineOption(QStringLiteral("reverse"),
1377  QGuiApplication::tr("Sets the application's layout direction to Qt::RightToLeft (debugging helper).")));
1378  options->append(QCommandLineOption(QStringLiteral("session"),
1379  QGuiApplication::tr("Restores the application from an earlier session."), QStringLiteral("session")));
1380 
1381  if (x11) {
1382  options->append(QCommandLineOption(QStringLiteral("display"),
1383  QGuiApplication::tr("Display name, overrides $DISPLAY."), QStringLiteral("display")));
1384  options->append(QCommandLineOption(QStringLiteral("name"),
1385  QGuiApplication::tr("Instance name according to ICCCM 4.1.2.5."), QStringLiteral("name")));
1386  options->append(QCommandLineOption(QStringLiteral("nograb"),
1387  QGuiApplication::tr("Disable mouse grabbing (useful in debuggers).")));
1388  options->append(QCommandLineOption(QStringLiteral("dograb"),
1389  QGuiApplication::tr("Force mouse grabbing (even when running in a debugger).")));
1390  options->append(QCommandLineOption(QStringLiteral("visual"),
1391  QGuiApplication::tr("ID of the X11 Visual to use."), QStringLiteral("id")));
1392  // Not using the "QStringList names" solution for those aliases, because it makes the first column too wide
1393  options->append(QCommandLineOption(QStringLiteral("geometry"),
1394  QGuiApplication::tr("Alias for --qwindowgeometry."), QStringLiteral("geometry")));
1395  options->append(QCommandLineOption(QStringLiteral("icon"),
1396  QGuiApplication::tr("Alias for --qwindowicon."), QStringLiteral("icon")));
1397  options->append(QCommandLineOption(QStringLiteral("title"),
1398  QGuiApplication::tr("Alias for --qwindowtitle."), QStringLiteral("title")));
1399  }
1400 }
1401 #endif // QT_CONFIG(commandlineparser)
1402 
1404 {
1406 
1407  // Load the platform integration
1408  QString platformPluginPath = QString::fromLocal8Bit(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
1409 
1410 
1411  QByteArray platformName;
1412 #ifdef QT_QPA_DEFAULT_PLATFORM_NAME
1413  platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
1414 #endif
1415 #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
1416  QList<QByteArray> platformArguments = platformName.split(':');
1417  QByteArray platformPluginBase = platformArguments.first();
1418 
1419  const bool hasWaylandDisplay = qEnvironmentVariableIsSet("WAYLAND_DISPLAY");
1420  const bool isWaylandSessionType = qgetenv("XDG_SESSION_TYPE") == "wayland";
1421 
1422  QVector<QByteArray> preferredPlatformOrder;
1423  const bool defaultIsXcb = platformPluginBase == "xcb";
1424  const QByteArray xcbPlatformName = defaultIsXcb ? platformName : "xcb";
1425  if (qEnvironmentVariableIsSet("DISPLAY")) {
1426  preferredPlatformOrder << xcbPlatformName;
1427  if (defaultIsXcb)
1428  platformName.clear();
1429  }
1430 
1431  const bool defaultIsWayland = !defaultIsXcb && platformPluginBase.startsWith("wayland");
1432  const QByteArray waylandPlatformName = defaultIsWayland ? platformName : "wayland";
1433  if (hasWaylandDisplay || isWaylandSessionType) {
1434  preferredPlatformOrder.prepend(waylandPlatformName);
1435 
1436  if (defaultIsWayland)
1437  platformName.clear();
1438  }
1439 
1440  if (!platformName.isEmpty())
1441  preferredPlatformOrder.append(platformName);
1442 
1443  platformName = preferredPlatformOrder.join(';');
1444 #endif
1445 
1446  bool platformExplicitlySelected = false;
1447  QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
1448  if (!platformNameEnv.isEmpty()) {
1449  platformName = platformNameEnv;
1450  platformExplicitlySelected = true;
1451  }
1452 
1453  QString platformThemeName = QString::fromLocal8Bit(qgetenv("QT_QPA_PLATFORMTHEME"));
1454 
1455  // Get command line params
1456 
1457  QString icon;
1458 
1459  int j = argc ? 1 : 0;
1460  for (int i=1; i<argc; i++) {
1461  if (!argv[i])
1462  continue;
1463  if (*argv[i] != '-') {
1464  argv[j++] = argv[i];
1465  continue;
1466  }
1467  const bool xcbIsDefault = platformName.startsWith("xcb");
1468  const char *arg = argv[i];
1469  if (arg[1] == '-') // startsWith("--")
1470  ++arg;
1471  if (strcmp(arg, "-platformpluginpath") == 0) {
1472  if (++i < argc)
1473  platformPluginPath = QFile::decodeName(argv[i]);
1474  } else if (strcmp(arg, "-platform") == 0) {
1475  if (++i < argc) {
1476  platformExplicitlySelected = true;
1477  platformName = argv[i];
1478  }
1479  } else if (strcmp(arg, "-platformtheme") == 0) {
1480  if (++i < argc)
1481  platformThemeName = QString::fromLocal8Bit(argv[i]);
1482  } else if (strcmp(arg, "-qwindowgeometry") == 0 || (xcbIsDefault && strcmp(arg, "-geometry") == 0)) {
1483  if (++i < argc)
1484  windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
1485  } else if (strcmp(arg, "-qwindowtitle") == 0 || (xcbIsDefault && strcmp(arg, "-title") == 0)) {
1486  if (++i < argc)
1488  } else if (strcmp(arg, "-qwindowicon") == 0 || (xcbIsDefault && strcmp(arg, "-icon") == 0)) {
1489  if (++i < argc) {
1491  }
1492  } else {
1493  argv[j++] = argv[i];
1494  }
1495  }
1496 
1497  if (j < argc) {
1498  argv[j] = nullptr;
1499  argc = j;
1500  }
1501 
1502  Q_UNUSED(platformExplicitlySelected);
1503 
1504  init_platform(QLatin1String(platformName), platformPluginPath, platformThemeName, argc, argv);
1505 
1506  if (!icon.isEmpty())
1508 }
1509 
1517 {
1519 
1520  if (platform_integration == nullptr)
1522 
1523  // The platform integration should not mess with the event dispatcher
1525 
1527 }
1528 
1530 {
1531  if (platform_integration == nullptr)
1533 
1535 }
1536 
1538 {
1539  Q_TRACE_SCOPE(QGuiApplicationPrivate_init);
1540 
1541 #if defined(Q_OS_MACOS)
1542  QMacAutoReleasePool pool;
1543 #endif
1544 
1546 
1547  QCoreApplicationPrivate::is_app_running = false; // Starting up.
1548 
1549  bool loadTestability = false;
1550  QList<QByteArray> pluginList;
1551  // Get command line params
1552 #ifndef QT_NO_SESSIONMANAGER
1553  QString session_id;
1554  QString session_key;
1555 # if defined(Q_OS_WIN)
1556  wchar_t guidstr[40];
1557  GUID guid;
1558  CoCreateGuid(&guid);
1559  StringFromGUID2(guid, guidstr, 40);
1560  session_id = QString::fromWCharArray(guidstr);
1561  CoCreateGuid(&guid);
1562  StringFromGUID2(guid, guidstr, 40);
1563  session_key = QString::fromWCharArray(guidstr);
1564 # endif
1565 #endif
1566  QString s;
1567  int j = argc ? 1 : 0;
1568  for (int i=1; i<argc; i++) {
1569  if (!argv[i])
1570  continue;
1571  if (*argv[i] != '-') {
1572  argv[j++] = argv[i];
1573  continue;
1574  }
1575  const char *arg = argv[i];
1576  if (arg[1] == '-') // startsWith("--")
1577  ++arg;
1578  if (strcmp(arg, "-plugin") == 0) {
1579  if (++i < argc)
1580  pluginList << argv[i];
1581  } else if (strcmp(arg, "-reverse") == 0) {
1582  force_reverse = true;
1583 #ifdef Q_OS_MAC
1584  } else if (strncmp(arg, "-psn_", 5) == 0) {
1585  // eat "-psn_xxxx" on Mac, which is passed when starting an app from Finder.
1586  // special hack to change working directory (for an app bundle) when running from finder
1587  if (QDir::currentPath() == QLatin1String("/")) {
1588  QCFType<CFURLRef> bundleURL(CFBundleCopyBundleURL(CFBundleGetMainBundle()));
1589  QString qbundlePath = QCFString(CFURLCopyFileSystemPath(bundleURL,
1590  kCFURLPOSIXPathStyle));
1591  if (qbundlePath.endsWith(QLatin1String(".app")))
1592  QDir::setCurrent(qbundlePath.section(QLatin1Char('/'), 0, -2));
1593  }
1594 #endif
1595 #ifndef QT_NO_SESSIONMANAGER
1596  } else if (strcmp(arg, "-session") == 0 && i < argc - 1) {
1597  ++i;
1598  if (argv[i] && *argv[i]) {
1599  session_id = QString::fromLatin1(argv[i]);
1600  int p = session_id.indexOf(QLatin1Char('_'));
1601  if (p >= 0) {
1602  session_key = session_id.mid(p +1);
1603  session_id = session_id.left(p);
1604  }
1605  is_session_restored = true;
1606  }
1607 #endif
1608  } else if (strcmp(arg, "-testability") == 0) {
1609  loadTestability = true;
1610  } else if (strncmp(arg, "-style=", 7) == 0) {
1611  s = QString::fromLocal8Bit(arg + 7);
1612  } else if (strcmp(arg, "-style") == 0 && i < argc - 1) {
1614  } else {
1615  argv[j++] = argv[i];
1616  }
1617 
1618  if (!s.isEmpty())
1619  styleOverride = s;
1620  }
1621 
1622  if (j < argc) {
1623  argv[j] = nullptr;
1624  argc = j;
1625  }
1626 
1627  // Load environment exported generic plugins
1628  QByteArray envPlugins = qgetenv("QT_QPA_GENERIC_PLUGINS");
1629  if (!envPlugins.isEmpty())
1630  pluginList += envPlugins.split(',');
1631 
1632  if (platform_integration == nullptr)
1634 
1635  updatePalette();
1637  initThemeHints();
1638 
1639 #ifndef QT_NO_CURSOR
1641 #endif
1642 
1643  // trigger registering of QVariant's GUI types
1645 
1646 #if QT_CONFIG(animation)
1647  // trigger registering of animation interpolators
1649 #endif
1650 
1651  // set a global share context when enabled unless there is already one
1652 #ifndef QT_NO_OPENGL
1653  if (qApp->testAttribute(Qt::AA_ShareOpenGLContexts) && !qt_gl_global_share_context()) {
1654  QOpenGLContext *ctx = new QOpenGLContext;
1656  ctx->create();
1658  ownGlobalShareContext = true;
1659  }
1660 #endif
1661 
1663 
1664  is_app_running = true;
1665  init_plugins(pluginList);
1667 
1668  Q_Q(QGuiApplication);
1669 #ifndef QT_NO_SESSIONMANAGER
1670  // connect to the session manager
1671  session_manager = new QSessionManager(q, session_id, session_key);
1672 #endif
1673 
1674 #if QT_CONFIG(library)
1675  if (qEnvironmentVariableIntValue("QT_LOAD_TESTABILITY") > 0)
1676  loadTestability = true;
1677 
1678  if (loadTestability) {
1679  QLibrary testLib(QStringLiteral("qttestability"));
1680  if (Q_UNLIKELY(!testLib.load())) {
1681  qCritical() << "Library qttestability load failed:" << testLib.errorString();
1682  } else {
1683  typedef void (*TasInitialize)(void);
1684  TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
1685  if (Q_UNLIKELY(!initFunction)) {
1686  qCritical("Library qttestability resolve failed!");
1687  } else {
1688  initFunction();
1689  }
1690  }
1691  }
1692 #else
1693  Q_UNUSED(loadTestability);
1694 #endif // QT_CONFIG(library)
1695 
1696  // trigger changed signal and event delivery
1697  QGuiApplication::setLayoutDirection(layout_direction);
1698 
1702 }
1703 
1704 extern void qt_cleanupFontDatabase();
1705 
1707 {
1708  is_app_closing = true;
1709  is_app_running = false;
1710 
1711  for (int i = 0; i < generic_plugin_list.count(); ++i)
1712  delete generic_plugin_list.at(i);
1714 
1715  clearFontUnlocked();
1716 
1717  QFont::cleanup();
1718 
1719 #ifndef QT_NO_CURSOR
1721 #endif
1722 
1723  layout_direction = Qt::LayoutDirectionAuto;
1724 
1726 
1729  delete inputMethod;
1730 
1732 
1734 
1735 #ifndef QT_NO_OPENGL
1736  if (ownGlobalShareContext) {
1737  delete qt_gl_global_share_context();
1739  }
1740 #endif
1741 
1743 
1744  delete platform_theme;
1745  platform_theme = nullptr;
1746  delete platform_integration;
1747  platform_integration = nullptr;
1748 
1749  window_list.clear();
1750  screen_list.clear();
1751 
1752  self = nullptr;
1753 }
1754 
1755 #if 0
1756 #ifndef QT_NO_CURSOR
1757 QCursor *overrideCursor();
1758 void setOverrideCursor(const QCursor &);
1759 void changeOverrideCursor(const QCursor &);
1760 void restoreOverrideCursor();
1761 #endif
1762 
1763 static QFont font();
1764 static QFont font(const QWidget*);
1765 static QFont font(const char *className);
1766 static void setFont(const QFont &, const char *className = nullptr);
1767 static QFontMetrics fontMetrics();
1768 
1769 #ifndef QT_NO_CLIPBOARD
1770 static QClipboard *clipboard();
1771 #endif
1772 #endif
1773 
1787 Qt::KeyboardModifiers QGuiApplication::keyboardModifiers()
1788 {
1790 }
1791 
1809 {
1810  CHECK_QAPP_INSTANCE(Qt::KeyboardModifiers{})
1812  return pi->queryKeyboardModifiers();
1813 }
1814 
1829 {
1831 }
1832 
1839 {
1841  return pi ? pi->nativeInterface() : nullptr;
1842 }
1843 
1848 QFunctionPointer QGuiApplication::platformFunction(const QByteArray &function)
1849 {
1851  if (!pi) {
1852  qWarning("QGuiApplication::platformFunction(): Must construct a QGuiApplication before accessing a platform function");
1853  return nullptr;
1854  }
1855 
1856  return pi->nativeInterface() ? pi->nativeInterface()->platformFunction(function) : nullptr;
1857 }
1858 
1883 {
1884 #ifndef QT_NO_ACCESSIBILITY
1886 #endif
1887  return QCoreApplication::exec();
1888 }
1889 
1891 {
1892  if (e->spontaneous()) {
1893  // Capture the current mouse and keyboard states. Doing so here is
1894  // required in order to support Qt Test synthesized events. Real mouse
1895  // and keyboard state updates from the platform plugin are managed by
1896  // QGuiApplicationPrivate::process(Mouse|Wheel|Key|Touch|Tablet)Event();
1897  // ### FIXME: Qt Test should not call qapp->notify(), but rather route
1898  // the events through the proper QPA interface. This is required to
1899  // properly generate all other events such as enter/leave etc.
1900  switch (e->type()) {
1901  case QEvent::MouseButtonPress: {
1902  QMouseEvent *me = static_cast<QMouseEvent *>(e);
1905  break;
1906  }
1908  QMouseEvent *me = static_cast<QMouseEvent *>(e);
1911  break;
1912  }
1914  QMouseEvent *me = static_cast<QMouseEvent *>(e);
1917  break;
1918  }
1919  case QEvent::KeyPress:
1920  case QEvent::KeyRelease:
1921  case QEvent::MouseMove:
1922 #if QT_CONFIG(wheelevent)
1923  case QEvent::Wheel:
1924 #endif
1925  case QEvent::TouchBegin:
1926  case QEvent::TouchUpdate:
1927  case QEvent::TouchEnd:
1928 #if QT_CONFIG(tabletevent)
1929  case QEvent::TabletMove:
1930  case QEvent::TabletPress:
1931  case QEvent::TabletRelease:
1932 #endif
1933  {
1934  QInputEvent *ie = static_cast<QInputEvent *>(e);
1936  break;
1937  }
1938  default:
1939  break;
1940  }
1941  }
1942 }
1943 
1947 {
1948  if (object->isWindowType()) {
1950  return true; // Platform plugin ate the event
1951  }
1952 
1954 
1955  return QCoreApplication::notify(object, event);
1956 }
1957 
1961 {
1962  if (e->type() == QEvent::LanguageChange) {
1963  // if the layout direction was set explicitly, then don't override it here
1964  if (layout_direction == Qt::LayoutDirectionAuto)
1965  setLayoutDirection(layout_direction);
1966  for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) {
1967  if (topLevelWindow->flags() != Qt::Desktop)
1968  postEvent(topLevelWindow, new QEvent(QEvent::LanguageChange));
1969  }
1970  } else if (e->type() == QEvent::ApplicationFontChange ||
1971  e->type() == QEvent::ApplicationPaletteChange) {
1972  for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) {
1973  if (topLevelWindow->flags() != Qt::Desktop)
1974  postEvent(topLevelWindow, new QEvent(e->type()));
1975  }
1976  } else if (e->type() == QEvent::Quit) {
1977  // Close open windows. This is done in order to deliver de-expose
1978  // events while the event loop is still running.
1979  for (QWindow *topLevelWindow : QGuiApplication::topLevelWindows()) {
1980  // Already closed windows will not have a platform window, skip those
1981  if (!topLevelWindow->handle())
1982  continue;
1983  if (!topLevelWindow->close()) {
1984  e->ignore();
1985  return true;
1986  }
1987  }
1988  }
1989 
1990  return QCoreApplication::event(e);
1991 }
1992 
1997 {
1998  return QCoreApplication::compressEvent(event, receiver, postedEvents);
1999 }
2000 
2002 {
2003  if (!window)
2004  return false;
2005  QPlatformWindow *platformWindow = window->handle();
2006  if (!platformWindow)
2007  return false;
2008  // spontaneous events come from the platform integration already, we don't need to send the events back
2009  if (event->spontaneous())
2010  return false;
2011  // let the platform window do any handling it needs to as well
2012  return platformWindow->windowEvent(event);
2013 }
2014 
2016 {
2017  return window->nativeEvent(eventType, message, result);
2018 }
2019 
2021 {
2022  Q_TRACE_SCOPE(QGuiApplicationPrivate_processWindowSystemEvent, e->type);
2023 
2024  switch(e->type) {
2027  break;
2030  break;
2033  break;
2036  break;
2039  break;
2042  break;
2045  break;
2048  break;
2051  break;
2054  break;
2057  break;
2061  break;
2064  break;
2068  break;
2072  break;
2076  break;
2080  break;
2084  break;
2088  break;
2092  break;
2095  break;
2098  break;
2102  break;
2106  break;
2110  break;
2111 #ifndef QT_NO_GESTURES
2115  break;
2116 #endif
2120  break;
2124  break;
2125 #ifndef QT_NO_CONTEXTMENU
2129  break;
2130 #endif
2133  break;
2134  default:
2135  qWarning() << "Unknown user input event type:" << e->type;
2136  break;
2137  }
2138 }
2139 
2153 {
2156  QWindow *window = e->window.data();
2157  const QPointingDevice *device = static_cast<const QPointingDevice *>(e->device);
2158  Q_ASSERT(device);
2160  bool positionChanged = QGuiApplicationPrivate::lastCursorPosition != e->globalPos;
2161  bool mouseMove = false;
2162  bool mousePress = false;
2163  const QPointF lastGlobalPosition = QGuiApplicationPrivate::lastCursorPosition;
2164  QPointF globalPoint = e->globalPos;
2165 
2166  if (qIsNaN(e->globalPos.x()) || qIsNaN(e->globalPos.y())) {
2167  qWarning("QGuiApplicationPrivate::processMouseEvent: Got NaN in mouse position");
2168  return;
2169  }
2170 
2171  type = e->buttonType;
2172  button = e->button;
2173 
2175  mouseMove = true;
2177  mousePress = true;
2178 
2179  if (!mouseMove && positionChanged) {
2180  QWindowSystemInterfacePrivate::MouseEvent moveEvent(window, e->timestamp,
2181  e->localPos, e->globalPos, e->buttons ^ button, e->modifiers, Qt::NoButton,
2183  e->source, e->nonClientArea);
2184  if (e->synthetic())
2186  processMouseEvent(&moveEvent); // mouse move excluding state change
2187  processMouseEvent(e); // the original mouse event
2188  return;
2189  }
2190  if (type == QEvent::MouseMove && !positionChanged) {
2191  // On Windows, and possibly other platforms, a touchpad can send a mouse move
2192  // that does not change position, between a press and a release. This may
2193  // confuse applications, so we always filter out these mouse events for
2194  // consistent behavior among platforms.
2195  return;
2196  }
2197 
2198  modifier_buttons = e->modifiers;
2199  QPointF localPoint = e->localPos;
2200  bool doubleClick = false;
2201  auto persistentEPD = devPriv->pointById(0);
2202 
2203  if (mouseMove) {
2205  const auto doubleClickDistance = (e->device && e->device->type() == QInputDevice::DeviceType::Mouse ?
2206  mouseDoubleClickDistance : touchDoubleTapDistance);
2207  const auto pressPos = persistentEPD->eventPoint.globalPressPosition();
2208  if (qAbs(globalPoint.x() - pressPos.x()) > doubleClickDistance ||
2209  qAbs(globalPoint.y() - pressPos.y()) > doubleClickDistance)
2211  } else {
2212  mouse_buttons = e->buttons;
2213  if (mousePress) {
2214  ulong doubleClickInterval = static_cast<ulong>(QGuiApplication::styleHints()->mouseDoubleClickInterval());
2215  doubleClick = e->timestamp - persistentEPD->eventPoint.pressTimestamp()
2216  < doubleClickInterval && button == mousePressButton;
2218  }
2219  }
2220 
2221  if (e->nullWindow()) {
2222  window = QGuiApplication::topLevelAt(globalPoint.toPoint());
2223  if (window) {
2224  // Moves and the release following a press must go to the same
2225  // window, even if the cursor has moved on over another window.
2226  if (e->buttons != Qt::NoButton) {
2229  else
2231  } else if (currentMousePressWindow) {
2233  currentMousePressWindow = nullptr;
2234  }
2235  localPoint = window->mapFromGlobal(globalPoint);
2236  }
2237  }
2238 
2239  if (!window)
2240  return;
2241 
2242 #ifndef QT_NO_CURSOR
2243  if (!e->synthetic()) {
2244  if (const QScreen *screen = window->screen())
2245  if (QPlatformCursor *cursor = screen->handle()->cursor()) {
2246  const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, screen);
2247  const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen);
2248  QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint,
2249  button, e->buttons, e->modifiers, e->source, device);
2250  // avoid incorrect velocity calculation: ev is in the native coordinate system,
2251  // but we need to consistently use the logical coordinate system for velocity
2252  // whenever QEventPoint::setTimestamp() is called
2253  ev.QInputEvent::setTimestamp(e->timestamp);
2254  cursor->pointerEvent(ev);
2255  }
2256  }
2257 #endif
2258 
2259  QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, e->buttons, e->modifiers, e->source, device);
2260  Q_ASSERT(devPriv->pointById(0) == persistentEPD); // we don't expect reallocation in QPlatformCursor::pointerEvenmt()
2261  // restore globalLastPosition to avoid invalidating the velocity calculations,
2262  // because the QPlatformCursor mouse event above was in native coordinates
2263  QMutableEventPoint::setGlobalLastPosition(persistentEPD->eventPoint, lastGlobalPosition);
2264  persistentEPD = nullptr; // incoming and synth events can cause reallocation during delivery, so don't use this again
2265  // ev now contains a detached copy of the QEventPoint from QPointingDevicePrivate::activePoints
2266  ev.setTimestamp(e->timestamp);
2267  if (window->d_func()->blockedByModalWindow && !qApp->d_func()->popupActive()) {
2268  // a modal window is blocking this window, don't allow mouse events through
2269  return;
2270  }
2271 
2272  if (doubleClick && (ev.type() == QEvent::MouseButtonPress)) {
2273  // QtBUG-25831, used to suppress delivery in qwidgetwindow.cpp
2275  }
2276 
2277  QGuiApplication::sendSpontaneousEvent(window, &ev);
2278  e->eventAccepted = ev.isAccepted();
2279  if (!e->synthetic() && !ev.isAccepted()
2280  && !e->nonClientArea
2284  point.id = 1;
2285  point.area = QHighDpi::toNativePixels(QRectF(globalPoint.x() - 2, globalPoint.y() - 2, 4, 4), window);
2286 
2287  // only translate left button related events to
2288  // avoid strange touch event sequences when several
2289  // buttons are pressed
2291  point.state = QEventPoint::State::Pressed;
2292  } else if (type == QEvent::MouseButtonRelease && button == Qt::LeftButton) {
2293  point.state = QEventPoint::State::Released;
2294  } else if (type == QEvent::MouseMove && (e->buttons & Qt::LeftButton)) {
2295  point.state = QEventPoint::State::Updated;
2296  } else {
2297  return;
2298  }
2299 
2300  points << point;
2301 
2303  const QList<QEventPoint> &touchPoints =
2305 
2306  QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, device, touchPoints, e->modifiers);
2308  processTouchEvent(&fake);
2309  }
2310  if (doubleClick) {
2312  if (!e->window.isNull() || e->nullWindow()) { // QTBUG-36364, check if window closed in response to press
2313  const QEvent::Type doubleClickType = e->nonClientArea ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
2314  QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
2315  button, e->buttons, e->modifiers, e->source, device);
2316  dblClickEvent.setTimestamp(e->timestamp);
2317  QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
2318  }
2319  }
2320  if (type == QEvent::MouseButtonRelease && e->buttons == Qt::NoButton) {
2321  if (auto *persistentEPD = devPriv->queryPointById(0)) {
2322  ev.setExclusiveGrabber(persistentEPD->eventPoint, nullptr);
2323  ev.clearPassiveGrabbers(persistentEPD->eventPoint);
2324  }
2325  }
2326 }
2327 
2329 {
2330 #if QT_CONFIG(wheelevent)
2331  QWindow *window = e->window.data();
2332  QPointF globalPoint = e->globalPos;
2333  QPointF localPoint = e->localPos;
2334 
2335  if (e->nullWindow()) {
2336  window = QGuiApplication::topLevelAt(globalPoint.toPoint());
2337  if (window)
2338  localPoint = window->mapFromGlobal(globalPoint);
2339  }
2340 
2341  if (!window)
2342  return;
2343 
2345  modifier_buttons = e->modifiers;
2346 
2347  if (window->d_func()->blockedByModalWindow) {
2348  // a modal window is blocking this window, don't allow wheel events through
2349  return;
2350  }
2351 
2352  const QPointingDevice *device = static_cast<const QPointingDevice *>(e->device);
2353  QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta,
2354  mouse_buttons, e->modifiers, e->phase, e->inverted, e->source, device);
2355  ev.setTimestamp(e->timestamp);
2356  QGuiApplication::sendSpontaneousEvent(window, &ev);
2357 #else
2358  Q_UNUSED(e);
2359 #endif // QT_CONFIG(wheelevent)
2360 }
2361 
2363 {
2364  QWindow *window = e->window.data();
2365  modifier_buttons = e->modifiers;
2366  if (e->nullWindow()
2367 #ifdef Q_OS_ANDROID
2368  || e->key == Qt::Key_Back || e->key == Qt::Key_Menu
2369 #endif
2370  ) {
2372  }
2373 
2374 #if defined(Q_OS_ANDROID)
2375  static bool backKeyPressAccepted = false;
2376  static bool menuKeyPressAccepted = false;
2377 #endif
2378 
2379 #if !defined(Q_OS_MACOS)
2380  // FIXME: Include OS X in this code path by passing the key event through
2381  // QPlatformInputContext::filterEvent().
2382  if (e->keyType == QEvent::KeyPress && window) {
2383  if (QWindowSystemInterface::handleShortcutEvent(window, e->timestamp, e->key, e->modifiers,
2384  e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers, e->unicode, e->repeat, e->repeatCount)) {
2385 #if defined(Q_OS_ANDROID)
2386  backKeyPressAccepted = e->key == Qt::Key_Back;
2387  menuKeyPressAccepted = e->key == Qt::Key_Menu;
2388 #endif
2389  return;
2390  }
2391  }
2392 #endif
2393 
2394  QKeyEvent ev(e->keyType, e->key, e->modifiers,
2395  e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers,
2396  e->unicode, e->repeat, e->repeatCount);
2397  ev.setTimestamp(e->timestamp);
2398 
2399  // only deliver key events when we have a window, and no modal window is blocking this window
2400 
2401  if (window && !window->d_func()->blockedByModalWindow)
2402  QGuiApplication::sendSpontaneousEvent(window, &ev);
2403 #ifdef Q_OS_ANDROID
2404  else
2405  ev.setAccepted(false);
2406 
2407  if (e->keyType == QEvent::KeyPress) {
2408  backKeyPressAccepted = e->key == Qt::Key_Back && ev.isAccepted();
2409  menuKeyPressAccepted = e->key == Qt::Key_Menu && ev.isAccepted();
2410  } else if (e->keyType == QEvent::KeyRelease) {
2411  if (e->key == Qt::Key_Back && !backKeyPressAccepted && !ev.isAccepted()) {
2412  if (window)
2414  } else if (e->key == Qt::Key_Menu && !menuKeyPressAccepted && !ev.isAccepted()) {
2416  }
2417  }
2418 #endif
2419  e->eventAccepted = ev.isAccepted();
2420 }
2421 
2423 {
2424  if (!e->enter)
2425  return;
2426  if (e->enter.data()->d_func()->blockedByModalWindow) {
2427  // a modal window is blocking this window, don't allow enter events through
2428  return;
2429  }
2430 
2431  currentMouseWindow = e->enter;
2432 
2433  // TODO later: EnterEvent must report _which_ mouse entered the window; for now we assume primaryPointingDevice()
2434  QEnterEvent event(e->localPos, e->localPos, e->globalPos);
2435 
2436  // Since we don't always track mouse moves that occur outside a window, any residual velocity
2437  // stored in the persistent QEventPoint may be inaccurate (especially in fast-moving autotests).
2438  // Reset the Kalman filter so that the velocity of the first mouse event after entering the window
2439  // will be based on a zero residual velocity (but the result can still be non-zero if the mouse
2440  // moves to a different position from where this enter event occurred; tests often do that).
2441  const QPointingDevicePrivate *devPriv = QPointingDevicePrivate::get(event.pointingDevice());
2442  auto epd = devPriv->queryPointById(event.points().first().id());
2443  Q_ASSERT(epd);
2444  QMutableEventPoint::setVelocity(epd->eventPoint, {});
2445 
2446  QCoreApplication::sendSpontaneousEvent(e->enter.data(), &event);
2447 }
2448 
2450 {
2451  if (!e->leave)
2452  return;
2453  if (e->leave.data()->d_func()->blockedByModalWindow) {
2454  // a modal window is blocking this window, don't allow leave events through
2455  return;
2456  }
2457 
2458  currentMouseWindow = nullptr;
2459 
2461  QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event);
2462 }
2463 
2465 {
2467  QWindow *newFocus = e->activated.data();
2468 
2469  if (previous == newFocus)
2470  return;
2471 
2472  if (newFocus)
2473  if (QPlatformWindow *platformWindow = newFocus->handle())
2474  if (platformWindow->isAlertState())
2475  platformWindow->setAlertState(false);
2476 
2477  QObject *previousFocusObject = previous ? previous->focusObject() : nullptr;
2478 
2479  if (previous) {
2480  QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange);
2481  QCoreApplication::sendSpontaneousEvent(previous, &focusAboutToChange);
2482  }
2483 
2485  if (!qApp)
2486  return;
2487 
2488  if (previous) {
2489  Qt::FocusReason r = e->reason;
2491  newFocus && (newFocus->flags() & Qt::Popup) == Qt::Popup)
2493  QFocusEvent focusOut(QEvent::FocusOut, r);
2494  QCoreApplication::sendSpontaneousEvent(previous, &focusOut);
2495  QObject::disconnect(previous, SIGNAL(focusObjectChanged(QObject*)),
2497  } else if (!platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
2499  }
2500 
2502  Qt::FocusReason r = e->reason;
2504  previous && (previous->flags() & Qt::Popup) == Qt::Popup)
2506  QFocusEvent focusIn(QEvent::FocusIn, r);
2507  QCoreApplication::sendSpontaneousEvent(QGuiApplicationPrivate::focus_window, &focusIn);
2510  } else if (!platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
2512  }
2513 
2514  if (self) {
2515  self->notifyActiveWindowChange(previous);
2516 
2517  if (previousFocusObject != qApp->focusObject() ||
2518  // We are getting an activation change but there is no new focusObject, and we also
2519  // don't have a previousFocusObject in the previously active window anymore. This can
2520  // happen when window gets destroyed (see QWidgetWindow::focusObject returning nullptr
2521  // when already in the QWidget destructor), so update the focusObject to avoid dangling
2522  // pointers. See also QWidget::clearFocus(), which tries to cover for this as well.
2523  (previous && previousFocusObject == nullptr && qApp->focusObject() == nullptr)) {
2524  self->_q_updateFocusObject(qApp->focusObject());
2525  }
2526  }
2527 
2528  emit qApp->focusWindowChanged(newFocus);
2529  if (previous)
2530  emit previous->activeChanged();
2531  if (newFocus)
2532  emit newFocus->activeChanged();
2533 }
2534 
2536 {
2537  if (QWindow *window = wse->window.data()) {
2539  window->d_func()->windowState = wse->newState;
2540  QGuiApplication::sendSpontaneousEvent(window, &e);
2541  }
2542 }
2543 
2545 {
2546  if (QWindow *window = wse->window.data()) {
2547  if (window->screen() == wse->screen.data())
2548  return;
2549  if (QWindow *topLevelWindow = window->d_func()->topLevelWindow(QWindow::ExcludeTransients)) {
2550  if (QScreen *screen = wse->screen.data())
2551  topLevelWindow->d_func()->setTopLevelScreen(screen, false /* recreate */);
2552  else // Fall back to default behavior, and try to find some appropriate screen
2553  topLevelWindow->setScreen(nullptr);
2554  }
2555 
2556  // We may have changed scaling; trigger resize event if needed,
2557  // except on Windows, where we send resize events during WM_DPICHANGED
2558  // event handling. FIXME: unify DPI change handling across all platforms.
2559 #ifndef Q_OS_WIN
2560  if (window->handle()) {
2563  }
2564 #endif
2565  }
2566 }
2567 
2569 {
2570  if (wse->window.isNull())
2571  return;
2572 
2573  // Handle by forwarding directly to QWindowPrivate, instead of sending spontaneous
2574  // QEvent like most other functions, as there's no QEvent type for the safe area
2575  // change, and we don't want to add one until we know that this is a good API.
2577 }
2578 
2580 {
2581  if (self)
2582  self->notifyThemeChanged();
2583  if (QWindow *window = tce->window.data()) {
2585  QGuiApplication::sendSpontaneousEvent(window, &e);
2586  }
2587 }
2588 
2590 {
2591  if (e->window.isNull())
2592  return;
2593 
2594  QWindow *window = e->window.data();
2595  if (!window)
2596  return;
2597 
2598  const QRect lastReportedGeometry = window->d_func()->geometry;
2599  const QRect requestedGeometry = e->requestedGeometry;
2600  const QRect actualGeometry = e->newGeometry;
2601 
2602  // We send size and move events only if the geometry has changed from
2603  // what was last reported, or if the user tried to set a new geometry,
2604  // but the window manager responded by keeping the old geometry. In the
2605  // latter case we send move/resize events with the same geometry as the
2606  // last reported geometry, to indicate that the window wasn't moved or
2607  // resized. Note that this logic does not apply to the property changes
2608  // of the window, as we don't treat them as part of this request/response
2609  // protocol of QWindow/QPA.
2610  const bool isResize = actualGeometry.size() != lastReportedGeometry.size()
2611  || requestedGeometry.size() != actualGeometry.size();
2612  const bool isMove = actualGeometry.topLeft() != lastReportedGeometry.topLeft()
2613  || requestedGeometry.topLeft() != actualGeometry.topLeft();
2614 
2615  window->d_func()->geometry = actualGeometry;
2616 
2617  if (isResize || window->d_func()->resizeEventPending) {
2618  QResizeEvent e(actualGeometry.size(), lastReportedGeometry.size());
2619  QGuiApplication::sendSpontaneousEvent(window, &e);
2620 
2621  window->d_func()->resizeEventPending = false;
2622 
2623  if (actualGeometry.width() != lastReportedGeometry.width())
2624  emit window->widthChanged(actualGeometry.width());
2625  if (actualGeometry.height() != lastReportedGeometry.height())
2626  emit window->heightChanged(actualGeometry.height());
2627  }
2628 
2629  if (isMove) {
2630  //### frame geometry
2631  QMoveEvent e(actualGeometry.topLeft(), lastReportedGeometry.topLeft());
2632  QGuiApplication::sendSpontaneousEvent(window, &e);
2633 
2634  if (actualGeometry.x() != lastReportedGeometry.x())
2635  emit window->xChanged(actualGeometry.x());
2636  if (actualGeometry.y() != lastReportedGeometry.y())
2637  emit window->yChanged(actualGeometry.y());
2638  }
2639 }
2640 
2642 {
2643  if (e->window.isNull())
2644  return;
2645  if (e->window.data()->d_func()->blockedByModalWindow) {
2646  // a modal window is blocking this window, don't allow close events through
2647  return;
2648  }
2649 
2651  QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
2652 
2653  e->eventAccepted = event.isAccepted();
2654 }
2655 
2657 {
2658  if (e->url.isEmpty())
2659  return;
2660 
2661  QFileOpenEvent event(e->url);
2662  QGuiApplication::sendSpontaneousEvent(qApp, &event);
2663 }
2664 
2666 {
2667  for (int i = 0; i < tabletDevicePoints.size(); ++i) {
2668  TabletPointData &pointData = tabletDevicePoints[i];
2669  if (pointData.deviceId == deviceId)
2670  return pointData;
2671  }
2672 
2673  tabletDevicePoints.append(TabletPointData(deviceId));
2674  return tabletDevicePoints.last();
2675 }
2676 
2678 {
2679 #if QT_CONFIG(tabletevent)
2680  const auto device = static_cast<const QPointingDevice *>(e->device);
2681  TabletPointData &pointData = tabletDevicePoint(device->uniqueId().numericId());
2682 
2684  if (e->buttons != pointData.state)
2685  type = (e->buttons > pointData.state) ? QEvent::TabletPress : QEvent::TabletRelease;
2686 
2687  QWindow *window = e->window.data();
2688  modifier_buttons = e->modifiers;
2689 
2690  bool localValid = true;
2691  // If window is null, pick one based on the global position and make sure all
2692  // subsequent events up to the release are delivered to that same window.
2693  // If window is given, just send to that.
2694  if (type == QEvent::TabletPress) {
2695  if (e->nullWindow()) {
2696  window = QGuiApplication::topLevelAt(e->global.toPoint());
2697  localValid = false;
2698  }
2699  if (!window)
2700  return;
2701  pointData.target = window;
2702  } else {
2703  if (e->nullWindow()) {
2704  window = pointData.target;
2705  localValid = false;
2706  }
2707  if (type == QEvent::TabletRelease)
2708  pointData.target = nullptr;
2709  if (!window)
2710  return;
2711  }
2712  QPointF local = e->local;
2713  if (!localValid) {
2714  QPointF delta = e->global - e->global.toPoint();
2715  local = window->mapFromGlobal(e->global.toPoint()) + delta;
2716  }
2717 
2718  // TODO stop deducing the button state change here: rather require it from the platform plugin, as with mouse events
2719  Qt::MouseButtons stateChange = e->buttons ^ pointData.state;
2721  for (int check = Qt::LeftButton; check <= int(Qt::MaxMouseButton); check = check << 1) {
2722  if (check & stateChange) {
2723  button = Qt::MouseButton(check);
2724  break;
2725  }
2726  }
2727 
2728  QTabletEvent tabletEvent(type, device, local, e->global,
2729  e->pressure, e->xTilt, e->yTilt,
2730  e->tangentialPressure, e->rotation, e->z,
2731  e->modifiers, button, e->buttons);
2732  tabletEvent.setAccepted(false);
2733  tabletEvent.setTimestamp(e->timestamp);
2734  QGuiApplication::sendSpontaneousEvent(window, &tabletEvent);
2735  pointData.state = e->buttons;
2736  if (!tabletEvent.isAccepted()
2739 
2740  const QEvent::Type mouseType = [&]() {
2741  switch (type) {
2745  default: Q_UNREACHABLE();
2746  }
2747  }();
2748  QWindowSystemInterfacePrivate::MouseEvent mouseEvent(window, e->timestamp, e->local,
2749  e->global, e->buttons, e->modifiers, button, mouseType, Qt::MouseEventNotSynthesized, false, device);
2751  processMouseEvent(&mouseEvent);
2752  }
2753 #else
2754  Q_UNUSED(e);
2755 #endif
2756 }
2757 
2759 {
2760 #if QT_CONFIG(tabletevent)
2761  const QPointingDevice *dev = static_cast<const QPointingDevice *>(e->device);
2762  QTabletEvent ev(QEvent::TabletEnterProximity, dev, QPointF(), QPointF(),
2763  0, 0, 0, 0, 0, 0, e->modifiers, Qt::NoButton,
2765  ev.setTimestamp(e->timestamp);
2766  QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
2767 #else
2768  Q_UNUSED(e);
2769 #endif
2770 }
2771 
2773 {
2774 #if QT_CONFIG(tabletevent)
2775  const QPointingDevice *dev = static_cast<const QPointingDevice *>(e->device);
2776  QTabletEvent ev(QEvent::TabletLeaveProximity, dev, QPointF(), QPointF(),
2777  0, 0, 0, 0, 0, 0, e->modifiers, Qt::NoButton,
2779  ev.setTimestamp(e->timestamp);
2780  QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
2781 #else
2782  Q_UNUSED(e);
2783 #endif
2784 }
2785 
2786 #ifndef QT_NO_GESTURES
2788 {
2789  if (e->window.isNull())
2790  return;
2791 
2792  const QPointingDevice *device = static_cast<const QPointingDevice *>(e->device);
2793  QNativeGestureEvent ev(e->type, device, e->fingerCount, e->pos, e->pos, e->globalPos, (e->intValue ? e->intValue : e->realValue),
2794  e->delta, e->sequenceId);
2795  ev.setTimestamp(e->timestamp);
2796  QGuiApplication::sendSpontaneousEvent(e->window, &ev);
2797 }
2798 #endif // QT_NO_GESTURES
2799 
2801 {
2802  if (!e->window)
2803  return;
2804 
2805  if (e->window->d_func()->blockedByModalWindow) {
2806  // a modal window is blocking this window, don't allow events through
2807  return;
2808  }
2809 
2811  QGuiApplication::sendSpontaneousEvent(e->window.data(), &ev);
2812 }
2813 
2814 #ifndef QT_NO_CONTEXTMENU
2816 {
2817  // Widgets do not care about mouse triggered context menu events. Also, do not forward event
2818  // to a window blocked by a modal window.
2819  if (!e->window || e->mouseTriggered || e->window->d_func()->blockedByModalWindow)
2820  return;
2821 
2822  QContextMenuEvent ev(QContextMenuEvent::Keyboard, e->pos, e->globalPos, e->modifiers);
2823  QGuiApplication::sendSpontaneousEvent(e->window.data(), &ev);
2824 }
2825 #endif
2826 
2828 {
2829  if (!QInputDevicePrivate::isRegistered(e->device))
2830  return;
2831 
2832  modifier_buttons = e->modifiers;
2833  QPointingDevice *device = const_cast<QPointingDevice *>(static_cast<const QPointingDevice *>(e->device));
2835 
2836  if (e->touchType == QEvent::TouchCancel) {
2837  // The touch sequence has been canceled (e.g. by the compositor).
2838  // Send the TouchCancel to all windows with active touches and clean up.
2840  touchEvent.setTimestamp(e->timestamp);
2841  QSet<QWindow *> windowsNeedingCancel;
2842 
2843  for (auto &epd : devPriv->activePoints.values()) {
2844  if (QWindow *w = QMutableEventPoint::window(epd.eventPoint))
2845  windowsNeedingCancel.insert(w);
2846  }
2847 
2848  for (QSet<QWindow *>::const_iterator winIt = windowsNeedingCancel.constBegin(),
2849  winItEnd = windowsNeedingCancel.constEnd(); winIt != winItEnd; ++winIt) {
2850  QGuiApplication::sendSpontaneousEvent(*winIt, &touchEvent);
2851  }
2852  if (!self->synthesizedMousePoints.isEmpty() && !e->synthetic()) {
2854  synthItEnd = self->synthesizedMousePoints.constEnd(); synthIt != synthItEnd; ++synthIt) {
2855  if (!synthIt->window)
2856  continue;
2857  QWindowSystemInterfacePrivate::MouseEvent fake(synthIt->window.data(),
2858  e->timestamp,
2859  synthIt->pos,
2860  synthIt->screenPos,
2861  Qt::NoButton,
2862  e->modifiers,
2866  false,
2867  device);
2869  processMouseEvent(&fake);
2870  }
2871  self->synthesizedMousePoints.clear();
2872  }
2873  self->lastTouchType = e->touchType;
2874  return;
2875  }
2876 
2877  // Prevent sending ill-formed event sequences: Cancel can only be followed by a Begin.
2878  if (self->lastTouchType == QEvent::TouchCancel && e->touchType != QEvent::TouchBegin)
2879  return;
2880 
2881  self->lastTouchType = e->touchType;
2882 
2883  QPointer<QWindow> window = e->window; // the platform hopefully tells us which window received the event
2885 
2886  // For each temporary QEventPoint from the QPA TouchEvent:
2887  // - update the persistent QEventPoint in QPointingDevicePrivate::activePoints with current values
2888  // - determine which window to deliver it to
2889  // - add it to the QTouchEvent instance for that window (QMutableTouchEvent::target() will be QWindow*, for now)
2890  for (auto &tempPt : e->points) {
2891  // update state
2892  auto epd = devPriv->pointById(tempPt.id());
2893  auto &ep = epd->eventPoint;
2894  epd->eventPoint.setAccepted(false);
2895  switch (tempPt.state()) {
2896  case QEventPoint::State::Pressed:
2897  // On touchpads, send all touch points to the same window.
2898  if (!window && e->device && e->device->type() == QInputDevice::DeviceType::TouchPad)
2899  window = devPriv->firstActiveWindow();
2900  // If the QPA event didn't tell us which window, find the one under the touchpoint position.
2901  if (!window)
2902  window = QGuiApplication::topLevelAt(tempPt.globalPosition().toPoint());
2903  QMutableEventPoint::setWindow(ep, window);
2904  break;
2905 
2906  case QEventPoint::State::Released:
2907  if (Q_UNLIKELY(!window.isNull() && window != QMutableEventPoint::window(ep)))
2908  qCWarning(lcPtrDispatch) << "delivering touch release to same window"
2909  << QMutableEventPoint::window(ep) << "not" << window.data();
2911  break;
2912 
2913  default: // update or stationary
2914  if (Q_UNLIKELY(!window.isNull() && window != QMutableEventPoint::window(ep)))
2915  qCWarning(lcPtrDispatch) << "delivering touch update to same window"
2916  << QMutableEventPoint::window(ep) << "not" << window.data();
2918  break;
2919  }
2920  // If we somehow still don't have a window, we can't deliver this touchpoint. (should never happen)
2921  if (Q_UNLIKELY(!window)) {
2922  qCWarning(lcPtrDispatch) << "skipping" << &tempPt << ": no target window";
2923  continue;
2924  }
2925  QMutableEventPoint::update(tempPt, ep);
2926 
2927  Q_ASSERT(window.data() != nullptr);
2928 
2929  // make the *scene* position the same as the *global* position
2930  QMutableEventPoint::setScenePosition(ep, tempPt.globalPosition());
2931 
2932  // store the scene position as local position, for now
2933  QMutableEventPoint::setPosition(ep, window->mapFromGlobal(tempPt.globalPosition()));
2934 
2935  // setTimeStamp has side effects, so we do it last
2936  QMutableEventPoint::setTimestamp(ep, e->timestamp);
2937 
2938  // add the touchpoint to the event that will be delivered to the window
2939  bool added = false;
2940  for (QMutableTouchEvent &ev : touchEvents) {
2941  if (ev.target() == window.data()) {
2942  ev.addPoint(ep);
2943  added = true;
2944  break;
2945  }
2946  }
2947  if (!added) {
2948  QMutableTouchEvent mte(e->touchType, device, e->modifiers, {ep});
2949  mte.setTimestamp(e->timestamp);
2950  mte.setTarget(window.data());
2951  touchEvents.append(mte);
2952  }
2953  }
2954 
2955  if (touchEvents.isEmpty())
2956  return;
2957 
2958  for (QMutableTouchEvent &touchEvent : touchEvents) {
2959  QWindow *window = static_cast<QWindow *>(touchEvent.target());
2960 
2961  QEvent::Type eventType;
2962  switch (touchEvent.touchPointStates()) {
2963  case QEventPoint::State::Pressed:
2964  eventType = QEvent::TouchBegin;
2965  break;
2966  case QEventPoint::State::Released:
2967  eventType = QEvent::TouchEnd;
2968  break;
2969  default:
2970  eventType = QEvent::TouchUpdate;
2971  break;
2972  }
2973 
2974  if (window->d_func()->blockedByModalWindow && !qApp->d_func()->popupActive()) {
2975  // a modal window is blocking this window, don't allow touch events through
2976 
2977  // QTBUG-37371 temporary fix; TODO: revisit when we have a forwarding solution
2978  if (touchEvent.type() == QEvent::TouchEnd) {
2979  // but don't leave dangling state: e.g.
2980  // QQuickWindowPrivate::itemForTouchPointId needs to be cleared.
2982  touchEvent.setTimestamp(e->timestamp);
2983  QGuiApplication::sendSpontaneousEvent(window, &touchEvent);
2984  }
2985  continue;
2986  }
2987 
2988  // Note: after the call to sendSpontaneousEvent, touchEvent.position() will have
2989  // changed to reflect the local position inside the last (random) widget it tried
2990  // to deliver the touch event to, and will therefore be invalid afterwards.
2991  QGuiApplication::sendSpontaneousEvent(window, &touchEvent);
2992 
2993  if (!e->synthetic() && !touchEvent.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)) {
2994  // exclude devices which generate their own mouse events
2996 
2997  QEvent::Type mouseEventType = QEvent::MouseMove;
2999  Qt::MouseButtons buttons = Qt::LeftButton;
3000  if (eventType == QEvent::TouchBegin || m_fakeMouseSourcePointId < 0) {
3001  m_fakeMouseSourcePointId = touchEvent.point(0).id();
3002  qCDebug(lcPtrDispatch) << "synthesizing mouse events from touchpoint" << m_fakeMouseSourcePointId;
3003  }
3004  if (m_fakeMouseSourcePointId >= 0) {
3005  const auto *touchPoint = touchEvent.pointById(m_fakeMouseSourcePointId);
3006  if (touchPoint) {
3007  switch (touchPoint->state()) {
3008  case QEventPoint::State::Pressed:
3009  mouseEventType = QEvent::MouseButtonPress;
3011  break;
3012  case QEventPoint::State::Released:
3013  mouseEventType = QEvent::MouseButtonRelease;
3015  buttons = Qt::NoButton;
3016  Q_ASSERT(m_fakeMouseSourcePointId == touchPoint->id());
3017  m_fakeMouseSourcePointId = -1;
3018  break;
3019  default:
3020  break;
3021  }
3022  if (touchPoint->state() != QEventPoint::State::Released) {
3023  self->synthesizedMousePoints.insert(window, SynthesizedMouseData(
3024  touchPoint->position(), touchPoint->globalPosition(), window));
3025  }
3026  // All touch events that are not accepted by the application will be translated to
3027  // left mouse button events instead (see AA_SynthesizeMouseForUnhandledTouchEvents docs).
3028  // TODO why go through QPA? Why not just send a QMouseEvent right from here?
3030  window->mapFromGlobal(touchPoint->globalPosition().toPoint()),
3031  touchPoint->globalPosition(),
3032  buttons,
3033  e->modifiers,
3034  button,
3035  mouseEventType,
3037  false,
3038  device);
3040  processMouseEvent(&fake);
3041  }
3042  }
3043  if (eventType == QEvent::TouchEnd)
3044  self->synthesizedMousePoints.clear();
3045  }
3046  }
3047  }
3048 
3049  // Remove released points from QPointingDevicePrivate::activePoints only after the event is
3050  // delivered. Widgets and Qt Quick are allowed to access them at any time before this.
3051  for (const QEventPoint &touchPoint : e->points) {
3052  if (touchPoint.state() == QEventPoint::State::Released)
3053  devPriv->removePointById(touchPoint.id());
3054  }
3055 }
3056 
3058 {
3059  // This operation only makes sense after the QGuiApplication constructor runs
3061  return;
3062 
3063  if (!e->screen)
3064  return;
3065 
3066  QScreen *s = e->screen.data();
3067  s->d_func()->orientation = e->orientation;
3068 
3069  emit s->orientationChanged(s->orientation());
3070 
3071  QScreenOrientationChangeEvent event(s, s->orientation());
3073 }
3074 
3076 {
3077  // This operation only makes sense after the QGuiApplication constructor runs
3079  return;
3080 
3081  if (!e->screen)
3082  return;
3083 
3084  QScreen *s = e->screen.data();
3085 
3086  bool geometryChanged = e->geometry != s->d_func()->geometry;
3087  s->d_func()->geometry = e->geometry;
3088 
3089  bool availableGeometryChanged = e->availableGeometry != s->d_func()->availableGeometry;
3090  s->d_func()->availableGeometry = e->availableGeometry;
3091 
3092  const Qt::ScreenOrientation primaryOrientation = s->primaryOrientation();
3093  if (geometryChanged)
3094  s->d_func()->updatePrimaryOrientation();
3095 
3096  s->d_func()->emitGeometryChangeSignals(geometryChanged, availableGeometryChanged);
3097 
3098  if (geometryChanged) {
3099  emit s->physicalSizeChanged(s->physicalSize());
3100  emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
3101 
3102  if (s->primaryOrientation() != primaryOrientation)
3103  emit s->primaryOrientationChanged(s->primaryOrientation());
3104  }
3105 
3107 }
3108 
3110 {
3111  // This operation only makes sense after the QGuiApplication constructor runs
3113  return;
3114 
3116 
3117  if (!e->screen)
3118  return;
3119 
3120  QScreen *s = e->screen.data();
3121  s->d_func()->logicalDpi = QDpi(e->dpiX, e->dpiY);
3122 
3123  emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch());
3124  s->d_func()->updateGeometriesWithSignals();
3125 
3127 }
3128 
3130 {
3131  // This operation only makes sense after the QGuiApplication constructor runs
3133  return;
3134 
3135  if (!e->screen)
3136  return;
3137 
3138  QScreen *s = e->screen.data();
3139  qreal rate = e->rate;
3140  // safeguard ourselves against buggy platform behavior...
3141  if (rate < 1.0)
3142  rate = 60.0;
3143  if (!qFuzzyCompare(s->d_func()->refreshRate, rate)) {
3144  s->d_func()->refreshRate = rate;
3145  emit s->refreshRateChanged(s->refreshRate());
3146  }
3147 }
3148 
3150 {
3151  if (!e->window)
3152  return;
3153 
3154  QWindow *window = e->window.data();
3155  if (!window)
3156  return;
3158 
3159  if (!p->receivedExpose) {
3160  if (p->resizeEventPending) {
3161  // as a convenience for plugins, send a resize event before the first expose event if they haven't done so
3162  // window->geometry() should have a valid size as soon as a handle exists.
3163  QResizeEvent e(window->geometry().size(), p->geometry.size());
3164  QGuiApplication::sendSpontaneousEvent(window, &e);
3165 
3166  p->resizeEventPending = false;
3167  }
3168 
3169  // FIXME: It would logically make sense to set this _after_ we've sent the
3170  // expose event to the window, to mark that it now has received an expose.
3171  // But some parts of Qt (mis)use this private member to check whether the
3172  // window has been mapped yet, which they do in code that is triggered
3173  // by the very same expose event we send below. To keep the code working
3174  // we need to set the variable up front, until the code has been fixed.
3175  p->receivedExpose = true;
3176  }
3177 
3178  // If the platform does not send paint events we need to synthesize them from expose events
3179  const bool shouldSynthesizePaintEvents = !platformIntegration()->hasCapability(QPlatformIntegration::PaintEvents);
3180 
3181  const bool wasExposed = p->exposed;
3182  p->exposed = e->isExposed && window->screen();
3183 
3184  // We treat expose events for an already exposed window as paint events
3185  if (wasExposed && p->exposed && shouldSynthesizePaintEvents) {
3186  QPaintEvent paintEvent(e->region);
3187  QCoreApplication::sendSpontaneousEvent(window, &paintEvent);
3188  if (paintEvent.isAccepted())
3189  return; // No need to send expose
3190 
3191  // The paint event was not accepted, so we fall through and send an expose
3192  // event instead, to maintain compatibility for clients that haven't adopted
3193  // paint events yet.
3194  }
3195 
3196  QExposeEvent exposeEvent(e->region);
3197  QCoreApplication::sendSpontaneousEvent(window, &exposeEvent);
3198  e->eventAccepted = exposeEvent.isAccepted();
3199 
3200  // If the window was just exposed we also need to send a paint event,
3201  // so that clients that implement paint events will draw something.
3202  // Note that we we can not skip this based on the expose event being
3203  // accepted, as clients may implement exposeEvent to track the state
3204  // change, but without drawing anything.
3205  if (!wasExposed && p->exposed && shouldSynthesizePaintEvents) {
3206  QPaintEvent paintEvent(e->region);
3207  QCoreApplication::sendSpontaneousEvent(window, &paintEvent);
3208  }
3209 }
3210 
3212 {
3213  Q_ASSERT_X(platformIntegration()->hasCapability(QPlatformIntegration::PaintEvents), "QGuiApplication",
3214  "The platform sent paint events without claiming support for it in QPlatformIntegration::capabilities()");
3215 
3216  if (!e->window)
3217  return;
3218 
3219  QPaintEvent paintEvent(e->region);
3220  QCoreApplication::sendSpontaneousEvent(e->window, &paintEvent);
3221 
3222  // We report back the accepted state to the platform, so that it can
3223  // decide when the best time to send the fallback expose event is.
3224  e->eventAccepted = paintEvent.isAccepted();
3225 }
3226 
3227 #if QT_CONFIG(draganddrop)
3228 
3234 static void updateMouseAndModifierButtonState(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
3235 {
3238 }
3239 
3240 QPlatformDragQtResponse QGuiApplicationPrivate::processDrag(QWindow *w, const QMimeData *dropData,
3241  const QPoint &p, Qt::DropActions supportedActions,
3242  Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
3243 {
3244  updateMouseAndModifierButtonState(buttons, modifiers);
3245 
3246  static Qt::DropAction lastAcceptedDropAction = Qt::IgnoreAction;
3247  QPlatformDrag *platformDrag = platformIntegration()->drag();
3248  if (!platformDrag || (w && w->d_func()->blockedByModalWindow)) {
3249  lastAcceptedDropAction = Qt::IgnoreAction;
3250  return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
3251  }
3252 
3253  if (!dropData) {
3254  currentDragWindow = nullptr;
3255  QDragLeaveEvent e;
3257  lastAcceptedDropAction = Qt::IgnoreAction;
3258  return QPlatformDragQtResponse(false, lastAcceptedDropAction, QRect());
3259  }
3260  QDragMoveEvent me(p, supportedActions, dropData, buttons, modifiers);
3261 
3262  if (w != currentDragWindow) {
3263  lastAcceptedDropAction = Qt::IgnoreAction;
3264  if (currentDragWindow) {
3265  QDragLeaveEvent e;
3267  }
3268  currentDragWindow = w;
3269  QDragEnterEvent e(p, supportedActions, dropData, buttons, modifiers);
3271  if (e.isAccepted() && e.dropAction() != Qt::IgnoreAction)
3272  lastAcceptedDropAction = e.dropAction();
3273  }
3274 
3275  // Handling 'DragEnter' should suffice for the application.
3276  if (lastAcceptedDropAction != Qt::IgnoreAction
3277  && (supportedActions & lastAcceptedDropAction)) {
3278  me.setDropAction(lastAcceptedDropAction);
3279  me.accept();
3280  }
3282  lastAcceptedDropAction = me.isAccepted() ?
3283  me.dropAction() : Qt::IgnoreAction;
3284  return QPlatformDragQtResponse(me.isAccepted(), lastAcceptedDropAction, me.answerRect());
3285 }
3286 
3287 QPlatformDropQtResponse QGuiApplicationPrivate::processDrop(QWindow *w, const QMimeData *dropData,
3288  const QPoint &p, Qt::DropActions supportedActions,
3289  Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers)
3290 {
3291  updateMouseAndModifierButtonState(buttons, modifiers);
3292 
3293  currentDragWindow = nullptr;
3294 
3295  QDropEvent de(p, supportedActions, dropData, buttons, modifiers);
3297 
3298  Qt::DropAction acceptedAction = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
3299  QPlatformDropQtResponse response(de.isAccepted(),acceptedAction);
3300  return response;
3301 }
3302 
3303 #endif // QT_CONFIG(draganddrop)
3304 
3305 #ifndef QT_NO_CLIPBOARD
3310 {
3311  if (QGuiApplicationPrivate::qt_clipboard == nullptr) {
3312  if (!qApp) {
3313  qWarning("QGuiApplication: Must construct a QGuiApplication before accessing a QClipboard");
3314  return nullptr;
3315  }
3317  }
3319 }
3320 #endif
3321 
3342 {
3345 
3347 }
3348 
3350 {
3351  if (app_pal) {
3352  if (setPalette(*app_pal) && qGuiApp)
3353  qGuiApp->d_func()->handlePaletteChanged();
3354  } else {
3355  setPalette(QPalette());
3356  }
3357 }
3358 
3359 void QGuiApplicationPrivate::clearPalette()
3360 {
3361  delete app_pal;
3362  app_pal = nullptr;
3363 }
3364 
3374 {
3376  qGuiApp->d_func()->handlePaletteChanged();
3377 }
3378 
3380 {
3381  // Resolve the palette against the theme palette, filling in
3382  // any missing roles, while keeping the original resolve mask.
3383  QPalette basePalette = qGuiApp ? qGuiApp->d_func()->basePalette() : Qt::gray;
3384  basePalette.setResolveMask(0); // The base palette only contributes missing colors roles
3385  QPalette resolvedPalette = palette.resolve(basePalette);
3386 
3387  if (app_pal && resolvedPalette == *app_pal && resolvedPalette.resolveMask() == app_pal->resolveMask())
3388  return false;
3389 
3390  if (!app_pal)
3391  app_pal = new QPalette(resolvedPalette);
3392  else
3393  *app_pal = resolvedPalette;
3394 
3396 
3397  return true;
3398 }
3399 
3400 /*
3401  Returns the base palette used to fill in missing roles in
3402  the current application palette.
3403 
3404  Normally this is the theme palette, but QApplication
3405  overrides this for compatibility reasons.
3406 */
3408 {
3409  return platformTheme() ? *platformTheme()->palette() : Qt::gray;
3410 }
3411 
3413 {
3414  if (!className) {
3415  Q_ASSERT(app_pal);
3418  emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal);
3420  }
3421 
3422  if (is_app_running && !is_app_closing) {
3425  }
3426 }
3427 
3429 {
3430  windowGeometrySpecification.applyTo(window);
3431 }
3432 
3450 {
3451  const auto locker = qt_scoped_lock(applicationFontMutex);
3452  if (!QGuiApplicationPrivate::self && !QGuiApplicationPrivate::app_font) {
3453  qWarning("QGuiApplication::font(): no QGuiApplication instance and no application font set.");
3454  return QFont(); // in effect: QFont((QFontPrivate*)nullptr), so no recursion
3455  }
3456  initFontUnlocked();
3458 }
3459 
3466 {
3467  auto locker = qt_unique_lock(applicationFontMutex);
3468  const bool emitChange = !QGuiApplicationPrivate::app_font
3472  else
3474  applicationResourceFlags |= ApplicationFontExplicitlySet;
3475 
3476  if (emitChange && qGuiApp) {
3478  locker.unlock();
3481  emit qGuiApp->fontChanged(font);
3485  }
3486 }
3487 
3507 {
3509  for (int i = 0; i < list.size(); ++i) {
3512  }
3513 }
3514 
3516 {
3517  if (prev) {
3519  QCoreApplication::sendEvent(prev, &de);
3520  }
3521  if (self->focus_window) {
3524  }
3525 }
3526 
3534 {
3536 }
3537 
3539 {
3547  QGuiApplicationPrivate::self->notifyWindowIconChanged();
3548 }
3549 
3551 {
3554  for (int i = 0; i < list.size(); ++i)
3556 }
3557 
3558 
3559 
3576 {
3578 }
3579 
3581 {
3583 }
3584 
3586 {
3587  if (!lastWindowClosed())
3588  return;
3589 
3590  if (in_exec)
3591  emit q_func()->lastWindowClosed();
3592 
3595 }
3596 
3611 {
3612  for (auto *window : QGuiApplication::topLevelWindows()) {
3613  auto *windowPrivate = qt_window_private(window);
3614  if (!windowPrivate->participatesInLastWindowClosed())
3615  continue;
3616 
3617  if (windowPrivate->treatAsVisible())
3618  return false;
3619  }
3620 
3621  return true;
3622 }
3623 
3625 {
3627  return false;
3628 
3630 }
3631 
3633 {
3636  else
3638 }
3639 
3641 {
3643  QGuiApplication::sendSpontaneousEvent(QGuiApplication::instance(), &event);
3644  windowSystemEvent->eventAccepted = event.isAccepted();
3645 }
3646 
3660 {
3662 }
3663 
3689 {
3691 }
3692 
3699 {
3701 }
3702 
3713 {
3714  if ((applicationState == state) && !forcePropagate)
3715  return;
3716 
3718 
3719  switch (state) {
3720  case Qt::ApplicationActive: {
3721  QEvent appActivate(QEvent::ApplicationActivate);
3722  QCoreApplication::sendSpontaneousEvent(qApp, &appActivate);
3723  break; }
3724  case Qt::ApplicationInactive: {
3725  QEvent appDeactivate(QEvent::ApplicationDeactivate);
3726  QCoreApplication::sendSpontaneousEvent(qApp, &appDeactivate);
3727  break; }
3728  default:
3729  break;
3730  }
3731 
3733  QCoreApplication::sendSpontaneousEvent(qApp, &event);
3734 
3735  emit qApp->applicationStateChanged(applicationState);
3736 }
3737 
3841 #ifndef QT_NO_SESSIONMANAGER
3843 {
3844  Q_D(const QGuiApplication);
3845  return d->is_session_restored;
3846 }
3847 
3849 {
3850  Q_D(const QGuiApplication);
3851  return d->session_manager->sessionId();
3852 }
3853 
3855 {
3856  Q_D(const QGuiApplication);
3857  return d->session_manager->sessionKey();
3858 }
3859 
3861 {
3862  Q_D(const QGuiApplication);
3863  return d->is_saving_session;
3864 }
3865 
3867 {
3868  Q_Q(QGuiApplication);
3869  is_saving_session = true;
3870  emit q->commitDataRequest(*session_manager);
3871  is_saving_session = false;
3872 }
3873 
3874 
3876 {
3877  Q_Q(QGuiApplication);
3878  is_saving_session = true;
3879  emit q->saveStateRequest(*session_manager);
3880  is_saving_session = false;
3881 }
3882 #endif //QT_NO_SESSIONMANAGER
3883 
3896 {
3903  }
3904 }
3905 
3920 {
3921  layout_direction = direction;
3923  direction = qt_detectRTLLanguage() ? Qt::RightToLeft : Qt::LeftToRight;
3924 
3925  // no change to the explicitly set or auto-detected layout direction
3926  if (direction == effective_layout_direction)
3927  return;
3928 
3929  effective_layout_direction = direction;
3930  if (qGuiApp) {
3931  emit qGuiApp->layoutDirectionChanged(direction);
3932  QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
3933  }
3934 }
3935 
3937 {
3938  /*
3939  effective_layout_direction defaults to Qt::LeftToRight, and is updated with what is
3940  auto-detected by a call to setLayoutDirection(Qt::LayoutDirectionAuto). This happens in
3941  QGuiApplicationPrivate::init and when the language changes (or before if the application
3942  calls the static function, but then no translators are installed so the auto-detection
3943  always yields Qt::LeftToRight).
3944  So we can be certain that it's always the right value.
3945  */
3946  return effective_layout_direction;
3947 }
3948 
3959 #ifndef QT_NO_CURSOR
3961 {
3962  CHECK_QAPP_INSTANCE(nullptr)
3963  return qGuiApp->d_func()->cursor_list.isEmpty() ? nullptr : &qGuiApp->d_func()->cursor_list.first();
3964 }
3965 
3975 {
3977  if (qGuiApp->d_func()->cursor_list.isEmpty())
3978  return;
3979  qGuiApp->d_func()->cursor_list.removeFirst();
3981 }
3982 #endif
3983 
3984 
3985 #ifndef QT_NO_CURSOR
3986 static inline void applyCursor(QWindow *w, QCursor c)
3987 {
3988  if (const QScreen *screen = w->screen())
3989  if (QPlatformCursor *cursor = screen->handle()->cursor())
3990  cursor->changeCursor(&c, w);
3991 }
3992 
3993 static inline void unsetCursor(QWindow *w)
3994 {
3995  if (const QScreen *screen = w->screen())
3996  if (QPlatformCursor *cursor = screen->handle()->cursor())
3997  cursor->changeCursor(nullptr, w);
3998 }
3999 
4000 static inline void applyCursor(const QList<QWindow *> &l, const QCursor &c)
4001 {
4002  for (int i = 0; i < l.size(); ++i) {
4003  QWindow *w = l.at(i);
4004  if (w->handle() && w->type() != Qt::Desktop)
4005  applyCursor(w, c);
4006  }
4007 }
4008 
4009 static inline void applyOverrideCursor(const QList<QScreen *> &screens, const QCursor &c)
4010 {
4011  for (QScreen *screen : screens) {
4012  if (QPlatformCursor *cursor = screen->handle()->cursor())
4013  cursor->setOverrideCursor(c);
4014  }
4015 }
4016 
4017 static inline void clearOverrideCursor(const QList<QScreen *> &screens)
4018 {
4019  for (QScreen *screen : screens) {
4020  if (QPlatformCursor *cursor = screen->handle()->cursor())
4021  cursor->clearOverrideCursor();
4022  }
4023 }
4024 
4025 static inline void applyWindowCursor(const QList<QWindow *> &l)
4026 {
4027  for (int i = 0; i < l.size(); ++i) {
4028  QWindow *w = l.at(i);
4029  if (w->handle() && w->type() != Qt::Desktop) {
4030  if (qt_window_private(w)->hasCursor) {
4031  applyCursor(w, w->cursor());
4032  } else {
4033  unsetCursor(w);
4034  }
4035  }
4036  }
4037 }
4038 
4066 {
4068  qGuiApp->d_func()->cursor_list.prepend(cursor);
4070  applyOverrideCursor(QGuiApplicationPrivate::screen_list, cursor);
4071  else
4073 }
4074 
4087 {
4089  if (qGuiApp->d_func()->cursor_list.isEmpty())
4090  return;
4091  qGuiApp->d_func()->cursor_list.removeFirst();
4092  if (qGuiApp->d_func()->cursor_list.size() > 0) {
4093  QCursor c(qGuiApp->d_func()->cursor_list.value(0));
4095  applyOverrideCursor(QGuiApplicationPrivate::screen_list, c);
4096  else
4097  applyCursor(QGuiApplicationPrivate::window_list, c);
4098  } else {
4100  clearOverrideCursor(QGuiApplicationPrivate::screen_list);
4101  applyWindowCursor(QGuiApplicationPrivate::window_list);
4102  }
4103 }
4104 #endif// QT_NO_CURSOR
4105 
4117 {
4121 }
4122 
4135 {
4137 }
4138 
4146 {
4148 }
4149 
4160 {
4161  CHECK_QAPP_INSTANCE(nullptr)
4162  if (!qGuiApp->d_func()->inputMethod)
4163  qGuiApp->d_func()->inputMethod = new QInputMethod();
4164  return qGuiApp->d_func()->inputMethod;
4165 }
4166 
4179 {
4180  Q_UNUSED(cshape);
4181  return QPixmap();
4182 }
4183 
4184 QPoint QGuiApplicationPrivate::QLastCursorPosition::toPoint() const noexcept
4185 {
4186  // Guard against the default initialization of qInf() (avoid UB or SIGFPE in conversion).
4187  if (Q_UNLIKELY(qIsInf(thePoint.x())))
4188  return QPoint(std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
4189  return thePoint.toPoint();
4190 }
4191 
4193 {
4194  updatePalette();
4195 
4197 
4198  if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
4199  const auto locker = qt_scoped_lock(applicationFontMutex);
4200  clearFontUnlocked();
4201  initFontUnlocked();
4202  }
4203  initThemeHints();
4204 }
4205 
4206 #if QT_CONFIG(draganddrop)
4207 void QGuiApplicationPrivate::notifyDragStarted(const QDrag *drag)
4208 {
4209  Q_UNUSED(drag);
4210 
4211 }
4212 #endif
4213 
4215 {
4216 #ifdef Q_OS_WIN
4217  if (!m_a8ColorProfile)
4218  m_a8ColorProfile = QColorTrcLut::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering
4219  return m_a8ColorProfile.get();
4220 #else
4221  return colorProfileForA32Text();
4222 #endif
4223 }
4224 
4226 {
4227  if (!m_a32ColorProfile)
4228  m_a32ColorProfile = QColorTrcLut::fromGamma(fontSmoothingGamma);
4229  return m_a32ColorProfile.get();
4230 }
4231 
4233 {
4234  Q_Q(QGuiApplication);
4235 
4237  const bool enabled = inputContext && QInputMethodPrivate::objectAcceptsInputMethod(object);
4238 
4240  if (inputContext)
4241  inputContext->setFocusObject(object);
4242  emit q->focusObjectChanged(object);
4243 }
4244 
4251  MouseFlagsShift = 16
4252 };
4253 
4255 {
4257 
4258  if (!m_inputDeviceManager)
4259  m_inputDeviceManager = new QInputDeviceManager(QGuiApplication::instance());
4260 
4261  return m_inputDeviceManager;
4262 }
4263 
4277 void *QGuiApplication::resolveInterface(const char *name, int revision) const
4278 {
4279  using namespace QNativeInterface;
4280  using namespace QNativeInterface::Private;
4281 
4282  auto *platformIntegration = QGuiApplicationPrivate::platformIntegration();
4283  Q_UNUSED(platformIntegration);
4284 
4285 #if defined(Q_OS_WIN)
4286  QT_NATIVE_INTERFACE_RETURN_IF(QWindowsApplication, platformIntegration);
4287 #endif
4288 #if QT_CONFIG(xcb)
4290 #endif
4291 
4292  return QCoreApplication::resolveInterface(name, revision);
4293 }
4294 
4295 #include "moc_qguiapplication.cpp"
4296 
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
#define value
[5]
static void setRootObject(QObject *object)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
const char * constData() const noexcept
Definition: qbytearray.h:144
QList< QByteArray > split(char sep) const
qsizetype indexOf(char c, qsizetype from=0) const
bool startsWith(QByteArrayView bv) const
Definition: qbytearray.h:192
bool isEmpty() const noexcept
Definition: qbytearray.h:129
void clear()
QByteArray mid(qsizetype index, qsizetype len=-1) const
QChar toUpper() const noexcept
Definition: qchar.h:480
The QClipboard class provides access to the window system clipboard. \inmodule QtGui.
Definition: qclipboard.h:56
The QCloseEvent class contains parameters that describe a close event.
Definition: qevent.h:629
static std::shared_ptr< QColorTrcLut > fromGamma(qreal gamma)
The QCommandLineOption class defines a possible command-line option. \inmodule QtCore.
The QContextMenuEvent class contains parameters that describe a context menu event....
Definition: qevent.h:665
The QCoreApplication class provides an event loop for Qt applications without UI.
void * resolveInterface(const char *name, int revision) const
static QCoreApplication * instance()
static bool sendEvent(QObject *receiver, QEvent *event)
bool event(QEvent *) override
virtual bool compressEvent(QEvent *, QObject *receiver, QPostEventList *)
virtual bool notify(QObject *, QEvent *)
static void processEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
void applicationNameChanged()
friend class QGuiApplication
static void setAttribute(Qt::ApplicationAttribute attribute, bool on=true)
[95]
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
static bool startingUp()
QString applicationName
the name of this application
QCoreApplicationPrivate::Type application_type
static QAbstractEventDispatcher * eventDispatcher
virtual bool canQuitAutomatically()
static void initialize()
Definition: qcursor.cpp:735
static void cleanup()
Definition: qcursor.cpp:720
The QCursor class provides a mouse cursor with an arbitrary shape.
Definition: qcursor.h:81
static bool isAbsolutePath(const QString &path)
Definition: qdir.h:211
static bool setCurrent(const QString &path)
Definition: qdir.cpp:1982
static QString toNativeSeparators(const QString &pathName)
Definition: qdir.cpp:916
static QString currentPath()
Definition: qdir.cpp:2006
The QDrag class provides support for MIME-based drag and drop data transfer.
Definition: qdrag.h:58
void start() noexcept
The QEnterEvent class contains parameters that describe an enter event.
Definition: qevent.h:197
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Definition: qcoreevent.h:58
virtual void setAccepted(bool accepted)
Definition: qcoreevent.h:310
@ TabletMove
Definition: qcoreevent.h:134
@ ApplicationPaletteChange
Definition: qcoreevent.h:106
@ ApplicationDeactivate
Definition: qcoreevent.h:179
@ NonClientAreaMouseButtonDblClick
Definition: qcoreevent.h:228
@ TabletEnterProximity
Definition: qcoreevent.h:222
@ None
Definition: qcoreevent.h:71
@ FocusAboutToChange
Definition: qcoreevent.h:81
@ EnterWhatsThisMode
Definition: qcoreevent.h:183
@ ApplicationLayoutDirectionChange
Definition: qcoreevent.h:105
@ WindowBlocked
Definition: qcoreevent.h:154
@ ApplicationActivate
Definition: qcoreevent.h:177
@ WindowUnblocked
Definition: qcoreevent.h:155
@ ApplicationWindowIconChange
Definition: qcoreevent.h:103
@ FocusOut
Definition: qcoreevent.h:80
@ KeyRelease
Definition: qcoreevent.h:78
@ Leave
Definition: qcoreevent.h:83
@ MouseMove
Definition: qcoreevent.h:76
@ KeyPress
Definition: qcoreevent.h:77
@ FocusIn
Definition: qcoreevent.h:79
@ TouchCancel
Definition: qcoreevent.h:277
@ ThemeChange
Definition: qcoreevent.h:279
@ MouseButtonPress
Definition: qcoreevent.h:73
@ TouchEnd
Definition: qcoreevent.h:256
@ TouchUpdate
Definition: qcoreevent.h:255
@ TouchBegin
Definition: qcoreevent.h:254
@ NonClientAreaMouseMove
Definition: qcoreevent.h:225
@ PlatformPanel
Definition: qcoreevent.h:283
@ WindowActivate
Definition: qcoreevent.h:96
@ LanguageChange
Definition: qcoreevent.h:136
@ TabletRelease
Definition: qcoreevent.h:140
@ TabletPress
Definition: qcoreevent.h:139
@ MouseButtonDblClick
Definition: qcoreevent.h:75
@ ApplicationFontChange
Definition: qcoreevent.h:104
@ Quit
Definition: qcoreevent.h:92
@ TabletLeaveProximity
Definition: qcoreevent.h:223
@ WindowDeactivate
Definition: qcoreevent.h:97
@ NonClientAreaMouseButtonPress
Definition: qcoreevent.h:226
@ MouseButtonRelease
Definition: qcoreevent.h:74
Type type() const
Definition: qcoreevent.h:307
bool isAccepted() const
Definition: qcoreevent.h:311
The QEventPoint class provides information about a point in a QPointerEvent.
Definition: qeventpoint.h:56
The QExposeEvent class contains event parameters for expose events. \inmodule QtGui.
Definition: qevent.h:574
static QString decodeName(const QByteArray &localFileName)
Definition: qfile.h:163
The QFileOpenEvent class provides an event that will be sent when there is a request to open a file o...
Definition: qevent.h:945
const mapped_container_type & values() const noexcept
Definition: qflatmap_p.h:594
The QFocusEvent class contains event parameters for widget focus events. \inmodule QtGui.
Definition: qevent.h:520
static bool removeAllApplicationFonts()
The QFont class specifies a query for a font used for drawing text.
Definition: qfont.h:56
static void initialize()
Definition: qfont.cpp:2231
static void cleanup()
Definition: qfont.cpp:2240
The QFontMetrics class provides font metrics information.
Definition: qfontmetrics.h:56
static QObject * create(const QString &, const QString &)
The QGuiApplication class manages the GUI application's control flow and main settings.
static QFunctionPointer platformFunction(const QByteArray &function)
static void setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy policy)
static Qt::ApplicationState applicationState()
static void setQuitOnLastWindowClosed(bool quit)
static QPlatformNativeInterface * platformNativeInterface()
bool notify(QObject *, QEvent *) override
static QWindowList topLevelWindows()
static QWindow * modalWindow()
static QWindow * topLevelAt(const QPoint &pos)
static void setDesktopFileName(const QString &name)
static void setFont(const QFont &)
bool isSavingSession() const
static QWindowList allWindows()
static QClipboard * clipboard()
QScreen * primaryScreen
the primary (or default) screen of the application.
bool isSessionRestored() const
static QPalette palette()
static QObject * focusObject()
static void setPalette(const QPalette &pal)
static QCursor * overrideCursor()
bool quitOnLastWindowClosed
whether the application implicitly quits when the last window is closed.
static void sync()
static QFont font()
bool compressEvent(QEvent *, QObject *receiver, QPostEventList *) override
static QStyleHints * styleHints()
static QWindow * focusWindow()
static void changeOverrideCursor(const QCursor &)
static void setApplicationDisplayName(const QString &name)
qreal devicePixelRatio() const
void applicationDisplayNameChanged()
QString sessionKey() const
static void setLayoutDirection(Qt::LayoutDirection direction)
static QInputMethod * inputMethod()
static Qt::KeyboardModifiers keyboardModifiers()
static Qt::KeyboardModifiers queryKeyboardModifiers()
static void setDesktopSettingsAware(bool on)
QString applicationDisplayName
the user-visible name of this application
static void setOverrideCursor(const QCursor &)
bool event(QEvent *) override
static void restoreOverrideCursor()
static bool desktopSettingsAware()
QString platformName
The name of the underlying platform plugin.
QString sessionId() const
QString desktopFileName
the base name of the desktop entry for this application
Qt::LayoutDirection layoutDirection
the default layout direction for this application
static QScreen * screenAt(const QPoint &point)
static QList< QScreen * > screens()
QIcon windowIcon
the default window icon
static Qt::MouseButtons mouseButtons()
static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy()
static void setWindowIcon(const QIcon &icon)
static QPlatformIntegration * platformIntegration()
static void processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
static void setApplicationState(Qt::ApplicationState state, bool forcePropagate=false)
static QPlatformTheme * platform_theme
static QPlatformTheme * platformTheme()
QHash< QWindow *, SynthesizedMouseData > synthesizedMousePoints
static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e)
static QWindow * focus_window
QSessionManager * session_manager
bool canQuitAutomatically() override
static void updateBlockedStatus(QWindow *window)
static void processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
static void showModalWindow(QWindow *window)
static bool processNativeEvent(QWindow *window, const QByteArray &eventType, void *message, qintptr *result)
static void processPaintEvent(QWindowSystemInterfacePrivate::PaintEvent *e)
static void processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
static void hideModalWindow(QWindow *window)
static QPointer< QWindow > currentDragWindow
static Qt::MouseButtons mouse_buttons
static void processFileOpenEvent(QWindowSystemInterfacePrivate::FileOpenEvent *e)
static Qt::MouseButton mousePressButton
static struct QGuiApplicationPrivate::QLastCursorPosition lastCursorPosition
virtual QPalette basePalette() const
static QWindowList window_list
static void processScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e)
void _q_updateFocusObject(QObject *object)
static Qt::ApplicationState applicationState
static TabletPointData & tabletDevicePoint(qint64 deviceId)
static void processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e)
static void processScreenRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e)
static QString * displayName
static void processScreenGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *e)
static void processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
static void processContextMenuEvent(QWindowSystemInterfacePrivate::ContextMenuEvent *e)
static QPlatformIntegration * platform_integration
static QList< QScreen * > screen_list
static QPalette * app_pal
static Qt::KeyboardModifiers modifier_buttons
static void processApplicationTermination(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
static void resetCachedDevicePixelRatio()
static void processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *e)
static void processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e)
static QWindow * currentMousePressWindow
static QString * desktopFileName
static QInputDeviceManager * inputDeviceManager()
static QList< QObject * > generic_plugin_list
QPixmap getPixmapCursor(Qt::CursorShape cshape)
static void processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
virtual bool isWindowBlocked(QWindow *window, QWindow **blockingWindow=nullptr) const
const QColorTrcLut * colorProfileForA8Text()
static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
static void processScreenLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e)
static QStyleHints * styleHints
static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e)
static void captureGlobalModifierState(QEvent *e)
static QClipboard * qt_clipboard
virtual void handlePaletteChanged(const char *className=nullptr)
static void processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *e)
static void processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
static QString styleOverride
static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e)
static void processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
void createEventDispatcher() override
QGuiApplicationPrivate(int &argc, char **argv, int flags)
static QList< TabletPointData > tabletDevicePoints
static bool sendQWindowEventToQPlatformWindow(QWindow *window, QEvent *event)
static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy
static void processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
virtual void notifyActiveWindowChange(QWindow *previous)
static bool setPalette(const QPalette &palette)
virtual void notifyLayoutDirectionChange()
static bool quitOnLastWindowClosed
void eventDispatcherReady() override
const QColorTrcLut * colorProfileForA32Text()
static void processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
static void processThemeChanged(QWindowSystemInterfacePrivate::ThemeChangeEvent *tce)
virtual void notifyThemeChanged()
static QWindow * currentMouseWindow
static void applyWindowGeometrySpecificationTo(QWindow *window)
static QString * platform_name
static void processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *e)
virtual void notifyWindowIconChanged()
The QHash::const_iterator class provides an STL-style const iterator for QHash.
Definition: qhash.h:1088
static void updateHighDpiScaling()
static void initHighDpiScaling()
The QIcon class provides scalable icons in different modes and states.
Definition: qicon.h:56
static QIcon fromTheme(const QString &name)
Definition: qicon.cpp:1311
Capabilities capabilities
Definition: qinputdevice.h:58
static bool isRegistered(const QInputDevice *dev)
The QInputEvent class is the base class for events that describe user input.
Definition: qevent.h:76
virtual void setTimestamp(quint64 timestamp)
Definition: qevent.h:88
Qt::KeyboardModifiers modifiers() const
Definition: qevent.h:85
The QInputMethod class provides access to the active text input method. \inmodule QtGui.
Definition: qinputmethod.h:55
static bool objectAcceptsInputMethod(QObject *object)
The QKeyEvent class describes a key event.
Definition: qevent.h:471
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
The QLibrary class loads shared libraries at runtime.
Definition: qlibrary.h:53
bool load()
Definition: qlibrary.cpp:810
QFunctionPointer resolve(const char *symbol)
Definition: qlibrary.cpp:1024
QString errorString() const
Definition: qlibrary.cpp:1097
static bool isDebugBuild()
static QStringList platformPluginArguments(const QString &platformName)
bool isEmpty() const noexcept
Definition: qlist.h:418
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
value_type takeFirst()
Definition: qlist.h:564
qsizetype count() const noexcept
Definition: qlist.h:415
void prepend(rvalue_ref t)
Definition: qlist.h:484
T & first()
Definition: qlist.h:643
void append(parameter_type t)
Definition: qlist.h:469
void clear()
Definition: qlist.h:445
The QMimeData class provides a container for data that records information about its MIME type.
Definition: qmimedata.h:52
The QMouseEvent class contains parameters that describe a mouse event.
Definition: qevent.h:231
The QMoveEvent class contains event parameters for move events. \inmodule QtGui.
Definition: qevent.h:558
static QWindow * window(const QEventPoint &p)
static Q_GUI_EXPORT void update(const QEventPoint &from, QEventPoint &to)
static Q_GUI_EXPORT void setTimestamp(QEventPoint &p, ulong t)
static QMutableSinglePointEvent * from(QSinglePointEvent *e)
Definition: qevent_p.h:93
void setDoubleClick(bool d=true)
Definition: qevent_p.h:101
void setTarget(QObject *target)
Definition: qevent_p.h:77
The QMutex class provides access serialization between threads.
Definition: qmutex.h:285
The QNativeGestureEvent class contains parameters that describe a gesture event. \inmodule QtGui.
uint unused
Definition: qobject.h:110
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
Definition: qobject.cpp:3048
The QOpenGLContext class represents a native OpenGL context, enabling OpenGL rendering on a QSurface.
void setFormat(const QSurfaceFormat &format)
The QPaintEvent class contains event parameters for paint events. \inmodule QtGui.
Definition: qevent.h:539
The QPalette class contains color groups for each widget state.
Definition: qpalette.h:55
void setResolveMask(ResolveMask mask)
Definition: qpalette.cpp:964
ResolveMask resolveMask() const
Definition: qpalette.cpp:956
static void clear()
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
static Capabilities capabilities()
virtual void setFocusObject(QObject *object)
static void setInputMethodAccepted(bool accepted)
static QPlatformIntegration * create(const QString &name, const QStringList &args, int &argc, char **argv, const QString &platformPluginPath=QString())
static QStringList keys(const QString &platformPluginPath=QString())
virtual QStringList themeNames() const
virtual QAbstractEventDispatcher * createEventDispatcher() const =0
virtual bool hasCapability(Capability cap) const
virtual QPlatformInputContext * inputContext() const
virtual void setApplicationIcon(const QIcon &icon) const
virtual QPlatformTheme * createPlatformTheme(const QString &name) const
virtual void quit() const
virtual QPlatformCursor * cursor() const
static QPlatformTheme * create(const QString &key, const QString &platformPluginPath=QString())
virtual void showPlatformMenuBar()
virtual const QPalette * palette(Palette type=SystemPalette) const
virtual QVariant themeHint(ThemeHint hint) const
virtual bool windowEvent(QEvent *event)
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
constexpr qreal x() const noexcept
Definition: qpoint.h:361
constexpr qreal y() const noexcept
Definition: qpoint.h:366
constexpr QPoint toPoint() const
Definition: qpoint.h:420
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:52
constexpr void setY(int y) noexcept
Definition: qpoint.h:170
constexpr void setX(int x) noexcept
Definition: qpoint.h:165
void setTimestamp(quint64 timestamp) override
Definition: qevent.cpp:362
void clearPassiveGrabbers(const QEventPoint &point)
Definition: qevent.cpp:457
void setExclusiveGrabber(const QEventPoint &point, QObject *exclusiveGrabber)
Definition: qevent.cpp:393
T * data() const
Definition: qpointer.h:76
bool isNull() const
Definition: qpointer.h:87
The QPointingDevice class describes a device from which mouse, touch or tablet events originate.
QPointingDeviceUniqueId uniqueId
QWindow * firstActiveWindow() const
static QPointingDevicePrivate * get(QPointingDevice *q)
EventPointData * queryPointById(int id) const
EventPointData * pointById(int id) const
Q_GADGETqint64 numericId
the numeric unique ID of the token represented by a touchpoint
Definition: qthread_p.h:98
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
constexpr int height() const noexcept
Definition: qrect.h:266
constexpr int bottom() const noexcept
Definition: qrect.h:209
constexpr QPoint topLeft() const noexcept
Definition: qrect.h:248
constexpr int top() const noexcept
Definition: qrect.h:203
constexpr int left() const noexcept
Definition: qrect.h:200
constexpr int x() const noexcept
Definition: qrect.h:212
constexpr QSize size() const noexcept
Definition: qrect.h:269
constexpr int width() const noexcept
Definition: qrect.h:263
constexpr int y() const noexcept
Definition: qrect.h:215
constexpr int right() const noexcept
Definition: qrect.h:206
The QResizeEvent class contains event parameters for resize events. \inmodule QtGui.
Definition: qevent.h:612
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition: qscreen.h:68
qreal devicePixelRatio
the screen's ratio between physical pixels and device-independent pixels
Definition: qscreen.h:95
QList< QScreen * > virtualSiblings() const
Definition: qscreen.cpp:447
QPlatformScreen * handle() const
Definition: qscreen.cpp:177
The QSessionManager class provides access to the session manager.
Definition: qset.h:54
const_iterator constBegin() const noexcept
Definition: qset.h:175
const_iterator constEnd() const noexcept
Definition: qset.h:179
iterator insert(const T &value)
Definition: qset.h:191
Qt::MouseButton button() const
Definition: qevent.h:147
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
constexpr int height() const noexcept
Definition: qsize.h:160
constexpr int width() const noexcept
Definition: qsize.h:157
static QString locate(StandardLocation type, const QString &fileName, LocateOptions options=LocateFile)
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString fromLatin1(QByteArrayView ba)
Definition: qstring.cpp:5488
const ushort * utf16() const
Definition: qstring.cpp:6491
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:7672
static QString fromLocal8Bit(QByteArrayView ba)
Definition: qstring.cpp:5563
QString mid(qsizetype position, qsizetype n=-1) const
Definition: qstring.cpp:4994
QString section(QChar sep, qsizetype start, qsizetype end=-1, SectionFlags flags=SectionDefault) const
Definition: qstring.h:1272
const QChar at(qsizetype i) const
Definition: qstring.h:1212
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:5143
bool isEmpty() const
Definition: qstring.h:1216
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
QString left(qsizetype n) const
Definition: qstring.cpp:4951
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:4197
The QStringList class provides a list of strings.
The QStyleHints class contains platform specific hints and settings. \inmodule QtGui.
Definition: qstylehints.h:53
int mouseDoubleClickInterval
the time limit in milliseconds that distinguishes a double click from two consecutive mouse clicks.
Definition: qstylehints.h:62
static QSurfaceFormat defaultFormat()
QEventPoint & point(int touchId)
The QTouchEvent class contains parameters that describe a touch event.
Definition: qevent.h:1020
bool isEmpty() const
void append(const T &t)
bool contains(const AT &t) const
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
int toInt(bool *ok=nullptr) const
Definition: qvariant.cpp:1833
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
The QWindow class represents a window in the underlying windowing system.
Definition: qwindow.h:99
Qt::WindowFlags flags
the window flags of the window
Definition: qwindow.h:115
Qt::WindowModality modality
the modality of the window
Definition: qwindow.h:114
virtual void processSafeAreaMarginsChanged()
Definition: qwindow_p.h:116
static QWindowPrivate * get(QWindow *window)
Definition: qwindow_p.h:125
The QWindowStateChangeEvent class provides the window state before a window state change.
Definition: qevent.h:999
static bool flushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
static void deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags)
static bool handleCloseEvent(QWindow *window)
static bool handleShortcutEvent(QWindow *window, ulong timestamp, int k, Qt::KeyboardModifiers mods, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString &text=QString(), bool autorep=false, ushort count=1)
static QList< QEventPoint > fromNativeTouchPoints(const QList< QWindowSystemInterface::TouchPoint > &points, const QWindow *window, QEvent::Type *type=nullptr)
QPushButton * button
[2]
QCursor cursor
double pi
[0]
double e
QList< QVariant > arguments
direction
fontMetrics
palette
else opt state
[0]
#define local
Definition: zutil.h:30
#define true
Definition: ftrandom.c:51
auto it unsigned count const
Definition: hb-iter.hh:848
T toNativePixels(const T &value, const C *context)
T fromNativePixels(const T &value, const C *context)
Lock qt_scoped_lock(Mutex &mutex)
Definition: qlocking_p.h:94
Lock qt_unique_lock(Mutex &mutex)
Definition: qlocking_p.h:100
void mousePress(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey=Qt::KeyboardModifiers(), QPoint pos=QPoint(), int delay=-1)
Definition: qtestmouse.h:159
QTouchEventSequence touchEvent(QWindow *window, QPointingDevice *device, bool autoCommit=true)
Definition: qtesttouch.h:78
Corner
Definition: qnamespace.h:1287
@ BottomLeftCorner
Definition: qnamespace.h:1290
@ TopRightCorner
Definition: qnamespace.h:1289
@ TopLeftCorner
Definition: qnamespace.h:1288
@ BottomRightCorner
Definition: qnamespace.h:1291
MouseButton
Definition: qnamespace.h:81
@ LeftButton
Definition: qnamespace.h:83
@ MaxMouseButton
Definition: qnamespace.h:116
@ NoButton
Definition: qnamespace.h:82
WindowModality
Definition: qnamespace.h:1563
@ WindowModal
Definition: qnamespace.h:1565
@ ApplicationModal
Definition: qnamespace.h:1566
LayoutDirection
Definition: qnamespace.h:1462
@ LeftToRight
Definition: qnamespace.h:1463
@ LayoutDirectionAuto
Definition: qnamespace.h:1466
@ RightToLeft
Definition: qnamespace.h:1464
@ MouseEventSynthesizedByQt
Definition: qnamespace.h:1706
@ MouseEventNotSynthesized
Definition: qnamespace.h:1704
ScreenOrientation
Definition: qnamespace.h:296
CursorShape
Definition: qnamespace.h:1176
@ gray
Definition: qnamespace.h:64
@ Key_Menu
Definition: qnamespace.h:748
@ Key_Back
Definition: qnamespace.h:867
@ NoModifier
Definition: qnamespace.h:1074
@ AA_SynthesizeMouseForUnhandledTabletEvents
Definition: qnamespace.h:484
@ AA_DontShowShortcutsInContextMenus
Definition: qnamespace.h:488
@ AA_ShareOpenGLContexts
Definition: qnamespace.h:472
@ AA_SetPalette
Definition: qnamespace.h:473
@ AA_SynthesizeMouseForUnhandledTouchEvents
Definition: qnamespace.h:462
@ AA_SynthesizeTouchForUnhandledMouseEvents
Definition: qnamespace.h:461
DropAction
Definition: qnamespace.h:1484
@ IgnoreAction
Definition: qnamespace.h:1490
ApplicationState
Definition: qnamespace.h:287
@ ApplicationActive
Definition: qnamespace.h:291
@ ApplicationInactive
Definition: qnamespace.h:290
HighDpiScaleFactorRoundingPolicy
Definition: qnamespace.h:1723
@ SkipEmptyParts
Definition: qnamespace.h:153
@ Desktop
Definition: qnamespace.h:240
@ ToolTip
Definition: qnamespace.h:238
@ Popup
Definition: qnamespace.h:236
FocusReason
Definition: qnamespace.h:1360
@ PopupFocusReason
Definition: qnamespace.h:1365
@ OtherFocusReason
Definition: qnamespace.h:1368
@ ActiveWindowFocusReason
Definition: qnamespace.h:1364
#define QString()
Definition: parse-defines.h:51
int PRIV() strcmp(PCRE2_SPTR str1, PCRE2_SPTR str2)
int PRIV() strncmp(PCRE2_SPTR str1, PCRE2_SPTR str2, size_t len)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if
set set set set set set set macro pixldst1 op
void
Definition: png.h:1080
#define Q_UNLIKELY(x)
#define QT_WARNING_POP
#define QT_WARNING_DISABLE_DEPRECATED
#define Q_UNREACHABLE()
#define QT_WARNING_PUSH
#define qApp
EGLOutputLayerEXT EGLint EGLAttrib value
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition: qfloat16.h:233
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition: qfloat16.h:249
bool qIsNaN(qfloat16 f) noexcept
Definition: qfloat16.h:221
bool qIsInf(qfloat16 f) noexcept
Definition: qfloat16.h:220
unsigned long ulong
Definition: qglobal.h:335
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
long long qint64
Definition: qglobal.h:298
ptrdiff_t qintptr
Definition: qglobal.h:309
Q_CORE_EXPORT void qt_call_post_routines()
Q_GUI_EXPORT bool qt_is_tty_app
void qRegisterGuiVariant()
#define Q_WINDOW_GEOMETRY_SPECIFICATION_INITIALIZER
@ MouseSourceMaskSrc
@ MouseCapsMask
@ MouseFlagsCapsMask
@ MouseSourceMaskDst
@ MouseFlagsShift
@ MouseSourceShift
Q_LOGGING_CATEGORY(lcQpaPluginLoading, "qt.qpa.plugin")
#define CHECK_QAPP_INSTANCE(...)
ApplicationResourceFlags
@ ApplicationFontExplicitlySet
void qt_cleanupFontDatabase()
#define qGuiApp
void qRegisterGuiGetInterpolator()
QPair< qreal, qreal > QDpi
#define qCritical
Definition: qlogging.h:180
#define qWarning
Definition: qlogging.h:179
#define qFatal
Definition: qlogging.h:181
#define qCInfo(category,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define QT_NATIVE_INTERFACE_RETURN_IF(NativeInterface, baseType)
#define SLOT(a)
Definition: qobjectdefs.h:87
#define SIGNAL(a)
Definition: qobjectdefs.h:88
GLenum type
Definition: qopengl.h:270
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: qopengl.h:270
void qt_gl_set_global_share_context(QOpenGLContext *context)
QOpenGLContext * qt_gl_global_share_context()
const GLfloat * m
GLboolean r
[2]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint object
[3]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei width
GLbitfield flags
GLuint name
struct _cl_event * event
Definition: qopenglext.h:2998
GLfixed GLfixed GLint GLint GLfixed points
Definition: qopenglext.h:5206
const GLubyte * c
Definition: qopenglext.h:12701
GLuint GLenum * rate
Definition: qopenglext.h:11002
GLdouble GLdouble GLdouble GLdouble q
Definition: qopenglext.h:259
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
#define Q_ASSERT_X(cond, x, msg)
Definition: qrandom.cpp:85
QPointF qAbs(const QPointF &p)
Definition: qscroller.cpp:119
SSL_CTX int(*) void arg)
#define QStringLiteral(str)
#define tr(X)
#define emit
Definition: qtmetamacros.h:85
#define Q_TRACE_SCOPE(x,...)
Definition: qtrace_p.h:138
Q_GUI_EXPORT QWindowPrivate * qt_window_private(QWindow *window)
Definition: qwindow.cpp:2855
bool testFlag(MaskType mask, FlagType flag)
const char className[16]
[1]
Definition: qwizard.cpp:135
Q_UNUSED(salary)
[21]
QScreen * screen
[1]
Definition: main.cpp:76
QThreadPool pool
QIcon icon
[15]
QObject::connect nullptr
setFont(font)
aWidget window() -> setWindowTitle("New Window Title")
[2]
QSizePolicy policy
QDBusArgument argument
QStringList list
[0]
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53
void applyTo(QWindow *window) const
static QWindowGeometrySpecification fromArgument(const QByteArray &a)