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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
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"
50 #include <QtCore/QAbstractEventDispatcher>
51 #include <QtCore/private/qcoreapplication_p.h>
52 #include <QtCore/private/qabstracteventdispatcher_p.h>
53 #include <QtCore/qmutex.h>
54 #include <QtCore/private/qthread_p.h>
59 #include <QtGui/QPlatformIntegration>
60 #include <QtGui/QGenericPluginFactory>
62 #include <QWindowSystemInterface>
63 #include "private/qwindowsysteminterface_qpa_p.h"
64 #include "private/qwindow_p.h"
65 #include "private/qkeymapper_p.h"
66 #include "private/qcursor_p.h"
67 #include "private/qdnd_p.h"
69 #include "qplatformcursor_qpa.h"
72 #include <QtGui/QPixmap>
74 #ifndef QT_NO_CLIPBOARD
75 #include <QtGui/QClipboard>
80 Q_GUI_EXPORT bool qt_is_gui_used = true;
82 Qt::MouseButtons QGuiApplicationPrivate::mouse_buttons = Qt::NoButton;
83 Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
85 int QGuiApplicationPrivate::keyboard_input_time = 400;
86 int QGuiApplicationPrivate::mouse_double_click_time = 400;
87 QPointF QGuiApplicationPrivate::lastCursorPosition(0.0, 0.0);
89 QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
91 bool QGuiApplicationPrivate::app_do_modal = false;
93 QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette
95 Qt::MouseButtons QGuiApplicationPrivate::buttons = Qt::NoButton;
96 ulong QGuiApplicationPrivate::mousePressTime = 0;
97 Qt::MouseButton QGuiApplicationPrivate::mousePressButton = Qt::NoButton;
98 int QGuiApplicationPrivate::mousePressX = 0;
99 int QGuiApplicationPrivate::mousePressY = 0;
100 int QGuiApplicationPrivate::mouse_double_click_distance = 5;
102 bool QGuiApplicationPrivate::quitOnLastWindowClosed = true;
104 static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
105 static bool force_reverse = false;
107 QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
109 #ifndef QT_NO_CLIPBOARD
110 QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
113 QList<QScreen *> QGuiApplicationPrivate::screen_list;
115 QWindowList QGuiApplicationPrivate::window_list;
116 QWindow *QGuiApplicationPrivate::active_window = 0;
118 Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
119 QFont *QGuiApplicationPrivate::app_font = 0;
121 extern int qRegisterGuiVariant();
122 extern int qUnregisterGuiVariant();
123 extern void qInitDrawhelperAsm();
124 extern void qInitImageConversions();
126 static bool qt_detectRTLLanguage()
128 return force_reverse ^
129 (QCoreApplication::tr("QT_LAYOUT_DIRECTION",
130 "Translate this string to the string 'LTR' in left-to-right"
131 " languages or to 'RTL' in right-to-left languages (such as Hebrew"
132 " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
136 QGuiApplication::QGuiApplication(int &argc, char **argv, int flags)
137 : QCoreApplication(*new QGuiApplicationPrivate(argc, argv, flags))
141 QCoreApplicationPrivate::eventDispatcher->startingUp();
144 QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p)
145 : QCoreApplication(p)
150 QGuiApplication::~QGuiApplication()
152 Q_D(QGuiApplication);
153 // flush clipboard contents
154 if (QGuiApplicationPrivate::qt_clipboard) {
155 QEvent event(QEvent::Clipboard);
156 QGuiApplication::sendEvent(QGuiApplicationPrivate::qt_clipboard, &event);
159 d->eventDispatcher->closingDown();
160 d->eventDispatcher = 0;
162 delete QGuiApplicationPrivate::qt_clipboard;
163 QGuiApplicationPrivate::qt_clipboard = 0;
165 delete QGuiApplicationPrivate::app_pal;
166 QGuiApplicationPrivate::app_pal = 0;
168 qUnregisterGuiVariant();
171 d->cursor_list.clear();
175 QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags)
176 : QCoreApplicationPrivate(argc, argv, flags)
181 QWindow *QGuiApplication::activeWindow()
183 return QGuiApplicationPrivate::active_window;
186 QWindowList QGuiApplication::topLevelWindows()
188 return QGuiApplicationPrivate::window_list;
191 QScreen *QGuiApplication::primaryScreen()
193 if (QGuiApplicationPrivate::screen_list.isEmpty())
195 return QGuiApplicationPrivate::screen_list.at(0);
198 QList<QScreen *> QGuiApplication::screens()
200 return QGuiApplicationPrivate::screen_list;
203 QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
205 QList<QScreen *> screens = QGuiApplication::screens();
206 QList<QScreen *>::const_iterator screen = screens.constBegin();
207 QList<QScreen *>::const_iterator end = screens.constEnd();
209 while (screen != end) {
210 if ((*screen)->geometry().contains(pos))
211 return (*screen)->handle()->topLevelAt(pos);
218 static void init_platform(QString name, const QString &platformPluginPath)
220 if (name.isEmpty()) {
221 const QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
222 #if defined(Q_OS_MAC)
223 const QString defaultPlatform = QLatin1String("cocoa");
224 #elif defined (Q_OS_WIN)
225 const QString defaultPlatform = QLatin1String("windows");
227 const QString defaultPlatform = QLatin1String("xcb");
229 if (keys.contains(defaultPlatform)) {
230 qWarning("No platform plugin argument was specified, defaulting to \"%s\".",
231 qPrintable(defaultPlatform));
232 name = defaultPlatform;
234 qFatal("No platform plugin argument was specified and the default plugin \"%s\" is not available",
235 qPrintable(defaultPlatform));
239 QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, platformPluginPath);
240 if (!QGuiApplicationPrivate::platform_integration) {
241 QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
242 QString fatalMessage =
243 QString::fromLatin1("Failed to load platform plugin \"%1\". Available platforms are: \n").arg(name);
244 foreach(const QString &key, keys) {
245 fatalMessage.append(key + QLatin1Char('\n'));
247 qFatal("%s", fatalMessage.toLocal8Bit().constData());
251 static void init_plugins(const QList<QByteArray> &pluginList)
253 for (int i = 0; i < pluginList.count(); ++i) {
254 QByteArray pluginSpec = pluginList.at(i);
255 qDebug() << "init_plugins" << i << pluginSpec;
256 int colonPos = pluginSpec.indexOf(':');
259 plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec), QString());
261 plugin = QGenericPluginFactory::create(QLatin1String(pluginSpec.mid(0, colonPos)),
262 QLatin1String(pluginSpec.mid(colonPos+1)));
263 qDebug() << " created" << plugin;
267 void QGuiApplicationPrivate::createPlatformIntegration()
269 Q_Q(QGuiApplication);
271 // Use the Qt menus by default. Platform plugins that
272 // want to enable a native menu implementation can clear
274 q->setAttribute(Qt::AA_DontUseNativeMenuBar, true);
276 // Load the platform integration
277 QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
278 QByteArray platformName;
279 #ifdef QT_QPA_DEFAULT_PLATFORM_NAME
280 platformName = QT_QPA_DEFAULT_PLATFORM_NAME;
282 QByteArray platformNameEnv = qgetenv("QT_QPA_PLATFORM");
283 if (!platformNameEnv.isEmpty()) {
284 platformName = platformNameEnv;
287 // Get command line params
289 int j = argc ? 1 : 0;
290 for (int i=1; i<argc; i++) {
291 if (argv[i] && *argv[i] != '-') {
295 QByteArray arg = argv[i];
296 if (arg == "-platformpluginpath") {
298 platformPluginPath = QLatin1String(argv[i]);
299 } else if (arg == "-platform") {
301 platformName = argv[i];
312 init_platform(QLatin1String(platformName), platformPluginPath);
316 void QGuiApplicationPrivate::createEventDispatcher()
318 if (platform_integration == 0)
319 createPlatformIntegration();
321 if (!eventDispatcher) {
322 QAbstractEventDispatcher *eventDispatcher = platform_integration->guiThreadEventDispatcher();
323 setEventDispatcher(eventDispatcher);
327 void QGuiApplicationPrivate::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
329 Q_Q(QGuiApplication);
331 if (!QCoreApplicationPrivate::eventDispatcher) {
332 QCoreApplicationPrivate::eventDispatcher = eventDispatcher;
333 QCoreApplicationPrivate::eventDispatcher->setParent(q);
334 threadData->eventDispatcher = eventDispatcher;
339 void QGuiApplicationPrivate::init()
341 QList<QByteArray> pluginList;
342 // Get command line params
344 int j = argc ? 1 : 0;
345 for (int i=1; i<argc; i++) {
346 if (argv[i] && *argv[i] != '-') {
350 QByteArray arg = argv[i];
351 if (arg == "-plugin") {
353 pluginList << argv[i];
354 } else if (arg == "-reverse") {
355 force_reverse = true;
356 QGuiApplication::setLayoutDirection(Qt::RightToLeft);
367 if (platform_integration == 0)
368 createPlatformIntegration();
370 init_plugins(pluginList);
372 // Set up which span functions should be used in raster engine...
373 qInitDrawhelperAsm();
374 // and QImage conversion functions
375 qInitImageConversions();
380 QCursorData::initialize();
383 // trigger registering of QVariant's GUI types
384 qRegisterGuiVariant();
386 is_app_running = true;
389 QGuiApplicationPrivate::~QGuiApplicationPrivate()
391 is_app_closing = true;
392 is_app_running = false;
397 QCursorData::cleanup();
400 layout_direction = Qt::LeftToRight;
404 delete platform_integration;
405 platform_integration = 0;
410 QCursor *overrideCursor();
411 void setOverrideCursor(const QCursor &);
412 void changeOverrideCursor(const QCursor &);
413 void restoreOverrideCursor();
417 static QFont font(const QWidget*);
418 static QFont font(const char *className);
419 static void setFont(const QFont &, const char* className = 0);
420 static QFontMetrics fontMetrics();
422 #ifndef QT_NO_CLIPBOARD
423 static QClipboard *clipboard();
427 Qt::KeyboardModifiers QGuiApplication::keyboardModifiers()
429 return QGuiApplicationPrivate::modifier_buttons;
432 Qt::MouseButtons QGuiApplication::mouseButtons()
434 return QGuiApplicationPrivate::mouse_buttons;
437 void QGuiApplication::setDoubleClickInterval(int ms)
439 QGuiApplicationPrivate::mouse_double_click_time = ms;
442 int QGuiApplication::doubleClickInterval()
444 return QGuiApplicationPrivate::mouse_double_click_time;
447 void QGuiApplication::setKeyboardInputInterval(int ms)
449 QGuiApplicationPrivate::keyboard_input_time = ms;
452 int QGuiApplication::keyboardInputInterval()
454 return QGuiApplicationPrivate::keyboard_input_time;
457 QPlatformNativeInterface *QGuiApplication::platformNativeInterface()
459 QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration();
460 return pi->nativeInterface();
463 int QGuiApplication::exec()
465 return QCoreApplication::exec();
468 bool QGuiApplication::notify(QObject *object, QEvent *event)
470 return QCoreApplication::notify(object, event);
473 bool QGuiApplication::event(QEvent *e)
475 if(e->type() == QEvent::LanguageChange) {
476 setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
478 return QCoreApplication::event(e);
481 bool QGuiApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
483 return QCoreApplication::compressEvent(event, receiver, postedEvents);
486 void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
489 case QWindowSystemInterfacePrivate::Mouse:
490 QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
492 case QWindowSystemInterfacePrivate::Wheel:
493 QGuiApplicationPrivate::processWheelEvent(static_cast<QWindowSystemInterfacePrivate::WheelEvent *>(e));
495 case QWindowSystemInterfacePrivate::Key:
496 QGuiApplicationPrivate::processKeyEvent(static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e));
498 case QWindowSystemInterfacePrivate::Touch:
499 QGuiApplicationPrivate::processTouchEvent(static_cast<QWindowSystemInterfacePrivate::TouchEvent *>(e));
501 case QWindowSystemInterfacePrivate::GeometryChange:
502 QGuiApplicationPrivate::processGeometryChangeEvent(static_cast<QWindowSystemInterfacePrivate::GeometryChangeEvent*>(e));
504 case QWindowSystemInterfacePrivate::Enter:
505 QGuiApplicationPrivate::processEnterEvent(static_cast<QWindowSystemInterfacePrivate::EnterEvent *>(e));
507 case QWindowSystemInterfacePrivate::Leave:
508 QGuiApplicationPrivate::processLeaveEvent(static_cast<QWindowSystemInterfacePrivate::LeaveEvent *>(e));
510 case QWindowSystemInterfacePrivate::ActivatedWindow:
511 QGuiApplicationPrivate::processActivatedEvent(static_cast<QWindowSystemInterfacePrivate::ActivatedWindowEvent *>(e));
513 case QWindowSystemInterfacePrivate::WindowStateChanged:
514 QGuiApplicationPrivate::processWindowStateChangedEvent(static_cast<QWindowSystemInterfacePrivate::WindowStateChangedEvent *>(e));
516 case QWindowSystemInterfacePrivate::Close:
517 QGuiApplicationPrivate::processCloseEvent(
518 static_cast<QWindowSystemInterfacePrivate::CloseEvent *>(e));
520 case QWindowSystemInterfacePrivate::ScreenCountChange:
521 QGuiApplicationPrivate::reportScreenCount(
522 static_cast<QWindowSystemInterfacePrivate::ScreenCountEvent *>(e));
524 case QWindowSystemInterfacePrivate::ScreenGeometry:
525 QGuiApplicationPrivate::reportGeometryChange(
526 static_cast<QWindowSystemInterfacePrivate::ScreenGeometryEvent *>(e));
528 case QWindowSystemInterfacePrivate::ScreenAvailableGeometry:
529 QGuiApplicationPrivate::reportAvailableGeometryChange(
530 static_cast<QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *>(e));
532 case QWindowSystemInterfacePrivate::Map:
533 QGuiApplicationPrivate::processMapEvent(static_cast<QWindowSystemInterfacePrivate::MapEvent *>(e));
535 case QWindowSystemInterfacePrivate::Unmap:
536 QGuiApplicationPrivate::processUnmapEvent(static_cast<QWindowSystemInterfacePrivate::UnmapEvent *>(e));
538 case QWindowSystemInterfacePrivate::Expose:
539 QGuiApplicationPrivate::processExposeEvent(static_cast<QWindowSystemInterfacePrivate::ExposeEvent *>(e));
542 qWarning() << "Unknown user input event type:" << e->type;
547 void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
551 Qt::MouseButtons stateChange = e->buttons ^ buttons;
552 if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
553 QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
554 new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons);
555 QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
556 stateChange = Qt::NoButton;
559 QWindow *window = e->window.data();
562 window = QGuiApplication::topLevelAt(e->globalPos.toPoint());
564 QPointF localPoint = e->localPos;
565 QPointF globalPoint = e->globalPos;
567 Qt::MouseButton button = Qt::NoButton;
569 if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
570 type = QEvent::MouseMove;
571 QGuiApplicationPrivate::lastCursorPosition = globalPoint;
572 if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance||
573 qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance)
574 mousePressButton = Qt::NoButton;
576 else { // check to see if a new button has been pressed/released
577 for (int check = Qt::LeftButton;
578 check <= Qt::XButton2;
579 check = check << 1) {
580 if (check & stateChange) {
581 button = Qt::MouseButton(check);
585 if (button == Qt::NoButton) {
586 // Ignore mouse events that don't change the current state
589 buttons = e->buttons;
590 if (button & e->buttons) {
591 if ((e->timestamp - mousePressTime) < static_cast<ulong>(QGuiApplication::doubleClickInterval()) && button == mousePressButton) {
592 type = QEvent::MouseButtonDblClick;
593 mousePressButton = Qt::NoButton;
596 type = QEvent::MouseButtonPress;
597 mousePressTime = e->timestamp;
598 mousePressButton = button;
599 const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint();
600 mousePressX = point.x();
601 mousePressY = point.y();
605 type = QEvent::MouseButtonRelease;
610 QMouseEvent ev(type, localPoint, globalPoint, button, buttons, QGuiApplication::keyboardModifiers());
612 QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
613 for (int i = 0; i < cursors.count(); ++i)
615 cursors.at(i).data()->pointerEvent(ev);
617 QGuiApplication::sendSpontaneousEvent(window, &ev);
623 //### there's a lot of duplicated logic here -- refactoring required!
625 void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::WheelEvent *e)
630 QPointF globalPoint = e->globalPos;
631 QGuiApplicationPrivate::lastCursorPosition = globalPoint;
633 QWindow *window = e->window.data();
636 QWheelEvent ev(e->localPos, e->globalPos, e->delta, buttons, QGuiApplication::keyboardModifiers(),
638 QGuiApplication::sendSpontaneousEvent(window, &ev);
645 // Remember, Qt convention is: keyboard state is state *before*
647 void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
649 QWindow *window = e->window.data();
653 QObject *target = window;
655 if (e->nativeScanCode || e->nativeVirtualKey || e->nativeModifiers) {
656 QKeyEventEx ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount,
657 e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers);
658 QGuiApplication::sendSpontaneousEvent(target, &ev);
660 QKeyEvent ev(e->keyType, e->key, e->modifiers, e->unicode, e->repeat, e->repeatCount);
661 QGuiApplication::sendSpontaneousEvent(target, &ev);
665 void QGuiApplicationPrivate::processEnterEvent(QWindowSystemInterfacePrivate::EnterEvent *e)
670 QEvent event(QEvent::Enter);
671 QCoreApplication::sendSpontaneousEvent(e->enter.data(), &event);
674 void QGuiApplicationPrivate::processLeaveEvent(QWindowSystemInterfacePrivate::LeaveEvent *e)
679 QEvent event(QEvent::Leave);
680 QCoreApplication::sendSpontaneousEvent(e->leave.data(), &event);
683 void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate::ActivatedWindowEvent *e)
688 QWindow *previous = QGuiApplicationPrivate::active_window;
689 QGuiApplicationPrivate::active_window = e->activated.data();
691 self->notifyActiveWindowChange(previous);
694 void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse)
696 if (QWindow *window = wse->window.data()) {
697 QWindowStateChangeEvent e(window->windowState());
698 window->d_func()->windowState = wse->newState;
699 QGuiApplication::sendSpontaneousEvent(window, &e);
703 void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePrivate::GeometryChangeEvent *e)
708 QWindow *window = e->tlw.data();
712 QRect newRect = e->newGeometry;
713 QRect cr = window->geometry();
715 bool isResize = cr.size() != newRect.size();
716 bool isMove = cr.topLeft() != newRect.topLeft();
718 window->d_func()->geometry = newRect;
721 QResizeEvent e(newRect.size(), cr.size());
722 QGuiApplication::sendSpontaneousEvent(window, &e);
727 QMoveEvent e(newRect.topLeft(), cr.topLeft());
728 QGuiApplication::sendSpontaneousEvent(window, &e);
732 void QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent *e)
734 if (e->window.isNull())
738 QGuiApplication::sendSpontaneousEvent(e->window.data(), &event);
741 void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *)
743 // translateRawTouchEvent(e->widget.data(), e->devType, e->points);
746 void QGuiApplicationPrivate::reportScreenCount(QWindowSystemInterfacePrivate::ScreenCountEvent *)
748 // This operation only makes sense after the QGuiApplication constructor runs
749 if (QCoreApplication::startingUp())
752 //QGuiApplication::desktop()->d_func()->updateScreenList();
753 // signal anything listening for creation or deletion of screens
754 //QDesktopWidget *desktop = QGuiApplication::desktop();
755 //emit desktop->screenCountChanged(e->count);
758 void QGuiApplicationPrivate::reportGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent *)
760 // This operation only makes sense after the QGuiApplication constructor runs
761 if (QCoreApplication::startingUp())
765 void QGuiApplicationPrivate::reportAvailableGeometryChange(
766 QWindowSystemInterfacePrivate::ScreenAvailableGeometryEvent *)
768 // This operation only makes sense after the QGuiApplication constructor runs
769 if (QCoreApplication::startingUp())
773 void QGuiApplicationPrivate::processMapEvent(QWindowSystemInterfacePrivate::MapEvent *e)
778 QEvent event(QEvent::Map);
779 QCoreApplication::sendSpontaneousEvent(e->mapped.data(), &event);
782 void QGuiApplicationPrivate::processUnmapEvent(QWindowSystemInterfacePrivate::UnmapEvent *e)
787 QEvent event(QEvent::Unmap);
788 QCoreApplication::sendSpontaneousEvent(e->unmapped.data(), &event);
791 void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e)
796 QExposeEvent event(e->region);
797 QCoreApplication::sendSpontaneousEvent(e->exposed.data(), &event);
800 Qt::DropAction QGuiApplicationPrivate::processDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
802 static QPointer<QWindow> currentDragWindow;
803 QDragManager *manager = QDragManager::self();
805 if (currentDragWindow.data() == w)
806 currentDragWindow = 0;
808 QGuiApplication::sendEvent(w, &e);
809 manager->global_accepted_action = Qt::IgnoreAction;
810 return Qt::IgnoreAction;
812 QDragMoveEvent me(p, manager->possible_actions, dropData,
813 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
814 if (w != currentDragWindow) {
815 if (currentDragWindow) {
817 QGuiApplication::sendEvent(currentDragWindow, &e);
818 manager->global_accepted_action = Qt::IgnoreAction;
820 currentDragWindow = w;
821 QDragEnterEvent e(p, manager->possible_actions, dropData,
822 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
823 QGuiApplication::sendEvent(w, &e);
824 manager->global_accepted_action = e.isAccepted() ? e.dropAction() : Qt::IgnoreAction;
825 if (manager->global_accepted_action != Qt::IgnoreAction) {
826 me.setDropAction(manager->global_accepted_action);
830 QGuiApplication::sendEvent(w, &me);
831 manager->global_accepted_action = me.isAccepted() ? me.dropAction() : Qt::IgnoreAction;
832 return manager->global_accepted_action;
835 Qt::DropAction QGuiApplicationPrivate::processDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
837 QDragManager *manager = QDragManager::self();
838 QDropEvent de(p, manager->possible_actions, dropData,
839 QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
840 QGuiApplication::sendEvent(w, &de);
841 manager->global_accepted_action = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
842 return manager->global_accepted_action;
845 #ifndef QT_NO_CLIPBOARD
846 QClipboard * QGuiApplication::clipboard()
848 if (QGuiApplicationPrivate::qt_clipboard == 0) {
850 qWarning("QGuiApplication: Must construct a QGuiApplication before accessing a QClipboard");
853 QGuiApplicationPrivate::qt_clipboard = new QClipboard(0);
855 return QGuiApplicationPrivate::qt_clipboard;
860 Returns the application palette.
862 \sa setPalette(), QWidget::palette()
864 QPalette QGuiApplication::palette()
866 if (!QGuiApplicationPrivate::app_pal)
867 QGuiApplicationPrivate::app_pal = new QPalette(Qt::black);
868 return *QGuiApplicationPrivate::app_pal;
871 QFont QGuiApplication::font()
873 QMutexLocker locker(applicationFontMutex());
874 if (!QGuiApplicationPrivate::app_font)
875 QGuiApplicationPrivate::app_font =
876 new QFont(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFont());
877 return *QGuiApplicationPrivate::app_font;
880 void QGuiApplication::setFont(const QFont &font)
882 QMutexLocker locker(applicationFontMutex());
883 if (!QGuiApplicationPrivate::app_font)
884 QGuiApplicationPrivate::app_font = new QFont(font);
886 *QGuiApplicationPrivate::app_font = font;
890 \fn bool QGuiApplication::isRightToLeft()
892 Returns true if the application's layout direction is
893 Qt::RightToLeft; otherwise returns false.
895 \sa layoutDirection(), isLeftToRight()
899 \fn bool QGuiApplication::isLeftToRight()
901 Returns true if the application's layout direction is
902 Qt::LeftToRight; otherwise returns false.
904 \sa layoutDirection(), isRightToLeft()
907 void QGuiApplicationPrivate::notifyLayoutDirectionChange()
911 void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
917 \property QGuiApplication::quitOnLastWindowClosed
919 \brief whether the application implicitly quits when the last window is
924 If this property is true, the applications quits when the last visible
925 primary window (i.e. window with no parent) is closed.
927 \sa quit(), QWindow::close()
930 void QGuiApplication::setQuitOnLastWindowClosed(bool quit)
932 QGuiApplicationPrivate::quitOnLastWindowClosed = quit;
937 bool QGuiApplication::quitOnLastWindowClosed()
939 return QGuiApplicationPrivate::quitOnLastWindowClosed;
944 void QGuiApplicationPrivate::emitLastWindowClosed()
946 if (qGuiApp && qGuiApp->d_func()->in_exec) {
947 if (QGuiApplicationPrivate::quitOnLastWindowClosed) {
948 // get ready to quit, this event might be removed if the
949 // event loop is re-entered, however
950 QGuiApplication::postEvent(qApp, new QEvent(QEvent::Quit));
952 emit qGuiApp->lastWindowClosed();
958 \property QGuiApplication::layoutDirection
959 \brief the default layout direction for this application
961 On system start-up, the default layout direction depends on the
962 application's language.
964 \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
967 void QGuiApplication::setLayoutDirection(Qt::LayoutDirection direction)
969 if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
972 layout_direction = direction;
974 QGuiApplicationPrivate::self->notifyLayoutDirectionChange();
977 Qt::LayoutDirection QGuiApplication::layoutDirection()
979 return layout_direction;
983 \fn QCursor *QGuiApplication::overrideCursor()
985 Returns the active application override cursor.
987 This function returns 0 if no application cursor has been defined (i.e. the
988 internal cursor stack is empty).
990 \sa setOverrideCursor(), restoreOverrideCursor()
993 QCursor *QGuiApplication::overrideCursor()
995 return qGuiApp->d_func()->cursor_list.isEmpty() ? 0 : &qGuiApp->d_func()->cursor_list.first();
999 Changes the currently active application override cursor to \a cursor.
1001 This function has no effect if setOverrideCursor() was not called.
1003 \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
1004 QWidget::setCursor()
1006 void QGuiApplication::changeOverrideCursor(const QCursor &cursor)
1008 if (qGuiApp->d_func()->cursor_list.isEmpty())
1010 qGuiApp->d_func()->cursor_list.removeFirst();
1011 setOverrideCursor(cursor);
1016 \fn void QGuiApplication::setOverrideCursor(const QCursor &cursor, bool replace)
1018 Use changeOverrideCursor(\a cursor) (if \a replace is true) or
1019 setOverrideCursor(\a cursor) (if \a replace is false).
1022 #ifndef QT_NO_CURSOR
1023 void QGuiApplication::setOverrideCursor(const QCursor &cursor)
1025 qGuiApp->d_func()->cursor_list.prepend(cursor);
1028 void QGuiApplication::restoreOverrideCursor()
1030 if (qGuiApp->d_func()->cursor_list.isEmpty())
1032 qGuiApp->d_func()->cursor_list.removeFirst();
1034 #endif// QT_NO_CURSOR
1037 // Returns the current platform used by keyBindings
1038 uint QGuiApplicationPrivate::currentKeyPlatform()
1040 uint platform = KB_Win;
1043 #elif defined Q_WS_X11
1045 // ## TODO: detect these
1047 if (X11->desktopEnvironment == DE_KDE)
1049 if (X11->desktopEnvironment == DE_GNOME)
1050 platform |= KB_Gnome;
1051 if (X11->desktopEnvironment == DE_CDE)
1061 Returns the current keyboard input locale.
1063 QLocale QGuiApplication::keyboardInputLocale()
1065 if (!QGuiApplicationPrivate::checkInstance("keyboardInputLocale"))
1066 return QLocale::c();
1067 return qt_keymapper_private()->keyboardInputLocale;
1073 Returns the current keyboard input direction.
1075 Qt::LayoutDirection QGuiApplication::keyboardInputDirection()
1077 if (!QGuiApplicationPrivate::checkInstance("keyboardInputDirection"))
1078 return Qt::LeftToRight;
1079 return qt_keymapper_private()->keyboardInputDirection;
1084 \fn void QGuiApplication::fontDatabaseChanged()
1086 This signal is emitted when application fonts are loaded or removed.
1088 \sa QFontDatabase::addApplicationFont(),
1089 QFontDatabase::addApplicationFontFromData(),
1090 QFontDatabase::removeAllApplicationFonts(),
1091 QFontDatabase::removeApplicationFont()
1094 // These pixmaps approximate the images in the Windows User Interface Guidelines.
1098 static const char * const move_xpm[] = {
1101 #if defined(Q_WS_WIN)
1103 "X c #FFFFFF", // Windows cursor is traditionally white
1106 "X c #000000", // X11 cursor is traditionally black
1131 static const char * const ignore_xpm[] = {
1136 "aa......................",
1137 "aXa.....................",
1138 "aXXa....................",
1139 "aXXXa...................",
1140 "aXXXXa..................",
1141 "aXXXXXa.................",
1142 "aXXXXXXa................",
1143 "aXXXXXXXa...............",
1144 "aXXXXXXXXa..............",
1145 "aXXXXXXXXXa.............",
1146 "aXXXXXXaaaa.............",
1147 "aXXXaXXa................",
1148 "aXXaaXXa................",
1149 "aXa..aXXa...............",
1150 "aa...aXXa...............",
1151 "a.....aXXa..............",
1152 "......aXXa.....XXXX.....",
1153 ".......aXXa..XXaaaaXX...",
1154 ".......aXXa.XaaaaaaaaX..",
1155 "........aa.XaaaXXXXaaaX.",
1156 "...........XaaaaX..XaaX.",
1157 "..........XaaXaaaX..XaaX",
1158 "..........XaaXXaaaX.XaaX",
1159 "..........XaaX.XaaaXXaaX",
1160 "..........XaaX..XaaaXaaX",
1161 "...........XaaX..XaaaaX.",
1162 "...........XaaaXXXXaaaX.",
1163 "............XaaaaaaaaX..",
1164 ".............XXaaaaXX...",
1165 "...............XXXX....."};
1169 static const char * const copy_xpm[] = {
1174 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
1175 "aa......................",
1176 "aXa.....................",
1177 "aXXa....................",
1178 "aXXXa...................",
1179 "aXXXXa..................",
1180 "aXXXXXa.................",
1181 "aXXXXXXa................",
1182 "aXXXXXXXa...............",
1183 "aXXXXXXXXa..............",
1184 "aXXXXXXXXXa.............",
1185 "aXXXXXXaaaa.............",
1186 "aXXXaXXa................",
1187 "aXXaaXXa................",
1188 "aXa..aXXa...............",
1189 "aa...aXXa...............",
1190 "a.....aXXa..............",
1191 "......aXXa..............",
1192 ".......aXXa.............",
1193 ".......aXXa.............",
1194 "........aa...aaaaaaaaaaa",
1196 "XX......................",
1197 "XaX.....................",
1198 "XaaX....................",
1199 "XaaaX...................",
1200 "XaaaaX..................",
1201 "XaaaaaX.................",
1202 "XaaaaaaX................",
1203 "XaaaaaaaX...............",
1204 "XaaaaaaaaX..............",
1205 "XaaaaaaaaaX.............",
1206 "XaaaaaaXXXX.............",
1207 "XaaaXaaX................",
1208 "XaaXXaaX................",
1209 "XaX..XaaX...............",
1210 "XX...XaaX...............",
1211 "X.....XaaX..............",
1212 "......XaaX..............",
1213 ".......XaaX.............",
1214 ".......XaaX.............",
1215 "........XX...aaaaaaaaaaa",
1217 ".............aXXXXXXXXXa",
1218 ".............aXXXXXXXXXa",
1219 ".............aXXXXaXXXXa",
1220 ".............aXXXXaXXXXa",
1221 ".............aXXaaaaaXXa",
1222 ".............aXXXXaXXXXa",
1223 ".............aXXXXaXXXXa",
1224 ".............aXXXXXXXXXa",
1225 ".............aXXXXXXXXXa",
1226 ".............aaaaaaaaaaa"};
1229 static const char * const link_xpm[] = {
1234 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
1235 "aa......................",
1236 "aXa.....................",
1237 "aXXa....................",
1238 "aXXXa...................",
1239 "aXXXXa..................",
1240 "aXXXXXa.................",
1241 "aXXXXXXa................",
1242 "aXXXXXXXa...............",
1243 "aXXXXXXXXa..............",
1244 "aXXXXXXXXXa.............",
1245 "aXXXXXXaaaa.............",
1246 "aXXXaXXa................",
1247 "aXXaaXXa................",
1248 "aXa..aXXa...............",
1249 "aa...aXXa...............",
1250 "a.....aXXa..............",
1251 "......aXXa..............",
1252 ".......aXXa.............",
1253 ".......aXXa.............",
1254 "........aa...aaaaaaaaaaa",
1256 "XX......................",
1257 "XaX.....................",
1258 "XaaX....................",
1259 "XaaaX...................",
1260 "XaaaaX..................",
1261 "XaaaaaX.................",
1262 "XaaaaaaX................",
1263 "XaaaaaaaX...............",
1264 "XaaaaaaaaX..............",
1265 "XaaaaaaaaaX.............",
1266 "XaaaaaaXXXX.............",
1267 "XaaaXaaX................",
1268 "XaaXXaaX................",
1269 "XaX..XaaX...............",
1270 "XX...XaaX...............",
1271 "X.....XaaX..............",
1272 "......XaaX..............",
1273 ".......XaaX.............",
1274 ".......XaaX.............",
1275 "........XX...aaaaaaaaaaa",
1277 ".............aXXXXXXXXXa",
1278 ".............aXXXaaaaXXa",
1279 ".............aXXXXaaaXXa",
1280 ".............aXXXaaaaXXa",
1281 ".............aXXaaaXaXXa",
1282 ".............aXXaaXXXXXa",
1283 ".............aXXaXXXXXXa",
1284 ".............aXXXaXXXXXa",
1285 ".............aXXXXXXXXXa",
1286 ".............aaaaaaaaaaa"};
1288 QPixmap QGuiApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
1290 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
1292 move_cursor = new QPixmap((const char **)move_xpm);
1293 copy_cursor = new QPixmap((const char **)copy_xpm);
1294 link_cursor = new QPixmap((const char **)link_xpm);
1296 ignore_cursor = new QPixmap((const char **)ignore_xpm);
1301 case Qt::DragMoveCursor:
1302 return *move_cursor;
1303 case Qt::DragCopyCursor:
1304 return *copy_cursor;
1305 case Qt::DragLinkCursor:
1306 return *link_cursor;
1308 case Qt::ForbiddenCursor:
1309 return *ignore_cursor;