1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qguiapplication.h"
44 #include "private/qguiapplication_p.h"
45 #include "private/qplatformintegrationfactory_qpa_p.h"
46 #include "private/qevent_p.h"
48 #include "qplatformfontdatabase_qpa.h"
49 #include "qplatformwindow_qpa.h"
50 #include "qplatformnativeinterface_qpa.h"
52 #include <QtCore/QAbstractEventDispatcher>
53 #include <QtCore/private/qcoreapplication_p.h>
54 #include <QtCore/private/qabstracteventdispatcher_p.h>
55 #include <QtCore/qmutex.h>
56 #include <QtCore/private/qthread_p.h>
61 #include <QtGui/QPlatformIntegration>
62 #include <QtGui/QGenericPluginFactory>
63 #include <QtGui/qstylehints.h>
64 #include <QtGui/qinputpanel.h>
66 #include <QWindowSystemInterface>
67 #include "private/qwindowsysteminterface_qpa_p.h"
68 #include "private/qwindow_p.h"
69 #include "private/qkeymapper_p.h"
70 #include "private/qcursor_p.h"
71 #include "private/qdnd_p.h"
73 #include "qplatformcursor_qpa.h"
76 #include <QtGui/QPixmap>
78 #ifndef QT_NO_CLIPBOARD
79 #include <QtGui/QClipboard>
84 Q_GUI_EXPORT bool qt_is_gui_used = true;
86 Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton;
87 Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
89 QPointF QGuiApplicationPrivate::lastCursorPosition(0.0, 0.0);
91 QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
93 QList<QObject *> QGuiApplicationPrivate::generic_plugin_list;
95 bool QGuiApplicationPrivate::app_do_modal = false;
97 QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette
99 Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
100 ulong QGuiApplicationPrivate::mousePressTime = 0;
101 Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
102 int QGuiApplicationPrivate::mousePressX = 0;
103 int QGuiApplicationPrivate::mousePressY = 0;
104 int QGuiApplicationPrivate::mouse_double_click_distance = 5;
106 bool QGuiApplicationPrivate::quitOnLastWindowClosed = true;
108 static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
109 static bool force_reverse = false;
111 QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
113 #ifndef QT_NO_CLIPBOARD
114 QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
117 QList<QScreen *> QGuiApplicationPrivate::screen_list;
119 QWindowList QGuiApplicationPrivate::window_list;
120 QWindow *QGuiApplicationPrivate::focus_window = 0;
122 Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
123 QFont *QGuiApplicationPrivate::app_font = 0;
125 extern int qRegisterGuiVariant();
126 extern int qUnregisterGuiVariant();
127 extern void qInitDrawhelperAsm();
128 extern void qInitImageConversions();
130 static bool qt_detectRTLLanguage()
132 return force_reverse ^
133 (QCoreApplication::tr("QT_LAYOUT_DIRECTION",
134 "Translate this string to the string 'LTR' in left-to-right"
135 " languages or to 'RTL' in right-to-left languages (such as Hebrew"
136 " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
140 QGuiApplication::QGuiApplication(int &argc, char **argv, int flags)
141 : QCoreApplication(*new QGuiApplicationPrivate(argc, argv, flags))
145 QCoreApplicationPrivate::eventDispatcher->startingUp();
148 QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p)
149 : QCoreApplication(p)
154 QGuiApplication::~QGuiApplication()
156 Q_D(QGuiApplication);
157 // flush clipboard contents
158 if (QGuiApplicationPrivate::qt_clipboard) {
159 QEvent event(QEvent::Clipboard);
160 QGuiApplication::sendEvent(QGuiApplicationPrivate::qt_clipboard, &event);
163 d->eventDispatcher->closingDown();
164 d->eventDispatcher = 0;
166 delete QGuiApplicationPrivate::qt_clipboard;
167 QGuiApplicationPrivate::qt_clipboard = 0;
169 delete QGuiApplicationPrivate::app_pal;
170 QGuiApplicationPrivate::app_pal = 0;
172 qUnregisterGuiVariant();
175 d->cursor_list.clear();
179 QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags)
180 : QCoreApplicationPrivate(argc, argv, flags),
187 QWindow *QGuiApplication::focusWindow()
189 return QGuiApplicationPrivate::focus_window;
192 QWindowList QGuiApplication::topLevelWindows()
194 return QGuiApplicationPrivate::window_list;
197 QScreen *QGuiApplication::primaryScreen()
199 if (QGuiApplicationPrivate::screen_list.isEmpty())
201 return QGuiApplicationPrivate::screen_list.at(0);
204 QList<QScreen *> QGuiApplication::screens()
206 return QGuiApplicationPrivate::screen_list;
209 QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
211 QList<QScreen *> screens = QGuiApplication::screens();
212 QList<QScreen *>::const_iterator screen = screens.constBegin();
213 QList<QScreen *>::const_iterator end = screens.constEnd();
215 while (screen != end) {
216 if ((*screen)->geometry().contains(pos))
217 return (*screen)->handle()->topLevelAt(pos);
224 static void init_platform(const QString &pluginArgument, const QString &platformPluginPath)
226 // Split into platform name and arguments
228 QStringList arguments;
229 foreach (const QString &token, pluginArgument.split(QLatin1Char(':'))) {
230 if (name.isEmpty()) {
233 arguments.push_back(token);
237 if (name.isEmpty()) {
238 const QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
239 #if defined(Q_OS_MAC)
240 const QString defaultPlatform = QLatin1String("cocoa");
241 #elif defined (Q_OS_WIN)
242 const QString defaultPlatform = QLatin1String("windows");
243 #elif !defined (QT_NO_XCB)
244 const QString defaultPlatform = QLatin1String("xcb");
245 #elif !defined (QT_NO_WAYLAND)
246 const QString defaultPlatform = QLatin1String("wayland");
248 const QString defaultPlatform = QLatin1String("minimal");
250 if (keys.contains(defaultPlatform)) {
251 qWarning("No platform plugin argument was specified, defaulting to \"%s\".",
252 qPrintable(defaultPlatform));
253 name = defaultPlatform;
255 qFatal("No platform plugin argument was specified and the default plugin \"%s\" is not available",
256 qPrintable(defaultPlatform));
260 QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
261 if (!QGuiApplicationPrivate::platform_integration) {
262 QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
263 QString fatalMessage =
264 QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
265 foreach(const QString &key, keys) {
266 fatalMessage.append(key + QLatin1Char('\n'));
268 qFatal("%s", fatalMessage.toLocal8Bit().constData());
271 // Set arguments as dynamic properties on the native interface as
272 // boolean 'foo' or strings: 'foo=bar'
273 if (!arguments.isEmpty()) {
274 QObject *nativeInterface = QGuiApplicationPrivate::platform_integration->nativeInterface();
275 foreach (const QString &argument, arguments) {
276 const int equalsPos = argument.indexOf(QLatin1Char('='));
277 const QByteArray name =
278 equalsPos != -1 ? argument.left(equalsPos).toAscii() : argument.toAscii();
279 const QVariant value =
280 equalsPos != -1 ? QVariant(argument.mid(equalsPos + 1)) : QVariant(true);
281 nativeInterface->setProperty(name.constData(), value);
286 static void init_plugins(const QList<QByteArray> &pluginList)
288 for (int i = 0; i < pluginList.count(); ++i) {
289 QByteArray pluginSpec = pluginList.at(i);
290 qDebug() << "init_plugins" << i << pluginSpec;
291 int colonPos = pluginSpec.indexOf(':');
294 plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec), QString());
296 plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
297 QLatin1String(pluginSpec.mid(colonPos+1)));
298 qDebug() << " created" << plugin;
300 QGuiApplicationPrivate::generic_plugin_list.append(plugin);
304 void QGuiApplicationPrivate::createPlatformIntegration()
306 Q_Q(QGuiApplication);
308 // Use the Qt menus by default. Platform plugins that
309 // want to enable a native menu implementation can clear
311 q->setAttribute(Qt::AA_DontUseNativeMenuBar, true);
313 // Load the platform integration
314 QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
315 QByteArray platformName;
316 #ifdef QT_QPA_DEFAULT_PLATFORM_NAME
317 platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
319 QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
320 if (!platformNameEnv.isEmpty()) {
321 platformName = platformNameEnv;
324 // Get command line params
326 int j = argc ? 1 : 0;
327 for (int i=1; i<argc; i++) {
328 if (argv[i] && *argv[i] != '-') {
332 QByteArray arg = argv[i];
333 if (arg == "-platformpluginpath") {
335 platformPluginPath = QLatin1String(argv[i]);
336 } else if (arg == "-platform") {
338 platformName = argv[i];
349 init_platform(QLatin1String(platformName), platformPluginPath);
353 void QGuiApplicationPrivate::createEventDispatcher()
355 if (platform_integration == 0)
356 createPlatformIntegration();
358 if (!eventDispatcher) {
359 QAbstractEventDispatcher *eventDispatcher = platform_integration->guiThreadEventDispatcher();
360 setEventDispatcher(eventDispatcher);
364 void QGuiApplicationPrivate::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
366 Q_Q(QGuiApplication);
368 if (!QCoreApplicationPrivate::eventDispatcher) {
369 QCoreApplicationPrivate::eventDispatcher = eventDispatcher;
370 QCoreApplicationPrivate::eventDispatcher->setParent(q);
371 threadData->eventDispatcher = eventDispatcher;
376 void QGuiApplicationPrivate::init()
378 QList<QByteArray> pluginList;
379 // Get command line params
381 int j = argc ? 1 : 0;
382 for (int i=1; i<argc; i++) {
383 if (argv[i] && *argv[i] != '-') {
387 QByteArray arg = argv[i];
388 if (arg == "-plugin") {
390 pluginList << argv[i];
391 } else if (arg == "-reverse") {
392 force_reverse = true;
393 QGuiApplication::setLayoutDirection(Qt::RightToLeft);
404 if (platform_integration == 0)
405 createPlatformIntegration();
407 init_plugins(pluginList);
409 // Set up which span functions should be used in raster engine...
410 qInitDrawhelperAsm();
411 // and QImage conversion functions
412 qInitImageConversions();
417 QCursorData::initialize();
420 // trigger registering of QVariant's GUI types
421 qRegisterGuiVariant();
423 is_app_running = true;
426 QGuiApplicationPrivate::~QGuiApplicationPrivate()
428 is_app_closing = true;
429 is_app_running = false;
431 for (int i = 0; i < generic_plugin_list.count(); ++i)
432 delete generic_plugin_list.at(i);
433 generic_plugin_list.clear();
438 QCursorData::cleanup();
441 layout_direction = Qt::LeftToRight;
448 delete platform_integration;
449 platform_integration = 0;
454 QCursor *overrideCursor();
455 void setOverrideCursor(const QCursor &);
456 void changeOverrideCursor(const QCursor &);
457 void restoreOverrideCursor();
461 static QFont font(const QWidget*);
462 static QFont font(const char *className);
463 static void setFont(const QFont &, const char* className = 0);
464 static QFontMetrics fontMetrics();
466 #ifndef QT_NO_CLIPBOARD
467 static QClipboard *clipboard();
471 Qt::KeyboardModifiers QGuiApplication::keyboardModifiers()
473 return QGuiApplicationPrivate::modifier_buttons;
476 Qt::MouseButtons QGuiApplication::mouseButtons()
478 return QGuiApplicationPrivate::mouse_buttons;
481 QPlatformNativeInterface *QGuiApplication::platformNativeInterface()
483 QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
484 return pi->nativeInterface();
487 int QGuiApplication::exec()
489 return QCoreApplication::exec();
492 bool QGuiApplication::notify(QObject *object, QEvent *event)
494 return QCoreApplication::notify(object, event);
497 bool QGuiApplication::event(QEvent *e)
499 if(e->type() == QEvent::LanguageChange) {
500 setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
502 return QCoreApplication::event(e);
505 bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
507 return QCoreApplication::compressEvent(event, receiver, postedEvents);
510 void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
513 case QWindowSystemInterfacePrivate::Mouse:
514 QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
516 case QWindowSystemInterfacePrivate::Wheel:
517 QGuiApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
519 case QWindowSystemInterfacePrivate::Key:
520 QGuiApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
522 case QWindowSystemInterfacePrivate::Touch:
523 QGuiApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
525 case QWindowSystemInterfacePrivate::GeometryChange:
526 QGuiApplicationPrivate::processGeometryChangeEvent(static_cast<QWindowSystemInterfacePrivate::GeometryChangeEvent*>(e));
528 case QWindowSystemInterfacePrivate::Enter:
529 QGuiApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
531 case QWindowSystemInterfacePrivate::Leave:
532 QGuiApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
534 case QWindowSystemInterfacePrivate::ActivatedWindow:
535 QGuiApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
537 case QWindowSystemInterfacePrivate::WindowStateChanged:
538 QGuiApplicationPrivate::processWindowStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowStateChangedEvent *>(e));
540 case QWindowSystemInterfacePrivate::Close:
541 QGuiApplicationPrivate::processCloseEvent(
542 static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
544 case QWindowSystemInterfacePrivate::ScreenOrientation:
545 QGuiApplicationPrivate::reportScreenOrientationChange(
546 static_cast<QWindowSystemInterfacePrivate::ScreenOrientationEvent *>(e));
548 case QWindowSystemInterfacePrivate::ScreenGeometry:
549 QGuiApplicationPrivate::reportGeometryChange(
550 static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
552 case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
553 QGuiApplicationPrivate::reportAvailableGeometryChange(
554 static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
556 case QWindowSystemInterfacePrivate::Map:
557 QGuiApplicationPrivate::processMapEvent(static_cast<QWindowSystemInterfacePrivate::MapEvent *>(e));
559 case QWindowSystemInterfacePrivate::Unmap:
560 QGuiApplicationPrivate::processUnmapEvent(static_cast<QWindowSystemInterfacePrivate::UnmapEvent *>(e));
562 case QWindowSystemInterfacePrivate::Expose:
563 QGuiApplicationPrivate::processExposeEvent(static_cast<QWindowSystemInterfacePrivate::ExposeEvent *>(e));
566 qWarning() << "Unknown user input event type:" << e->type;
571 void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
575 Qt::MouseButtons stateChange = e->buttons ^ buttons;
576 if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
577 QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
578 new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons, e->modifiers);
579 QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
580 stateChange = Qt::NoButton;
583 QWindow *window = e->window.data();
586 window = QGuiApplication::topLevelAt(e->globalPos.toPoint());
588 QPointF localPoint = e->localPos;
589 QPointF globalPoint = e->globalPos;
591 Qt::MouseButton button = Qt::NoButton;
593 if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
594 type = QEvent::MouseMove;
595 QGuiApplicationPrivate::lastCursorPosition = globalPoint;
596 if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
597 qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
598 mousePressButton = Qt::NoButton;
600 else { // check to see if a new button has been pressed/released
601 for (int check = Qt::LeftButton;
602 check <= Qt::XButton2;
603 check = check << 1) {
604 if (check & stateChange) {
605 button = Qt::MouseButton(check);
609 if (button == Qt::NoButton) {
610 // Ignore mouse events that don't change the current state
613 buttons = e->buttons;
614 if (button & e->buttons) {
615 if ((e->timestamp - mousePressTime) < static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval()) &&
616 button == mousePressButton) {
617 type = QEvent::MouseButtonDblClick;
618 mousePressButton = Qt::NoButton;
621 type = QEvent::MouseButtonPress;
622 mousePressTime = e->timestamp;
623 mousePressButton = button;
624 const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
625 mousePressX = point.x();
626 mousePressY = point.y();
630 type = QEvent::MouseButtonRelease;
635 QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
636 ev.setTimestamp(e->timestamp);
638 QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
639 for (int i = 0; i < cursors.count(); ++i)
641 cursors.at(i).data()->pointerEvent(ev);
643 QGuiApplication::sendSpontaneousEvent(window, &ev);
649 //### there's a lot of duplicated logic here -- refactoring required!
651 void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
656 QPointF globalPoint = e->globalPos;
657 QGuiApplicationPrivate::lastCursorPosition = globalPoint;
659 QWindow *window = e->window.data();
662 QWheelEvent ev(e->localPos, e->globalPos, e->delta, buttons, e->modifiers,
664 ev.setTimestamp(e->timestamp);
665 QGuiApplication::sendSpontaneousEvent(window, &ev);
672 // Remember, Qt convention is: keyboard state is state *before*
674 void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
676 QWindow *window = e->window.data();
678 window = QGuiApplication::activeWindow();
682 QObject *target = window;
684 if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) {
685 QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount,
686 e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers);
687 ev.setTimestamp(e->timestamp);
688 QGuiApplication::sendSpontaneousEvent(target, &ev);
690 QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
691 ev.setTimestamp(e->timestamp);
692 QGuiApplication::sendSpontaneousEvent(target, &ev);
696 void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
701 QEvent event(QEvent::Enter);
702 QCoreApplication::sendSpontaneousEvent(e->enter.data(), &event);
705 void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
710 QEvent event(QEvent::Leave);
711 QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event);
714 void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
719 QWindow *previous = QGuiApplicationPrivate::focus_window;
720 QGuiApplicationPrivate::focus_window = e->activated.data();
722 if (previous == QGuiApplicationPrivate::focus_window)
726 QFocusEvent focusOut(QEvent::FocusOut);
727 QCoreApplication::sendSpontaneousEvent(previous, &focusOut);
730 QFocusEvent focusIn(QEvent::FocusIn);
731 QCoreApplication::sendSpontaneousEvent(QGuiApplicationPrivate::focus_window, &focusIn);
734 self->notifyActiveWindowChange(previous);
737 void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
739 if (QWindow *window = wse->window.data()) {
740 QWindowStateChangeEvent e(window->windowState());
741 window->d_func()->windowState = wse->newState;
742 QGuiApplication::sendSpontaneousEvent(window, &e);
746 void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
751 QWindow *window = e->tlw.data();
755 QRect newRect = e->newGeometry;
756 QRect cr = window->d_func()->geometry;
758 bool isResize = cr.size() != newRect.size();
759 bool isMove = cr.topLeft() != newRect.topLeft();
761 window->d_func()->geometry = newRect;
763 if (isResize || window->d_func()->resizeEventPending) {
764 QResizeEvent e(newRect.size(), cr.size());
765 QGuiApplication::sendSpontaneousEvent(window, &e);
767 window->d_func()->resizeEventPending = false;
772 QMoveEvent e(newRect.topLeft(), cr.topLeft());
773 QGuiApplication::sendSpontaneousEvent(window, &e);
777 void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
779 if (e->window.isNull())
783 QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
786 void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
788 QWindow *window = e->window.data();
789 QGuiApplicationPrivate *d = self;
790 typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
791 QHash<QWindow *, StatesAndTouchPoints> windowsNeedingEvents;
793 for (int i = 0; i < e->points.count(); ++i) {
794 QTouchEvent::TouchPoint touchPoint = e->points.at(i);
795 // explicitly detach from the original touch point that we got, so even
796 // if the touchpoint structs are reused, we will make a copy that we'll
797 // deliver to the user (which might want to store the struct for later use).
798 touchPoint.d = touchPoint.d->detach();
801 QWeakPointer<QWindow> w;
802 QTouchEvent::TouchPoint previousTouchPoint;
803 switch (touchPoint.state()) {
804 case Qt::TouchPointPressed:
805 if (e->devType == QTouchEvent::TouchPad) {
806 // on touch-pads, send all touch points to the same widget
807 w = d->windowForTouchPointId.isEmpty()
808 ? QWeakPointer<QWindow>()
809 : d->windowForTouchPointId.constBegin().value();
813 // determine which window this event will go to
815 window = QGuiApplication::topLevelAt(touchPoint.screenPos().toPoint());
821 d->windowForTouchPointId[touchPoint.id()] = w;
822 touchPoint.d->startScreenPos = touchPoint.screenPos();
823 touchPoint.d->lastScreenPos = touchPoint.screenPos();
824 touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
825 touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
826 if (touchPoint.pressure() < qreal(0.))
827 touchPoint.d->pressure = qreal(1.);
829 d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
832 case Qt::TouchPointReleased:
833 w = d->windowForTouchPointId.take(touchPoint.id());
836 previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
837 touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
838 touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
839 touchPoint.d->startPos = previousTouchPoint.startPos();
840 touchPoint.d->lastPos = previousTouchPoint.pos();
841 touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
842 touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
843 if (touchPoint.pressure() < qreal(0.))
844 touchPoint.d->pressure = qreal(0.);
848 w = d->windowForTouchPointId.value(touchPoint.id());
851 Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
852 previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
853 touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
854 touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
855 touchPoint.d->startPos = previousTouchPoint.startPos();
856 touchPoint.d->lastPos = previousTouchPoint.pos();
857 touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
858 touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
859 if (touchPoint.pressure() < qreal(0.))
860 touchPoint.d->pressure = qreal(1.);
862 // Stationary points might not be delivered down to the receiving item
863 // and get their position transformed, keep the old values instead.
864 if (touchPoint.state() != Qt::TouchPointStationary)
865 d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
869 Q_ASSERT(w.data() != 0);
871 // make the *scene* functions return the same as the *screen* functions
872 touchPoint.d->sceneRect = touchPoint.screenRect();
873 touchPoint.d->startScenePos = touchPoint.startScreenPos();
874 touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
876 StatesAndTouchPoints &maskAndPoints = windowsNeedingEvents[w.data()];
877 maskAndPoints.first |= touchPoint.state();
878 if (touchPoint.isPrimary())
879 maskAndPoints.first |= Qt::TouchPointPrimary;
880 maskAndPoints.second.append(touchPoint);
883 if (windowsNeedingEvents.isEmpty())
886 QHash<QWindow *, StatesAndTouchPoints>::ConstIterator it = windowsNeedingEvents.constBegin();
887 const QHash<QWindow *, StatesAndTouchPoints>::ConstIterator end = windowsNeedingEvents.constEnd();
888 for (; it != end; ++it) {
889 QWindow *w = it.key();
891 QEvent::Type eventType;
892 switch (it.value().first & Qt::TouchPointStateMask) {
893 case Qt::TouchPointPressed:
894 eventType = QEvent::TouchBegin;
896 case Qt::TouchPointReleased:
897 eventType = QEvent::TouchEnd;
899 case Qt::TouchPointStationary:
900 // don't send the event if nothing changed
903 eventType = QEvent::TouchUpdate;
907 QTouchEvent touchEvent(eventType,
912 touchEvent.setTimestamp(e->timestamp);
914 for (int i = 0; i < touchEvent.touchPoints().count(); ++i) {
915 QTouchEvent::TouchPoint &touchPoint = touchEvent._touchPoints[i];
917 // preserve the sub-pixel resolution
918 QRectF rect = touchPoint.screenRect();
919 const QPointF screenPos = rect.center();
920 const QPointF delta = screenPos - screenPos.toPoint();
922 rect.moveCenter(w->mapFromGlobal(screenPos.toPoint()) + delta);
923 touchPoint.d->rect = rect;
924 if (touchPoint.state() == Qt::TouchPointPressed) {
925 touchPoint.d->startPos = w->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
926 touchPoint.d->lastPos = w->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
930 QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
934 void QGuiApplicationPrivate::reportScreenOrientationChange(QWindowSystemInterfacePrivate::ScreenOrientationEvent *e)
936 // This operation only makes sense after the QGuiApplication constructor runs
937 if (QCoreApplication::startingUp())
943 QScreen *s = e->screen.data();
944 emit s->currentOrientationChanged(s->currentOrientation());
946 QScreenOrientationChangeEvent event(s, s->currentOrientation());
947 QCoreApplication::sendEvent(QCoreApplication::instance(), &event);
950 void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *)
952 // This operation only makes sense after the QGuiApplication constructor runs
953 if (QCoreApplication::startingUp())
957 void QGuiApplicationPrivate::reportAvailableGeometryChange(
958 QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *)
960 // This operation only makes sense after the QGuiApplication constructor runs
961 if (QCoreApplication::startingUp())
965 void QGuiApplicationPrivate::processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e)
970 QEvent event(QEvent::Map);
971 QCoreApplication::sendSpontaneousEvent(e->mapped.data(), &event);
974 void QGuiApplicationPrivate::processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e)
979 QEvent event(QEvent::Unmap);
980 QCoreApplication::sendSpontaneousEvent(e->unmapped.data(), &event);
983 void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
988 QWindow *window = e->exposed.data();
990 QExposeEvent exposeEvent(e->region);
991 QCoreApplication::sendSpontaneousEvent(window, &exposeEvent);
994 Qt::DropAction QGuiApplicationPrivate::processDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
996 static QPointer<QWindow> currentDragWindow;
997 QDragManager *manager = QDragManager::self();
999 if (currentDragWindow.data() == w)
1000 currentDragWindow = 0;
1002 QGuiApplication::sendEvent(w, &e);
1003 manager->global_accepted_action = Qt::IgnoreAction;
1004 return Qt::IgnoreAction;
1006 QDragMoveEvent me(p, manager->possible_actions, dropData,
1007 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1008 if (w != currentDragWindow) {
1009 if (currentDragWindow) {
1011 QGuiApplication::sendEvent(currentDragWindow, &e);
1012 manager->global_accepted_action = Qt::IgnoreAction;
1014 currentDragWindow = w;
1015 QDragEnterEvent e(p, manager->possible_actions, dropData,
1016 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1017 QGuiApplication::sendEvent(w, &e);
1018 manager->global_accepted_action = e.isAccepted() ? e.dropAction() : Qt::IgnoreAction;
1019 if (manager->global_accepted_action != Qt::IgnoreAction) {
1020 me.setDropAction(manager->global_accepted_action);
1024 QGuiApplication::sendEvent(w, &me);
1025 manager->global_accepted_action = me.isAccepted() ? me.dropAction() : Qt::IgnoreAction;
1026 return manager->global_accepted_action;
1029 Qt::DropAction QGuiApplicationPrivate::processDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
1031 QDragManager *manager = QDragManager::self();
1032 QDropEvent de(p, manager->possible_actions, dropData,
1033 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
1034 QGuiApplication::sendEvent(w, &de);
1035 manager->global_accepted_action = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
1036 return manager->global_accepted_action;
1039 #ifndef QT_NO_CLIPBOARD
1040 QClipboard * QGuiApplication::clipboard()
1042 if (QGuiApplicationPrivate::qt_clipboard == 0) {
1044 qWarning("QGuiApplication: Must construct a QGuiApplication before accessing a QClipboard");
1047 QGuiApplicationPrivate::qt_clipboard = new QClipboard(0);
1049 return QGuiApplicationPrivate::qt_clipboard;
1054 Returns the application palette.
1056 \sa setPalette(), QWidget::palette()
1058 QPalette QGuiApplication::palette()
1060 if (!QGuiApplicationPrivate::app_pal)
1061 QGuiApplicationPrivate::app_pal = new QPalette(Qt::black);
1062 return *QGuiApplicationPrivate::app_pal;
1065 QFont QGuiApplication::font()
1067 QMutexLocker locker(applicationFontMutex());
1068 if (!QGuiApplicationPrivate::app_font)
1069 QGuiApplicationPrivate::app_font =
1070 new QFont(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFont());
1071 return *QGuiApplicationPrivate::app_font;
1074 void QGuiApplication::setFont(const QFont &font)
1076 QMutexLocker locker(applicationFontMutex());
1077 if (!QGuiApplicationPrivate::app_font)
1078 QGuiApplicationPrivate::app_font = new QFont(font);
1080 *QGuiApplicationPrivate::app_font = font;
1084 \fn bool QGuiApplication::isRightToLeft()
1086 Returns true if the application's layout direction is
1087 Qt::RightToLeft; otherwise returns false.
1089 \sa layoutDirection(), isLeftToRight()
1093 \fn bool QGuiApplication::isLeftToRight()
1095 Returns true if the application's layout direction is
1096 Qt::LeftToRight; otherwise returns false.
1098 \sa layoutDirection(), isRightToLeft()
1101 void QGuiApplicationPrivate::notifyLayoutDirectionChange()
1105 void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
1111 \property QGuiApplication::quitOnLastWindowClosed
1113 \brief whether the application implicitly quits when the last window is
1116 The default is true.
1118 If this property is true, the applications quits when the last visible
1119 primary window (i.e. window with no parent) is closed.
1121 \sa quit(), QWindow::close()
1124 void QGuiApplication::setQuitOnLastWindowClosed(bool quit)
1126 QGuiApplicationPrivate::quitOnLastWindowClosed = quit;
1131 bool QGuiApplication::quitOnLastWindowClosed()
1133 return QGuiApplicationPrivate::quitOnLastWindowClosed;
1138 void QGuiApplicationPrivate::emitLastWindowClosed()
1140 if (qGuiApp && qGuiApp->d_func()->in_exec) {
1141 if (QGuiApplicationPrivate::quitOnLastWindowClosed) {
1142 // get ready to quit, this event might be removed if the
1143 // event loop is re-entered, however
1144 QGuiApplication::postEvent(qApp, new QEvent(QEvent::Quit));
1146 emit qGuiApp->lastWindowClosed();
1152 \property QGuiApplication::layoutDirection
1153 \brief the default layout direction for this application
1155 On system start-up, the default layout direction depends on the
1156 application's language.
1158 \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
1161 void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
1163 if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
1166 layout_direction = direction;
1168 QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
1171 Qt::LayoutDirection QGuiApplication::layoutDirection()
1173 return layout_direction;
1177 \fn QCursor *QGuiApplication::overrideCursor()
1179 Returns the active application override cursor.
1181 This function returns 0 if no application cursor has been defined (i.e. the
1182 internal cursor stack is empty).
1184 \sa setOverrideCursor(), restoreOverrideCursor()
1186 #ifndef QT_NO_CURSOR
1187 QCursor *QGuiApplication::overrideCursor()
1189 return qGuiApp->d_func()->cursor_list.isEmpty() ? 0 : &qGuiApp->d_func()->cursor_list.first();
1193 Changes the currently active application override cursor to \a cursor.
1195 This function has no effect if setOverrideCursor() was not called.
1197 \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
1198 QWidget::setCursor()
1200 void QGuiApplication::changeOverrideCursor(const QCursor &cursor)
1202 if (qGuiApp->d_func()->cursor_list.isEmpty())
1204 qGuiApp->d_func()->cursor_list.removeFirst();
1205 setOverrideCursor(cursor);
1210 #ifndef QT_NO_CURSOR
1211 static void applyCursor(QWindow *w, const QCursor &c)
1214 QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
1215 int cursorCount = cursors.count();
1216 for (int i = 0; i < cursorCount; ++i) {
1217 const QWeakPointer<QPlatformCursor> &cursor(cursors.at(i));
1219 cursor.data()->changeCursor(&cc, w);
1223 static inline void applyCursor(const QList<QWindow *> &l, const QCursor &c)
1225 for (int i = 0; i < l.size(); ++i) {
1226 QWindow *w = l.at(i);
1227 if (w->handle() && w->windowType() != Qt::Desktop)
1233 \fn void QGuiApplication::setOverrideCursor(const QCursor &cursor)
1235 Sets the application override cursor to \a cursor.
1237 Application override cursors are intended for showing the user that the
1238 application is in a special state, for example during an operation that
1239 might take some time.
1241 This cursor will be displayed in all the application's widgets until
1242 restoreOverrideCursor() or another setOverrideCursor() is called.
1244 Application cursors are stored on an internal stack. setOverrideCursor()
1245 pushes the cursor onto the stack, and restoreOverrideCursor() pops the
1246 active cursor off the stack. changeOverrideCursor() changes the curently
1247 active application override cursor.
1249 Every setOverrideCursor() must eventually be followed by a corresponding
1250 restoreOverrideCursor(), otherwise the stack will never be emptied.
1253 \snippet doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp 0
1255 \sa overrideCursor(), restoreOverrideCursor(), changeOverrideCursor(),
1256 QWidget::setCursor()
1258 void QGuiApplication::setOverrideCursor(const QCursor &cursor)
1260 qGuiApp->d_func()->cursor_list.prepend(cursor);
1261 applyCursor(QGuiApplicationPrivate::window_list, cursor);
1265 \fn void QGuiApplication::restoreOverrideCursor()
1267 Undoes the last setOverrideCursor().
1269 If setOverrideCursor() has been called twice, calling
1270 restoreOverrideCursor() will activate the first cursor set. Calling this
1271 function a second time restores the original widgets' cursors.
1273 \sa setOverrideCursor(), overrideCursor()
1275 void QGuiApplication::restoreOverrideCursor()
1277 if (qGuiApp->d_func()->cursor_list.isEmpty())
1279 qGuiApp->d_func()->cursor_list.removeFirst();
1280 QCursor c(qGuiApp->d_func()->cursor_list.value(0, QCursor()));
1281 applyCursor(QGuiApplicationPrivate::window_list, c);
1283 #endif// QT_NO_CURSOR
1288 returns the style hints.
1290 The style hints encapsulate a set of platform dependent properties
1291 such as double click intervals, full width selection and others.
1293 The hints can be used to integrate tighter with the underlying platform.
1297 QStyleHints *QGuiApplication::styleHints() const
1299 Q_D(const QGuiApplication);
1301 const_cast<QGuiApplicationPrivate *>(d)->styleHints = new QStyleHints();
1302 return d->styleHints;
1309 returns the input panel.
1311 The input panel returns properties about the state and position of
1312 the virtual keyboard. It also provides information about the position of the
1313 current focused input element.
1317 QInputPanel *QGuiApplication::inputPanel() const
1319 Q_D(const QGuiApplication);
1321 const_cast<QGuiApplicationPrivate *>(d)->inputPanel = new QInputPanel();
1322 return d->inputPanel;
1326 // Returns the current platform used by keyBindings
1327 uint QGuiApplicationPrivate::currentKeyPlatform()
1329 uint platform = KB_Win;
1332 #elif defined Q_WS_X11 // ## TODO: detect these
1335 if (X11->desktopEnvironment == DE_KDE)
1337 if (X11->desktopEnvironment == DE_GNOME)
1338 platform |= KB_Gnome;
1339 if (X11->desktopEnvironment == DE_CDE)
1349 Returns the current keyboard input locale.
1351 QLocale QGuiApplication::keyboardInputLocale()
1353 if (!QGuiApplicationPrivate::checkInstance("keyboardInputLocale"))
1354 return QLocale::c();
1355 return qt_keymapper_private()->keyboardInputLocale;
1361 Returns the current keyboard input direction.
1363 Qt::LayoutDirection QGuiApplication::keyboardInputDirection()
1365 if (!QGuiApplicationPrivate::checkInstance("keyboardInputDirection"))
1366 return Qt::LeftToRight;
1367 return qt_keymapper_private()->keyboardInputDirection;
1372 \fn void QGuiApplication::fontDatabaseChanged()
1374 This signal is emitted when application fonts are loaded or removed.
1376 \sa QFontDatabase::addApplicationFont(),
1377 QFontDatabase::addApplicationFontFromData(),
1378 QFontDatabase::removeAllApplicationFonts(),
1379 QFontDatabase::removeApplicationFont()
1382 // These pixmaps approximate the images in the Windows User Interface Guidelines.
1386 static const char * const move_xpm[] = {
1390 "X c #000000", // X11 cursor is traditionally black
1414 static const char * const copy_xpm[] = {
1419 "XX......................",
1420 "XaX.....................",
1421 "XaaX....................",
1422 "XaaaX...................",
1423 "XaaaaX..................",
1424 "XaaaaaX.................",
1425 "XaaaaaaX................",
1426 "XaaaaaaaX...............",
1427 "XaaaaaaaaX..............",
1428 "XaaaaaaaaaX.............",
1429 "XaaaaaaXXXX.............",
1430 "XaaaXaaX................",
1431 "XaaXXaaX................",
1432 "XaX..XaaX...............",
1433 "XX...XaaX...............",
1434 "X.....XaaX..............",
1435 "......XaaX..............",
1436 ".......XaaX.............",
1437 ".......XaaX.............",
1438 "........XX...aaaaaaaaaaa",
1439 ".............aXXXXXXXXXa",
1440 ".............aXXXXXXXXXa",
1441 ".............aXXXXaXXXXa",
1442 ".............aXXXXaXXXXa",
1443 ".............aXXaaaaaXXa",
1444 ".............aXXXXaXXXXa",
1445 ".............aXXXXaXXXXa",
1446 ".............aXXXXXXXXXa",
1447 ".............aXXXXXXXXXa",
1448 ".............aaaaaaaaaaa"};
1451 static const char * const link_xpm[] = {
1456 "XX......................",
1457 "XaX.....................",
1458 "XaaX....................",
1459 "XaaaX...................",
1460 "XaaaaX..................",
1461 "XaaaaaX.................",
1462 "XaaaaaaX................",
1463 "XaaaaaaaX...............",
1464 "XaaaaaaaaX..............",
1465 "XaaaaaaaaaX.............",
1466 "XaaaaaaXXXX.............",
1467 "XaaaXaaX................",
1468 "XaaXXaaX................",
1469 "XaX..XaaX...............",
1470 "XX...XaaX...............",
1471 "X.....XaaX..............",
1472 "......XaaX..............",
1473 ".......XaaX.............",
1474 ".......XaaX.............",
1475 "........XX...aaaaaaaaaaa",
1476 ".............aXXXXXXXXXa",
1477 ".............aXXXaaaaXXa",
1478 ".............aXXXXaaaXXa",
1479 ".............aXXXaaaaXXa",
1480 ".............aXXaaaXaXXa",
1481 ".............aXXaaXXXXXa",
1482 ".............aXXaXXXXXXa",
1483 ".............aXXXaXXXXXa",
1484 ".............aXXXXXXXXXa",
1485 ".............aaaaaaaaaaa"};
1487 QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)