1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qplatformdefs.h"
43 #include "qabstracteventdispatcher.h"
44 #include "qaccessible.h"
45 #include "qapplication.h"
46 #include "qclipboard.h"
47 #include "qcursor.h"
48 #include "qdesktopwidget.h"
49 #include "qdir.h"
50 #include "qevent.h"
51 #include "qfile.h"
52 #include "qfileinfo.h"
53 #include "qgraphicsscene.h"
54 #include "qhash.h"
55 #include "qset.h"
56 #include "qlayout.h"
57 #include "qsessionmanager.h"
58 #include "qstyle.h"
59 #include "qstylefactory.h"
60 #include "qtextcodec.h"
61 #include "qtranslator.h"
62 #include "qvariant.h"
63 #include "qwidget.h"
64 #include "qdnd_p.h"
65 #include "qcolormap.h"
66 #include "qdebug.h"
67 #include "private/qgraphicssystemfactory_p.h"
68 #include "private/qgraphicssystem_p.h"
69 #include "private/qstylesheetstyle_p.h"
70 #include "private/qstyle_p.h"
71 #include "qmessagebox.h"
72 #include <QtGui/qgraphicsproxywidget.h>
73 
74 #ifdef QT_GRAPHICSSYSTEM_RUNTIME
75 #include "private/qgraphicssystem_runtime_p.h"
76 #endif
77 
78 #include "qinputcontext.h"
79 #include "qkeymapper_p.h"
80 
81 #ifdef Q_WS_X11
82 #include <private/qt_x11_p.h>
83 #endif
84 
85 #if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN)
86 #include "qinputcontextfactory.h"
87 #endif
88 
89 #include "qguiplatformplugin_p.h"
90 
91 #include <qthread.h>
92 #include <private/qthread_p.h>
93 
94 #include <private/qfont_p.h>
95 
96 #include <stdlib.h>
97 
98 #if defined(Q_WS_X11) && !defined(QT_NO_EGL)
99 #include <link.h>
100 #endif
101 
102 #include "qapplication_p.h"
103 #include "qevent_p.h"
104 #include "qwidget_p.h"
105 
106 #include "qapplication.h"
107 
108 #include "qgesture.h"
109 #include "private/qgesturemanager_p.h"
110 
111 #ifndef QT_NO_LIBRARY
112 #include "qlibrary.h"
113 #endif
114 
115 #ifdef Q_WS_WINCE
116 #include "qdatetime.h"
117 #include "qguifunctions_wince.h"
118 extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp
119 extern bool qt_wince_is_mobile();     //qguifunctions_wince.cpp
120 extern bool qt_wince_is_pocket_pc();  //qguifunctions_wince.cpp
121 #endif
122 
123 #include "qdatetime.h"
124 
125 #ifdef QT_MAC_USE_COCOA
126 #include <private/qt_cocoa_helpers_mac_p.h>
127 #endif
128 
129 //#define ALIEN_DEBUG
130 
131 #if defined(Q_OS_SYMBIAN)
132 #include "qt_s60_p.h"
133 #endif
134 
initResources()135 static void initResources()
136 {
137 #if defined(Q_WS_WINCE)
138     Q_INIT_RESOURCE_EXTERN(qstyle_wince)
139     Q_INIT_RESOURCE(qstyle_wince);
140 #elif defined(Q_OS_SYMBIAN)
141     Q_INIT_RESOURCE_EXTERN(qstyle_s60)
142     Q_INIT_RESOURCE(qstyle_s60);
143 #else
144     Q_INIT_RESOURCE_EXTERN(qstyle)
145     Q_INIT_RESOURCE(qstyle);
146 #endif
147     Q_INIT_RESOURCE_EXTERN(qmessagebox)
148     Q_INIT_RESOURCE(qmessagebox);
149 #if !defined(QT_NO_PRINTDIALOG)
150     Q_INIT_RESOURCE_EXTERN(qprintdialog)
151     Q_INIT_RESOURCE(qprintdialog);
152 #endif
153 #ifdef Q_WS_MAC
154     Q_INIT_RESOURCE_EXTERN(macresources)
155     Q_INIT_RESOURCE(macresources);
156 #endif
157 }
158 
159 QT_BEGIN_NAMESPACE
160 
161 Q_CORE_EXPORT void qt_call_post_routines();
162 
163 QApplication::Type qt_appType=QApplication::Tty;
164 QApplicationPrivate *QApplicationPrivate::self = 0;
165 
166 QInputContext *QApplicationPrivate::inputContext = 0;
167 
168 bool QApplicationPrivate::quitOnLastWindowClosed = true;
169 
170 #ifdef Q_OS_SYMBIAN
171 bool QApplicationPrivate::inputContextBeingCreated = false;
172 #endif
173 
174 #ifdef Q_WS_WINCE
175 int QApplicationPrivate::autoMaximizeThreshold = -1;
176 bool QApplicationPrivate::autoSipEnabled = false;
177 #else
178 bool QApplicationPrivate::autoSipEnabled = true;
179 #endif
180 
QApplicationPrivate(int & argc,char ** argv,QApplication::Type type,int flags)181 QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags)
182     : QCoreApplicationPrivate(argc, argv, flags)
183 {
184     application_type = type;
185     qt_appType = type;
186 
187 #ifndef QT_NO_SESSIONMANAGER
188     is_session_restored = false;
189 #endif
190 
191     quitOnLastWindowClosed = true;
192 
193 #ifdef QT3_SUPPORT
194     qt_compat_used = 0;
195     qt_compat_resolved = 0;
196     qt_tryAccelEvent = 0;
197     qt_tryComposeUnicode = 0;
198     qt_dispatchAccelEvent = 0;
199 #endif
200 #if defined(Q_WS_QWS) && !defined(QT_NO_DIRECTPAINTER)
201     directPainters = 0;
202 #endif
203 
204 #ifndef QT_NO_GESTURES
205     gestureManager = 0;
206     gestureWidget = 0;
207 #endif // QT_NO_GESTURES
208 
209 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
210     move_cursor = 0;
211     copy_cursor = 0;
212     link_cursor = 0;
213 #endif
214 #if defined(Q_WS_WIN)
215     ignore_cursor = 0;
216 #endif
217 
218     if (!self)
219         self = this;
220 }
221 
~QApplicationPrivate()222 QApplicationPrivate::~QApplicationPrivate()
223 {
224     if (self == this)
225         self = 0;
226 }
227 
228 /*!
229     \class QApplication
230     \brief The QApplication class manages the GUI application's control
231     flow and main settings.
232 
233     QApplication contains the main event loop, where all events from the window
234     system and other sources are processed and dispatched. It also handles the
235     application's initialization, finalization, and provides session
236     management. In addition, QApplication handles most of the system-wide and
237     application-wide settings.
238 
239     For any GUI application using Qt, there is precisely \bold one QApplication
240     object, no matter whether the application has 0, 1, 2 or more windows at
241     any given time. For non-GUI Qt applications, use QCoreApplication instead,
242     as it does not depend on the \l QtGui library.
243 
244     The QApplication object is accessible through the instance() function that
245     returns a pointer equivalent to the global qApp pointer.
246 
247     QApplication's main areas of responsibility are:
248         \list
249             \o  It initializes the application with the user's desktop settings
250                 such as palette(), font() and doubleClickInterval(). It keeps
251                 track of these properties in case the user changes the desktop
252                 globally, for example through some kind of control panel.
253 
254             \o  It performs event handling, meaning that it receives events
255                 from the underlying window system and dispatches them to the
256                 relevant widgets. By using sendEvent() and postEvent() you can
257                 send your own events to widgets.
258 
259             \o  It parses common command line arguments and sets its internal
260                 state accordingly. See the \l{QApplication::QApplication()}
261                 {constructor documentation} below for more details.
262 
263             \o  It defines the application's look and feel, which is
264                 encapsulated in a QStyle object. This can be changed at runtime
265                 with setStyle().
266 
267             \o  It specifies how the application is to allocate colors. See
268                 setColorSpec() for details.
269 
270             \o  It provides localization of strings that are visible to the
271                 user via translate().
272 
273             \o  It provides some magical objects like the desktop() and the
274                 clipboard().
275 
276             \o  It knows about the application's windows. You can ask which
277                 widget is at a certain position using widgetAt(), get a list of
278                 topLevelWidgets() and closeAllWindows(), etc.
279 
280             \o  It manages the application's mouse cursor handling, see
281                 setOverrideCursor()
282 
283             \o  On the X window system, it provides functions to flush and sync
284                 the communication stream, see flushX() and syncX().
285 
286             \o  It provides support for sophisticated \l{Session Management}
287                 {session management}. This makes it possible for applications
288                 to terminate gracefully when the user logs out, to cancel a
289                 shutdown process if termination isn't possible and even to
290                 preserve the entire application's state for a future session.
291                 See isSessionRestored(), sessionId() and commitData() and
292                 saveState() for details.
293         \endlist
294 
295     Since the QApplication object does so much initialization, it \e{must} be
296     created before any other objects related to the user interface are created.
297     QApplication also deals with common command line arguments. Hence, it is
298     usually a good idea to create it \e before any interpretation or
299     modification of \c argv is done in the application itself.
300 
301     \table
302     \header
303         \o{2,1} Groups of functions
304 
305         \row
306         \o  System settings
307         \o  desktopSettingsAware(),
308             setDesktopSettingsAware(),
309             cursorFlashTime(),
310             setCursorFlashTime(),
311             doubleClickInterval(),
312             setDoubleClickInterval(),
313             setKeyboardInputInterval(),
314             wheelScrollLines(),
315             setWheelScrollLines(),
316             palette(),
317             setPalette(),
318             font(),
319             setFont(),
320             fontMetrics().
321 
322         \row
323         \o  Event handling
324         \o  exec(),
325             processEvents(),
326             exit(),
327             quit().
328             sendEvent(),
329             postEvent(),
330             sendPostedEvents(),
331             removePostedEvents(),
332             hasPendingEvents(),
333             notify(),
334             macEventFilter(),
335             qwsEventFilter(),
336             x11EventFilter(),
337             x11ProcessEvent(),
338             winEventFilter().
339 
340         \row
341         \o  GUI Styles
342         \o  style(),
343             setStyle().
344 
345         \row
346         \o  Color usage
347         \o  colorSpec(),
348             setColorSpec(),
349             qwsSetCustomColors().
350 
351         \row
352         \o  Text handling
353         \o  installTranslator(),
354             removeTranslator()
355             translate().
356 
357         \row
358         \o  Widgets
359         \o  allWidgets(),
360             topLevelWidgets(),
361             desktop(),
362             activePopupWidget(),
363             activeModalWidget(),
364             clipboard(),
365             focusWidget(),
366             activeWindow(),
367             widgetAt().
368 
369         \row
370         \o  Advanced cursor handling
371         \o  overrideCursor(),
372             setOverrideCursor(),
373             restoreOverrideCursor().
374 
375         \row
376         \o  X Window System synchronization
377         \o  flushX(),
378             syncX().
379 
380         \row
381         \o  Session management
382         \o  isSessionRestored(),
383             sessionId(),
384             commitData(),
385             saveState().
386 
387         \row
388         \o  Miscellaneous
389         \o  closeAllWindows(),
390             startingUp(),
391             closingDown(),
392             type().
393     \endtable
394 
395     \sa QCoreApplication, QAbstractEventDispatcher, QEventLoop, QSettings
396 */
397 
398 /*!
399     \enum QApplication::Type
400 
401     \value Tty a console application
402     \value GuiClient a GUI client application
403     \value GuiServer a GUI server application (for Qt for Embedded Linux)
404 */
405 
406 /*!
407     \enum QApplication::ColorSpec
408 
409     \value NormalColor the default color allocation policy
410     \value CustomColor the same as NormalColor for X11; allocates colors
411     to a palette on demand under Windows
412     \value ManyColor the right choice for applications that use thousands of
413     colors
414 
415     See setColorSpec() for full details.
416 */
417 
418 /*!
419     \fn QWidget *QApplication::topLevelAt(const QPoint &point)
420 
421     Returns the top-level widget at the given \a point; returns 0 if
422     there is no such widget.
423 */
424 
425 /*!
426     \fn QWidget *QApplication::topLevelAt(int x, int y)
427 
428     \overload
429 
430     Returns the top-level widget at the point (\a{x}, \a{y}); returns
431     0 if there is no such widget.
432 */
433 
434 
435 /*
436     The qt_init() and qt_cleanup() functions are implemented in the
437     qapplication_xyz.cpp file.
438 */
439 
440 void qt_init(QApplicationPrivate *priv, int type
441 #ifdef Q_WS_X11
442               , Display *display = 0, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0
443 #endif
444    );
445 void qt_cleanup();
446 
447 Qt::MouseButtons QApplicationPrivate::mouse_buttons = Qt::NoButton;
448 Qt::KeyboardModifiers QApplicationPrivate::modifier_buttons = Qt::NoModifier;
449 
450 QStyle *QApplicationPrivate::app_style = 0;        // default application style
451 QString QApplicationPrivate::styleOverride;        // style override
452 
453 #ifndef QT_NO_STYLE_STYLESHEET
454 QString QApplicationPrivate::styleSheet;           // default application stylesheet
455 #endif
456 QPointer<QWidget> QApplicationPrivate::leaveAfterRelease = 0;
457 
458 int QApplicationPrivate::app_cspec = QApplication::NormalColor;
459 QPalette *QApplicationPrivate::app_pal = 0;        // default application palette
460 QPalette *QApplicationPrivate::sys_pal = 0;        // default system palette
461 QPalette *QApplicationPrivate::set_pal = 0;        // default palette set by programmer
462 
463 QGraphicsSystem *QApplicationPrivate::graphics_system = 0; // default graphics system
464 #if defined(Q_WS_QPA)
465 QPlatformIntegration *QApplicationPrivate::platform_integration = 0;
466 #endif
467 QString QApplicationPrivate::graphics_system_name;         // graphics system id - for delayed initialization
468 bool QApplicationPrivate::runtime_graphics_system = false;
469 
470 Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
471 QFont *QApplicationPrivate::app_font = 0;        // default application font
472 QFont *QApplicationPrivate::sys_font = 0;        // default system font
473 QFont *QApplicationPrivate::set_font = 0;        // default font set by programmer
474 
475 QIcon *QApplicationPrivate::app_icon = 0;
476 QWidget *QApplicationPrivate::main_widget = 0;        // main application widget
477 QWidget *QApplicationPrivate::focus_widget = 0;        // has keyboard input focus
478 QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
479 QWidget *QApplicationPrivate::active_window = 0;        // toplevel with keyboard focus
480 bool QApplicationPrivate::obey_desktop_settings = true;        // use winsys resources
481 int QApplicationPrivate::cursor_flash_time = 1000;        // text caret flash time
482 int QApplicationPrivate::mouse_double_click_time = 400;        // mouse dbl click limit
483 int QApplicationPrivate::keyboard_input_time = 400; // keyboard input interval
484 #ifndef QT_NO_WHEELEVENT
485 int QApplicationPrivate::wheel_scroll_lines;   // number of lines to scroll
486 #endif
487 bool qt_is_gui_used;
488 bool Q_GUI_EXPORT qt_tab_all_widgets = true;
489 bool qt_in_tab_key_event = false;
490 int qt_antialiasing_threshold = -1;
491 static int drag_time = 500;
492 #ifndef QT_GUI_DRAG_DISTANCE
493 #define QT_GUI_DRAG_DISTANCE 4
494 #endif
495 #ifdef Q_OS_SYMBIAN
496 // The screens are a bit too small to for your thumb when using only 4 pixels drag distance.
497 static int drag_distance = 12; //XXX move to qplatformdefs.h
498 #else
499 static int drag_distance = QT_GUI_DRAG_DISTANCE;
500 #endif
501 static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
502 QSize QApplicationPrivate::app_strut = QSize(0,0); // no default application strut
503 bool QApplicationPrivate::animate_ui = true;
504 bool QApplicationPrivate::animate_menu = false;
505 bool QApplicationPrivate::fade_menu = false;
506 bool QApplicationPrivate::animate_combo = false;
507 bool QApplicationPrivate::animate_tooltip = false;
508 bool QApplicationPrivate::fade_tooltip = false;
509 bool QApplicationPrivate::animate_toolbox = false;
510 bool QApplicationPrivate::widgetCount = false;
511 bool QApplicationPrivate::load_testability = false;
512 #ifdef QT_KEYPAD_NAVIGATION
513 #  ifdef Q_OS_SYMBIAN
514 Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
515 #  else
516 Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder;
517 #  endif
518 QWidget *QApplicationPrivate::oldEditFocus = 0;
519 #endif
520 
521 bool qt_tabletChokeMouse = false;
522 static bool force_reverse = false;
523 
isAlien(QWidget * widget)524 inline bool QApplicationPrivate::isAlien(QWidget *widget)
525 {
526     if (!widget)
527         return false;
528 #if defined(Q_WS_QWS) || defined(Q_WS_QPA)
529     return !widget->isWindow()
530 # ifdef Q_BACKINGSTORE_SUBSURFACES
531         && !(widget->d_func()->maybeTopData() && widget->d_func()->maybeTopData()->windowSurface)
532 # endif
533         ;
534 #else
535     return !widget->internalWinId();
536 #endif
537 }
538 
539 // ######## move to QApplicationPrivate
540 // Default application palettes and fonts (per widget type)
Q_GLOBAL_STATIC(PaletteHash,app_palettes)541 Q_GLOBAL_STATIC(PaletteHash, app_palettes)
542 PaletteHash *qt_app_palettes_hash()
543 {
544     return app_palettes();
545 }
546 
Q_GLOBAL_STATIC(FontHash,app_fonts)547 Q_GLOBAL_STATIC(FontHash, app_fonts)
548 FontHash *qt_app_fonts_hash()
549 {
550     return app_fonts();
551 }
552 
553 QWidgetList *QApplicationPrivate::popupWidgets = 0;        // has keyboard input focus
554 
555 QDesktopWidget *qt_desktopWidget = 0;                // root window widgets
556 #ifndef QT_NO_CLIPBOARD
557 QClipboard              *qt_clipboard = 0;        // global clipboard object
558 #endif
559 QWidgetList * qt_modal_stack=0;                // stack of modal widgets
560 
561 /*!
562     \internal
563 */
process_cmdline()564 void QApplicationPrivate::process_cmdline()
565 {
566     // process platform-indep command line
567     if (!qt_is_gui_used || !argc)
568         return;
569 
570     int i, j;
571 
572     j = 1;
573     for (i=1; i<argc; i++) { // if you add anything here, modify QCoreApplication::arguments()
574         if (argv[i] && *argv[i] != '-') {
575             argv[j++] = argv[i];
576             continue;
577         }
578         QByteArray arg = argv[i];
579         arg = arg;
580         QString s;
581         if (arg == "-qdevel" || arg == "-qdebug") {
582             // obsolete argument
583         } else if (arg.indexOf("-style=", 0) != -1) {
584             s = QString::fromLocal8Bit(arg.right(arg.length() - 7).toLower());
585         } else if (arg == "-style" && i < argc-1) {
586             s = QString::fromLocal8Bit(argv[++i]).toLower();
587 #ifndef QT_NO_SESSIONMANAGER
588         } else if (arg == "-session" && i < argc-1) {
589             ++i;
590             if (argv[i] && *argv[i]) {
591                 session_id = QString::fromLatin1(argv[i]);
592                 int p = session_id.indexOf(QLatin1Char('_'));
593                 if (p >= 0) {
594                     session_key = session_id.mid(p +1);
595                     session_id = session_id.left(p);
596                 }
597                 is_session_restored = true;
598             }
599 #endif
600 #ifndef QT_NO_STYLE_STYLESHEET
601         } else if (arg == "-stylesheet" && i < argc -1) {
602             styleSheet = QLatin1String("file:///");
603             styleSheet.append(QString::fromLocal8Bit(argv[++i]));
604         } else if (arg.indexOf("-stylesheet=") != -1) {
605             styleSheet = QLatin1String("file:///");
606             styleSheet.append(QString::fromLocal8Bit(arg.right(arg.length() - 12)));
607 #endif
608         } else if (qstrcmp(arg, "-reverse") == 0) {
609             force_reverse = true;
610             QApplication::setLayoutDirection(Qt::RightToLeft);
611         } else if (qstrcmp(arg, "-widgetcount") == 0) {
612             widgetCount = true;
613         } else if (qstrcmp(arg, "-testability") == 0) {
614             load_testability = true;
615         } else if (arg == "-graphicssystem" && i < argc-1) {
616             graphics_system_name = QString::fromLocal8Bit(argv[++i]);
617         } else {
618             argv[j++] = argv[i];
619         }
620         if (!s.isEmpty()) {
621             if (app_style) {
622                 delete app_style;
623                 app_style = 0;
624             }
625             styleOverride = s;
626         }
627     }
628 
629     if(j < argc) {
630         argv[j] = 0;
631         argc = j;
632     }
633 }
634 
635 /*!
636     Initializes the window system and constructs an application object with
637     \a argc command line arguments in \a argv.
638 
639     \warning The data referred to by \a argc and \a argv must stay valid for
640     the entire lifetime of the QApplication object. In addition, \a argc must
641     be greater than zero and \a argv must contain at least one valid character
642     string.
643 
644     The global \c qApp pointer refers to this application object. Only one
645     application object should be created.
646 
647     This application object must be constructed before any \l{QPaintDevice}
648     {paint devices} (including widgets, pixmaps, bitmaps etc.).
649 
650     \note \a argc and \a argv might be changed as Qt removes command line
651     arguments that it recognizes.
652 
653     Qt debugging options (not available if Qt was compiled without the QT_DEBUG
654     flag defined):
655     \list
656         \o  -nograb, tells Qt that it must never grab the mouse or the
657             keyboard.
658         \o  -dograb (only under X11), running under a debugger can cause an
659             implicit -nograb, use -dograb to override.
660         \o  -sync (only under X11), switches to synchronous mode for
661             debugging.
662     \endlist
663 
664     See \l{Debugging Techniques} for a more detailed explanation.
665 
666     All Qt programs automatically support the following command line options:
667     \list
668         \o  -style= \e style, sets the application GUI style. Possible values
669             are \c motif, \c windows, and \c platinum. If you compiled Qt with
670             additional styles or have additional styles as plugins these will
671             be available to the \c -style command line option.
672         \o  -style \e style, is the same as listed above.
673         \o  -stylesheet= \e stylesheet, sets the application \l styleSheet. The
674             value must be a path to a file that contains the Style Sheet.
675             \note Relative URLs in the Style Sheet file are relative to the
676             Style Sheet file's path.
677         \o  -stylesheet \e stylesheet, is the same as listed above.
678         \o  -session= \e session, restores the application from an earlier
679             \l{Session Management}{session}.
680         \o  -session \e session, is the same as listed above.
681         \o  -widgetcount, prints debug message at the end about number of
682             widgets left undestroyed and maximum number of widgets existed at
683             the same time
684         \o  -reverse, sets the application's layout direction to
685             Qt::RightToLeft
686         \o  -graphicssystem, sets the backend to be used for on-screen widgets
687             and QPixmaps. Available options are \c{raster} and \c{opengl}.
688         \o  -qmljsdebugger=, activates the QML/JS debugger with a specified port.
689             The value must be of format port:1234[,block], where block is optional
690             and will make the application wait until a debugger connects to it.
691     \endlist
692 
693     The X11 version of Qt supports some traditional X11 command line options:
694     \list
695         \o  -display \e display, sets the X display (default is $DISPLAY).
696         \o  -geometry \e geometry, sets the client geometry of the first window
697             that is shown.
698         \o  -fn or \c -font \e font, defines the application font. The font
699             should be specified using an X logical font description. Note that
700             this option is ignored when Qt is built with fontconfig support enabled.
701         \o  -bg or \c -background \e color, sets the default background color
702             and an application palette (light and dark shades are calculated).
703         \o  -fg or \c -foreground \e color, sets the default foreground color.
704         \o  -btn or \c -button \e color, sets the default button color.
705         \o  -name \e name, sets the application name.
706         \o  -title \e title, sets the application title.
707         \o  -visual \c TrueColor, forces the application to use a TrueColor
708             visual on an 8-bit display.
709         \o  -ncols \e count, limits the number of colors allocated in the color
710             cube on an 8-bit display, if the application is using the
711             QApplication::ManyColor color specification. If \e count is 216
712             then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green,
713             and 6 of blue); for other values, a cube approximately proportional
714             to a 2x3x1 cube is used.
715         \o  -cmap, causes the application to install a private color map on an
716             8-bit display.
717         \o  -im, sets the input method server (equivalent to setting the
718             XMODIFIERS environment variable)
719         \o  -inputstyle, defines how the input is inserted into the given
720             widget, e.g., \c onTheSpot makes the input appear directly in the
721             widget, while \c overTheSpot makes the input appear in a box
722             floating over the widget and is not inserted until the editing is
723             done.
724     \endlist
725 
726     \section1 X11 Notes
727 
728     If QApplication fails to open the X11 display, it will terminate
729     the process. This behavior is consistent with most X11
730     applications.
731 
732     \sa arguments()
733 */
734 
QApplication(int & argc,char ** argv)735 QApplication::QApplication(int &argc, char **argv)
736     : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
737 { Q_D(QApplication); d->construct(); }
738 
QApplication(int & argc,char ** argv,int _internal)739 QApplication::QApplication(int &argc, char **argv, int _internal)
740     : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
741 { Q_D(QApplication); d->construct(); }
742 
743 
744 /*!
745     Constructs an application object with \a argc command line arguments in
746     \a argv. If \a GUIenabled is true, a GUI application is constructed,
747     otherwise a non-GUI (console) application is created.
748 
749     \warning The data referred to by \a argc and \a argv must stay valid for
750     the entire lifetime of the QApplication object. In addition, \a argc must
751     be greater than zero and \a argv must contain at least one valid character
752     string.
753 
754     Set \a GUIenabled to false for programs without a graphical user interface
755     that should be able to run without a window system.
756 
757     On X11, the window system is initialized if \a GUIenabled is true. If
758     \a GUIenabled is false, the application does not connect to the X server.
759     On Windows and Mac OS, currently the window system is always initialized,
760     regardless of the value of GUIenabled. This may change in future versions
761     of Qt.
762 
763     The following example shows how to create an application that uses a
764     graphical interface when available.
765 
766     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 0
767 */
768 
QApplication(int & argc,char ** argv,bool GUIenabled)769 QApplication::QApplication(int &argc, char **argv, bool GUIenabled )
770     : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, 0x040000))
771 { Q_D(QApplication); d->construct(); }
772 
QApplication(int & argc,char ** argv,bool GUIenabled,int _internal)773 QApplication::QApplication(int &argc, char **argv, bool GUIenabled , int _internal)
774     : QCoreApplication(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, _internal))
775 { Q_D(QApplication); d->construct();}
776 
777 
778 
779 /*!
780     Constructs an application object with \a argc command line arguments in
781     \a argv.
782 
783     \warning The data referred to by \a argc and \a argv must stay valid for
784     the entire lifetime of the QApplication object. In addition, \a argc must
785     be greater than zero and \a argv must contain at least one valid character
786     string.
787 
788     With Qt for Embedded Linux, passing QApplication::GuiServer for \a type
789     makes this application the server (equivalent to running with the
790     \c -qws option).
791 */
QApplication(int & argc,char ** argv,Type type)792 QApplication::QApplication(int &argc, char **argv, Type type)
793     : QCoreApplication(*new QApplicationPrivate(argc, argv, type, 0x040000))
794 { Q_D(QApplication); d->construct(); }
795 
QApplication(int & argc,char ** argv,Type type,int _internal)796 QApplication::QApplication(int &argc, char **argv, Type type , int _internal)
797     : QCoreApplication(*new QApplicationPrivate(argc, argv, type, _internal))
798 { Q_D(QApplication); d->construct(); }
799 
800 #if defined(Q_WS_X11) && !defined(QT_NO_EGL)
qt_matchLibraryName(dl_phdr_info * info,size_t,void * data)801 static int qt_matchLibraryName(dl_phdr_info *info, size_t, void *data)
802 {
803     const char *name = static_cast<const char *>(data);
804     return strstr(info->dlpi_name, name) != 0;
805 }
806 #endif
807 
808 /*!
809     \internal
810 */
construct(Display * dpy,Qt::HANDLE visual,Qt::HANDLE cmap)811 void QApplicationPrivate::construct(
812 #ifdef Q_WS_X11
813                                     Display *dpy, Qt::HANDLE visual, Qt::HANDLE cmap
814 #endif
815                                     )
816 {
817     initResources();
818 
819     qt_is_gui_used = (qt_appType != QApplication::Tty);
820     process_cmdline();
821     // the environment variable has the lowest precedence of runtime graphicssystem switches
822     if (graphics_system_name.isEmpty())
823         graphics_system_name = QString::fromLocal8Bit(qgetenv("QT_GRAPHICSSYSTEM"));
824 
825 #if defined(Q_WS_X11) && !defined(QT_NO_EGL)
826     if (graphics_system_name.isEmpty()) {
827         bool linksWithMeeGoTouch = dl_iterate_phdr(qt_matchLibraryName, const_cast<char *>("libmeegotouchcore"));
828         bool linksWithMeeGoGraphicsSystemHelper = dl_iterate_phdr(qt_matchLibraryName, const_cast<char *>("libQtMeeGoGraphicsSystemHelper"));
829 
830         if (linksWithMeeGoTouch && !linksWithMeeGoGraphicsSystemHelper) {
831             qWarning("Running non-meego graphics system enabled  MeeGo touch, forcing native graphicssystem\n");
832             graphics_system_name = QLatin1String("native");
833         }
834     }
835 #endif
836 
837     // Must be called before initialize()
838     qt_init(this, qt_appType
839 #ifdef Q_WS_X11
840             , dpy, visual, cmap
841 #endif
842             );
843     initialize();
844     eventDispatcher->startingUp();
845 
846 #ifdef QT_EVAL
847     extern void qt_gui_eval_init(uint);
848     qt_gui_eval_init(application_type);
849 #endif
850 
851 #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
852     symbianInit();
853 #endif
854 
855 #ifndef QT_NO_LIBRARY
856     if(load_testability) {
857         QLibrary testLib(QLatin1String("qttestability"));
858         if (testLib.load()) {
859             typedef void (*TasInitialize)(void);
860             TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
861 #ifdef Q_OS_SYMBIAN
862             // resolving method by name does not work on Symbian OS so need to use ordinal
863             if(!initFunction) {
864                 initFunction = (TasInitialize)testLib.resolve("1");
865             }
866 #endif
867             if (initFunction) {
868                 initFunction();
869             } else {
870                 qCritical("Library qttestability resolve failed!");
871             }
872         } else {
873             qCritical("Library qttestability load failed!");
874         }
875     }
876 
877     //make sure the plugin is loaded
878     if (qt_is_gui_used)
879         qt_guiPlatformPlugin();
880 #endif
881 
882 #ifdef Q_OS_SYMBIAN
883     symbianHandleLiteModeStartup();
884 #endif
885 }
886 
887 #if defined(Q_WS_X11)
888 // ### a string literal is a cont char*
889 // ### using it as a char* is wrong and could lead to segfaults
890 // ### if aargv is modified someday
891 // ########## make it work with argc == argv == 0
892 static int aargc = 1;
893 static char *aargv[] = { (char*)"unknown", 0 };
894 
895 /*!
896     \fn QApplication::QApplication(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
897 
898     Creates an application, given an already open display \a display. If
899     \a visual and \a colormap are non-zero, the application will use those
900     values as the default Visual and Colormap contexts.
901 
902     \warning Qt only supports TrueColor visuals at depths higher than 8
903     bits-per-pixel.
904 
905     This function is only available on X11.
906 */
QApplication(Display * dpy,Qt::HANDLE visual,Qt::HANDLE colormap)907 QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
908     : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient, 0x040000))
909 {
910     if (! dpy)
911         qWarning("QApplication: Invalid Display* argument");
912     Q_D(QApplication);
913     d->construct(dpy, visual, colormap);
914 }
915 
QApplication(Display * dpy,Qt::HANDLE visual,Qt::HANDLE colormap,int _internal)916 QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
917     : QCoreApplication(*new QApplicationPrivate(aargc, aargv, GuiClient, _internal))
918 {
919     if (! dpy)
920         qWarning("QApplication: Invalid Display* argument");
921     Q_D(QApplication);
922     d->construct(dpy, visual, colormap);
923     QApplicationPrivate::app_compile_version = _internal;
924 }
925 
926 /*!
927     \fn QApplication::QApplication(Display *display, int &argc, char **argv,
928         Qt::HANDLE visual, Qt::HANDLE colormap)
929 
930     Creates an application, given an already open \a display and using \a argc
931     command line arguments in \a argv. If \a visual and \a colormap are
932     non-zero, the application will use those values as the default Visual
933     and Colormap contexts.
934 
935     \warning Qt only supports TrueColor visuals at depths higher than 8
936     bits-per-pixel.
937 
938     This function is only available on X11.
939 */
QApplication(Display * dpy,int & argc,char ** argv,Qt::HANDLE visual,Qt::HANDLE colormap)940 QApplication::QApplication(Display *dpy, int &argc, char **argv,
941                            Qt::HANDLE visual, Qt::HANDLE colormap)
942     : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
943 {
944     if (! dpy)
945         qWarning("QApplication: Invalid Display* argument");
946     Q_D(QApplication);
947     d->construct(dpy, visual, colormap);
948 }
949 
QApplication(Display * dpy,int & argc,char ** argv,Qt::HANDLE visual,Qt::HANDLE colormap,int _internal)950 QApplication::QApplication(Display *dpy, int &argc, char **argv,
951                            Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
952     : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
953 {
954     if (! dpy)
955         qWarning("QApplication: Invalid Display* argument");
956     Q_D(QApplication);
957     d->construct(dpy, visual, colormap);
958     QApplicationPrivate::app_compile_version = _internal;
959 }
960 
961 #endif // Q_WS_X11
962 
963 extern void qInitDrawhelperAsm();
964 extern void qInitImageConversions();
965 extern int qRegisterGuiVariant();
966 extern int qUnregisterGuiVariant();
967 #ifndef QT_NO_STATEMACHINE
968 extern int qRegisterGuiStateMachine();
969 extern int qUnregisterGuiStateMachine();
970 #endif
971 
972 /*!
973   \fn void QApplicationPrivate::initialize()
974 
975   Initializes the QApplication object, called from the constructors.
976 */
initialize()977 void QApplicationPrivate::initialize()
978 {
979     QWidgetPrivate::mapper = new QWidgetMapper;
980     QWidgetPrivate::allWidgets = new QWidgetSet;
981 
982 #if !defined(Q_WS_X11) && !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
983     // initialize the graphics system - on X11 this is initialized inside
984     // qt_init() in qapplication_x11.cpp because of several reasons.
985     // On QWS, the graphics system is set by the QScreen plugin.
986     // We don't use graphics systems in Qt QPA
987     graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
988 #endif
989 
990     if (qt_appType != QApplication::Tty)
991         (void) QApplication::style();  // trigger creation of application style
992     // trigger registering of QVariant's GUI types
993     qRegisterGuiVariant();
994 #ifndef QT_NO_STATEMACHINE
995     // trigger registering of QStateMachine's GUI types
996     qRegisterGuiStateMachine();
997 #endif
998 
999     is_app_running = true; // no longer starting up
1000 
1001     Q_Q(QApplication);
1002 #ifndef QT_NO_SESSIONMANAGER
1003     // connect to the session manager
1004     session_manager = new QSessionManager(q, session_id, session_key);
1005 #endif
1006 
1007     if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0)
1008         q->setAttribute(Qt::AA_NativeWindows);
1009 
1010 #ifdef Q_WS_WINCE
1011 #ifdef QT_AUTO_MAXIMIZE_THRESHOLD
1012     autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD;
1013 #else
1014     if (qt_wince_is_mobile())
1015         autoMaximizeThreshold = 50;
1016     else
1017         autoMaximizeThreshold = -1;
1018 #endif //QT_AUTO_MAXIMIZE_THRESHOLD
1019 #endif //Q_WS_WINCE
1020 
1021     // Set up which span functions should be used in raster engine...
1022     qInitDrawhelperAsm();
1023     // and QImage conversion functions
1024     qInitImageConversions();
1025 
1026 #ifndef QT_NO_WHEELEVENT
1027     QApplicationPrivate::wheel_scroll_lines = 3;
1028 #endif
1029 
1030 #ifdef Q_WS_S60
1031     q->setAttribute(Qt::AA_S60DisablePartialScreenInputMode);
1032 #endif
1033 
1034     if (qt_is_gui_used)
1035         initializeMultitouch();
1036 }
1037 
1038 /*!
1039     Returns the type of application (\l Tty, GuiClient, or
1040     GuiServer). The type is set when constructing the QApplication
1041     object.
1042 */
type()1043 QApplication::Type QApplication::type()
1044 {
1045     return qt_appType;
1046 }
1047 
1048 /*****************************************************************************
1049   Functions returning the active popup and modal widgets.
1050  *****************************************************************************/
1051 
1052 /*!
1053     Returns the active popup widget.
1054 
1055     A popup widget is a special top-level widget that sets the \c
1056     Qt::WType_Popup widget flag, e.g. the QMenu widget. When the application
1057     opens a popup widget, all events are sent to the popup. Normal widgets and
1058     modal widgets cannot be accessed before the popup widget is closed.
1059 
1060     Only other popup widgets may be opened when a popup widget is shown. The
1061     popup widgets are organized in a stack. This function returns the active
1062     popup widget at the top of the stack.
1063 
1064     \sa activeModalWidget(), topLevelWidgets()
1065 */
1066 
activePopupWidget()1067 QWidget *QApplication::activePopupWidget()
1068 {
1069     return QApplicationPrivate::popupWidgets && !QApplicationPrivate::popupWidgets->isEmpty() ?
1070         QApplicationPrivate::popupWidgets->last() : 0;
1071 }
1072 
1073 
1074 /*!
1075     Returns the active modal widget.
1076 
1077     A modal widget is a special top-level widget which is a subclass of QDialog
1078     that specifies the modal parameter of the constructor as true. A modal
1079     widget must be closed before the user can continue with other parts of the
1080     program.
1081 
1082     Modal widgets are organized in a stack. This function returns the active
1083     modal widget at the top of the stack.
1084 
1085     \sa activePopupWidget(), topLevelWidgets()
1086 */
1087 
activeModalWidget()1088 QWidget *QApplication::activeModalWidget()
1089 {
1090     return qt_modal_stack && !qt_modal_stack->isEmpty() ? qt_modal_stack->first() : 0;
1091 }
1092 
1093 /*!
1094     Cleans up any window system resources that were allocated by this
1095     application. Sets the global variable \c qApp to 0.
1096 */
1097 
~QApplication()1098 QApplication::~QApplication()
1099 {
1100     Q_D(QApplication);
1101 
1102 #ifndef QT_NO_CLIPBOARD
1103     // flush clipboard contents
1104     if (qt_clipboard) {
1105         QEvent event(QEvent::Clipboard);
1106         QApplication::sendEvent(qt_clipboard, &event);
1107     }
1108 #endif
1109 
1110     //### this should probable be done even later
1111     qt_call_post_routines();
1112 
1113     // kill timers before closing down the dispatcher
1114     d->toolTipWakeUp.stop();
1115     d->toolTipFallAsleep.stop();
1116 
1117     d->eventDispatcher->closingDown();
1118     d->eventDispatcher = 0;
1119     QApplicationPrivate::is_app_closing = true;
1120     QApplicationPrivate::is_app_running = false;
1121 
1122     delete QWidgetPrivate::mapper;
1123     QWidgetPrivate::mapper = 0;
1124 
1125     // delete all widgets
1126     if (QWidgetPrivate::allWidgets) {
1127         QWidgetSet *mySet = QWidgetPrivate::allWidgets;
1128         QWidgetPrivate::allWidgets = 0;
1129         for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
1130             register QWidget *w = *it;
1131             if (!w->parent())                        // window
1132                 w->destroy(true, true);
1133         }
1134         delete mySet;
1135     }
1136 
1137     delete qt_desktopWidget;
1138     qt_desktopWidget = 0;
1139 
1140 #ifndef QT_NO_CLIPBOARD
1141     delete qt_clipboard;
1142     qt_clipboard = 0;
1143 #endif
1144 
1145 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
1146     delete d->move_cursor; d->move_cursor = 0;
1147     delete d->copy_cursor; d->copy_cursor = 0;
1148     delete d->link_cursor; d->link_cursor = 0;
1149 #endif
1150 #if defined(Q_WS_WIN)
1151     delete d->ignore_cursor; d->ignore_cursor = 0;
1152 #endif
1153 
1154     delete QApplicationPrivate::app_pal;
1155     QApplicationPrivate::app_pal = 0;
1156     delete QApplicationPrivate::sys_pal;
1157     QApplicationPrivate::sys_pal = 0;
1158     delete QApplicationPrivate::set_pal;
1159     QApplicationPrivate::set_pal = 0;
1160     app_palettes()->clear();
1161 
1162     {
1163         QMutexLocker locker(applicationFontMutex());
1164         delete QApplicationPrivate::app_font;
1165         QApplicationPrivate::app_font = 0;
1166     }
1167     delete QApplicationPrivate::sys_font;
1168     QApplicationPrivate::sys_font = 0;
1169     delete QApplicationPrivate::set_font;
1170     QApplicationPrivate::set_font = 0;
1171     app_fonts()->clear();
1172 
1173     delete QApplicationPrivate::app_style;
1174     QApplicationPrivate::app_style = 0;
1175     delete QApplicationPrivate::app_icon;
1176     QApplicationPrivate::app_icon = 0;
1177     delete QApplicationPrivate::graphics_system;
1178     QApplicationPrivate::graphics_system = 0;
1179 #ifndef QT_NO_CURSOR
1180     d->cursor_list.clear();
1181 #endif
1182 
1183 #ifndef QT_NO_DRAGANDDROP
1184     if (qt_is_gui_used)
1185         delete QDragManager::self();
1186 #endif
1187 
1188     d->cleanupMultitouch();
1189 
1190     qt_cleanup();
1191 
1192     if (QApplicationPrivate::widgetCount)
1193         qDebug("Widgets left: %i    Max widgets: %i \n", QWidgetPrivate::instanceCounter, QWidgetPrivate::maxInstances);
1194 #ifndef QT_NO_SESSIONMANAGER
1195     delete d->session_manager;
1196     d->session_manager = 0;
1197 #endif //QT_NO_SESSIONMANAGER
1198 
1199     QApplicationPrivate::obey_desktop_settings = true;
1200     QApplicationPrivate::cursor_flash_time = 1000;
1201     QApplicationPrivate::mouse_double_click_time = 400;
1202     QApplicationPrivate::keyboard_input_time = 400;
1203 
1204     drag_time = 500;
1205     drag_distance = 4;
1206     layout_direction = Qt::LeftToRight;
1207     QApplicationPrivate::app_strut = QSize(0, 0);
1208     QApplicationPrivate::animate_ui = true;
1209     QApplicationPrivate::animate_menu = false;
1210     QApplicationPrivate::fade_menu = false;
1211     QApplicationPrivate::animate_combo = false;
1212     QApplicationPrivate::animate_tooltip = false;
1213     QApplicationPrivate::fade_tooltip = false;
1214     QApplicationPrivate::widgetCount = false;
1215 
1216 #ifndef QT_NO_STATEMACHINE
1217     // trigger unregistering of QStateMachine's GUI types
1218     qUnregisterGuiStateMachine();
1219 #endif
1220     // trigger unregistering of QVariant's GUI types
1221     qUnregisterGuiVariant();
1222 }
1223 
1224 
1225 /*!
1226     \fn QWidget *QApplication::widgetAt(const QPoint &point)
1227 
1228     Returns the widget at global screen position \a point, or 0 if there is no
1229     Qt widget there.
1230 
1231     This function can be slow.
1232 
1233     \sa QCursor::pos(), QWidget::grabMouse(), QWidget::grabKeyboard()
1234 */
widgetAt(const QPoint & p)1235 QWidget *QApplication::widgetAt(const QPoint &p)
1236 {
1237     QWidget *window = QApplication::topLevelAt(p);
1238     if (!window)
1239         return 0;
1240 
1241     QWidget *child = 0;
1242 
1243     if (!window->testAttribute(Qt::WA_TransparentForMouseEvents))
1244         child = window->childAt(window->mapFromGlobal(p));
1245 
1246     if (child)
1247         return child;
1248 
1249     if (window->testAttribute(Qt::WA_TransparentForMouseEvents)) {
1250         //shoot a hole in the widget and try once again,
1251         //suboptimal on Qt for Embedded Linux where we do
1252         //know the stacking order of the toplevels.
1253         int x = p.x();
1254         int y = p.y();
1255         QRegion oldmask = window->mask();
1256         QPoint wpoint = window->mapFromGlobal(QPoint(x, y));
1257         QRegion newmask = (oldmask.isEmpty() ? QRegion(window->rect()) : oldmask)
1258                           - QRegion(wpoint.x(), wpoint.y(), 1, 1);
1259         window->setMask(newmask);
1260         QWidget *recurse = 0;
1261         if (QApplication::topLevelAt(p) != window) // verify recursion will terminate
1262             recurse = widgetAt(x, y);
1263         if (oldmask.isEmpty())
1264             window->clearMask();
1265         else
1266             window->setMask(oldmask);
1267         return recurse;
1268     }
1269     return window;
1270 }
1271 
1272 /*!
1273     \fn QWidget *QApplication::widgetAt(int x, int y)
1274 
1275     \overload
1276 
1277     Returns the widget at global screen position (\a x, \a y), or 0 if there is
1278     no Qt widget there.
1279 */
1280 
1281 /*!
1282     \fn void QApplication::setArgs(int argc, char **argv)
1283     \internal
1284 */
1285 
1286 
1287 
1288 /*!
1289     \internal
1290 */
compressEvent(QEvent * event,QObject * receiver,QPostEventList * postedEvents)1291 bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1292 {
1293     if ((event->type() == QEvent::UpdateRequest
1294 #ifdef QT3_SUPPORT
1295           || event->type() == QEvent::LayoutHint
1296 #endif
1297           || event->type() == QEvent::LayoutRequest
1298           || event->type() == QEvent::Resize
1299           || event->type() == QEvent::Move
1300           || event->type() == QEvent::LanguageChange
1301           || event->type() == QEvent::UpdateSoftKeys
1302           || event->type() == QEvent::InputMethod)) {
1303         for (QPostEventList::const_iterator it = postedEvents->constBegin(); it != postedEvents->constEnd(); ++it) {
1304             const QPostEvent &cur = *it;
1305             if (cur.receiver != receiver || cur.event == 0 || cur.event->type() != event->type())
1306                 continue;
1307             if (cur.event->type() == QEvent::LayoutRequest
1308 #ifdef QT3_SUPPORT
1309                  || cur.event->type() == QEvent::LayoutHint
1310 #endif
1311                  || cur.event->type() == QEvent::UpdateRequest) {
1312                 ;
1313             } else if (cur.event->type() == QEvent::Resize) {
1314                 ((QResizeEvent *)(cur.event))->s = ((QResizeEvent *)event)->s;
1315             } else if (cur.event->type() == QEvent::Move) {
1316                 ((QMoveEvent *)(cur.event))->p = ((QMoveEvent *)event)->p;
1317             } else if (cur.event->type() == QEvent::LanguageChange) {
1318                 ;
1319             } else if (cur.event->type() == QEvent::UpdateSoftKeys) {
1320                 ;
1321             } else if ( cur.event->type() == QEvent::InputMethod ) {
1322                 *(QInputMethodEvent *)(cur.event) = *(QInputMethodEvent *)event;
1323             } else {
1324                 continue;
1325             }
1326             delete event;
1327             return true;
1328         }
1329         return false;
1330     }
1331     return QCoreApplication::compressEvent(event, receiver, postedEvents);
1332 }
1333 
1334 /*!
1335     \property QApplication::styleSheet
1336     \brief the application style sheet
1337     \since 4.2
1338 
1339     By default, this property returns an empty string unless the user specifies
1340     the \c{-stylesheet} option on the command line when running the application.
1341 
1342     \sa QWidget::setStyle(), {Qt Style Sheets}
1343 */
1344 
1345 /*!
1346     \property QApplication::autoMaximizeThreshold
1347     \since 4.4
1348     \brief defines a threshold for auto maximizing widgets
1349 
1350     \bold{The auto maximize threshold is only available as part of Qt for
1351     Windows CE.}
1352 
1353     This property defines a threshold for the size of a window as a percentage
1354     of the screen size. If the minimum size hint of a window exceeds the
1355     threshold, calling show() will cause the window to be maximized
1356     automatically.
1357 
1358     Setting the threshold to 100 or greater means that the widget will always
1359     be maximized. Alternatively, setting the threshold to 50 means that the
1360     widget will be maximized only if the vertical minimum size hint is at least
1361     50% of the vertical screen size.
1362 
1363     Setting the threshold to -1 disables the feature.
1364 
1365     On Windows CE the default is -1 (i.e., it is disabled).
1366     On Windows Mobile the default is 40.
1367 */
1368 
1369 /*!
1370     \property QApplication::autoSipEnabled
1371     \since 4.5
1372     \brief toggles automatic SIP (software input panel) visibility
1373 
1374     Set this property to \c true to automatically display the SIP when entering
1375     widgets that accept keyboard input. This property only affects widgets with
1376     the WA_InputMethodEnabled attribute set, and is typically used to launch
1377     a virtual keyboard on devices which have very few or no keys.
1378 
1379     \bold{ The property only has an effect on platforms which use software input
1380     panels, such as Windows CE and Symbian.}
1381 
1382     The default is platform dependent.
1383 */
1384 
1385 #ifdef Q_WS_WINCE
setAutoMaximizeThreshold(const int threshold)1386 void QApplication::setAutoMaximizeThreshold(const int threshold)
1387 {
1388     QApplicationPrivate::autoMaximizeThreshold = threshold;
1389 }
1390 
autoMaximizeThreshold() const1391 int QApplication::autoMaximizeThreshold() const
1392 {
1393     return QApplicationPrivate::autoMaximizeThreshold;
1394 }
1395 #endif
1396 
setAutoSipEnabled(const bool enabled)1397 void QApplication::setAutoSipEnabled(const bool enabled)
1398 {
1399     QApplicationPrivate::autoSipEnabled = enabled;
1400 }
1401 
autoSipEnabled() const1402 bool QApplication::autoSipEnabled() const
1403 {
1404     return QApplicationPrivate::autoSipEnabled;
1405 }
1406 
1407 #ifndef QT_NO_STYLE_STYLESHEET
1408 
styleSheet() const1409 QString QApplication::styleSheet() const
1410 {
1411     return QApplicationPrivate::styleSheet;
1412 }
1413 
setStyleSheet(const QString & styleSheet)1414 void QApplication::setStyleSheet(const QString& styleSheet)
1415 {
1416     QApplicationPrivate::styleSheet = styleSheet;
1417     QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
1418     if (styleSheet.isEmpty()) { // application style sheet removed
1419         if (!proxy)
1420             return; // there was no stylesheet before
1421         setStyle(proxy->base);
1422     } else if (proxy) { // style sheet update, just repolish
1423         proxy->repolish(qApp);
1424     } else { // stylesheet set the first time
1425         QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
1426         QApplicationPrivate::app_style->setParent(newProxy);
1427         setStyle(newProxy);
1428     }
1429 }
1430 
1431 #endif // QT_NO_STYLE_STYLESHEET
1432 
1433 /*!
1434     Returns the application's style object.
1435 
1436     \sa setStyle(), QStyle
1437 */
style()1438 QStyle *QApplication::style()
1439 {
1440     if (QApplicationPrivate::app_style)
1441         return QApplicationPrivate::app_style;
1442     if (!qt_is_gui_used) {
1443         Q_ASSERT(!"No style available in non-gui applications!");
1444         return 0;
1445     }
1446 
1447     if (!QApplicationPrivate::app_style) {
1448         // Compile-time search for default style
1449         //
1450         QString style;
1451 #ifdef QT_BUILD_INTERNAL
1452         QString envStyle = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
1453 #else
1454         QString envStyle;
1455 #endif
1456         if (!QApplicationPrivate::styleOverride.isEmpty()) {
1457             style = QApplicationPrivate::styleOverride;
1458         } else if (!envStyle.isEmpty()) {
1459             style = envStyle;
1460         } else {
1461             style = QApplicationPrivate::desktopStyleKey();
1462         }
1463 
1464         QStyle *&app_style = QApplicationPrivate::app_style;
1465         app_style = QStyleFactory::create(style);
1466         if (!app_style) {
1467             QStringList styles = QStyleFactory::keys();
1468             for (int i = 0; i < styles.size(); ++i) {
1469                 if ((app_style = QStyleFactory::create(styles.at(i))))
1470                     break;
1471             }
1472         }
1473         if (!app_style) {
1474             Q_ASSERT(!"No styles available!");
1475             return 0;
1476         }
1477     }
1478     // take ownership of the style
1479     QApplicationPrivate::app_style->setParent(qApp);
1480 
1481     if (!QApplicationPrivate::sys_pal)
1482         QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
1483     if (QApplicationPrivate::set_pal) // repolish set palette with the new style
1484         QApplication::setPalette(*QApplicationPrivate::set_pal);
1485 
1486 #ifndef QT_NO_STYLE_STYLESHEET
1487     if (!QApplicationPrivate::styleSheet.isEmpty()) {
1488         qApp->setStyleSheet(QApplicationPrivate::styleSheet);
1489     } else
1490 #endif
1491         QApplicationPrivate::app_style->polish(qApp);
1492 
1493     return QApplicationPrivate::app_style;
1494 }
1495 
1496 /*!
1497     Sets the application's GUI style to \a style. Ownership of the style object
1498     is transferred to QApplication, so QApplication will delete the style
1499     object on application exit or when a new style is set and the old style is
1500     still the parent of the application object.
1501 
1502     Example usage:
1503     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 1
1504 
1505     When switching application styles, the color palette is set back to the
1506     initial colors or the system defaults. This is necessary since certain
1507     styles have to adapt the color palette to be fully style-guide compliant.
1508 
1509     Setting the style before a palette has been set, i.e., before creating
1510     QApplication, will cause the application to use QStyle::standardPalette()
1511     for the palette.
1512 
1513     \warning Qt style sheets are currently not supported for custom QStyle
1514     subclasses. We plan to address this in some future release.
1515 
1516     \sa style(), QStyle, setPalette(), desktopSettingsAware()
1517 */
setStyle(QStyle * style)1518 void QApplication::setStyle(QStyle *style)
1519 {
1520     if (!style || style == QApplicationPrivate::app_style)
1521         return;
1522 
1523     QWidgetList all = allWidgets();
1524 
1525     // clean up the old style
1526     if (QApplicationPrivate::app_style) {
1527         if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1528             for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
1529                 register QWidget *w = *it;
1530                 if (!(w->windowType() == Qt::Desktop) &&        // except desktop
1531                      w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
1532                     QApplicationPrivate::app_style->unpolish(w);
1533                 }
1534             }
1535         }
1536         QApplicationPrivate::app_style->unpolish(qApp);
1537     }
1538 
1539     QStyle *old = QApplicationPrivate::app_style; // save
1540 
1541 #ifndef QT_NO_STYLE_STYLESHEET
1542     if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
1543         // we have a stylesheet already and a new style is being set
1544         QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
1545         style->setParent(newProxy);
1546         QApplicationPrivate::app_style = newProxy;
1547     } else
1548 #endif // QT_NO_STYLE_STYLESHEET
1549         QApplicationPrivate::app_style = style;
1550     QApplicationPrivate::app_style->setParent(qApp); // take ownership
1551 
1552     // take care of possible palette requirements of certain gui
1553     // styles. Do it before polishing the application since the style
1554     // might call QApplication::setPalette() itself
1555     if (QApplicationPrivate::set_pal) {
1556         QApplication::setPalette(*QApplicationPrivate::set_pal);
1557     } else if (QApplicationPrivate::sys_pal) {
1558         QApplicationPrivate::initializeWidgetPaletteHash();
1559         QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
1560     } else if (!QApplicationPrivate::sys_pal) {
1561         // Initialize the sys_pal if it hasn't happened yet...
1562         QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
1563     }
1564 
1565     // initialize the application with the new style
1566     QApplicationPrivate::app_style->polish(qApp);
1567 
1568     // re-polish existing widgets if necessary
1569     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1570         for (QWidgetList::ConstIterator it1 = all.constBegin(); it1 != all.constEnd(); ++it1) {
1571             register QWidget *w = *it1;
1572             if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
1573                 if (w->style() == QApplicationPrivate::app_style)
1574                     QApplicationPrivate::app_style->polish(w);                // repolish
1575 #ifndef QT_NO_STYLE_STYLESHEET
1576                 else
1577                     w->setStyleSheet(w->styleSheet()); // touch
1578 #endif
1579             }
1580         }
1581 
1582         for (QWidgetList::ConstIterator it2 = all.constBegin(); it2 != all.constEnd(); ++it2) {
1583             register QWidget *w = *it2;
1584             if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
1585                     QEvent e(QEvent::StyleChange);
1586                     QApplication::sendEvent(w, &e);
1587 #ifdef QT3_SUPPORT
1588                     if (old)
1589                         w->styleChange(*old);
1590 #endif
1591                     w->update();
1592             }
1593         }
1594     }
1595 
1596 #ifndef QT_NO_STYLE_STYLESHEET
1597     if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
1598         oldProxy->deref();
1599     } else
1600 #endif
1601     if (old && old->parent() == qApp) {
1602         delete old;
1603     }
1604 
1605     if (QApplicationPrivate::focus_widget) {
1606         QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
1607         QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
1608         QApplicationPrivate::focus_widget->update();
1609     }
1610 }
1611 
1612 /*!
1613     \overload
1614 
1615     Requests a QStyle object for \a style from the QStyleFactory.
1616 
1617     The string must be one of the QStyleFactory::keys(), typically one of
1618     "windows", "motif", "cde", "plastique", "windowsxp", or "macintosh". Style
1619     names are case insensitive.
1620 
1621     Returns 0 if an unknown \a style is passed, otherwise the QStyle object
1622     returned is set as the application's GUI style.
1623 
1624     \warning To ensure that the application's style is set correctly, it is
1625     best to call this function before the QApplication constructor, if
1626     possible.
1627 */
setStyle(const QString & style)1628 QStyle* QApplication::setStyle(const QString& style)
1629 {
1630     QStyle *s = QStyleFactory::create(style);
1631     if (!s)
1632         return 0;
1633 
1634     setStyle(s);
1635     return s;
1636 }
1637 
1638 /*!
1639     \since 4.5
1640 
1641     Sets the default graphics backend to \a system, which will be used for
1642     on-screen widgets and QPixmaps. The available systems are \c{"native"},
1643     \c{"raster"} and \c{"opengl"}.
1644 
1645     There are several ways to set the graphics backend, in order of decreasing
1646     precedence:
1647     \list
1648         \o the application commandline \c{-graphicssystem} switch
1649         \o QApplication::setGraphicsSystem()
1650         \o the QT_GRAPHICSSYSTEM environment variable
1651         \o the Qt configure \c{-graphicssystem} switch
1652     \endlist
1653     If the highest precedence switch sets an invalid name, the error will be
1654     ignored and the default backend will be used.
1655 
1656     \warning This function is only effective before the QApplication constructor
1657     is called.
1658 
1659     \note The \c{"opengl"} option is currently experimental.
1660 */
1661 
setGraphicsSystem(const QString & system)1662 void QApplication::setGraphicsSystem(const QString &system)
1663 {
1664 #ifdef Q_WS_QPA
1665         Q_UNUSED(system);
1666 #else
1667 # ifdef QT_GRAPHICSSYSTEM_RUNTIME
1668     if (QApplicationPrivate::graphics_system_name == QLatin1String("runtime")) {
1669         QRuntimeGraphicsSystem *r =
1670                 static_cast<QRuntimeGraphicsSystem *>(QApplicationPrivate::graphics_system);
1671         r->setGraphicsSystem(system);
1672     } else
1673 # endif
1674         QApplicationPrivate::graphics_system_name = system;
1675 #endif
1676 }
1677 
1678 /*!
1679     Returns the color specification.
1680 
1681     \sa QApplication::setColorSpec()
1682 */
1683 
colorSpec()1684 int QApplication::colorSpec()
1685 {
1686     return QApplicationPrivate::app_cspec;
1687 }
1688 
1689 /*!
1690     Sets the color specification for the application to \a spec.
1691 
1692     The color specification controls how the application allocates colors when
1693     run on a display with a limited amount of colors, e.g. 8 bit / 256 color
1694     displays.
1695 
1696     The color specification must be set before you create the QApplication
1697     object.
1698 
1699     The options are:
1700     \list
1701         \o  QApplication::NormalColor. This is the default color allocation
1702             strategy. Use this option if your application uses buttons, menus,
1703             texts and pixmaps with few colors. With this option, the
1704             application uses system global colors. This works fine for most
1705             applications under X11, but on the Windows platform, it may cause
1706             dithering of non-standard colors.
1707         \o  QApplication::CustomColor. Use this option if your application
1708             needs a small number of custom colors. On X11, this option is the
1709             same as NormalColor. On Windows, Qt creates a Windows palette, and
1710             allocates colors to it on demand.
1711         \o  QApplication::ManyColor. Use this option if your application is
1712             very color hungry, e.g., it requires thousands of colors. \br
1713             Under X11 the effect is:
1714             \list
1715                 \o  For 256-color displays which have at best a 256 color true
1716                     color visual, the default visual is used, and colors are
1717                     allocated from a color cube. The color cube is the 6x6x6
1718                     (216 color) "Web palette" (the red, green, and blue
1719                     components always have one of the following values: 0x00,
1720                     0x33, 0x66, 0x99, 0xCC, or 0xFF), but the number of colors
1721                     can be changed by the \e -ncols option. The user can force
1722                     the application to use the true color visual with the
1723                     \l{QApplication::QApplication()}{-visual} option.
1724                 \o  For 256-color displays which have a true color visual with
1725                     more than 256 colors, use that visual. Silicon Graphics X
1726                     servers this feature, for example. They provide an 8 bit
1727                     visual by default but can deliver true color when asked.
1728             \endlist
1729             On Windows, Qt creates a Windows palette, and fills it with a color
1730             cube.
1731     \endlist
1732 
1733     Be aware that the CustomColor and ManyColor choices may lead to colormap
1734     flashing: The foreground application gets (most) of the available colors,
1735     while the background windows will look less attractive.
1736 
1737     Example:
1738 
1739     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 2
1740 
1741     \sa colorSpec()
1742 */
1743 
setColorSpec(int spec)1744 void QApplication::setColorSpec(int spec)
1745 {
1746     if (qApp)
1747         qWarning("QApplication::setColorSpec: This function must be "
1748                  "called before the QApplication object is created");
1749     QApplicationPrivate::app_cspec = spec;
1750 }
1751 
1752 /*!
1753     \property QApplication::globalStrut
1754     \brief the minimum size that any GUI element that the user can interact
1755            with should have
1756 
1757     For example, no button should be resized to be smaller than the global
1758     strut size. The strut size should be considered when reimplementing GUI
1759     controls that may be used on touch-screens or similar I/O devices.
1760 
1761     Example:
1762 
1763     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 3
1764 
1765     By default, this property contains a QSize object with zero width and height.
1766 */
globalStrut()1767 QSize QApplication::globalStrut()
1768 {
1769     return QApplicationPrivate::app_strut;
1770 }
1771 
setGlobalStrut(const QSize & strut)1772 void QApplication::setGlobalStrut(const QSize& strut)
1773 {
1774     QApplicationPrivate::app_strut = strut;
1775 }
1776 
1777 /*!
1778     Returns the application palette.
1779 
1780     \sa setPalette(), QWidget::palette()
1781 */
palette()1782 QPalette QApplication::palette()
1783 {
1784     if (!QApplicationPrivate::app_pal)
1785         QApplicationPrivate::app_pal = new QPalette(Qt::black);
1786     return *QApplicationPrivate::app_pal;
1787 }
1788 
1789 /*!
1790     \fn QPalette QApplication::palette(const QWidget* widget)
1791     \overload
1792 
1793     If a \a widget is passed, the default palette for the widget's class is
1794     returned. This may or may not be the application palette. In most cases
1795     there is no special palette for certain types of widgets, but one notable
1796     exception is the popup menu under Windows, if the user has defined a
1797     special background color for menus in the display settings.
1798 
1799     \sa setPalette(), QWidget::palette()
1800 */
palette(const QWidget * w)1801 QPalette QApplication::palette(const QWidget* w)
1802 {
1803     PaletteHash *hash = app_palettes();
1804     if (w && hash && hash->size()) {
1805         QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(w->metaObject()->className());
1806         if (it != hash->constEnd())
1807             return *it;
1808         for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
1809             if (w->inherits(it.key()))
1810                 return it.value();
1811         }
1812     }
1813     return palette();
1814 }
1815 
1816 /*!
1817     \overload
1818 
1819     Returns the palette for widgets of the given \a className.
1820 
1821     \sa setPalette(), QWidget::palette()
1822 */
palette(const char * className)1823 QPalette QApplication::palette(const char *className)
1824 {
1825     if (!QApplicationPrivate::app_pal)
1826         palette();
1827     PaletteHash *hash = app_palettes();
1828     if (className && hash && hash->size()) {
1829         QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(className);
1830         if (it != hash->constEnd())
1831             return *it;
1832     }
1833     return *QApplicationPrivate::app_pal;
1834 }
1835 
setPalette_helper(const QPalette & palette,const char * className,bool clearWidgetPaletteHash)1836 void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash)
1837 {
1838     QPalette pal = palette;
1839 
1840     if (QApplicationPrivate::app_style)
1841         QApplicationPrivate::app_style->polish(pal); // NB: non-const reference
1842 
1843     bool all = false;
1844     PaletteHash *hash = app_palettes();
1845     if (!className) {
1846         if (QApplicationPrivate::app_pal && pal.isCopyOf(*QApplicationPrivate::app_pal))
1847             return;
1848         if (!QApplicationPrivate::app_pal)
1849             QApplicationPrivate::app_pal = new QPalette(pal);
1850         else
1851             *QApplicationPrivate::app_pal = pal;
1852         if (hash && hash->size()) {
1853             all = true;
1854             if (clearWidgetPaletteHash)
1855                 hash->clear();
1856         }
1857     } else if (hash) {
1858         hash->insert(className, pal);
1859     }
1860 
1861     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1862         // Send ApplicationPaletteChange to qApp itself, and to the widgets.
1863         QEvent e(QEvent::ApplicationPaletteChange);
1864         QApplication::sendEvent(QApplication::instance(), &e);
1865 
1866         QWidgetList wids = QApplication::allWidgets();
1867         for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
1868             register QWidget *w = *it;
1869             if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
1870                 QApplication::sendEvent(w, &e);
1871         }
1872 
1873         // Send to all scenes as well.
1874 #ifndef QT_NO_GRAPHICSVIEW
1875         QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
1876         for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
1877              it != scenes.constEnd(); ++it) {
1878             QApplication::sendEvent(*it, &e);
1879         }
1880 #endif //QT_NO_GRAPHICSVIEW
1881     }
1882     if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) {
1883         if (!QApplicationPrivate::set_pal)
1884             QApplicationPrivate::set_pal = new QPalette(palette);
1885         else
1886             *QApplicationPrivate::set_pal = palette;
1887     }
1888 }
1889 
1890 /*!
1891     Changes the default application palette to \a palette.
1892 
1893     If \a className is passed, the change applies only to widgets that inherit
1894     \a className (as reported by QObject::inherits()). If \a className is left
1895     0, the change affects all widgets, thus overriding any previously set class
1896     specific palettes.
1897 
1898     The palette may be changed according to the current GUI style in
1899     QStyle::polish().
1900 
1901     \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
1902     When using style sheets, the palette of a widget can be customized using
1903     the "color", "background-color", "selection-color",
1904     "selection-background-color" and "alternate-background-color".
1905 
1906     \note Some styles do not use the palette for all drawing, for instance, if
1907     they make use of native theme engines. This is the case for the Windows XP,
1908     Windows Vista, and Mac OS X styles.
1909 
1910     \sa QWidget::setPalette(), palette(), QStyle::polish()
1911 */
1912 
setPalette(const QPalette & palette,const char * className)1913 void QApplication::setPalette(const QPalette &palette, const char* className)
1914 {
1915     QApplicationPrivate::setPalette_helper(palette, className, /*clearWidgetPaletteHash=*/ true);
1916 }
1917 
1918 
1919 
setSystemPalette(const QPalette & pal)1920 void QApplicationPrivate::setSystemPalette(const QPalette &pal)
1921 {
1922     QPalette adjusted;
1923 
1924 #if 0
1925     // adjust the system palette to avoid dithering
1926     QColormap cmap = QColormap::instance();
1927     if (cmap.depths() > 4 && cmap.depths() < 24) {
1928         for (int g = 0; g < QPalette::NColorGroups; g++)
1929             for (int i = 0; i < QPalette::NColorRoles; i++) {
1930                 QColor color = pal.color((QPalette::ColorGroup)g, (QPalette::ColorRole)i);
1931                 color = cmap.colorAt(cmap.pixel(color));
1932                 adjusted.setColor((QPalette::ColorGroup)g, (QPalette::ColorRole) i, color);
1933             }
1934     }
1935 #else
1936     adjusted = pal;
1937 #endif
1938 
1939     if (!sys_pal)
1940         sys_pal = new QPalette(adjusted);
1941     else
1942         *sys_pal = adjusted;
1943 
1944 
1945     if (!QApplicationPrivate::set_pal)
1946         QApplication::setPalette(*sys_pal);
1947 }
1948 
1949 /*!
1950     Returns the default application font.
1951 
1952     \sa fontMetrics(), QWidget::font()
1953 */
font()1954 QFont QApplication::font()
1955 {
1956     QMutexLocker locker(applicationFontMutex());
1957     if (!QApplicationPrivate::app_font) {
1958 #if defined(Q_OS_BLACKBERRY)
1959         // See http://docs.blackberry.com/en/developers/deliverables/41577/typography.jsp
1960         // which recommends using font family "Slate Pro" and normal font size of 8 points
1961         QApplicationPrivate::app_font = new QFont(QLatin1String("Slate Pro"));
1962         QApplicationPrivate::app_font->setPointSize(8);
1963 #else
1964         QApplicationPrivate::app_font = new QFont(QLatin1String("Helvetica"));
1965 #endif
1966     }
1967     return *QApplicationPrivate::app_font;
1968 }
1969 
1970 /*!
1971     \overload
1972 
1973     Returns the default font for the \a widget.
1974 
1975     \sa fontMetrics(), QWidget::setFont()
1976 */
1977 
font(const QWidget * widget)1978 QFont QApplication::font(const QWidget *widget)
1979 {
1980     FontHash *hash = app_fonts();
1981 
1982 #ifdef Q_WS_MAC
1983     // short circuit for small and mini controls
1984     if (widget->testAttribute(Qt::WA_MacSmallSize)) {
1985         return hash->value("QSmallFont");
1986     } else if (widget->testAttribute(Qt::WA_MacMiniSize)) {
1987         return hash->value("QMiniFont");
1988     }
1989 #endif
1990     if (widget && hash  && hash->size()) {
1991         QHash<QByteArray, QFont>::ConstIterator it =
1992                 hash->constFind(widget->metaObject()->className());
1993         if (it != hash->constEnd())
1994             return it.value();
1995         for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
1996             if (widget->inherits(it.key()))
1997                 return it.value();
1998         }
1999     }
2000     return font();
2001 }
2002 
2003 /*!
2004     \overload
2005 
2006     Returns the font for widgets of the given \a className.
2007 
2008     \sa setFont(), QWidget::font()
2009 */
font(const char * className)2010 QFont QApplication::font(const char *className)
2011 {
2012     FontHash *hash = app_fonts();
2013     if (className && hash && hash->size()) {
2014         QHash<QByteArray, QFont>::ConstIterator it = hash->constFind(className);
2015         if (it != hash->constEnd())
2016             return *it;
2017     }
2018     return font();
2019 }
2020 
2021 
2022 /*!
2023     Changes the default application font to \a font. If \a className is passed,
2024     the change applies only to classes that inherit \a className (as reported
2025     by QObject::inherits()).
2026 
2027     On application start-up, the default font depends on the window system. It
2028     can vary depending on both the window system version and the locale. This
2029     function lets you override the default font; but overriding may be a bad
2030     idea because, for example, some locales need extra large fonts to support
2031     their special characters.
2032 
2033     \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
2034     The font of an application can be customized using the "font" style sheet
2035     property. To set a bold font for all QPushButtons, set the application
2036     styleSheet() as "QPushButton { font: bold }"
2037 
2038     \sa font(), fontMetrics(), QWidget::setFont()
2039 */
2040 
setFont(const QFont & font,const char * className)2041 void QApplication::setFont(const QFont &font, const char *className)
2042 {
2043     bool all = false;
2044     FontHash *hash = app_fonts();
2045     if (!className) {
2046         QMutexLocker locker(applicationFontMutex());
2047         if (!QApplicationPrivate::app_font)
2048             QApplicationPrivate::app_font = new QFont(font);
2049         else
2050             *QApplicationPrivate::app_font = font;
2051         if (hash && hash->size()) {
2052             all = true;
2053             hash->clear();
2054         }
2055     } else if (hash) {
2056         hash->insert(className, font);
2057     }
2058     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
2059         // Send ApplicationFontChange to qApp itself, and to the widgets.
2060         QEvent e(QEvent::ApplicationFontChange);
2061         QApplication::sendEvent(QApplication::instance(), &e);
2062 
2063         QWidgetList wids = QApplication::allWidgets();
2064         for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
2065             register QWidget *w = *it;
2066             if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
2067                 sendEvent(w, &e);
2068         }
2069 
2070 #ifndef QT_NO_GRAPHICSVIEW
2071         // Send to all scenes as well.
2072         QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
2073         for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
2074              it != scenes.constEnd(); ++it) {
2075             QApplication::sendEvent(*it, &e);
2076         }
2077 #endif //QT_NO_GRAPHICSVIEW
2078     }
2079     if (!className && (!QApplicationPrivate::sys_font || !font.isCopyOf(*QApplicationPrivate::sys_font))) {
2080         if (!QApplicationPrivate::set_font)
2081             QApplicationPrivate::set_font = new QFont(font);
2082         else
2083             *QApplicationPrivate::set_font = font;
2084     }
2085 }
2086 
2087 /*! \internal
2088 */
setSystemFont(const QFont & font)2089 void QApplicationPrivate::setSystemFont(const QFont &font)
2090 {
2091      if (!sys_font)
2092         sys_font = new QFont(font);
2093     else
2094         *sys_font = font;
2095 
2096     if (!QApplicationPrivate::set_font)
2097         QApplication::setFont(*sys_font);
2098 }
2099 
2100 /*! \internal
2101 */
desktopStyleKey()2102 QString QApplicationPrivate::desktopStyleKey()
2103 {
2104     return qt_guiPlatformPlugin()->styleName();
2105 }
2106 
2107 /*!
2108     \property QApplication::windowIcon
2109     \brief the default window icon
2110 
2111     \sa QWidget::setWindowIcon(), {Setting the Application Icon}
2112 */
windowIcon()2113 QIcon QApplication::windowIcon()
2114 {
2115     return QApplicationPrivate::app_icon ? *QApplicationPrivate::app_icon : QIcon();
2116 }
2117 
setWindowIcon(const QIcon & icon)2118 void QApplication::setWindowIcon(const QIcon &icon)
2119 {
2120     if (!QApplicationPrivate::app_icon)
2121         QApplicationPrivate::app_icon = new QIcon();
2122     *QApplicationPrivate::app_icon = icon;
2123     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
2124 #ifdef Q_WS_MAC
2125         void qt_mac_set_app_icon(const QPixmap &); //qapplication_mac.cpp
2126         QSize size = QApplicationPrivate::app_icon->actualSize(QSize(128, 128));
2127         qt_mac_set_app_icon(QApplicationPrivate::app_icon->pixmap(size));
2128 #endif
2129         QEvent e(QEvent::ApplicationWindowIconChange);
2130         QWidgetList all = QApplication::allWidgets();
2131         for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
2132             register QWidget *w = *it;
2133             if (w->isWindow())
2134                 sendEvent(w, &e);
2135         }
2136     }
2137 }
2138 
2139 /*!
2140     Returns a list of the top-level widgets (windows) in the application.
2141 
2142     \note Some of the top-level widgets may be hidden, for example a tooltip if
2143     no tooltip is currently shown.
2144 
2145     Example:
2146 
2147     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 4
2148 
2149     \sa allWidgets(), QWidget::isWindow(), QWidget::isHidden()
2150 */
topLevelWidgets()2151 QWidgetList QApplication::topLevelWidgets()
2152 {
2153     QWidgetList list;
2154     QWidgetList all = allWidgets();
2155 
2156     for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
2157         QWidget *w = *it;
2158         if (w->isWindow() && w->windowType() != Qt::Desktop)
2159             list.append(w);
2160     }
2161     return list;
2162 }
2163 
2164 /*!
2165     Returns a list of all the widgets in the application.
2166 
2167     The list is empty (QList::isEmpty()) if there are no widgets.
2168 
2169     \note Some of the widgets may be hidden.
2170 
2171     Example:
2172     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 5
2173 
2174     \sa topLevelWidgets(), QWidget::isVisible()
2175 */
2176 
allWidgets()2177 QWidgetList QApplication::allWidgets()
2178 {
2179     if (QWidgetPrivate::allWidgets)
2180         return QWidgetPrivate::allWidgets->toList();
2181     return QWidgetList();
2182 }
2183 
2184 /*!
2185     Returns the application widget that has the keyboard input focus, or 0 if
2186     no widget in this application has the focus.
2187 
2188     \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged()
2189 */
2190 
focusWidget()2191 QWidget *QApplication::focusWidget()
2192 {
2193     return QApplicationPrivate::focus_widget;
2194 }
2195 
setFocusWidget(QWidget * focus,Qt::FocusReason reason)2196 void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
2197 {
2198 #ifndef QT_NO_GRAPHICSVIEW
2199     if (focus && focus->window()->graphicsProxyWidget())
2200         return;
2201 #endif
2202 
2203     hidden_focus_widget = 0;
2204 
2205     if (focus != focus_widget) {
2206         if (focus && focus->isHidden()) {
2207             hidden_focus_widget = focus;
2208             return;
2209         }
2210 
2211         if (focus && (reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason)
2212             && qt_in_tab_key_event)
2213             focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
2214         else if (focus && reason == Qt::ShortcutFocusReason) {
2215             focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
2216         }
2217         QWidget *prev = focus_widget;
2218         focus_widget = focus;
2219 #ifndef QT_NO_IM
2220         if (prev && ((reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason
2221             && prev->testAttribute(Qt::WA_InputMethodEnabled))
2222             // Do reset the input context, in case the new focus widget won't accept keyboard input
2223             // or it is not created fully yet.
2224             || (focus_widget && (!focus_widget->testAttribute(Qt::WA_InputMethodEnabled)
2225             || !focus_widget->testAttribute(Qt::WA_WState_Created))))) {
2226              QInputContext *qic = prev->inputContext();
2227             if(qic) {
2228                 qic->reset();
2229                 qic->setFocusWidget(0);
2230             }
2231         }
2232 #endif //QT_NO_IM
2233 
2234         if(focus_widget)
2235             focus_widget->d_func()->setFocus_sys();
2236 
2237         if (reason != Qt::NoFocusReason) {
2238 
2239             //send events
2240             if (prev) {
2241 #ifdef QT_KEYPAD_NAVIGATION
2242                 if (QApplication::keypadNavigationEnabled()) {
2243                     if (prev->hasEditFocus() && reason != Qt::PopupFocusReason
2244 #ifdef Q_OS_SYMBIAN
2245                             && reason != Qt::ActiveWindowFocusReason
2246 #endif
2247                             )
2248                         prev->setEditFocus(false);
2249                 }
2250 #endif
2251 #ifndef QT_NO_IM
2252                 if (focus) {
2253                     QInputContext *prevIc;
2254                     prevIc = prev->inputContext();
2255                     if (prevIc && prevIc != focus->inputContext()) {
2256                         QEvent closeSIPEvent(QEvent::CloseSoftwareInputPanel);
2257                         QApplication::sendEvent(prev, &closeSIPEvent);
2258                     }
2259                 }
2260 #endif
2261                 QFocusEvent out(QEvent::FocusOut, reason);
2262                 QPointer<QWidget> that = prev;
2263                 QApplication::sendEvent(prev, &out);
2264                 if (that)
2265                     QApplication::sendEvent(that->style(), &out);
2266             }
2267             if(focus && QApplicationPrivate::focus_widget == focus) {
2268 #ifndef QT_NO_IM
2269                 if (focus->testAttribute(Qt::WA_InputMethodEnabled)) {
2270                     QInputContext *qic = focus->inputContext();
2271                     if (qic && focus->testAttribute(Qt::WA_WState_Created)
2272                         && focus->isEnabled())
2273                         qic->setFocusWidget(focus);
2274                 }
2275 #endif //QT_NO_IM
2276                 QFocusEvent in(QEvent::FocusIn, reason);
2277                 QPointer<QWidget> that = focus;
2278                 QApplication::sendEvent(focus, &in);
2279                 if (that)
2280                     QApplication::sendEvent(that->style(), &in);
2281             }
2282             emit qApp->focusChanged(prev, focus_widget);
2283         }
2284     }
2285 }
2286 
2287 
2288 /*!
2289     Returns the application top-level window that has the keyboard input focus,
2290     or 0 if no application window has the focus. There might be an
2291     activeWindow() even if there is no focusWidget(), for example if no widget
2292     in that window accepts key events.
2293 
2294     \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget()
2295 */
2296 
activeWindow()2297 QWidget *QApplication::activeWindow()
2298 {
2299     return QApplicationPrivate::active_window;
2300 }
2301 
2302 /*!
2303     Returns display (screen) font metrics for the application font.
2304 
2305     \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
2306 */
2307 
fontMetrics()2308 QFontMetrics QApplication::fontMetrics()
2309 {
2310     return desktop()->fontMetrics();
2311 }
2312 
2313 
2314 /*!
2315     Closes all top-level windows.
2316 
2317     This function is particularly useful for applications with many top-level
2318     windows. It could, for example, be connected to a \gui{Exit} entry in the
2319     \gui{File} menu:
2320 
2321     \snippet examples/mainwindows/mdi/mainwindow.cpp 0
2322 
2323     The windows are closed in random order, until one window does not accept
2324     the close event. The application quits when the last window was
2325     successfully closed; this can be turned off by setting
2326     \l quitOnLastWindowClosed to false.
2327 
2328     \sa quitOnLastWindowClosed, lastWindowClosed(), QWidget::close(),
2329     QWidget::closeEvent(), lastWindowClosed(), quit(), topLevelWidgets(),
2330     QWidget::isWindow()
2331 */
closeAllWindows()2332 void QApplication::closeAllWindows()
2333 {
2334     bool did_close = true;
2335     QWidget *w;
2336     while ((w = activeModalWidget()) && did_close) {
2337         if (!w->isVisible() || w->data->is_closing)
2338             break;
2339         did_close = w->close();
2340     }
2341     QWidgetList list = QApplication::topLevelWidgets();
2342     for (int i = 0; did_close && i < list.size(); ++i) {
2343         w = list.at(i);
2344         if (w->isVisible()
2345             && w->windowType() != Qt::Desktop
2346             && !w->data->is_closing) {
2347             did_close = w->close();
2348             list = QApplication::topLevelWidgets();
2349             i = -1;
2350         }
2351     }
2352 }
2353 
2354 /*!
2355     Displays a simple message box about Qt. The message includes the version
2356     number of Qt being used by the application.
2357 
2358     This is useful for inclusion in the \gui Help menu of an application, as
2359     shown in the \l{mainwindows/menus}{Menus} example.
2360 
2361     This function is a convenience slot for QMessageBox::aboutQt().
2362 */
aboutQt()2363 void QApplication::aboutQt()
2364 {
2365 #ifndef QT_NO_MESSAGEBOX
2366     QMessageBox::aboutQt(
2367 #ifdef Q_WS_MAC
2368             0
2369 #else
2370             activeWindow()
2371 #endif // Q_WS_MAC
2372             );
2373 #endif // QT_NO_MESSAGEBOX
2374 }
2375 
2376 
2377 /*!
2378     \fn void QApplication::lastWindowClosed()
2379 
2380     This signal is emitted from QApplication::exec() when the last visible
2381     primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose
2382     attribute set is closed.
2383 
2384     By default,
2385 
2386     \list
2387         \o  this attribute is set for all widgets except transient windows such
2388             as splash screens, tool windows, and popup menus
2389 
2390         \o  QApplication implicitly quits when this signal is emitted.
2391     \endlist
2392 
2393     This feature can be turned off by setting \l quitOnLastWindowClosed to
2394     false.
2395 
2396     \sa QWidget::close()
2397 */
2398 
2399 /*!
2400     \since 4.1
2401     \fn void QApplication::focusChanged(QWidget *old, QWidget *now)
2402 
2403     This signal is emitted when the widget that has keyboard focus changed from
2404     \a old to \a now, i.e., because the user pressed the tab-key, clicked into
2405     a widget or changed the active window. Both \a old and \a now can be the
2406     null-pointer.
2407 
2408     The signal is emitted after both widget have been notified about the change
2409     through QFocusEvent.
2410 
2411     \sa QWidget::setFocus(), QWidget::clearFocus(), Qt::FocusReason
2412 */
2413 
2414 /*!
2415     \since 4.5
2416     \fn void QApplication::fontDatabaseChanged()
2417 
2418     This signal is emitted when application fonts are loaded or removed.
2419 
2420     \sa QFontDatabase::addApplicationFont(),
2421     QFontDatabase::addApplicationFontFromData(),
2422     QFontDatabase::removeAllApplicationFonts(),
2423     QFontDatabase::removeApplicationFont()
2424 */
2425 
2426 #ifndef QT_NO_TRANSLATION
qt_detectRTLLanguage()2427 static bool qt_detectRTLLanguage()
2428 {
2429     return force_reverse ^
2430         (QApplication::tr("QT_LAYOUT_DIRECTION",
2431                          "Translate this string to the string 'LTR' in left-to-right"
2432                          " languages or to 'RTL' in right-to-left languages (such as Hebrew"
2433                          " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
2434 }
2435 #if defined(Q_WS_MAC)
2436 static const char *application_menu_strings[] = {
2437     QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
2438     QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
2439     QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
2440     QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
2441     QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
2442     QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
2443     QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
2444     };
qt_mac_applicationmenu_string(int type)2445 QString qt_mac_applicationmenu_string(int type)
2446 {
2447     QString menuString = QString::fromLatin1(application_menu_strings[type]);
2448     QString translated = qApp->translate("QMenuBar", application_menu_strings[type]);
2449     if (translated != menuString)
2450         return translated;
2451     else
2452         return qApp->translate("MAC_APPLICATION_MENU",
2453                                application_menu_strings[type]);
2454 }
2455 #endif
2456 #endif
2457 
2458 /*!\reimp
2459 
2460 */
event(QEvent * e)2461 bool QApplication::event(QEvent *e)
2462 {
2463     Q_D(QApplication);
2464     if(e->type() == QEvent::Close) {
2465 #if defined(Q_OS_SYMBIAN)
2466         // In order to have proper application-exit effects on Symbian, certain
2467         // native APIs have to be called _before_ closing/destroying the widgets.
2468         bool effectStarted = qt_beginFullScreenEffect();
2469 #endif
2470         QCloseEvent *ce = static_cast<QCloseEvent*>(e);
2471         ce->accept();
2472         closeAllWindows();
2473 
2474         QWidgetList list = topLevelWidgets();
2475         for (int i = 0; i < list.size(); ++i) {
2476             QWidget *w = list.at(i);
2477             if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
2478                  (!(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
2479                 ce->ignore();
2480                 break;
2481             }
2482         }
2483         if (ce->isAccepted()) {
2484             return true;
2485         } else {
2486 #if defined(Q_OS_SYMBIAN)
2487             if (effectStarted)
2488                 qt_abortFullScreenEffect();
2489 #endif
2490         }
2491     } else if(e->type() == QEvent::LanguageChange) {
2492 #ifndef QT_NO_TRANSLATION
2493         setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
2494 #endif
2495 #if defined(QT_MAC_USE_COCOA)
2496         qt_mac_post_retranslateAppMenu();
2497 #endif
2498         QWidgetList list = topLevelWidgets();
2499         for (int i = 0; i < list.size(); ++i) {
2500             QWidget *w = list.at(i);
2501             if (!(w->windowType() == Qt::Desktop))
2502                 postEvent(w, new QEvent(QEvent::LanguageChange));
2503         }
2504 #ifndef Q_OS_WIN
2505     } else if (e->type() == QEvent::LocaleChange) {
2506         // on Windows the event propagation is taken care by the
2507         // WM_SETTINGCHANGE event handler.
2508         QWidgetList list = topLevelWidgets();
2509         for (int i = 0; i < list.size(); ++i) {
2510             QWidget *w = list.at(i);
2511             if (!(w->windowType() == Qt::Desktop)) {
2512                 if (!w->testAttribute(Qt::WA_SetLocale))
2513                     w->d_func()->setLocale_helper(QLocale(), true);
2514             }
2515         }
2516 #endif
2517     } else if (e->type() == QEvent::Timer) {
2518         QTimerEvent *te = static_cast<QTimerEvent*>(e);
2519         Q_ASSERT(te != 0);
2520         if (te->timerId() == d->toolTipWakeUp.timerId()) {
2521             d->toolTipWakeUp.stop();
2522             if (d->toolTipWidget) {
2523                 QWidget *w = d->toolTipWidget->window();
2524                 // show tooltip if WA_AlwaysShowToolTips is set, or if
2525                 // any ancestor of d->toolTipWidget is the active
2526                 // window
2527                 bool showToolTip = w->testAttribute(Qt::WA_AlwaysShowToolTips);
2528                 while (w && !showToolTip) {
2529                     showToolTip = w->isActiveWindow();
2530                     w = w->parentWidget();
2531                     w = w ? w->window() : 0;
2532                 }
2533                 if (showToolTip) {
2534                     QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos);
2535                     QApplication::sendEvent(d->toolTipWidget, &e);
2536                     if (e.isAccepted())
2537                         d->toolTipFallAsleep.start(2000, this);
2538                 }
2539             }
2540         } else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
2541             d->toolTipFallAsleep.stop();
2542         }
2543     }
2544     return QCoreApplication::event(e);
2545 }
2546 #if !defined(Q_WS_X11)
2547 
2548 // The doc and X implementation of this function is in qapplication_x11.cpp
2549 
syncX()2550 void QApplication::syncX()        {}                // do nothing
2551 
2552 #endif
2553 
2554 /*!
2555     \fn Qt::WindowsVersion QApplication::winVersion()
2556 
2557     Use \l QSysInfo::WindowsVersion instead.
2558 */
2559 
2560 /*!
2561     \fn void QApplication::setActiveWindow(QWidget* active)
2562 
2563     Sets the active window to the \a active widget in response to a system
2564     event. The function is called from the platform specific event handlers.
2565 
2566     \warning This function does \e not set the keyboard focus to the active
2567     widget. Call QWidget::activateWindow() instead.
2568 
2569     It sets the activeWindow() and focusWidget() attributes and sends proper
2570     \l{QEvent::WindowActivate}{WindowActivate}/\l{QEvent::WindowDeactivate}
2571     {WindowDeactivate} and \l{QEvent::FocusIn}{FocusIn}/\l{QEvent::FocusOut}
2572     {FocusOut} events to all appropriate widgets. The window will then be
2573     painted in active state (e.g. cursors in line edits will blink), and it
2574     will have tool tips enabled.
2575 
2576     \sa activeWindow(), QWidget::activateWindow()
2577 */
setActiveWindow(QWidget * act)2578 void QApplication::setActiveWindow(QWidget* act)
2579 {
2580     QWidget* window = act?act->window():0;
2581 
2582     if (QApplicationPrivate::active_window == window)
2583         return;
2584 
2585 #ifndef QT_NO_GRAPHICSVIEW
2586     if (window && window->graphicsProxyWidget()) {
2587         // Activate the proxy's view->viewport() ?
2588         return;
2589     }
2590 #endif
2591 
2592     QWidgetList toBeActivated;
2593     QWidgetList toBeDeactivated;
2594 
2595     if (QApplicationPrivate::active_window) {
2596         if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
2597             QWidgetList list = topLevelWidgets();
2598             for (int i = 0; i < list.size(); ++i) {
2599                 QWidget *w = list.at(i);
2600                 if (w->isVisible() && w->isActiveWindow())
2601                     toBeDeactivated.append(w);
2602             }
2603         } else {
2604             toBeDeactivated.append(QApplicationPrivate::active_window);
2605         }
2606     }
2607 
2608 #if !defined(Q_WS_MAC)
2609     QWidget *previousActiveWindow =  QApplicationPrivate::active_window;
2610 #endif
2611     QApplicationPrivate::active_window = window;
2612 
2613     if (QApplicationPrivate::active_window) {
2614         if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
2615             QWidgetList list = topLevelWidgets();
2616             for (int i = 0; i < list.size(); ++i) {
2617                 QWidget *w = list.at(i);
2618                 if (w->isVisible() && w->isActiveWindow())
2619                     toBeActivated.append(w);
2620             }
2621         } else {
2622             toBeActivated.append(QApplicationPrivate::active_window);
2623         }
2624 
2625     }
2626 
2627     // first the activation/deactivation events
2628     QEvent activationChange(QEvent::ActivationChange);
2629     QEvent windowActivate(QEvent::WindowActivate);
2630     QEvent windowDeactivate(QEvent::WindowDeactivate);
2631 
2632 #if !defined(Q_WS_MAC)
2633     if (!previousActiveWindow) {
2634         QEvent appActivate(QEvent::ApplicationActivate);
2635         sendSpontaneousEvent(qApp, &appActivate);
2636     }
2637 #endif
2638 
2639     for (int i = 0; i < toBeActivated.size(); ++i) {
2640         QWidget *w = toBeActivated.at(i);
2641         sendSpontaneousEvent(w, &windowActivate);
2642         sendSpontaneousEvent(w, &activationChange);
2643     }
2644 
2645 #ifdef QT_MAC_USE_COCOA
2646     // In case the user clicked on a child window, we need to
2647     // reestablish the stacking order of the window so
2648     // it pops in front of other child windows in cocoa:
2649     qt_cocoaStackChildWindowOnTopOfOtherChildren(window);
2650 #endif
2651 
2652     for(int i = 0; i < toBeDeactivated.size(); ++i) {
2653         QWidget *w = toBeDeactivated.at(i);
2654         sendSpontaneousEvent(w, &windowDeactivate);
2655         sendSpontaneousEvent(w, &activationChange);
2656     }
2657 
2658 #if !defined(Q_WS_MAC)
2659     if (!QApplicationPrivate::active_window) {
2660         QEvent appDeactivate(QEvent::ApplicationDeactivate);
2661         sendSpontaneousEvent(qApp, &appDeactivate);
2662     }
2663 #endif
2664 
2665     if (QApplicationPrivate::popupWidgets == 0) { // !inPopupMode()
2666         // then focus events
2667         if (!QApplicationPrivate::active_window && QApplicationPrivate::focus_widget) {
2668             QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
2669         } else if (QApplicationPrivate::active_window) {
2670             QWidget *w = QApplicationPrivate::active_window->focusWidget();
2671             if (w && w->isVisible() /*&& w->focusPolicy() != QWidget::NoFocus*/)
2672                 w->setFocus(Qt::ActiveWindowFocusReason);
2673             else {
2674                 w = QApplicationPrivate::focusNextPrevChild_helper(QApplicationPrivate::active_window, true);
2675                 if (w) {
2676                     w->setFocus(Qt::ActiveWindowFocusReason);
2677                 } else {
2678                     // If the focus widget is not in the activate_window, clear the focus
2679                     w = QApplicationPrivate::focus_widget;
2680                     if (!w && QApplicationPrivate::active_window->focusPolicy() != Qt::NoFocus)
2681                         QApplicationPrivate::setFocusWidget(QApplicationPrivate::active_window, Qt::ActiveWindowFocusReason);
2682                     else if (!QApplicationPrivate::active_window->isAncestorOf(w))
2683                         QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
2684                 }
2685             }
2686         }
2687     }
2688 }
2689 
2690 /*!internal
2691  * Helper function that returns the new focus widget, but does not set the focus reason.
2692  * Returns 0 if a new focus widget could not be found.
2693  * Shared with QGraphicsProxyWidgetPrivate::findFocusChild()
2694 */
focusNextPrevChild_helper(QWidget * toplevel,bool next)2695 QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next)
2696 {
2697     uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
2698 
2699     QWidget *f = toplevel->focusWidget();
2700     if (!f)
2701         f = toplevel;
2702 
2703     QWidget *w = f;
2704     QWidget *test = f->d_func()->focus_next;
2705     while (test && test != f) {
2706         if ((test->focusPolicy() & focus_flag) == focus_flag
2707             && !(test->d_func()->extra && test->d_func()->extra->focus_proxy)
2708             && test->isVisibleTo(toplevel) && test->isEnabled()
2709             && !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
2710             && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
2711             w = test;
2712             if (next)
2713                 break;
2714         }
2715         test = test->d_func()->focus_next;
2716     }
2717     if (w == f) {
2718         if (qt_in_tab_key_event) {
2719             w->window()->setAttribute(Qt::WA_KeyboardFocusChange);
2720             w->update();
2721         }
2722         return 0;
2723     }
2724     return w;
2725 }
2726 
2727 /*!
2728     \fn void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave)
2729     \internal
2730 
2731     Creates the proper Enter/Leave event when widget \a enter is entered and
2732     widget \a leave is left.
2733  */
dispatchEnterLeave(QWidget * enter,QWidget * leave)2734 void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
2735 #if 0
2736     if (leave) {
2737         QEvent e(QEvent::Leave);
2738         QApplication::sendEvent(leave, & e);
2739     }
2740     if (enter) {
2741         QEvent e(QEvent::Enter);
2742         QApplication::sendEvent(enter, & e);
2743     }
2744     return;
2745 #endif
2746 
2747     QWidget* w ;
2748     if ((!enter && !leave) || (enter == leave))
2749         return;
2750 #ifdef ALIEN_DEBUG
2751     qDebug() << "QApplicationPrivate::dispatchEnterLeave, ENTER:" << enter << "LEAVE:" << leave;
2752 #endif
2753     QWidgetList leaveList;
2754     QWidgetList enterList;
2755 
2756     bool sameWindow = leave && enter && leave->window() == enter->window();
2757     if (leave && !sameWindow) {
2758         w = leave;
2759         do {
2760             leaveList.append(w);
2761         } while (!w->isWindow() && (w = w->parentWidget()));
2762     }
2763     if (enter && !sameWindow) {
2764         w = enter;
2765         do {
2766             enterList.prepend(w);
2767         } while (!w->isWindow() && (w = w->parentWidget()));
2768     }
2769     if (sameWindow) {
2770         int enterDepth = 0;
2771         int leaveDepth = 0;
2772         w = enter;
2773         while (!w->isWindow() && (w = w->parentWidget()))
2774             enterDepth++;
2775         w = leave;
2776         while (!w->isWindow() && (w = w->parentWidget()))
2777             leaveDepth++;
2778         QWidget* wenter = enter;
2779         QWidget* wleave = leave;
2780         while (enterDepth > leaveDepth) {
2781             wenter = wenter->parentWidget();
2782             enterDepth--;
2783         }
2784         while (leaveDepth > enterDepth) {
2785             wleave = wleave->parentWidget();
2786             leaveDepth--;
2787         }
2788         while (!wenter->isWindow() && wenter != wleave) {
2789             wenter = wenter->parentWidget();
2790             wleave = wleave->parentWidget();
2791         }
2792 
2793         w = leave;
2794         while (w != wleave) {
2795             leaveList.append(w);
2796             w = w->parentWidget();
2797         }
2798         w = enter;
2799         while (w != wenter) {
2800             enterList.prepend(w);
2801             w = w->parentWidget();
2802         }
2803     }
2804 
2805     QEvent leaveEvent(QEvent::Leave);
2806     for (int i = 0; i < leaveList.size(); ++i) {
2807         w = leaveList.at(i);
2808         if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
2809 #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC)
2810             if (leaveAfterRelease == w)
2811                 leaveAfterRelease = 0;
2812 #endif
2813             QApplication::sendEvent(w, &leaveEvent);
2814             if (w->testAttribute(Qt::WA_Hover) &&
2815                 (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
2816                 Q_ASSERT(instance());
2817                 QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos));
2818                 qApp->d_func()->notify_helper(w, &he);
2819             }
2820         }
2821     }
2822     QPoint posEnter = QCursor::pos();
2823     QEvent enterEvent(QEvent::Enter);
2824     for (int i = 0; i < enterList.size(); ++i) {
2825         w = enterList.at(i);
2826         if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
2827             QApplication::sendEvent(w, &enterEvent);
2828             if (w->testAttribute(Qt::WA_Hover) &&
2829                 (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
2830                 QHoverEvent he(QEvent::HoverEnter, w->mapFromGlobal(posEnter), QPoint(-1, -1));
2831                 qApp->d_func()->notify_helper(w, &he);
2832             }
2833         }
2834     }
2835 
2836 #ifndef QT_NO_CURSOR
2837     // Update cursor for alien/graphics widgets.
2838 
2839     const bool enterOnAlien = (enter && (isAlien(enter) || enter->testAttribute(Qt::WA_DontShowOnScreen)));
2840 #if defined(Q_WS_X11) || defined(Q_WS_QPA)
2841     //Whenever we leave an alien widget on X11, we need to reset its nativeParentWidget()'s cursor.
2842     // This is not required on Windows as the cursor is reset on every single mouse move.
2843     QWidget *parentOfLeavingCursor = 0;
2844     for (int i = 0; i < leaveList.size(); ++i) {
2845         w = leaveList.at(i);
2846         if (!isAlien(w))
2847             break;
2848         if (w->testAttribute(Qt::WA_SetCursor)) {
2849             QWidget *parent = w->parentWidget();
2850             while (parent && parent->d_func()->data.in_destructor)
2851                 parent = parent->parentWidget();
2852             parentOfLeavingCursor = parent;
2853             //continue looping, we need to find the downest alien widget with a cursor.
2854             // (downest on the screen)
2855         }
2856     }
2857     //check that we will not call qt_x11_enforce_cursor twice with the same native widget
2858     if (parentOfLeavingCursor && (!enterOnAlien
2859         || parentOfLeavingCursor->effectiveWinId() != enter->effectiveWinId())) {
2860 #ifndef QT_NO_GRAPHICSVIEW
2861         if (!parentOfLeavingCursor->window()->graphicsProxyWidget())
2862 #endif
2863         {
2864 #if defined(Q_WS_X11)
2865             qt_x11_enforce_cursor(parentOfLeavingCursor,true);
2866 #elif defined(Q_WS_QPA)
2867             if (enter == QApplication::desktop()) {
2868                 qt_qpa_set_cursor(enter, true);
2869             } else {
2870                 qt_qpa_set_cursor(parentOfLeavingCursor, true);
2871             }
2872 #endif
2873         }
2874     }
2875 #endif
2876     if (enterOnAlien) {
2877         QWidget *cursorWidget = enter;
2878         while (!cursorWidget->isWindow() && !cursorWidget->isEnabled())
2879             cursorWidget = cursorWidget->parentWidget();
2880 
2881         if (!cursorWidget)
2882             return;
2883 
2884 #ifndef QT_NO_GRAPHICSVIEW
2885         if (cursorWidget->window()->graphicsProxyWidget()) {
2886             QWidgetPrivate::nearestGraphicsProxyWidget(cursorWidget)->setCursor(cursorWidget->cursor());
2887         } else
2888 #endif
2889         {
2890 #if defined(Q_WS_WIN)
2891             qt_win_set_cursor(cursorWidget, true);
2892 #elif defined(Q_WS_X11)
2893             qt_x11_enforce_cursor(cursorWidget, true);
2894 #elif defined(Q_OS_SYMBIAN)
2895             qt_symbian_set_cursor(cursorWidget, true);
2896 #elif defined(Q_WS_QPA)
2897             qt_qpa_set_cursor(cursorWidget, true);
2898 #endif
2899         }
2900     }
2901 #endif
2902 }
2903 
2904 /* exported for the benefit of testing tools */
qt_tryModalHelper(QWidget * widget,QWidget ** rettop)2905 Q_GUI_EXPORT bool qt_tryModalHelper(QWidget *widget, QWidget **rettop)
2906 {
2907     return QApplicationPrivate::tryModalHelper(widget, rettop);
2908 }
2909 
2910 /*! \internal
2911     Returns true if \a widget is blocked by a modal window.
2912  */
isBlockedByModal(QWidget * widget)2913 bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
2914 {
2915     widget = widget->window();
2916     if (!modalState())
2917         return false;
2918     if (QApplication::activePopupWidget() == widget)
2919         return false;
2920 
2921     for (int i = 0; i < qt_modal_stack->size(); ++i) {
2922         QWidget *modalWidget = qt_modal_stack->at(i);
2923 
2924         {
2925             // check if the active modal widget is our widget or a parent of our widget
2926             QWidget *w = widget;
2927             while (w) {
2928                 if (w == modalWidget)
2929                     return false;
2930                 w = w->parentWidget();
2931             }
2932 #ifdef Q_WS_WIN
2933             if ((widget->testAttribute(Qt::WA_WState_Created) || widget->data->winid)
2934                 && (modalWidget->testAttribute(Qt::WA_WState_Created) || modalWidget->data->winid)
2935                 && IsChild(modalWidget->data->winid, widget->data->winid))
2936                 return false;
2937 #endif
2938         }
2939 
2940         Qt::WindowModality windowModality = modalWidget->windowModality();
2941         if (windowModality == Qt::NonModal) {
2942             // determine the modality type if it hasn't been set on the
2943             // modalWidget, this normally happens when waiting for a
2944             // native dialog. use WindowModal if we are the child of a
2945             // group leader; otherwise use ApplicationModal.
2946             QWidget *m = modalWidget;
2947             while (m && !m->testAttribute(Qt::WA_GroupLeader)) {
2948                 m = m->parentWidget();
2949                 if (m)
2950                     m = m->window();
2951             }
2952             windowModality = (m && m->testAttribute(Qt::WA_GroupLeader))
2953                              ? Qt::WindowModal
2954                              : Qt::ApplicationModal;
2955         }
2956 
2957         switch (windowModality) {
2958         case Qt::ApplicationModal:
2959             {
2960                 QWidget *groupLeaderForWidget = widget;
2961                 while (groupLeaderForWidget && !groupLeaderForWidget->testAttribute(Qt::WA_GroupLeader))
2962                     groupLeaderForWidget = groupLeaderForWidget->parentWidget();
2963 
2964                 if (groupLeaderForWidget) {
2965                     // if \a widget has WA_GroupLeader, it can only be blocked by ApplicationModal children
2966                     QWidget *m = modalWidget;
2967                     while (m && m != groupLeaderForWidget && !m->testAttribute(Qt::WA_GroupLeader))
2968                         m = m->parentWidget();
2969                     if (m == groupLeaderForWidget)
2970                         return true;
2971                 } else if (modalWidget != widget) {
2972                     return true;
2973                 }
2974                 break;
2975             }
2976         case Qt::WindowModal:
2977             {
2978                 QWidget *w = widget;
2979                 do {
2980                     QWidget *m = modalWidget;
2981                     do {
2982                         if (m == w)
2983                             return true;
2984                         m = m->parentWidget();
2985                         if (m)
2986                             m = m->window();
2987                     } while (m);
2988                     w = w->parentWidget();
2989                     if (w)
2990                         w = w->window();
2991                 } while (w);
2992                 break;
2993             }
2994         default:
2995             Q_ASSERT_X(false, "QApplication", "internal error, a modal widget cannot be modeless");
2996             break;
2997         }
2998     }
2999     return false;
3000 }
3001 
3002 /*!\internal
3003  */
enterModal(QWidget * widget)3004 void QApplicationPrivate::enterModal(QWidget *widget)
3005 {
3006     QSet<QWidget*> blocked;
3007     QList<QWidget*> windows = QApplication::topLevelWidgets();
3008     for (int i = 0; i < windows.count(); ++i) {
3009         QWidget *window = windows.at(i);
3010         if (window->windowType() != Qt::Tool && isBlockedByModal(window))
3011             blocked.insert(window);
3012     }
3013 
3014     enterModal_sys(widget);
3015 
3016     windows = QApplication::topLevelWidgets();
3017     QEvent e(QEvent::WindowBlocked);
3018     for (int i = 0; i < windows.count(); ++i) {
3019         QWidget *window = windows.at(i);
3020         if (!blocked.contains(window) && window->windowType() != Qt::Tool && isBlockedByModal(window))
3021             QApplication::sendEvent(window, &e);
3022     }
3023 }
3024 
3025 /*!\internal
3026  */
leaveModal(QWidget * widget)3027 void QApplicationPrivate::leaveModal(QWidget *widget)
3028 {
3029     QSet<QWidget*> blocked;
3030     QList<QWidget*> windows = QApplication::topLevelWidgets();
3031     for (int i = 0; i < windows.count(); ++i) {
3032         QWidget *window = windows.at(i);
3033         if (window->windowType() != Qt::Tool && isBlockedByModal(window))
3034             blocked.insert(window);
3035     }
3036 
3037     leaveModal_sys(widget);
3038 
3039     windows = QApplication::topLevelWidgets();
3040     QEvent e(QEvent::WindowUnblocked);
3041     for (int i = 0; i < windows.count(); ++i) {
3042         QWidget *window = windows.at(i);
3043         if(blocked.contains(window) && window->windowType() != Qt::Tool && !isBlockedByModal(window))
3044             QApplication::sendEvent(window, &e);
3045     }
3046 }
3047 
3048 
3049 
3050 /*!\internal
3051 
3052   Called from qapplication_\e{platform}.cpp, returns true
3053   if the widget should accept the event.
3054  */
tryModalHelper(QWidget * widget,QWidget ** rettop)3055 bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop)
3056 {
3057     QWidget *top = QApplication::activeModalWidget();
3058     if (rettop)
3059         *rettop = top;
3060 
3061     // the active popup widget always gets the input event
3062     if (QApplication::activePopupWidget())
3063         return true;
3064 
3065 #if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
3066     top = QApplicationPrivate::tryModalHelper_sys(top);
3067     if (rettop)
3068         *rettop = top;
3069 #endif
3070 
3071     return !isBlockedByModal(widget->window());
3072 }
3073 
3074 /*
3075    \internal
3076 */
pickMouseReceiver(QWidget * candidate,const QPoint & globalPos,QPoint & pos,QEvent::Type type,Qt::MouseButtons buttons,QWidget * buttonDown,QWidget * alienWidget)3077 QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint &globalPos,
3078                                                 QPoint &pos, QEvent::Type type,
3079                                                 Qt::MouseButtons buttons, QWidget *buttonDown,
3080                                                 QWidget *alienWidget)
3081 {
3082     Q_ASSERT(candidate);
3083 
3084     QWidget *mouseGrabber = QWidget::mouseGrabber();
3085     if (((type == QEvent::MouseMove && buttons) || (type == QEvent::MouseButtonRelease))
3086             && !buttonDown && !mouseGrabber) {
3087         return 0;
3088     }
3089 
3090     if (alienWidget && alienWidget->internalWinId())
3091         alienWidget = 0;
3092 
3093     QWidget *receiver = candidate;
3094 
3095     if (!mouseGrabber)
3096         mouseGrabber = (buttonDown && !isBlockedByModal(buttonDown)) ? buttonDown : alienWidget;
3097 
3098     if (mouseGrabber && mouseGrabber != candidate) {
3099         receiver = mouseGrabber;
3100         pos = receiver->mapFromGlobal(globalPos);
3101 #ifdef ALIEN_DEBUG
3102         qDebug() << "  ** receiver adjusted to:" << receiver << "pos:" << pos;
3103 #endif
3104     }
3105 
3106     return receiver;
3107 
3108 }
3109 
3110 /*
3111    \internal
3112 */
sendMouseEvent(QWidget * receiver,QMouseEvent * event,QWidget * alienWidget,QWidget * nativeWidget,QWidget ** buttonDown,QPointer<QWidget> & lastMouseReceiver,bool spontaneous)3113 bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
3114                                          QWidget *alienWidget, QWidget *nativeWidget,
3115                                          QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
3116                                          bool spontaneous)
3117 {
3118     Q_ASSERT(receiver);
3119     Q_ASSERT(event);
3120     Q_ASSERT(nativeWidget);
3121     Q_ASSERT(buttonDown);
3122 
3123     if (alienWidget && !isAlien(alienWidget))
3124         alienWidget = 0;
3125 
3126     QPointer<QWidget> receiverGuard = receiver;
3127     QPointer<QWidget> nativeGuard = nativeWidget;
3128     QPointer<QWidget> alienGuard = alienWidget;
3129     QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
3130 
3131     const bool graphicsWidget = nativeWidget->testAttribute(Qt::WA_DontShowOnScreen);
3132 
3133     if (*buttonDown) {
3134         if (!graphicsWidget) {
3135             // Register the widget that shall receive a leave event
3136             // after the last button is released.
3137             if ((alienWidget || !receiver->internalWinId()) && !leaveAfterRelease && !QWidget::mouseGrabber())
3138                 leaveAfterRelease = *buttonDown;
3139             if (event->type() == QEvent::MouseButtonRelease && !event->buttons())
3140                 *buttonDown = 0;
3141         }
3142     } else if (lastMouseReceiver) {
3143         // Dispatch enter/leave if we move:
3144         // 1) from an alien widget to another alien widget or
3145         //    from a native widget to an alien widget (first OR case)
3146         // 2) from an alien widget to a native widget (second OR case)
3147         if ((alienWidget && alienWidget != lastMouseReceiver)
3148             || (isAlien(lastMouseReceiver) && !alienWidget)) {
3149             if (activePopupWidget) {
3150                 if (!QWidget::mouseGrabber())
3151                     dispatchEnterLeave(alienWidget ? alienWidget : nativeWidget, lastMouseReceiver);
3152             } else {
3153                 dispatchEnterLeave(receiver, lastMouseReceiver);
3154             }
3155 
3156         }
3157     }
3158 
3159 #ifdef ALIEN_DEBUG
3160     qDebug() << "QApplicationPrivate::sendMouseEvent: receiver:" << receiver
3161              << "pos:" << event->pos() << "alien" << alienWidget << "button down"
3162              << *buttonDown << "last" << lastMouseReceiver << "leave after release"
3163              << leaveAfterRelease;
3164 #endif
3165 
3166     // We need this quard in case someone opens a modal dialog / popup. If that's the case
3167     // leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
3168     const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
3169     bool result;
3170     if (spontaneous)
3171         result = QApplication::sendSpontaneousEvent(receiver, event);
3172     else
3173         result = QApplication::sendEvent(receiver, event);
3174 
3175     if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
3176         && !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
3177         // Dispatch enter/leave if:
3178         // 1) the mouse grabber is an alien widget
3179         // 2) the button is released on an alien widget
3180         QWidget *enter = 0;
3181         if (nativeGuard)
3182             enter = alienGuard ? alienWidget : nativeWidget;
3183         else // The receiver is typically deleted on mouse release with drag'n'drop.
3184             enter = QApplication::widgetAt(event->globalPos());
3185         dispatchEnterLeave(enter, leaveAfterRelease);
3186         leaveAfterRelease = 0;
3187         lastMouseReceiver = enter;
3188     } else if (!wasLeaveAfterRelease) {
3189         if (activePopupWidget) {
3190             if (!QWidget::mouseGrabber())
3191                 lastMouseReceiver = alienGuard ? alienWidget : (nativeGuard ? nativeWidget : 0);
3192         } else {
3193             lastMouseReceiver = receiverGuard ? receiver : QApplication::widgetAt(event->globalPos());
3194         }
3195     }
3196 
3197     return result;
3198 }
3199 
3200 #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
3201 /*
3202     This function should only be called when the widget changes visibility, i.e.
3203     when the \a widget is shown, hidden or deleted. This function does nothing
3204     if the widget is a top-level or native, i.e. not an alien widget. In that
3205     case enter/leave events are genereated by the underlying windowing system.
3206 */
3207 extern QPointer<QWidget> qt_last_mouse_receiver;
3208 extern QWidget *qt_button_down;
sendSyntheticEnterLeave(QWidget * widget)3209 void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
3210 {
3211 #ifndef QT_NO_CURSOR
3212 #if defined(Q_WS_QWS) || defined(Q_WS_QPA)
3213     if (!widget || widget->isWindow())
3214         return;
3215 #else
3216     if (!widget || widget->internalWinId() || widget->isWindow())
3217         return;
3218 #endif
3219     const bool widgetInShow = widget->isVisible() && !widget->data->in_destructor;
3220     if (!widgetInShow && widget != qt_last_mouse_receiver)
3221         return; // Widget was not under the cursor when it was hidden/deleted.
3222 
3223     if (widgetInShow && widget->parentWidget()->data->in_show)
3224         return; // Ingore recursive show.
3225 
3226     QWidget *mouseGrabber = QWidget::mouseGrabber();
3227     if (mouseGrabber && mouseGrabber != widget)
3228         return; // Someone else has the grab; enter/leave should not occur.
3229 
3230     QWidget *tlw = widget->window();
3231     if (tlw->data->in_destructor || tlw->data->is_closing)
3232         return; // Closing down the business.
3233 
3234     if (widgetInShow && (!qt_last_mouse_receiver || qt_last_mouse_receiver->window() != tlw))
3235         return; // Mouse cursor not inside the widget's top-level.
3236 
3237     const QPoint globalPos(QCursor::pos());
3238     QPoint pos = tlw->mapFromGlobal(globalPos);
3239 
3240     // Find the current widget under the mouse. If this function was called from
3241     // the widget's destructor, we have to make sure childAt() doesn't take into
3242     // account widgets that are about to be destructed.
3243     QWidget *widgetUnderCursor = tlw->d_func()->childAt_helper(pos, widget->data->in_destructor);
3244     if (!widgetUnderCursor)
3245         widgetUnderCursor = tlw;
3246     else
3247         pos = widgetUnderCursor->mapFrom(tlw, pos);
3248 
3249     if (widgetInShow && widgetUnderCursor != widget && !widget->isAncestorOf(widgetUnderCursor))
3250         return; // Mouse cursor not inside the widget or any of its children.
3251 
3252     if (widget->data->in_destructor && qt_button_down == widget)
3253         qt_button_down = 0;
3254 
3255     // Send enter/leave events followed by a mouse move on the entered widget.
3256     QMouseEvent e(QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
3257     sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
3258 #endif // QT_NO_CURSOR
3259 }
3260 #endif // Q_WS_WIN || Q_WS_X11 || Q_WS_MAC
3261 
3262 /*!
3263     Returns the desktop widget (also called the root window).
3264 
3265     The desktop may be composed of multiple screens, so it would be incorrect,
3266     for example, to attempt to \e center some widget in the desktop's geometry.
3267     QDesktopWidget has various functions for obtaining useful geometries upon
3268     the desktop, such as QDesktopWidget::screenGeometry() and
3269     QDesktopWidget::availableGeometry().
3270 
3271     On X11, it is also possible to draw on the desktop.
3272 */
desktop()3273 QDesktopWidget *QApplication::desktop()
3274 {
3275     if (!qt_desktopWidget || // not created yet
3276          !(qt_desktopWidget->windowType() == Qt::Desktop)) { // reparented away
3277         qt_desktopWidget = new QDesktopWidget();
3278     }
3279     return qt_desktopWidget;
3280 }
3281 
3282 #ifndef QT_NO_CLIPBOARD
3283 /*!
3284     Returns a pointer to the application global clipboard.
3285 
3286     \note The QApplication object should already be constructed before
3287     accessing the clipboard.
3288 */
clipboard()3289 QClipboard *QApplication::clipboard()
3290 {
3291     if (qt_clipboard == 0) {
3292         if (!qApp) {
3293             qWarning("QApplication: Must construct a QApplication before accessing a QClipboard");
3294             return 0;
3295         }
3296         qt_clipboard = new QClipboard(0);
3297     }
3298     return qt_clipboard;
3299 }
3300 #endif // QT_NO_CLIPBOARD
3301 
3302 /*!
3303     Sets whether Qt should use the system's standard colors, fonts, etc., to
3304     \a on. By default, this is true.
3305 
3306     This function must be called before creating the QApplication object, like
3307     this:
3308 
3309     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 6
3310 
3311     \sa desktopSettingsAware()
3312 */
setDesktopSettingsAware(bool on)3313 void QApplication::setDesktopSettingsAware(bool on)
3314 {
3315     QApplicationPrivate::obey_desktop_settings = on;
3316 }
3317 
3318 /*!
3319     Returns true if Qt is set to use the system's standard colors, fonts, etc.;
3320     otherwise returns false. The default is true.
3321 
3322     \sa setDesktopSettingsAware()
3323 */
desktopSettingsAware()3324 bool QApplication::desktopSettingsAware()
3325 {
3326     return QApplicationPrivate::obey_desktop_settings;
3327 }
3328 
3329 /*!
3330     Returns the current state of the modifier keys on the keyboard. The current
3331     state is updated sychronously as the event queue is emptied of events that
3332     will spontaneously change the keyboard state (QEvent::KeyPress and
3333     QEvent::KeyRelease events).
3334 
3335     It should be noted this may not reflect the actual keys held on the input
3336     device at the time of calling but rather the modifiers as last reported in
3337     one of the above events. If no keys are being held Qt::NoModifier is
3338     returned.
3339 
3340     \sa mouseButtons(), queryKeyboardModifiers()
3341 */
3342 
keyboardModifiers()3343 Qt::KeyboardModifiers QApplication::keyboardModifiers()
3344 {
3345     return QApplicationPrivate::modifier_buttons;
3346 }
3347 
3348 /*!
3349     \fn Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
3350 
3351     Queries and returns the state of the modifier keys on the keyboard.
3352     Unlike keyboardModifiers, this method returns the actual keys held
3353     on the input device at the time of calling the method.
3354 
3355     It does not rely on the keypress events having been received by this
3356     process, which makes it possible to check the modifiers while moving
3357     a window, for instance. Note that in most cases, you should use
3358     keyboardModifiers(), which is faster and more accurate since it contains
3359     the state of the modifiers as they were when the currently processed
3360     event was received.
3361 
3362     \sa keyboardModifiers()
3363 
3364     \since 4.8
3365 */
3366 
3367 /*!
3368     Returns the current state of the buttons on the mouse. The current state is
3369     updated syncronously as the event queue is emptied of events that will
3370     spontaneously change the mouse state (QEvent::MouseButtonPress and
3371     QEvent::MouseButtonRelease events).
3372 
3373     It should be noted this may not reflect the actual buttons held on the
3374     input device at the time of calling but rather the mouse buttons as last
3375     reported in one of the above events. If no mouse buttons are being held
3376     Qt::NoButton is returned.
3377 
3378     \sa keyboardModifiers()
3379 */
3380 
mouseButtons()3381 Qt::MouseButtons QApplication::mouseButtons()
3382 {
3383     return QApplicationPrivate::mouse_buttons;
3384 }
3385 
3386 /*!
3387     \fn bool QApplication::isSessionRestored() const
3388 
3389     Returns true if the application has been restored from an earlier
3390     \l{Session Management}{session}; otherwise returns false.
3391 
3392     \sa sessionId(), commitData(), saveState()
3393 */
3394 
3395 
3396 /*!
3397     \fn QString QApplication::sessionId() const
3398 
3399     Returns the current \l{Session Management}{session's} identifier.
3400 
3401     If the application has been restored from an earlier session, this
3402     identifier is the same as it was in that previous session. The session
3403     identifier is guaranteed to be unique both for different applications
3404     and for different instances of the same application.
3405 
3406     \sa isSessionRestored(), sessionKey(), commitData(), saveState()
3407 */
3408 
3409 /*!
3410     \fn QString QApplication::sessionKey() const
3411 
3412     Returns the session key in the current \l{Session Management}{session}.
3413 
3414     If the application has been restored from an earlier session, this key is
3415     the same as it was when the previous session ended.
3416 
3417     The session key changes with every call of commitData() or saveState().
3418 
3419     \sa isSessionRestored(), sessionId(), commitData(), saveState()
3420 */
3421 #ifndef QT_NO_SESSIONMANAGER
isSessionRestored() const3422 bool QApplication::isSessionRestored() const
3423 {
3424     Q_D(const QApplication);
3425     return d->is_session_restored;
3426 }
3427 
sessionId() const3428 QString QApplication::sessionId() const
3429 {
3430     Q_D(const QApplication);
3431     return d->session_id;
3432 }
3433 
sessionKey() const3434 QString QApplication::sessionKey() const
3435 {
3436     Q_D(const QApplication);
3437     return d->session_key;
3438 }
3439 #endif
3440 
3441 /*!
3442     \since 4.7.4
3443     \fn void QApplication::aboutToReleaseGpuResources()
3444 
3445     This signal is emitted when application is about to release all
3446     GPU resources associated to contexts owned by application.
3447 
3448     The signal is particularly useful if your application has allocated
3449     GPU resources directly apart from Qt and needs to do some last-second
3450     cleanup.
3451 
3452     \warning This signal is only emitted on Symbian.
3453 
3454     \sa aboutToUseGpuResources()
3455 */
3456 
3457 /*!
3458     \since 4.7.4
3459     \fn void QApplication::aboutToUseGpuResources()
3460 
3461     This signal is emitted when application is about to use GPU resources.
3462 
3463     The signal is particularly useful if your application needs to know
3464     when GPU resources are be available.
3465 
3466    \warning This signal is only emitted on Symbian.
3467 
3468    \sa aboutToReleaseGpuResources()
3469 */
3470 
3471 /*!
3472     \since 4.2
3473     \fn void QApplication::commitDataRequest(QSessionManager &manager)
3474 
3475     This signal deals with \l{Session Management}{session management}. It is
3476     emitted when the QSessionManager wants the application to commit all its
3477     data.
3478 
3479     Usually this means saving all open files, after getting permission from
3480     the user. Furthermore you may want to provide a means by which the user
3481     can cancel the shutdown.
3482 
3483     You should not exit the application within this signal. Instead,
3484     the session manager may or may not do this afterwards, depending on the
3485     context.
3486 
3487     \warning Within this signal, no user interaction is possible, \e
3488     unless you ask the \a manager for explicit permission. See
3489     QSessionManager::allowsInteraction() and
3490     QSessionManager::allowsErrorInteraction() for details and example
3491     usage.
3492 
3493     \note You should use Qt::DirectConnection when connecting to this signal.
3494 
3495     \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
3496 */
3497 
3498 /*!
3499     This function deals with \l{Session Management}{session management}. It is
3500     invoked when the QSessionManager wants the application to commit all its
3501     data.
3502 
3503     Usually this means saving all open files, after getting permission from the
3504     user. Furthermore you may want to provide a means by which the user can
3505     cancel the shutdown.
3506 
3507     You should not exit the application within this function. Instead, the
3508     session manager may or may not do this afterwards, depending on the
3509     context.
3510 
3511     \warning Within this function, no user interaction is possible, \e
3512     unless you ask the \a manager for explicit permission. See
3513     QSessionManager::allowsInteraction() and
3514     QSessionManager::allowsErrorInteraction() for details and example
3515     usage.
3516 
3517     The default implementation requests interaction and sends a close event to
3518     all visible top-level widgets. If any event was rejected, the shutdown is
3519     canceled.
3520 
3521     \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
3522 */
3523 #ifndef QT_NO_SESSIONMANAGER
commitData(QSessionManager & manager)3524 void QApplication::commitData(QSessionManager& manager )
3525 {
3526     emit commitDataRequest(manager);
3527     if (manager.allowsInteraction()) {
3528         QWidgetList done;
3529         QWidgetList list = QApplication::topLevelWidgets();
3530         bool cancelled = false;
3531         for (int i = 0; !cancelled && i < list.size(); ++i) {
3532             QWidget* w = list.at(i);
3533             if (w->isVisible() && !done.contains(w)) {
3534                 cancelled = !w->close();
3535                 if (!cancelled)
3536                     done.append(w);
3537                 list = QApplication::topLevelWidgets();
3538                 i = -1;
3539             }
3540         }
3541         if (cancelled)
3542             manager.cancel();
3543     }
3544 }
3545 
3546 /*!
3547     \since 4.2
3548     \fn void QApplication::saveStateRequest(QSessionManager &manager)
3549 
3550     This signal deals with \l{Session Management}{session management}. It is
3551     invoked when the \l{QSessionManager}{session manager} wants the application
3552     to preserve its state for a future session.
3553 
3554     For example, a text editor would create a temporary file that includes the
3555     current contents of its edit buffers, the location of the cursor and other
3556     aspects of the current editing session.
3557 
3558     You should never exit the application within this signal. Instead, the
3559     session manager may or may not do this afterwards, depending on the
3560     context. Futhermore, most session managers will very likely request a saved
3561     state immediately after the application has been started. This permits the
3562     session manager to learn about the application's restart policy.
3563 
3564     \warning Within this function, no user interaction is possible, \e
3565     unless you ask the \a manager for explicit permission. See
3566     QSessionManager::allowsInteraction() and
3567     QSessionManager::allowsErrorInteraction() for details.
3568 
3569     \note You should use Qt::DirectConnection when connecting to this signal.
3570 
3571     \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
3572 */
3573 
3574 /*!
3575     This function deals with \l{Session Management}{session management}. It is
3576     invoked when the \l{QSessionManager}{session manager} wants the application
3577     to preserve its state for a future session.
3578 
3579     For example, a text editor would create a temporary file that includes the
3580     current contents of its edit buffers, the location of the cursor and other
3581     aspects of the current editing session.
3582 
3583     You should never exit the application within this function. Instead, the
3584     session manager may or may not do this afterwards, depending on the
3585     context. Futhermore, most session managers will very likely request a saved
3586     state immediately after the application has been started. This permits the
3587     session manager to learn about the application's restart policy.
3588 
3589     \warning Within this function, no user interaction is possible, \e
3590     unless you ask the \a manager for explicit permission. See
3591     QSessionManager::allowsInteraction() and
3592     QSessionManager::allowsErrorInteraction() for details.
3593 
3594     \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
3595 */
3596 
saveState(QSessionManager & manager)3597 void QApplication::saveState(QSessionManager &manager)
3598 {
3599     emit saveStateRequest(manager);
3600 }
3601 #endif //QT_NO_SESSIONMANAGER
3602 /*
3603   Sets the time after which a drag should start to \a ms ms.
3604 
3605   \sa startDragTime()
3606 */
3607 
setStartDragTime(int ms)3608 void QApplication::setStartDragTime(int ms)
3609 {
3610     drag_time = ms;
3611 }
3612 
3613 /*!
3614     \property QApplication::startDragTime
3615     \brief the time in milliseconds that a mouse button must be held down
3616     before a drag and drop operation will begin
3617 
3618     If you support drag and drop in your application, and want to start a drag
3619     and drop operation after the user has held down a mouse button for a
3620     certain amount of time, you should use this property's value as the delay.
3621 
3622     Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit, for
3623     starting a drag.
3624 
3625     The default value is 500 ms.
3626 
3627     \sa startDragDistance(), {Drag and Drop}
3628 */
3629 
startDragTime()3630 int QApplication::startDragTime()
3631 {
3632     return drag_time;
3633 }
3634 
3635 /*
3636     Sets the distance after which a drag should start to \a l pixels.
3637 
3638     \sa startDragDistance()
3639 */
3640 
setStartDragDistance(int l)3641 void QApplication::setStartDragDistance(int l)
3642 {
3643     drag_distance = l;
3644 }
3645 
3646 /*!
3647     \property QApplication::startDragDistance
3648 
3649     If you support drag and drop in your application, and want to start a drag
3650     and drop operation after the user has moved the cursor a certain distance
3651     with a button held down, you should use this property's value as the
3652     minimum distance required.
3653 
3654     For example, if the mouse position of the click is stored in \c startPos
3655     and the current position (e.g. in the mouse move event) is \c currentPos,
3656     you can find out if a drag should be started with code like this:
3657 
3658     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 7
3659 
3660     Qt uses this value internally, e.g. in QFileDialog.
3661 
3662     The default value is 4 pixels.
3663 
3664     \sa startDragTime() QPoint::manhattanLength() {Drag and Drop}
3665 */
3666 
startDragDistance()3667 int QApplication::startDragDistance()
3668 {
3669     return drag_distance;
3670 }
3671 
3672 /*!
3673     \fn void QApplication::setReverseLayout(bool reverse)
3674 
3675     Use setLayoutDirection() instead.
3676 */
3677 
3678 /*!
3679     \fn void QApplication::reverseLayout()
3680 
3681     Use layoutDirection() instead.
3682 */
3683 
3684 /*!
3685     \fn bool QApplication::isRightToLeft()
3686 
3687     Returns true if the application's layout direction is
3688     Qt::RightToLeft; otherwise returns false.
3689 
3690     \sa layoutDirection(), isLeftToRight()
3691 */
3692 
3693 /*!
3694     \fn bool QApplication::isLeftToRight()
3695 
3696     Returns true if the application's layout direction is
3697     Qt::LeftToRight; otherwise returns false.
3698 
3699     \sa layoutDirection(), isRightToLeft()
3700 */
3701 
3702 /*!
3703     \property QApplication::layoutDirection
3704     \brief the default layout direction for this application
3705 
3706     On system start-up, the default layout direction depends on the
3707     application's language.
3708 
3709     \sa QWidget::layoutDirection, isLeftToRight(), isRightToLeft()
3710  */
3711 
setLayoutDirection(Qt::LayoutDirection direction)3712 void QApplication::setLayoutDirection(Qt::LayoutDirection direction)
3713 {
3714     if (layout_direction == direction || direction == Qt::LayoutDirectionAuto)
3715         return;
3716 
3717     layout_direction = direction;
3718 
3719     QWidgetList list = topLevelWidgets();
3720     for (int i = 0; i < list.size(); ++i) {
3721         QWidget *w = list.at(i);
3722         QEvent ev(QEvent::ApplicationLayoutDirectionChange);
3723         sendEvent(w, &ev);
3724     }
3725 }
3726 
layoutDirection()3727 Qt::LayoutDirection QApplication::layoutDirection()
3728 {
3729     return layout_direction;
3730 }
3731 
3732 
3733 /*!
3734     \obsolete
3735 
3736     Strips out vertical alignment flags and transforms an alignment \a align
3737     of Qt::AlignLeft into Qt::AlignLeft or Qt::AlignRight according to the
3738     language used.
3739 */
3740 
3741 #ifdef QT3_SUPPORT
horizontalAlignment(Qt::Alignment align)3742 Qt::Alignment QApplication::horizontalAlignment(Qt::Alignment align)
3743 {
3744     return QStyle::visualAlignment(layoutDirection(), align);
3745 }
3746 #endif
3747 
3748 
3749 /*!
3750     \fn QCursor *QApplication::overrideCursor()
3751 
3752     Returns the active application override cursor.
3753 
3754     This function returns 0 if no application cursor has been defined (i.e. the
3755     internal cursor stack is empty).
3756 
3757     \sa setOverrideCursor(), restoreOverrideCursor()
3758 */
3759 #ifndef QT_NO_CURSOR
overrideCursor()3760 QCursor *QApplication::overrideCursor()
3761 {
3762     return qApp->d_func()->cursor_list.isEmpty() ? 0 : &qApp->d_func()->cursor_list.first();
3763 }
3764 
3765 /*!
3766     Changes the currently active application override cursor to \a cursor.
3767 
3768     This function has no effect if setOverrideCursor() was not called.
3769 
3770     \sa setOverrideCursor(), overrideCursor(), restoreOverrideCursor(),
3771     QWidget::setCursor()
3772  */
changeOverrideCursor(const QCursor & cursor)3773 void QApplication::changeOverrideCursor(const QCursor &cursor)
3774 {
3775     if (qApp->d_func()->cursor_list.isEmpty())
3776         return;
3777     qApp->d_func()->cursor_list.removeFirst();
3778     setOverrideCursor(cursor);
3779 }
3780 #endif
3781 
3782 /*!
3783     \fn void QApplication::setOverrideCursor(const QCursor &cursor, bool replace)
3784 
3785     Use changeOverrideCursor(\a cursor) (if \a replace is true) or
3786     setOverrideCursor(\a cursor) (if \a replace is false).
3787 */
3788 
3789 /*!
3790     Enters the main event loop and waits until exit() is called, then returns
3791     the value that was set to exit() (which is 0 if exit() is called via
3792     quit()).
3793 
3794     It is necessary to call this function to start event handling. The main
3795     event loop receives events from the window system and dispatches these to
3796     the application widgets.
3797 
3798     Generally, no user interaction can take place before calling exec(). As a
3799     special case, modal widgets like QMessageBox can be used before calling
3800     exec(), because modal widgets call exec() to start a local event loop.
3801 
3802     To make your application perform idle processing, i.e., executing a special
3803     function whenever there are no pending events, use a QTimer with 0 timeout.
3804     More advanced idle processing schemes can be achieved using processEvents().
3805 
3806     We recommend that you connect clean-up code to the
3807     \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your
3808     application's \c{main()} function. This is because, on some platforms the
3809     QApplication::exec() call may not return. For example, on the Windows
3810     platform, when the user logs off, the system terminates the process after Qt
3811     closes all top-level windows. Hence, there is \e{no guarantee} that the
3812     application will have time to exit its event loop and execute code at the
3813     end of the \c{main()} function, after the QApplication::exec() call.
3814 
3815     \sa quitOnLastWindowClosed, quit(), exit(), processEvents(),
3816         QCoreApplication::exec()
3817 */
exec()3818 int QApplication::exec()
3819 {
3820 #ifndef QT_NO_ACCESSIBILITY
3821     QAccessible::setRootObject(qApp);
3822 #endif
3823     return QCoreApplication::exec();
3824 }
3825 
3826 /*! \reimp
3827  */
notify(QObject * receiver,QEvent * e)3828 bool QApplication::notify(QObject *receiver, QEvent *e)
3829 {
3830     Q_D(QApplication);
3831     // no events are delivered after ~QCoreApplication() has started
3832     if (QApplicationPrivate::is_app_closing)
3833         return true;
3834 
3835     if (receiver == 0) {                        // serious error
3836         qWarning("QApplication::notify: Unexpected null receiver");
3837         return true;
3838     }
3839 
3840 #ifndef QT_NO_DEBUG
3841     d->checkReceiverThread(receiver);
3842 #endif
3843 
3844     // capture the current mouse/keyboard state
3845     if(e->spontaneous()) {
3846         if (e->type() == QEvent::KeyPress
3847             || e->type() == QEvent::KeyRelease) {
3848             QKeyEvent *ke = static_cast<QKeyEvent*>(e);
3849             QApplicationPrivate::modifier_buttons = ke->modifiers();
3850         } else if(e->type() == QEvent::MouseButtonPress
3851             || e->type() == QEvent::MouseButtonRelease) {
3852                 QMouseEvent *me = static_cast<QMouseEvent*>(e);
3853                 QApplicationPrivate::modifier_buttons = me->modifiers();
3854                 if(me->type() == QEvent::MouseButtonPress)
3855                     QApplicationPrivate::mouse_buttons |= me->button();
3856                 else
3857                     QApplicationPrivate::mouse_buttons &= ~me->button();
3858             }
3859 #if !defined(QT_NO_WHEELEVENT) || !defined(QT_NO_TABLETEVENT)
3860             else if (false
3861 #  ifndef QT_NO_WHEELEVENT
3862                      || e->type() == QEvent::Wheel
3863 #  endif
3864 #  ifndef QT_NO_TABLETEVENT
3865                      || e->type() == QEvent::TabletMove
3866                      || e->type() == QEvent::TabletPress
3867                      || e->type() == QEvent::TabletRelease
3868 #  endif
3869                      ) {
3870             QInputEvent *ie = static_cast<QInputEvent*>(e);
3871             QApplicationPrivate::modifier_buttons = ie->modifiers();
3872         }
3873 #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT
3874     }
3875 
3876 #ifndef QT_NO_GESTURES
3877     // walk through parents and check for gestures
3878     if (d->gestureManager) {
3879         switch (e->type()) {
3880         case QEvent::Paint:
3881         case QEvent::MetaCall:
3882         case QEvent::DeferredDelete:
3883         case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
3884         case QEvent::Drop: case QEvent::DragResponse:
3885         case QEvent::ChildAdded: case QEvent::ChildPolished:
3886 #ifdef QT3_SUPPORT
3887         case QEvent::ChildInsertedRequest:
3888         case QEvent::ChildInserted:
3889         case QEvent::LayoutHint:
3890 #endif
3891         case QEvent::ChildRemoved:
3892         case QEvent::UpdateRequest:
3893         case QEvent::UpdateLater:
3894         case QEvent::AccessibilityPrepare:
3895         case QEvent::LocaleChange:
3896         case QEvent::Style:
3897         case QEvent::IconDrag:
3898         case QEvent::StyleChange:
3899         case QEvent::AccessibilityHelp:
3900         case QEvent::AccessibilityDescription:
3901         case QEvent::GraphicsSceneDragEnter:
3902         case QEvent::GraphicsSceneDragMove:
3903         case QEvent::GraphicsSceneDragLeave:
3904         case QEvent::GraphicsSceneDrop:
3905         case QEvent::DynamicPropertyChange:
3906         case QEvent::NetworkReplyUpdated:
3907             break;
3908         default:
3909             if (d->gestureManager->thread() == QThread::currentThread()) {
3910                 if (receiver->isWidgetType()) {
3911                     if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
3912                         return true;
3913                 } else {
3914                     // a special case for events that go to QGesture objects.
3915                     // We pass the object to the gesture manager and it'll figure
3916                     // out if it's QGesture or not.
3917                     if (d->gestureManager->filterEvent(receiver, e))
3918                         return true;
3919                 }
3920             }
3921             break;
3922         }
3923     }
3924 #endif // QT_NO_GESTURES
3925 
3926     // User input and window activation makes tooltips sleep
3927     switch (e->type()) {
3928     case QEvent::Wheel:
3929     case QEvent::ActivationChange:
3930     case QEvent::KeyPress:
3931     case QEvent::KeyRelease:
3932     case QEvent::FocusOut:
3933     case QEvent::FocusIn:
3934     case QEvent::MouseButtonPress:
3935     case QEvent::MouseButtonRelease:
3936     case QEvent::MouseButtonDblClick:
3937         d->toolTipFallAsleep.stop();
3938         // fall-through
3939     case QEvent::Leave:
3940         d->toolTipWakeUp.stop();
3941     default:
3942         break;
3943     }
3944 
3945     bool res = false;
3946     if (!receiver->isWidgetType()) {
3947         res = d->notify_helper(receiver, e);
3948     } else switch (e->type()) {
3949 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
3950     case QEvent::Accel:
3951         {
3952             if (d->use_compat()) {
3953                 QKeyEvent* key = static_cast<QKeyEvent*>(e);
3954                 res = d->notify_helper(receiver, e);
3955 
3956                 if (!res && !key->isAccepted())
3957                     res = d->qt_dispatchAccelEvent(static_cast<QWidget *>(receiver), key);
3958 
3959                 // next lines are for compatibility with Qt <= 3.0.x: old
3960                 // QAccel was listening on toplevel widgets
3961                 if (!res && !key->isAccepted() && !static_cast<QWidget *>(receiver)->isWindow())
3962                     res = d->notify_helper(static_cast<QWidget *>(receiver)->window(), e);
3963             }
3964             break;
3965         }
3966 #endif //QT3_SUPPORT && !QT_NO_SHORTCUT
3967     case QEvent::ShortcutOverride:
3968     case QEvent::KeyPress:
3969     case QEvent::KeyRelease:
3970         {
3971             bool isWidget = receiver->isWidgetType();
3972             bool isGraphicsWidget = false;
3973 #ifndef QT_NO_GRAPHICSVIEW
3974             isGraphicsWidget = !isWidget && qobject_cast<QGraphicsWidget *>(receiver);
3975 #endif
3976             if (!isWidget && !isGraphicsWidget) {
3977                 res = d->notify_helper(receiver, e);
3978                 break;
3979             }
3980 
3981             QKeyEvent* key = static_cast<QKeyEvent*>(e);
3982 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
3983             if (d->use_compat() && d->qt_tryComposeUnicode(static_cast<QWidget*>(receiver), key))
3984                 break;
3985 #endif
3986             if (key->type()==QEvent::KeyPress) {
3987 #ifndef QT_NO_SHORTCUT
3988                 // Try looking for a Shortcut before sending key events
3989                 if ((res = qApp->d_func()->shortcutMap.tryShortcutEvent(receiver, key)))
3990                     return res;
3991 #endif
3992                 qt_in_tab_key_event = (key->key() == Qt::Key_Backtab
3993                                        || key->key() == Qt::Key_Tab
3994                                        || key->key() == Qt::Key_Left
3995                                        || key->key() == Qt::Key_Up
3996                                        || key->key() == Qt::Key_Right
3997                                        || key->key() == Qt::Key_Down);
3998             }
3999             bool def = key->isAccepted();
4000             QPointer<QObject> pr = receiver;
4001             while (receiver) {
4002                 if (def)
4003                     key->accept();
4004                 else
4005                     key->ignore();
4006                 res = d->notify_helper(receiver, e);
4007                 QWidget *w = isWidget ? static_cast<QWidget *>(receiver) : 0;
4008 #ifndef QT_NO_GRAPHICSVIEW
4009                 QGraphicsWidget *gw = isGraphicsWidget ? static_cast<QGraphicsWidget *>(receiver) : 0;
4010 #endif
4011 
4012                 if ((res && key->isAccepted())
4013                     /*
4014                        QLineEdit will emit a signal on Key_Return, but
4015                        ignore the event, and sometimes the connected
4016                        slot deletes the QLineEdit (common in itemview
4017                        delegates), so we have to check if the widget
4018                        was destroyed even if the event was ignored (to
4019                        prevent a crash)
4020 
4021                        note that we don't have to reset pw while
4022                        propagating (because the original receiver will
4023                        be destroyed if one of its ancestors is)
4024                     */
4025                     || !pr
4026                     || (isWidget && (w->isWindow() || !w->parentWidget()))
4027 #ifndef QT_NO_GRAPHICSVIEW
4028                     || (isGraphicsWidget && (gw->isWindow() || !gw->parentWidget()))
4029 #endif
4030                     ) {
4031                     break;
4032                 }
4033 
4034 #ifndef QT_NO_GRAPHICSVIEW
4035                 receiver = w ? (QObject *)w->parentWidget() : (QObject *)gw->parentWidget();
4036 #else
4037                 receiver = w->parentWidget();
4038 #endif
4039             }
4040             qt_in_tab_key_event = false;
4041         }
4042         break;
4043     case QEvent::MouseButtonPress:
4044     case QEvent::MouseButtonRelease:
4045     case QEvent::MouseButtonDblClick:
4046     case QEvent::MouseMove:
4047         {
4048             QWidget* w = static_cast<QWidget *>(receiver);
4049 
4050             QMouseEvent* mouse = static_cast<QMouseEvent*>(e);
4051             QPoint relpos = mouse->pos();
4052 
4053             if (e->spontaneous()) {
4054 #ifndef QT_NO_IM
4055                 QInputContext *ic = w->inputContext();
4056                 if (ic
4057                         && w->testAttribute(Qt::WA_InputMethodEnabled)
4058                         && ic->filterEvent(mouse))
4059                     return true;
4060 #endif
4061 
4062                 if (e->type() == QEvent::MouseButtonPress) {
4063                     QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
4064                                                                          Qt::ClickFocus,
4065                                                                          Qt::MouseFocusReason);
4066                 }
4067 
4068                 // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
4069                 // like Mac OS X (probably others too), can optimize their views by not
4070                 // dispatching mouse move events. We have attributes to control hover,
4071                 // and mouse tracking, but as long as we are deciding to implement this
4072                 // feature without choice of opting-in or out, you ALWAYS have to have
4073                 // tracking enabled. Therefore, the other properties give a false sense of
4074                 // performance enhancement.
4075                 if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
4076                     d->toolTipWidget = w;
4077                     d->toolTipPos = relpos;
4078                     d->toolTipGlobalPos = mouse->globalPos();
4079                     d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
4080                 }
4081             }
4082 
4083             bool eventAccepted = mouse->isAccepted();
4084 
4085             QPointer<QWidget> pw = w;
4086             while (w) {
4087                 QMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->buttons(),
4088                                mouse->modifiers());
4089                 me.spont = mouse->spontaneous();
4090                 // throw away any mouse-tracking-only mouse events
4091                 if (!w->hasMouseTracking()
4092                     && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
4093                     // but still send them through all application event filters (normally done by notify_helper)
4094                     for (int i = 0; i < d->eventFilters.size(); ++i) {
4095                         register QObject *obj = d->eventFilters.at(i);
4096                         if (!obj)
4097                             continue;
4098                         if (obj->d_func()->threadData != w->d_func()->threadData) {
4099                             qWarning("QApplication: Object event filter cannot be in a different thread.");
4100                             continue;
4101                         }
4102                         if (obj->eventFilter(w, w == receiver ? mouse : &me))
4103                             break;
4104                     }
4105                     res = true;
4106                 } else {
4107                     w->setAttribute(Qt::WA_NoMouseReplay, false);
4108                     res = d->notify_helper(w, w == receiver ? mouse : &me);
4109                     e->spont = false;
4110                 }
4111                 eventAccepted = (w == receiver ? mouse : &me)->isAccepted();
4112                 if (res && eventAccepted)
4113                     break;
4114                 if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
4115                     break;
4116                 relpos += w->pos();
4117                 w = w->parentWidget();
4118             }
4119 
4120             mouse->setAccepted(eventAccepted);
4121 
4122             if (e->type() == QEvent::MouseMove) {
4123                 if (!pw)
4124                     break;
4125 
4126                 w = static_cast<QWidget *>(receiver);
4127                 relpos = mouse->pos();
4128                 QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
4129                 while (w) {
4130                     if (w->testAttribute(Qt::WA_Hover) &&
4131                         (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
4132                         QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff);
4133                         d->notify_helper(w, &he);
4134                     }
4135                     if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
4136                         break;
4137                     relpos += w->pos();
4138                     w = w->parentWidget();
4139                 }
4140             }
4141 
4142             d->hoverGlobalPos = mouse->globalPos();
4143         }
4144         break;
4145 #ifndef QT_NO_WHEELEVENT
4146     case QEvent::Wheel:
4147         {
4148             QWidget* w = static_cast<QWidget *>(receiver);
4149             QWheelEvent* wheel = static_cast<QWheelEvent*>(e);
4150             QPoint relpos = wheel->pos();
4151             bool eventAccepted = wheel->isAccepted();
4152 
4153             if (e->spontaneous()) {
4154                 QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
4155                                                                      Qt::WheelFocus,
4156                                                                      Qt::MouseFocusReason);
4157             }
4158 
4159             while (w) {
4160                 QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->buttons(),
4161                                wheel->modifiers(), wheel->orientation());
4162                 we.spont = wheel->spontaneous();
4163                 res = d->notify_helper(w, w == receiver ? wheel : &we);
4164                 eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted();
4165                 e->spont = false;
4166                 if ((res && eventAccepted)
4167                     || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
4168                     break;
4169 
4170                 relpos += w->pos();
4171                 w = w->parentWidget();
4172             }
4173             wheel->setAccepted(eventAccepted);
4174         }
4175         break;
4176 #endif
4177 #ifndef QT_NO_CONTEXTMENU
4178     case QEvent::ContextMenu:
4179         {
4180             QWidget* w = static_cast<QWidget *>(receiver);
4181             QContextMenuEvent *context = static_cast<QContextMenuEvent*>(e);
4182             QPoint relpos = context->pos();
4183             bool eventAccepted = context->isAccepted();
4184             while (w) {
4185                 QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->modifiers());
4186                 ce.spont = e->spontaneous();
4187                 res = d->notify_helper(w, w == receiver ? context : &ce);
4188                 eventAccepted = ((w == receiver) ? context : &ce)->isAccepted();
4189                 e->spont = false;
4190 
4191                 if ((res && eventAccepted)
4192                     || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
4193                     break;
4194 
4195                 relpos += w->pos();
4196                 w = w->parentWidget();
4197             }
4198             context->setAccepted(eventAccepted);
4199         }
4200         break;
4201 #endif // QT_NO_CONTEXTMENU
4202 #ifndef QT_NO_TABLETEVENT
4203     case QEvent::TabletMove:
4204     case QEvent::TabletPress:
4205     case QEvent::TabletRelease:
4206         {
4207             QWidget *w = static_cast<QWidget *>(receiver);
4208             QTabletEvent *tablet = static_cast<QTabletEvent*>(e);
4209             QPoint relpos = tablet->pos();
4210             bool eventAccepted = tablet->isAccepted();
4211             while (w) {
4212                 QTabletEvent te(tablet->type(), relpos, tablet->globalPos(),
4213                                 tablet->hiResGlobalPos(), tablet->device(), tablet->pointerType(),
4214                                 tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
4215                                 tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
4216                                 tablet->modifiers(), tablet->uniqueId());
4217                 te.spont = e->spontaneous();
4218                 res = d->notify_helper(w, w == receiver ? tablet : &te);
4219                 eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted();
4220                 e->spont = false;
4221                 if ((res && eventAccepted)
4222                      || w->isWindow()
4223                      || w->testAttribute(Qt::WA_NoMousePropagation))
4224                     break;
4225 
4226                 relpos += w->pos();
4227                 w = w->parentWidget();
4228             }
4229             tablet->setAccepted(eventAccepted);
4230             qt_tabletChokeMouse = tablet->isAccepted();
4231         }
4232         break;
4233 #endif // QT_NO_TABLETEVENT
4234 
4235 #if !defined(QT_NO_TOOLTIP) || !defined(QT_NO_WHATSTHIS)
4236     case QEvent::ToolTip:
4237     case QEvent::WhatsThis:
4238     case QEvent::QueryWhatsThis:
4239         {
4240             QWidget* w = static_cast<QWidget *>(receiver);
4241             QHelpEvent *help = static_cast<QHelpEvent*>(e);
4242             QPoint relpos = help->pos();
4243             bool eventAccepted = help->isAccepted();
4244             while (w) {
4245                 QHelpEvent he(help->type(), relpos, help->globalPos());
4246                 he.spont = e->spontaneous();
4247                 res = d->notify_helper(w, w == receiver ? help : &he);
4248                 e->spont = false;
4249                 eventAccepted = (w == receiver ? help : &he)->isAccepted();
4250                 if ((res && eventAccepted) || w->isWindow())
4251                     break;
4252 
4253                 relpos += w->pos();
4254                 w = w->parentWidget();
4255             }
4256             help->setAccepted(eventAccepted);
4257         }
4258         break;
4259 #endif
4260 #if !defined(QT_NO_STATUSTIP) || !defined(QT_NO_WHATSTHIS)
4261     case QEvent::StatusTip:
4262     case QEvent::WhatsThisClicked:
4263         {
4264             QWidget *w = static_cast<QWidget *>(receiver);
4265             while (w) {
4266                 res = d->notify_helper(w, e);
4267                 if ((res && e->isAccepted()) || w->isWindow())
4268                     break;
4269                 w = w->parentWidget();
4270             }
4271         }
4272         break;
4273 #endif
4274 
4275 #ifndef QT_NO_DRAGANDDROP
4276     case QEvent::DragEnter: {
4277             QWidget* w = static_cast<QWidget *>(receiver);
4278             QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(e);
4279 #ifdef Q_WS_MAC
4280             // HIView has a slight difference in how it delivers events to children and parents
4281             // It will not give a leave to a child's parent when it enters a child.
4282             QWidget *currentTarget = QDragManager::self()->currentTarget();
4283             if (currentTarget) {
4284                 // Assume currentTarget did not get a leave
4285                 QDragLeaveEvent event;
4286                 QApplication::sendEvent(currentTarget, &event);
4287             }
4288 #endif
4289 #ifndef QT_NO_GRAPHICSVIEW
4290             // QGraphicsProxyWidget handles its own propagation,
4291             // and we must not change QDragManagers currentTarget.
4292             QWExtra *extra = w->window()->d_func()->extra;
4293             if (extra && extra->proxyWidget) {
4294                 res = d->notify_helper(w, dragEvent);
4295                 break;
4296             }
4297 #endif
4298             while (w) {
4299                 if (w->isEnabled() && w->acceptDrops()) {
4300                     res = d->notify_helper(w, dragEvent);
4301                     if (res && dragEvent->isAccepted()) {
4302                         QDragManager::self()->setCurrentTarget(w);
4303                         break;
4304                     }
4305                 }
4306                 if (w->isWindow())
4307                     break;
4308                 dragEvent->p = w->mapToParent(dragEvent->p);
4309                 w = w->parentWidget();
4310             }
4311         }
4312         break;
4313     case QEvent::DragMove:
4314     case QEvent::Drop:
4315     case QEvent::DragLeave: {
4316             QWidget* w = static_cast<QWidget *>(receiver);
4317 #ifndef QT_NO_GRAPHICSVIEW
4318             // QGraphicsProxyWidget handles its own propagation,
4319             // and we must not change QDragManagers currentTarget.
4320             QWExtra *extra = w->window()->d_func()->extra;
4321             bool isProxyWidget = extra && extra->proxyWidget;
4322             if (!isProxyWidget)
4323 #endif
4324                 w = QDragManager::self()->currentTarget();
4325 
4326             if (!w) {
4327 #ifdef Q_WS_MAC
4328                 // HIView has a slight difference in how it delivers events to children and parents
4329                 // It will not give an enter to a child's parent when it leaves the child.
4330                 if (e->type() == QEvent::DragLeave)
4331                     break;
4332                 // Assume that w did not get an enter.
4333                 QDropEvent *dropEvent = static_cast<QDropEvent *>(e);
4334                 QDragEnterEvent dragEnterEvent(dropEvent->pos(), dropEvent->possibleActions(),
4335                                                dropEvent->mimeData(), dropEvent->mouseButtons(),
4336                                                dropEvent->keyboardModifiers());
4337                 QApplication::sendEvent(receiver, &dragEnterEvent);
4338                 w = QDragManager::self()->currentTarget();
4339                 if (!w)
4340 #endif
4341                     break;
4342             }
4343             if (e->type() == QEvent::DragMove || e->type() == QEvent::Drop) {
4344                 QDropEvent *dragEvent = static_cast<QDropEvent *>(e);
4345                 QWidget *origReciver = static_cast<QWidget *>(receiver);
4346                 while (origReciver && w != origReciver) {
4347                     dragEvent->p = origReciver->mapToParent(dragEvent->p);
4348                     origReciver = origReciver->parentWidget();
4349                 }
4350             }
4351             res = d->notify_helper(w, e);
4352             if (e->type() != QEvent::DragMove
4353 #ifndef QT_NO_GRAPHICSVIEW
4354                 && !isProxyWidget
4355 #endif
4356                 )
4357                 QDragManager::self()->setCurrentTarget(0, e->type() == QEvent::Drop);
4358         }
4359         break;
4360 #endif
4361     case QEvent::TouchBegin:
4362     // Note: TouchUpdate and TouchEnd events are never propagated
4363     {
4364         QWidget *widget = static_cast<QWidget *>(receiver);
4365         QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
4366         bool eventAccepted = touchEvent->isAccepted();
4367         if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
4368             // give the widget focus if the focus policy allows it
4369             QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
4370                                                                  Qt::ClickFocus,
4371                                                                  Qt::MouseFocusReason);
4372         }
4373 
4374         while (widget) {
4375             // first, try to deliver the touch event
4376             bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
4377             touchEvent->setWidget(widget);
4378             touchEvent->setAccepted(acceptTouchEvents);
4379             QWeakPointer<QWidget> p = widget;
4380             res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
4381             eventAccepted = touchEvent->isAccepted();
4382             if (p.isNull()) {
4383                 // widget was deleted
4384                 widget = 0;
4385             } else {
4386                 widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
4387             }
4388             touchEvent->spont = false;
4389             if (res && eventAccepted) {
4390                 // the first widget to accept the TouchBegin gets an implicit grab.
4391                 for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
4392                     const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
4393                     d->widgetForTouchPointId[touchPoint.id()] = widget;
4394                 }
4395                 break;
4396             } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
4397                 break;
4398             }
4399             QPoint offset = widget->pos();
4400             widget = widget->parentWidget();
4401             touchEvent->setWidget(widget);
4402             for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) {
4403                 QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i];
4404                 QRectF rect = pt.rect();
4405                 rect.moveCenter(offset);
4406                 pt.d->rect = rect;
4407                 pt.d->startPos = pt.startPos() + offset;
4408                 pt.d->lastPos = pt.lastPos() + offset;
4409             }
4410         }
4411 
4412         touchEvent->setAccepted(eventAccepted);
4413         break;
4414     }
4415     case QEvent::RequestSoftwareInputPanel:
4416     case QEvent::CloseSoftwareInputPanel:
4417 #ifndef QT_NO_IM
4418         if (receiver->isWidgetType()) {
4419             QWidget *w = static_cast<QWidget *>(receiver);
4420             QInputContext *ic = w->inputContext();
4421             if (ic && ic->filterEvent(e)) {
4422                 break;
4423             }
4424         }
4425 #endif
4426         res = d->notify_helper(receiver, e);
4427         break;
4428 
4429 #ifndef QT_NO_GESTURES
4430     case QEvent::NativeGesture:
4431     {
4432         // only propagate the first gesture event (after the GID_BEGIN)
4433         QWidget *w = static_cast<QWidget *>(receiver);
4434         while (w) {
4435             e->ignore();
4436             res = d->notify_helper(w, e);
4437             if ((res && e->isAccepted()) || w->isWindow())
4438                 break;
4439             w = w->parentWidget();
4440         }
4441         break;
4442     }
4443     case QEvent::Gesture:
4444     case QEvent::GestureOverride:
4445     {
4446         if (receiver->isWidgetType()) {
4447             QWidget *w = static_cast<QWidget *>(receiver);
4448             QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
4449             QList<QGesture *> allGestures = gestureEvent->gestures();
4450 
4451             bool eventAccepted = gestureEvent->isAccepted();
4452             bool wasAccepted = eventAccepted;
4453             while (w) {
4454                 // send only gestures the widget expects
4455                 QList<QGesture *> gestures;
4456                 QWidgetPrivate *wd = w->d_func();
4457                 for (int i = 0; i < allGestures.size();) {
4458                     QGesture *g = allGestures.at(i);
4459                     Qt::GestureType type = g->gestureType();
4460                     QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
4461                             wd->gestureContext.find(type);
4462                     bool deliver = contextit != wd->gestureContext.end() &&
4463                         (g->state() == Qt::GestureStarted || w == receiver ||
4464                          (contextit.value() & Qt::ReceivePartialGestures));
4465                     if (deliver) {
4466                         allGestures.removeAt(i);
4467                         gestures.append(g);
4468                     } else {
4469                         ++i;
4470                     }
4471                 }
4472                 if (!gestures.isEmpty()) { // we have gestures for this w
4473                     QGestureEvent ge(gestures);
4474                     ge.t = gestureEvent->t;
4475                     ge.spont = gestureEvent->spont;
4476                     ge.m_accept = wasAccepted;
4477                     ge.d_func()->accepted = gestureEvent->d_func()->accepted;
4478                     res = d->notify_helper(w, &ge);
4479                     gestureEvent->spont = false;
4480                     eventAccepted = ge.isAccepted();
4481                     for (int i = 0; i < gestures.size(); ++i) {
4482                         QGesture *g = gestures.at(i);
4483                         // Ignore res [event return value] because handling of multiple gestures
4484                         // packed into a single QEvent depends on not consuming the event
4485                         if (eventAccepted || ge.isAccepted(g)) {
4486                             // if the gesture was accepted, mark the target widget for it
4487                             gestureEvent->d_func()->targetWidgets[g->gestureType()] = w;
4488                             gestureEvent->setAccepted(g, true);
4489                         } else {
4490                             // if the gesture was explicitly ignored by the application,
4491                             // put it back so a parent can get it
4492                             allGestures.append(g);
4493                         }
4494                     }
4495                 }
4496                 if (allGestures.isEmpty()) // everything delivered
4497                     break;
4498                 if (w->isWindow())
4499                     break;
4500                 w = w->parentWidget();
4501             }
4502             foreach (QGesture *g, allGestures)
4503                 gestureEvent->setAccepted(g, false);
4504             gestureEvent->m_accept = false; // to make sure we check individual gestures
4505         } else {
4506             res = d->notify_helper(receiver, e);
4507         }
4508         break;
4509     }
4510 #endif // QT_NO_GESTURES
4511 #ifdef QT_MAC_USE_COCOA
4512     case QEvent::Enter:
4513         if (receiver->isWidgetType()) {
4514             QWidget *w = static_cast<QWidget *>(receiver);
4515             if (w->testAttribute(Qt::WA_AcceptTouchEvents))
4516                 qt_widget_private(w)->registerTouchWindow(true);
4517         }
4518         res = d->notify_helper(receiver, e);
4519     break;
4520     case QEvent::Leave:
4521         if (receiver->isWidgetType()) {
4522             QWidget *w = static_cast<QWidget *>(receiver);
4523             if (w->testAttribute(Qt::WA_AcceptTouchEvents))
4524                 qt_widget_private(w)->registerTouchWindow(false);
4525         }
4526         res = d->notify_helper(receiver, e);
4527     break;
4528 #endif
4529     default:
4530         res = d->notify_helper(receiver, e);
4531         break;
4532     }
4533 
4534     return res;
4535 }
4536 
notify_helper(QObject * receiver,QEvent * e)4537 bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
4538 {
4539     // send to all application event filters
4540     if (sendThroughApplicationEventFilters(receiver, e))
4541         return true;
4542 
4543     if (receiver->isWidgetType()) {
4544         QWidget *widget = static_cast<QWidget *>(receiver);
4545 
4546 #if !defined(Q_WS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR))
4547         // toggle HasMouse widget state on enter and leave
4548         if ((e->type() == QEvent::Enter || e->type() == QEvent::DragEnter) &&
4549             (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == widget->window()))
4550             widget->setAttribute(Qt::WA_UnderMouse, true);
4551         else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave)
4552             widget->setAttribute(Qt::WA_UnderMouse, false);
4553 #endif
4554 
4555         if (QLayout *layout=widget->d_func()->layout) {
4556             layout->widgetEvent(e);
4557         }
4558     }
4559 
4560     // send to all receiver event filters
4561     if (sendThroughObjectEventFilters(receiver, e))
4562         return true;
4563 
4564     // deliver the event
4565     bool consumed = receiver->event(e);
4566     e->spont = false;
4567     return consumed;
4568 }
4569 
4570 
4571 /*!
4572     \class QSessionManager
4573     \brief The QSessionManager class provides access to the session manager.
4574 
4575     A session manager in a desktop environment (in which Qt GUI applications
4576     live) keeps track of a session, which is a group of running applications,
4577     each of which has a particular state. The state of an application contains
4578     (most notably) the documents the application has open and the position and
4579     size of its windows.
4580 
4581     The session manager is used to save the session, e.g., when the machine is
4582     shut down, and to restore a session, e.g., when the machine is started up.
4583     We recommend that you use QSettings to save an application's settings,
4584     for example, window positions, recently used files, etc. When the
4585     application is restarted by the session manager, you can restore the
4586     settings.
4587 
4588     QSessionManager provides an interface between the application and the
4589     session manager so that the program can work well with the session manager.
4590     In Qt, session management requests for action are handled by the two
4591     virtual functions QApplication::commitData() and QApplication::saveState().
4592     Both provide a reference to a session manager object as argument, to allow
4593     the application to communicate with the session manager. The session
4594     manager can only be accessed through these functions.
4595 
4596     No user interaction is possible \e unless the application gets explicit
4597     permission from the session manager. You ask for permission by calling
4598     allowsInteraction() or, if it is really urgent, allowsErrorInteraction().
4599     Qt does not enforce this, but the session manager may.
4600 
4601     You can try to abort the shutdown process by calling cancel(). The default
4602     commitData() function does this if some top-level window rejected its
4603     closeEvent().
4604 
4605     For sophisticated session managers provided on Unix/X11, QSessionManager
4606     offers further possibilities to fine-tune an application's session
4607     management behavior: setRestartCommand(), setDiscardCommand(),
4608     setRestartHint(), setProperty(), requestPhase2(). See the respective
4609     function descriptions for further details.
4610 
4611     \sa QApplication, {Session Management}
4612 */
4613 
4614 /*! \enum QSessionManager::RestartHint
4615 
4616     This enum type defines the circumstances under which this application wants
4617     to be restarted by the session manager. The current values are:
4618 
4619     \value  RestartIfRunning    If the application is still running when the
4620                                 session is shut down, it wants to be restarted
4621                                 at the start of the next session.
4622 
4623     \value  RestartAnyway       The application wants to be started at the
4624                                 start of the next session, no matter what.
4625                                 (This is useful for utilities that run just
4626                                 after startup and then quit.)
4627 
4628     \value  RestartImmediately  The application wants to be started immediately
4629                                 whenever it is not running.
4630 
4631     \value  RestartNever        The application does not want to be restarted
4632                                 automatically.
4633 
4634     The default hint is \c RestartIfRunning.
4635 */
4636 
4637 
4638 /*!
4639     \fn QString QSessionManager::sessionId() const
4640 
4641     Returns the identifier of the current session.
4642 
4643     If the application has been restored from an earlier session, this
4644     identifier is the same as it was in the earlier session.
4645 
4646     \sa sessionKey(), QApplication::sessionId()
4647 */
4648 
4649 /*!
4650     \fn QString QSessionManager::sessionKey() const
4651 
4652     Returns the session key in the current session.
4653 
4654     If the application has been restored from an earlier session, this key is
4655     the same as it was when the previous session ended.
4656 
4657     The session key changes with every call of commitData() or saveState().
4658 
4659     \sa sessionId(), QApplication::sessionKey()
4660 */
4661 
4662 /*!
4663     \fn void* QSessionManager::handle() const
4664 
4665     \internal
4666 */
4667 
4668 /*!
4669     \fn bool QSessionManager::allowsInteraction()
4670 
4671     Asks the session manager for permission to interact with the user. Returns
4672     true if interaction is permitted; otherwise returns false.
4673 
4674     The rationale behind this mechanism is to make it possible to synchronize
4675     user interaction during a shutdown. Advanced session managers may ask all
4676     applications simultaneously to commit their data, resulting in a much
4677     faster shutdown.
4678 
4679     When the interaction is completed we strongly recommend releasing the user
4680     interaction semaphore with a call to release(). This way, other
4681     applications may get the chance to interact with the user while your
4682     application is still busy saving data. (The semaphore is implicitly
4683     released when the application exits.)
4684 
4685     If the user decides to cancel the shutdown process during the interaction
4686     phase, you must tell the session manager that this has happened by calling
4687     cancel().
4688 
4689     Here's an example of how an application's QApplication::commitData() might
4690     be implemented:
4691 
4692     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 8
4693 
4694     If an error occurred within the application while saving its data, you may
4695     want to try allowsErrorInteraction() instead.
4696 
4697     \sa QApplication::commitData(), release(), cancel()
4698 */
4699 
4700 
4701 /*!
4702     \fn bool QSessionManager::allowsErrorInteraction()
4703 
4704     Returns true if error interaction is permitted; otherwise returns false.
4705 
4706     This is similar to allowsInteraction(), but also enables the application to
4707     tell the user about any errors that occur. Session managers may give error
4708     interaction requests higher priority, which means that it is more likely
4709     that an error interaction is permitted. However, you are still not
4710     guaranteed that the session manager will allow interaction.
4711 
4712     \sa allowsInteraction(), release(), cancel()
4713 */
4714 
4715 /*!
4716     \fn void QSessionManager::release()
4717 
4718     Releases the session manager's interaction semaphore after an interaction
4719     phase.
4720 
4721     \sa allowsInteraction(), allowsErrorInteraction()
4722 */
4723 
4724 /*!
4725     \fn void QSessionManager::cancel()
4726 
4727     Tells the session manager to cancel the shutdown process.  Applications
4728     should not call this function without asking the user first.
4729 
4730     \sa allowsInteraction(), allowsErrorInteraction()
4731 */
4732 
4733 /*!
4734     \fn void QSessionManager::setRestartHint(RestartHint hint)
4735 
4736     Sets the application's restart hint to \a hint. On application startup, the
4737     hint is set to \c RestartIfRunning.
4738 
4739     \note These flags are only hints, a session manager may or may not respect
4740     them.
4741 
4742     We recommend setting the restart hint in QApplication::saveState() because
4743     most session managers perform a checkpoint shortly after an application's
4744     startup.
4745 
4746     \sa restartHint()
4747 */
4748 
4749 /*!
4750     \fn QSessionManager::RestartHint QSessionManager::restartHint() const
4751 
4752     Returns the application's current restart hint. The default is
4753     \c RestartIfRunning.
4754 
4755     \sa setRestartHint()
4756 */
4757 
4758 /*!
4759     \fn void QSessionManager::setRestartCommand(const QStringList& command)
4760 
4761     If the session manager is capable of restoring sessions it will execute
4762     \a command in order to restore the application. The command defaults to
4763 
4764     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 9
4765 
4766     The \c -session option is mandatory; otherwise QApplication cannot tell
4767     whether it has been restored or what the current session identifier is.
4768     See QApplication::isSessionRestored() and QApplication::sessionId() for
4769     details.
4770 
4771     If your application is very simple, it may be possible to store the entire
4772     application state in additional command line options. This is usually a
4773     very bad idea because command lines are often limited to a few hundred
4774     bytes. Instead, use QSettings, temporary files, or a database for this
4775     purpose. By marking the data with the unique sessionId(), you will be able
4776     to restore the application in a future  session.
4777 
4778     \sa restartCommand(), setDiscardCommand(), setRestartHint()
4779 */
4780 
4781 /*!
4782     \fn QStringList QSessionManager::restartCommand() const
4783 
4784     Returns the currently set restart command.
4785 
4786     To iterate over the list, you can use the \l foreach pseudo-keyword:
4787 
4788     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 10
4789 
4790     \sa setRestartCommand(), restartHint()
4791 */
4792 
4793 /*!
4794     \fn void QSessionManager::setDiscardCommand(const QStringList& list)
4795 
4796     Sets the discard command to the given \a list.
4797 
4798     \sa discardCommand(), setRestartCommand()
4799 */
4800 
4801 
4802 /*!
4803     \fn QStringList QSessionManager::discardCommand() const
4804 
4805     Returns the currently set discard command.
4806 
4807     To iterate over the list, you can use the \l foreach pseudo-keyword:
4808 
4809     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 11
4810 
4811     \sa setDiscardCommand(), restartCommand(), setRestartCommand()
4812 */
4813 
4814 /*!
4815     \fn void QSessionManager::setManagerProperty(const QString &name, const QString &value)
4816     \overload
4817 
4818     Low-level write access to the application's identification and state
4819     records are kept in the session manager.
4820 
4821     The property called \a name has its value set to the string \a value.
4822 */
4823 
4824 /*!
4825     \fn void QSessionManager::setManagerProperty(const QString& name,
4826                                                  const QStringList& value)
4827 
4828     Low-level write access to the application's identification and state record
4829     are kept in the session manager.
4830 
4831     The property called \a name has its value set to the string list \a value.
4832 */
4833 
4834 /*!
4835     \fn bool QSessionManager::isPhase2() const
4836 
4837     Returns true if the session manager is currently performing a second
4838     session management phase; otherwise returns false.
4839 
4840     \sa requestPhase2()
4841 */
4842 
4843 /*!
4844     \fn void QSessionManager::requestPhase2()
4845 
4846     Requests a second session management phase for the application. The
4847     application may then return immediately from the QApplication::commitData()
4848     or QApplication::saveState() function, and they will be called again once
4849     most or all other applications have finished their session management.
4850 
4851     The two phases are useful for applications such as the X11 window manager
4852     that need to store information about another application's windows and
4853     therefore have to wait until these applications have completed their
4854     respective session management tasks.
4855 
4856     \note If another application has requested a second phase it may get called
4857     before, simultaneously with, or after your application's second phase.
4858 
4859     \sa isPhase2()
4860 */
4861 
4862 /*****************************************************************************
4863   Stubbed session management support
4864  *****************************************************************************/
4865 #ifndef QT_NO_SESSIONMANAGER
4866 #if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
4867 
4868 #if defined(Q_OS_WINCE)
qt_CoCreateGuid(GUID * guid)4869 HRESULT qt_CoCreateGuid(GUID* guid)
4870 {
4871     // We will use the following information to create the GUID
4872     // 1. absolute path to application
4873     wchar_t tempFilename[MAX_PATH];
4874     if (!GetModuleFileName(0, tempFilename, MAX_PATH))
4875         return S_FALSE;
4876     unsigned int hash = qHash(QString::fromWCharArray(tempFilename));
4877     guid->Data1 = hash;
4878     // 2. creation time of file
4879     QFileInfo info(QString::fromWCharArray(tempFilename));
4880     guid->Data2 = qHash(info.created().toTime_t());
4881     // 3. current system time
4882     guid->Data3 = qHash(QDateTime::currentDateTime().toTime_t());
4883     return S_OK;
4884 }
4885 #if !defined(OLE32_MCOMGUID) || defined(QT_WINCE_FORCE_CREATE_GUID)
4886 #define CoCreateGuid qt_CoCreateGuid
4887 #endif
4888 
4889 #endif
4890 
4891 class QSessionManagerPrivate : public QObjectPrivate
4892 {
4893 public:
4894     QStringList restartCommand;
4895     QStringList discardCommand;
4896     QString sessionId;
4897     QString sessionKey;
4898     QSessionManager::RestartHint restartHint;
4899 };
4900 
4901 QSessionManager* qt_session_manager_self = 0;
QSessionManager(QApplication * app,QString & id,QString & key)4902 QSessionManager::QSessionManager(QApplication * app, QString &id, QString &key)
4903     : QObject(*new QSessionManagerPrivate, app)
4904 {
4905     Q_D(QSessionManager);
4906     setObjectName(QLatin1String("qt_sessionmanager"));
4907     qt_session_manager_self = this;
4908 #if defined(Q_WS_WIN)
4909     wchar_t guidstr[40];
4910     GUID guid;
4911     CoCreateGuid(&guid);
4912     StringFromGUID2(guid, guidstr, 40);
4913     id = QString::fromWCharArray(guidstr);
4914     CoCreateGuid(&guid);
4915     StringFromGUID2(guid, guidstr, 40);
4916     key = QString::fromWCharArray(guidstr);
4917 #endif
4918     d->sessionId = id;
4919     d->sessionKey = key;
4920     d->restartHint = RestartIfRunning;
4921 }
4922 
~QSessionManager()4923 QSessionManager::~QSessionManager()
4924 {
4925     qt_session_manager_self = 0;
4926 }
4927 
sessionId() const4928 QString QSessionManager::sessionId() const
4929 {
4930     Q_D(const QSessionManager);
4931     return d->sessionId;
4932 }
4933 
sessionKey() const4934 QString QSessionManager::sessionKey() const
4935 {
4936     Q_D(const QSessionManager);
4937     return d->sessionKey;
4938 }
4939 
4940 
4941 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
handle() const4942 void* QSessionManager::handle() const
4943 {
4944     return 0;
4945 }
4946 #endif
4947 
4948 #if !defined(Q_WS_WIN)
allowsInteraction()4949 bool QSessionManager::allowsInteraction()
4950 {
4951     return true;
4952 }
4953 
allowsErrorInteraction()4954 bool QSessionManager::allowsErrorInteraction()
4955 {
4956     return true;
4957 }
release()4958 void QSessionManager::release()
4959 {
4960 }
4961 
cancel()4962 void QSessionManager::cancel()
4963 {
4964 }
4965 #endif
4966 
4967 
setRestartHint(QSessionManager::RestartHint hint)4968 void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
4969 {
4970     Q_D(QSessionManager);
4971     d->restartHint = hint;
4972 }
4973 
restartHint() const4974 QSessionManager::RestartHint QSessionManager::restartHint() const
4975 {
4976     Q_D(const QSessionManager);
4977     return d->restartHint;
4978 }
4979 
setRestartCommand(const QStringList & command)4980 void QSessionManager::setRestartCommand(const QStringList& command)
4981 {
4982     Q_D(QSessionManager);
4983     d->restartCommand = command;
4984 }
4985 
restartCommand() const4986 QStringList QSessionManager::restartCommand() const
4987 {
4988     Q_D(const QSessionManager);
4989     return d->restartCommand;
4990 }
4991 
setDiscardCommand(const QStringList & command)4992 void QSessionManager::setDiscardCommand(const QStringList& command)
4993 {
4994     Q_D(QSessionManager);
4995     d->discardCommand = command;
4996 }
4997 
discardCommand() const4998 QStringList QSessionManager::discardCommand() const
4999 {
5000     Q_D(const QSessionManager);
5001     return d->discardCommand;
5002 }
5003 
setManagerProperty(const QString &,const QString &)5004 void QSessionManager::setManagerProperty(const QString&, const QString&)
5005 {
5006 }
5007 
setManagerProperty(const QString &,const QStringList &)5008 void QSessionManager::setManagerProperty(const QString&, const QStringList&)
5009 {
5010 }
5011 
isPhase2() const5012 bool QSessionManager::isPhase2() const
5013 {
5014     return false;
5015 }
5016 
requestPhase2()5017 void QSessionManager::requestPhase2()
5018 {
5019 }
5020 
5021 #endif
5022 #endif // QT_NO_SESSIONMANAGER
5023 
5024 /*!
5025     \typedef QApplication::ColorMode
5026     \compat
5027 
5028     Use ColorSpec instead.
5029 */
5030 
5031 /*!
5032     \fn Qt::MacintoshVersion QApplication::macVersion()
5033 
5034     Use QSysInfo::MacintoshVersion instead.
5035 */
5036 
5037 /*!
5038     \fn QApplication::ColorMode QApplication::colorMode()
5039 
5040     Use colorSpec() instead, and use ColorSpec as the enum type.
5041 */
5042 
5043 /*!
5044     \fn void QApplication::setColorMode(ColorMode mode)
5045 
5046     Use setColorSpec() instead, and pass a ColorSpec value instead.
5047 */
5048 
5049 /*!
5050     \fn bool QApplication::hasGlobalMouseTracking()
5051 
5052     This feature does not exist anymore. This function always returns true
5053     in Qt 4.
5054 */
5055 
5056 /*!
5057     \fn void QApplication::setGlobalMouseTracking(bool dummy)
5058 
5059     This function does nothing in Qt 4. The \a dummy parameter is ignored.
5060 */
5061 
5062 /*!
5063     \fn void QApplication::flushX()
5064 
5065     Use flush() instead.
5066 */
5067 
5068 /*!
5069     \fn void QApplication::setWinStyleHighlightColor(const QColor &c)
5070 
5071     Use the palette instead.
5072 
5073     \oldcode
5074     app.setWinStyleHighlightColor(color);
5075     \newcode
5076     QPalette palette(QApplication::palette());
5077     palette.setColor(QPalette::Highlight, color);
5078     QApplication::setPalette(palette);
5079     \endcode
5080 */
5081 
5082 /*!
5083     \fn void QApplication::setPalette(const QPalette &pal, bool b, const char* className = 0)
5084 
5085     Use the two-argument overload instead.
5086 */
5087 
5088 /*!
5089     \fn void QApplication::setFont(const QFont &font, bool b, const char* className = 0)
5090 
5091     Use the two-argument overload instead.
5092 */
5093 
5094 /*!
5095     \fn const QColor &QApplication::winStyleHighlightColor()
5096 
5097     Use QApplication::palette().color(QPalette::Active, QPalette::Highlight) instead.
5098 */
5099 
5100 /*!
5101     \fn QWidget *QApplication::widgetAt(int x, int y, bool child)
5102 
5103     Use the two-argument widgetAt() overload to get the child widget. To get
5104     the top-level widget do this:
5105 
5106     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 12
5107 */
5108 
5109 /*!
5110     \fn QWidget *QApplication::widgetAt(const QPoint &point, bool child)
5111 
5112     Use the single-argument widgetAt() overload to get the child widget. To get
5113     the top-level widget do this:
5114 
5115     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 13
5116 */
5117 
5118 #ifdef QT3_SUPPORT
mainWidget()5119 QWidget *QApplication::mainWidget()
5120 {
5121     return QApplicationPrivate::main_widget;
5122 }
5123 #endif
inPopupMode() const5124 bool QApplicationPrivate::inPopupMode() const
5125 {
5126     return QApplicationPrivate::popupWidgets != 0;
5127 }
5128 
5129 /*!
5130     \property QApplication::quitOnLastWindowClosed
5131 
5132     \brief whether the application implicitly quits when the last window is
5133     closed.
5134 
5135     The default is true.
5136 
5137     If this property is true, the applications quits when the last visible
5138     primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose
5139     attribute set is closed. By default this attribute is set for all widgets
5140     except for sub-windows. Refer to \l{Qt::WindowType} for a detailed list of
5141     Qt::Window objects.
5142 
5143     \sa quit(), QWidget::close()
5144  */
5145 
setQuitOnLastWindowClosed(bool quit)5146 void QApplication::setQuitOnLastWindowClosed(bool quit)
5147 {
5148     QApplicationPrivate::quitOnLastWindowClosed = quit;
5149 }
5150 
quitOnLastWindowClosed()5151 bool QApplication::quitOnLastWindowClosed()
5152 {
5153     return QApplicationPrivate::quitOnLastWindowClosed;
5154 }
5155 
emitLastWindowClosed()5156 void QApplicationPrivate::emitLastWindowClosed()
5157 {
5158     if (qApp && qApp->d_func()->in_exec) {
5159         if (QApplicationPrivate::quitOnLastWindowClosed) {
5160             // get ready to quit, this event might be removed if the
5161             // event loop is re-entered, however
5162             QApplication::postEvent(qApp, new QEvent(QEvent::Quit));
5163         }
5164         emit qApp->lastWindowClosed();
5165     }
5166 }
5167 
5168 /*! \variable QApplication::NormalColors
5169     \compat
5170 
5171     Use \l NormalColor instead.
5172 */
5173 
5174 /*! \variable QApplication::CustomColors
5175     \compat
5176 
5177     Use \l CustomColor instead.
5178 */
5179 
5180 #ifdef QT_KEYPAD_NAVIGATION
5181 /*!
5182     Sets the kind of focus navigation Qt should use to \a mode.
5183 
5184     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
5185     only.
5186 
5187     \note On Windows CE this feature is disabled by default for touch device
5188           mkspecs. To enable keypad navigation, build Qt with
5189           QT_KEYPAD_NAVIGATION defined.
5190 
5191     \note On Symbian, setting the mode to Qt::NavigationModeCursorAuto will enable a
5192           virtual mouse cursor on non touchscreen devices, which is controlled
5193           by the cursor keys if there is no analog pointer device.
5194           On other platforms and on touchscreen devices, it has the same
5195           meaning as Qt::NavigationModeNone.
5196 
5197     \since 4.6
5198 
5199     \sa keypadNavigationEnabled()
5200 */
setNavigationMode(Qt::NavigationMode mode)5201 void QApplication::setNavigationMode(Qt::NavigationMode mode)
5202 {
5203 #ifdef Q_OS_SYMBIAN
5204     QApplicationPrivate::setNavigationMode(mode);
5205 #else
5206     QApplicationPrivate::navigationMode = mode;
5207 #endif
5208 }
5209 
5210 /*!
5211     Returns what kind of focus navigation Qt is using.
5212 
5213     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
5214     only.
5215 
5216     \note On Windows CE this feature is disabled by default for touch device
5217           mkspecs. To enable keypad navigation, build Qt with
5218           QT_KEYPAD_NAVIGATION defined.
5219 
5220     \note On Symbian, the default mode is Qt::NavigationModeNone for touch
5221           devices, and Qt::NavigationModeKeypadDirectional.
5222 
5223     \since 4.6
5224 
5225     \sa keypadNavigationEnabled()
5226 */
navigationMode()5227 Qt::NavigationMode QApplication::navigationMode()
5228 {
5229     return QApplicationPrivate::navigationMode;
5230 }
5231 
5232 /*!
5233     Sets whether Qt should use focus navigation suitable for use with a
5234     minimal keypad.
5235 
5236     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
5237     only.
5238 
5239     \note On Windows CE this feature is disabled by default for touch device
5240           mkspecs. To enable keypad navigation, build Qt with
5241           QT_KEYPAD_NAVIGATION defined.
5242 
5243     \deprecated
5244 
5245     \sa setNavigationMode()
5246 */
setKeypadNavigationEnabled(bool enable)5247 void QApplication::setKeypadNavigationEnabled(bool enable)
5248 {
5249     if (enable) {
5250 #ifdef Q_OS_SYMBIAN
5251         QApplication::setNavigationMode(Qt::NavigationModeKeypadDirectional);
5252 #else
5253         QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder);
5254 #endif
5255     }
5256     else {
5257         QApplication::setNavigationMode(Qt::NavigationModeNone);
5258     }
5259 }
5260 
5261 /*!
5262     Returns true if Qt is set to use keypad navigation; otherwise returns
5263     false.  The default value is true on Symbian, but false on other platforms.
5264 
5265     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
5266     only.
5267 
5268     \note On Windows CE this feature is disabled by default for touch device
5269           mkspecs. To enable keypad navigation, build Qt with
5270           QT_KEYPAD_NAVIGATION defined.
5271 
5272     \deprecated
5273 
5274     \sa navigationMode()
5275 */
keypadNavigationEnabled()5276 bool QApplication::keypadNavigationEnabled()
5277 {
5278     return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
5279         QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
5280 }
5281 #endif
5282 
5283 /*!
5284     \fn void QApplication::alert(QWidget *widget, int msec)
5285     \since 4.3
5286 
5287     Causes an alert to be shown for \a widget if the window is not the active
5288     window. The alert is shown for \a msec miliseconds. If \a msec is zero (the
5289     default), then the alert is shown indefinitely until the window becomes
5290     active again.
5291 
5292     Currently this function does nothing on Qt for Embedded Linux.
5293 
5294     On Mac OS X, this works more at the application level and will cause the
5295     application icon to bounce in the dock.
5296 
5297     On Windows, this causes the window's taskbar entry to flash for a time. If
5298     \a msec is zero, the flashing will stop and the taskbar entry will turn a
5299     different color (currently orange).
5300 
5301     On X11, this will cause the window to be marked as "demands attention", the
5302     window must not be hidden (i.e. not have hide() called on it, but be
5303     visible in some sort of way) in order for this to work.
5304 */
5305 
5306 /*!
5307     \property QApplication::cursorFlashTime
5308     \brief the text cursor's flash (blink) time in milliseconds
5309 
5310     The flash time is the time required to display, invert and restore the
5311     caret display. Usually the text cursor is displayed for half the cursor
5312     flash time, then hidden for the same amount of time, but this may vary.
5313 
5314     The default value on X11 is 1000 milliseconds. On Windows, the
5315     \gui{Control Panel} value is used and setting this property sets the cursor
5316     flash time for all applications.
5317 
5318     We recommend that widgets do not cache this value as it may change at any
5319     time if the user changes the global desktop settings.
5320 */
5321 
5322 /*!
5323     \property QApplication::doubleClickInterval
5324     \brief the time limit in milliseconds that distinguishes a double click
5325     from two consecutive mouse clicks
5326 
5327     The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
5328     operating system's value is used. However, on Windows and Symbian OS,
5329     calling this function sets the double click interval for all applications.
5330 */
5331 
5332 /*!
5333     \property QApplication::keyboardInputInterval
5334     \brief the time limit in milliseconds that distinguishes a key press
5335     from two consecutive key presses
5336     \since 4.2
5337 
5338     The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
5339     operating system's value is used.
5340 */
5341 
5342 /*!
5343     \property QApplication::wheelScrollLines
5344     \brief the number of lines to scroll a widget, when the
5345     mouse wheel is rotated.
5346 
5347     If the value exceeds the widget's number of visible lines, the widget
5348     should interpret the scroll operation as a single \e{page up} or
5349     \e{page down}. If the widget is an \l{QAbstractItemView}{item view class},
5350     then the result of scrolling one \e line depends on the setting of the
5351     widget's \l{QAbstractItemView::verticalScrollMode()}{scroll mode}. Scroll
5352     one \e line can mean \l{QAbstractItemView::ScrollPerItem}{scroll one item}
5353     or \l{QAbstractItemView::ScrollPerPixel}{scroll one pixel}.
5354 
5355     By default, this property has a value of 3.
5356 */
5357 
5358 /*!
5359     \fn void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
5360 
5361     Enables the UI effect \a effect if \a enable is true, otherwise the effect
5362     will not be used.
5363 
5364     \note All effects are disabled on screens running at less than 16-bit color
5365     depth.
5366 
5367     \sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware()
5368 */
5369 
5370 /*!
5371     \fn bool QApplication::isEffectEnabled(Qt::UIEffect effect)
5372 
5373     Returns true if \a effect is enabled; otherwise returns false.
5374 
5375     By default, Qt will try to use the desktop settings. To prevent this, call
5376     setDesktopSettingsAware(false).
5377 
5378     \note All effects are disabled on screens running at less than 16-bit color
5379     depth.
5380 
5381     \sa setEffectEnabled(), Qt::UIEffect
5382 */
5383 
5384 /*!
5385     \fn QWidget *QApplication::mainWidget()
5386 
5387     Returns the main application widget, or 0 if there is no main widget.
5388 */
5389 
5390 /*!
5391     \fn void QApplication::setMainWidget(QWidget *mainWidget)
5392 
5393     Sets the application's main widget to \a mainWidget.
5394 
5395     In most respects the main widget is like any other widget, except that if
5396     it is closed, the application exits. QApplication does \e not take
5397     ownership of the \a mainWidget, so if you create your main widget on the
5398     heap you must delete it yourself.
5399 
5400     You need not have a main widget; connecting lastWindowClosed() to quit()
5401     is an alternative.
5402 
5403     On X11, this function also resizes and moves the main widget according
5404     to the \e -geometry command-line option, so you should set the default
5405     geometry (using \l QWidget::setGeometry()) before calling setMainWidget().
5406 
5407     \sa mainWidget(), exec(), quit()
5408 */
5409 
5410 /*!
5411     \fn void QApplication::beep()
5412 
5413     Sounds the bell, using the default volume and sound. The function is \e not
5414     available in Qt for Embedded Linux.
5415 */
5416 
5417 /*!
5418     \fn void QApplication::setOverrideCursor(const QCursor &cursor)
5419 
5420     Sets the application override cursor to \a cursor.
5421 
5422     Application override cursors are intended for showing the user that the
5423     application is in a special state, for example during an operation that
5424     might take some time.
5425 
5426     This cursor will be displayed in all the application's widgets until
5427     restoreOverrideCursor() or another setOverrideCursor() is called.
5428 
5429     Application cursors are stored on an internal stack. setOverrideCursor()
5430     pushes the cursor onto the stack, and restoreOverrideCursor() pops the
5431     active cursor off the stack. changeOverrideCursor() changes the curently
5432     active application override cursor.
5433 
5434     Every setOverrideCursor() must eventually be followed by a corresponding
5435     restoreOverrideCursor(), otherwise the stack will never be emptied.
5436 
5437     Example:
5438     \snippet doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp 0
5439 
5440     \sa overrideCursor(), restoreOverrideCursor(), changeOverrideCursor(),
5441     QWidget::setCursor()
5442 */
5443 
5444 /*!
5445     \fn void QApplication::restoreOverrideCursor()
5446 
5447     Undoes the last setOverrideCursor().
5448 
5449     If setOverrideCursor() has been called twice, calling
5450     restoreOverrideCursor() will activate the first cursor set. Calling this
5451     function a second time restores the original widgets' cursors.
5452 
5453     \sa setOverrideCursor(), overrideCursor()
5454 */
5455 
5456 /*!
5457     \macro qApp
5458     \relates QApplication
5459 
5460     A global pointer referring to the unique application object. It is
5461     equivalent to the pointer returned by the QCoreApplication::instance()
5462     function except that, in GUI applications, it is a pointer to a
5463     QApplication instance.
5464 
5465     Only one application object can be created.
5466 
5467     \sa QCoreApplication::instance()
5468 */
5469 
5470 #ifndef QT_NO_IM
5471 // ************************************************************************
5472 // Input Method support
5473 // ************************************************************************
5474 
5475 /*!
5476     This function replaces the QInputContext instance used by the application
5477     with \a inputContext.
5478 
5479     Qt takes ownership of the given \a inputContext.
5480 
5481     \sa inputContext()
5482 */
setInputContext(QInputContext * inputContext)5483 void QApplication::setInputContext(QInputContext *inputContext)
5484 {
5485     if (inputContext == QApplicationPrivate::inputContext)
5486         return;
5487     if (!inputContext) {
5488         qWarning("QApplication::setInputContext: called with 0 input context");
5489         return;
5490     }
5491     delete QApplicationPrivate::inputContext;
5492     QApplicationPrivate::inputContext = inputContext;
5493     QApplicationPrivate::inputContext->setParent(this);
5494 }
5495 
5496 /*!
5497     Returns the QInputContext instance used by the application.
5498 
5499     \sa setInputContext()
5500 */
inputContext() const5501 QInputContext *QApplication::inputContext() const
5502 {
5503     Q_D(const QApplication);
5504     Q_UNUSED(d);// only static members being used.
5505     if (QApplicationPrivate::is_app_closing)
5506         return d->inputContext;
5507 #ifdef Q_WS_X11
5508     if (!X11)
5509         return 0;
5510     if (!d->inputContext) {
5511         QApplication *that = const_cast<QApplication *>(this);
5512         QInputContext *qic = QInputContextFactory::create(X11->default_im, that);
5513         // fallback to default X Input Method.
5514         if (!qic)
5515             qic = QInputContextFactory::create(QLatin1String("xim"), that);
5516         that->d_func()->inputContext = qic;
5517     }
5518 #elif defined(Q_OS_SYMBIAN)
5519     if (!d->inputContext) {
5520         QApplication *that = const_cast<QApplication *>(this);
5521         const QStringList keys = QInputContextFactory::keys();
5522         // Try hbim and coefep first, then try others.
5523         if (keys.contains(QLatin1String("hbim"))) {
5524             that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("hbim"), that);
5525         } else if (keys.contains(QLatin1String("coefep"))) {
5526             if (!that->d_func()->inputContextBeingCreated) {
5527                 that->d_func()->inputContextBeingCreated = true;
5528                 that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("coefep"), that);
5529                 that->d_func()->inputContextBeingCreated = false;
5530             }
5531         } else {
5532             for (int c = 0; c < keys.size() && !d->inputContext; ++c) {
5533                 that->d_func()->inputContext = QInputContextFactory::create(keys[c], that);
5534             }
5535         }
5536     }
5537 #endif
5538     return d->inputContext;
5539 }
5540 #endif // QT_NO_IM
5541 
5542 //Returns the current platform used by keyBindings
currentPlatform()5543 uint QApplicationPrivate::currentPlatform(){
5544     uint platform = KB_Win;
5545 #ifdef Q_WS_MAC
5546     platform = KB_Mac;
5547 #elif defined Q_WS_X11
5548     platform = KB_X11;
5549     if (X11->desktopEnvironment == DE_KDE)
5550         platform |= KB_KDE;
5551     if (X11->desktopEnvironment == DE_GNOME)
5552         platform |= KB_Gnome;
5553     if (X11->desktopEnvironment == DE_CDE)
5554         platform |= KB_CDE;
5555 #elif defined(Q_OS_SYMBIAN)
5556     platform = KB_S60;
5557 #endif
5558     return platform;
5559 }
5560 
qt_sendSpontaneousEvent(QObject * receiver,QEvent * event)5561 bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
5562 {
5563     return QCoreApplication::sendSpontaneousEvent(receiver, event);
5564 }
5565 
5566 
5567 /*!
5568     \since 4.2
5569 
5570     Returns the current keyboard input locale.
5571 */
keyboardInputLocale()5572 QLocale QApplication::keyboardInputLocale()
5573 {
5574     if (!QApplicationPrivate::checkInstance("keyboardInputLocale"))
5575         return QLocale::c();
5576     return qt_keymapper_private()->keyboardInputLocale;
5577 }
5578 
5579 /*!
5580     \since 4.2
5581 
5582     Returns the current keyboard input direction.
5583 */
keyboardInputDirection()5584 Qt::LayoutDirection QApplication::keyboardInputDirection()
5585 {
5586     if (!QApplicationPrivate::checkInstance("keyboardInputDirection"))
5587         return Qt::LeftToRight;
5588     return qt_keymapper_private()->keyboardInputDirection;
5589 }
5590 
giveFocusAccordingToFocusPolicy(QWidget * widget,Qt::FocusPolicy focusPolicy,Qt::FocusReason focusReason)5591 void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
5592                                                           Qt::FocusPolicy focusPolicy,
5593                                                           Qt::FocusReason focusReason)
5594 {
5595     QWidget *focusWidget = widget;
5596     while (focusWidget) {
5597         if (focusWidget->isEnabled()
5598             && QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
5599             focusWidget->setFocus(focusReason);
5600             break;
5601         }
5602         if (focusWidget->isWindow())
5603             break;
5604         focusWidget = focusWidget->parentWidget();
5605     }
5606 }
5607 
shouldSetFocus(QWidget * w,Qt::FocusPolicy policy)5608 bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
5609 {
5610     QWidget *f = w;
5611     while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
5612         f = f->d_func()->extra->focus_proxy;
5613 
5614     if ((w->focusPolicy() & policy) != policy)
5615         return false;
5616     if (w != f && (f->focusPolicy() & policy) != policy)
5617         return false;
5618     return true;
5619 }
5620 
5621 /*! \fn QDecoration &QApplication::qwsDecoration()
5622     Return the QWSDecoration used for decorating windows.
5623 
5624     \warning This method is non-portable. It is only available in
5625     Qt for Embedded Linux.
5626 
5627     \sa QDecoration
5628 */
5629 
5630 /*!
5631     \fn void QApplication::qwsSetDecoration(QDecoration *decoration)
5632 
5633     Sets the QDecoration derived class to use for decorating the
5634     windows used by Qt for Embedded Linux to the \a decoration
5635     specified.
5636 
5637     This method is non-portable. It is only available in Qt for Embedded Linux.
5638 
5639     \sa QDecoration
5640 */
5641 
5642 /*! \fn QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
5643     \overload
5644 
5645     Requests a QDecoration object for \a decoration from the
5646     QDecorationFactory.
5647 
5648     The string must be one of the QDecorationFactory::keys(). Keys are case
5649     insensitive.
5650 
5651     A later call to the QApplication constructor will override the requested
5652     style when a "-style" option is passed in as a commandline parameter.
5653 
5654     Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object
5655     returned is set as the application's GUI style.
5656 */
5657 
5658 /*!
5659     \fn bool QApplication::qwsEventFilter(QWSEvent *event)
5660 
5661     This virtual function is only implemented under Qt for Embedded Linux.
5662 
5663     If you create an application that inherits QApplication and
5664     reimplement this function, you get direct access to all QWS (Q
5665     Window System) events that the are received from the QWS master
5666     process. The events are passed in the \a event parameter.
5667 
5668     Return true if you want to stop the event from being processed.
5669     Return false for normal event dispatching. The default
5670     implementation returns false.
5671 */
5672 
5673 /*! \fn void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
5674     Set Qt for Embedded Linux custom color table.
5675 
5676     Qt for Embedded Linux on 8-bpp displays allocates a standard 216 color cube.
5677     The remaining 40 colors may be used by setting a custom color
5678     table in the QWS master process before any clients connect.
5679 
5680     \a colorTable is an array of up to 40 custom colors. \a start is
5681     the starting index (0-39) and \a numColors is the number of colors
5682     to be set (1-40).
5683 
5684     This method is non-portable. It is available \e only in
5685     Qt for Embedded Linux.
5686 
5687     \note The custom colors will not be used by the default screen
5688     driver. To make use of the new colors, implement a custom screen
5689     driver, or use QDirectPainter.
5690 */
5691 
5692 /*! \fn int QApplication::qwsProcessEvent(QWSEvent* event)
5693     \internal
5694 */
5695 
5696 /*! \fn int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
5697     \internal
5698 */
5699 
5700 /*! \fn int QApplication::x11ProcessEvent(XEvent* event)
5701     This function does the core processing of individual X
5702     \a{event}s, normally by dispatching Qt events to the right
5703     destination.
5704 
5705     It returns 1 if the event was consumed by special handling, 0 if
5706     the \a event was consumed by normal handling, and -1 if the \a
5707     event was for an unrecognized widget.
5708 
5709     \sa x11EventFilter()
5710 */
5711 
5712 /*!
5713     \fn bool QApplication::x11EventFilter(XEvent *event)
5714 
5715     \warning This virtual function is only implemented under X11.
5716 
5717     If you create an application that inherits QApplication and
5718     reimplement this function, you get direct access to all X events
5719     that the are received from the X server. The events are passed in
5720     the \a event parameter.
5721 
5722     Return true if you want to stop the event from being processed.
5723     Return false for normal event dispatching. The default
5724     implementation returns false.
5725 
5726     It is only the directly addressed messages that are filtered.
5727     You must install an event filter directly on the event
5728     dispatcher, which is returned by
5729     QAbstractEventDispatcher::instance(), to handle system wide
5730     messages.
5731 
5732     \sa x11ProcessEvent()
5733 */
5734 
5735 /*! \fn void QApplication::winFocus(QWidget *widget, bool gotFocus)
5736     \internal
5737     \since 4.1
5738 
5739     If \a gotFocus is true, \a widget will become the active window.
5740     Otherwise the active window is reset to 0.
5741 */
5742 
5743 /*! \fn void QApplication::winMouseButtonUp()
5744   \internal
5745  */
5746 
5747 /*! \fn void QApplication::syncX()
5748   Synchronizes with the X server in the X11 implementation.
5749   This normally takes some time. Does nothing on other platforms.
5750 */
5751 
updateTouchPointsForWidget(QWidget * widget,QTouchEvent * touchEvent)5752 void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
5753 {
5754     for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
5755         QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
5756 
5757         // preserve the sub-pixel resolution
5758         QRectF rect = touchPoint.screenRect();
5759         const QPointF screenPos = rect.center();
5760         const QPointF delta = screenPos - screenPos.toPoint();
5761 
5762         rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
5763         touchPoint.d->rect = rect;
5764         if (touchPoint.state() == Qt::TouchPointPressed) {
5765             touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
5766             touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
5767         }
5768     }
5769 }
5770 
initializeMultitouch()5771 void QApplicationPrivate::initializeMultitouch()
5772 {
5773     widgetForTouchPointId.clear();
5774     appCurrentTouchPoints.clear();
5775 
5776     initializeMultitouch_sys();
5777 }
5778 
cleanupMultitouch()5779 void QApplicationPrivate::cleanupMultitouch()
5780 {
5781     cleanupMultitouch_sys();
5782 
5783     widgetForTouchPointId.clear();
5784     appCurrentTouchPoints.clear();
5785 }
5786 
findClosestTouchPointId(const QPointF & screenPos)5787 int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
5788 {
5789     int closestTouchPointId = -1;
5790     qreal closestDistance = qreal(0.);
5791     foreach (const QTouchEvent::TouchPoint &touchPoint, appCurrentTouchPoints) {
5792         qreal distance = QLineF(screenPos, touchPoint.screenPos()).length();
5793         if (closestTouchPointId == -1 || distance < closestDistance) {
5794             closestTouchPointId = touchPoint.id();
5795             closestDistance = distance;
5796         }
5797     }
5798     return closestTouchPointId;
5799 }
5800 
translateRawTouchEvent(QWidget * window,QTouchEvent::DeviceType deviceType,const QList<QTouchEvent::TouchPoint> & touchPoints)5801 void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
5802                                                  QTouchEvent::DeviceType deviceType,
5803                                                  const QList<QTouchEvent::TouchPoint> &touchPoints)
5804 {
5805     QApplicationPrivate *d = self;
5806     typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
5807     QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents;
5808 
5809     for (int i = 0; i < touchPoints.count(); ++i) {
5810         QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
5811         // explicitly detach from the original touch point that we got, so even
5812         // if the touchpoint structs are reused, we will make a copy that we'll
5813         // deliver to the user (which might want to store the struct for later use).
5814         touchPoint.d = touchPoint.d->detach();
5815 
5816         // update state
5817         QWeakPointer<QWidget> widget;
5818         switch (touchPoint.state()) {
5819         case Qt::TouchPointPressed:
5820         {
5821             if (deviceType == QTouchEvent::TouchPad) {
5822                 // on touch-pads, send all touch points to the same widget
5823                 widget = d->widgetForTouchPointId.isEmpty()
5824                          ? QWeakPointer<QWidget>()
5825                          : d->widgetForTouchPointId.constBegin().value();
5826             }
5827 
5828             if (!widget) {
5829                 // determine which widget this event will go to
5830                 if (!window)
5831                     window = QApplication::topLevelAt(touchPoint.screenPos().toPoint());
5832                 if (!window)
5833                     continue;
5834                 widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
5835                 if (!widget)
5836                     widget = window;
5837             }
5838 
5839             if (deviceType == QTouchEvent::TouchScreen) {
5840                 int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
5841                 QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId).data();
5842                 if (closestWidget
5843                     && (widget.data()->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget.data()))) {
5844                     widget = closestWidget;
5845                 }
5846             }
5847 
5848             d->widgetForTouchPointId[touchPoint.id()] = widget;
5849             touchPoint.d->startScreenPos = touchPoint.screenPos();
5850             touchPoint.d->lastScreenPos = touchPoint.screenPos();
5851             touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
5852             touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
5853             if (touchPoint.pressure() < qreal(0.))
5854                 touchPoint.d->pressure = qreal(1.);
5855 
5856             d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
5857             break;
5858         }
5859         case Qt::TouchPointReleased:
5860         {
5861             widget = d->widgetForTouchPointId.take(touchPoint.id());
5862             if (!widget)
5863                 continue;
5864 
5865             QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
5866             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
5867             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
5868             touchPoint.d->startPos = previousTouchPoint.startPos();
5869             touchPoint.d->lastPos = previousTouchPoint.pos();
5870             touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
5871             touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
5872             if (touchPoint.pressure() < qreal(0.))
5873                 touchPoint.d->pressure = qreal(0.);
5874             break;
5875         }
5876         default:
5877             widget = d->widgetForTouchPointId.value(touchPoint.id());
5878             if (!widget)
5879                 continue;
5880 
5881             Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
5882             QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
5883             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
5884             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
5885             touchPoint.d->startPos = previousTouchPoint.startPos();
5886             touchPoint.d->lastPos = previousTouchPoint.pos();
5887             touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
5888             touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
5889             if (touchPoint.pressure() < qreal(0.))
5890                 touchPoint.d->pressure = qreal(1.);
5891             d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
5892             break;
5893         }
5894         Q_ASSERT(widget.data() != 0);
5895 
5896         // make the *scene* functions return the same as the *screen* functions
5897         touchPoint.d->sceneRect = touchPoint.screenRect();
5898         touchPoint.d->startScenePos = touchPoint.startScreenPos();
5899         touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
5900 
5901         StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget.data()];
5902         maskAndPoints.first |= touchPoint.state();
5903         if (touchPoint.isPrimary())
5904             maskAndPoints.first |= Qt::TouchPointPrimary;
5905         maskAndPoints.second.append(touchPoint);
5906     }
5907 
5908     if (widgetsNeedingEvents.isEmpty())
5909         return;
5910 
5911     QHash<QWidget *, StatesAndTouchPoints>::ConstIterator it = widgetsNeedingEvents.constBegin();
5912     const QHash<QWidget *, StatesAndTouchPoints>::ConstIterator end = widgetsNeedingEvents.constEnd();
5913     for (; it != end; ++it) {
5914         QWidget *widget = it.key();
5915         if (!QApplicationPrivate::tryModalHelper(widget, 0))
5916             continue;
5917 
5918         QEvent::Type eventType;
5919         switch (it.value().first & Qt::TouchPointStateMask) {
5920         case Qt::TouchPointPressed:
5921             eventType = QEvent::TouchBegin;
5922             break;
5923         case Qt::TouchPointReleased:
5924             eventType = QEvent::TouchEnd;
5925             break;
5926         case Qt::TouchPointStationary:
5927             // don't send the event if nothing changed
5928             continue;
5929         default:
5930             eventType = QEvent::TouchUpdate;
5931             break;
5932         }
5933 
5934         QTouchEvent touchEvent(eventType,
5935                                deviceType,
5936                                QApplication::keyboardModifiers(),
5937                                it.value().first,
5938                                it.value().second);
5939         updateTouchPointsForWidget(widget, &touchEvent);
5940 
5941         switch (touchEvent.type()) {
5942         case QEvent::TouchBegin:
5943         {
5944             // if the TouchBegin handler recurses, we assume that means the event
5945             // has been implicitly accepted and continue to send touch events
5946             widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
5947             (void ) QApplication::sendSpontaneousEvent(widget, &touchEvent);
5948             break;
5949         }
5950         default:
5951             if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) {
5952                 if (touchEvent.type() == QEvent::TouchEnd)
5953                     widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
5954                 (void) QApplication::sendSpontaneousEvent(widget, &touchEvent);
5955             }
5956             break;
5957         }
5958     }
5959 }
5960 
qt_translateRawTouchEvent(QWidget * window,QTouchEvent::DeviceType deviceType,const QList<QTouchEvent::TouchPoint> & touchPoints)5961 Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
5962                                             QTouchEvent::DeviceType deviceType,
5963                                             const QList<QTouchEvent::TouchPoint> &touchPoints)
5964 {
5965     QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
5966 }
5967 
5968 #ifndef QT_NO_GESTURES
instance()5969 QGestureManager* QGestureManager::instance()
5970 {
5971     QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
5972     if (!qAppPriv)
5973         return 0;
5974     if (!qAppPriv->gestureManager)
5975         qAppPriv->gestureManager = new QGestureManager(qApp);
5976     return qAppPriv->gestureManager;
5977 }
5978 #endif // QT_NO_GESTURES
5979 
5980 // These pixmaps approximate the images in the Windows User Interface Guidelines.
5981 
5982 // XPM
5983 
5984 static const char * const move_xpm[] = {
5985 "11 20 3 1",
5986 ".        c None",
5987 #if defined(Q_WS_WIN)
5988 "a        c #000000",
5989 "X        c #FFFFFF", // Windows cursor is traditionally white
5990 #else
5991 "a        c #FFFFFF",
5992 "X        c #000000", // X11 cursor is traditionally black
5993 #endif
5994 "aa.........",
5995 "aXa........",
5996 "aXXa.......",
5997 "aXXXa......",
5998 "aXXXXa.....",
5999 "aXXXXXa....",
6000 "aXXXXXXa...",
6001 "aXXXXXXXa..",
6002 "aXXXXXXXXa.",
6003 "aXXXXXXXXXa",
6004 "aXXXXXXaaaa",
6005 "aXXXaXXa...",
6006 "aXXaaXXa...",
6007 "aXa..aXXa..",
6008 "aa...aXXa..",
6009 "a.....aXXa.",
6010 "......aXXa.",
6011 ".......aXXa",
6012 ".......aXXa",
6013 "........aa."};
6014 
6015 #ifdef Q_WS_WIN
6016 /* XPM */
6017 static const char * const ignore_xpm[] = {
6018 "24 30 3 1",
6019 ".        c None",
6020 "a        c #000000",
6021 "X        c #FFFFFF",
6022 "aa......................",
6023 "aXa.....................",
6024 "aXXa....................",
6025 "aXXXa...................",
6026 "aXXXXa..................",
6027 "aXXXXXa.................",
6028 "aXXXXXXa................",
6029 "aXXXXXXXa...............",
6030 "aXXXXXXXXa..............",
6031 "aXXXXXXXXXa.............",
6032 "aXXXXXXaaaa.............",
6033 "aXXXaXXa................",
6034 "aXXaaXXa................",
6035 "aXa..aXXa...............",
6036 "aa...aXXa...............",
6037 "a.....aXXa..............",
6038 "......aXXa.....XXXX.....",
6039 ".......aXXa..XXaaaaXX...",
6040 ".......aXXa.XaaaaaaaaX..",
6041 "........aa.XaaaXXXXaaaX.",
6042 "...........XaaaaX..XaaX.",
6043 "..........XaaXaaaX..XaaX",
6044 "..........XaaXXaaaX.XaaX",
6045 "..........XaaX.XaaaXXaaX",
6046 "..........XaaX..XaaaXaaX",
6047 "...........XaaX..XaaaaX.",
6048 "...........XaaaXXXXaaaX.",
6049 "............XaaaaaaaaX..",
6050 ".............XXaaaaXX...",
6051 "...............XXXX....."};
6052 #endif
6053 
6054 /* XPM */
6055 static const char * const copy_xpm[] = {
6056 "24 30 3 1",
6057 ".        c None",
6058 "a        c #000000",
6059 "X        c #FFFFFF",
6060 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
6061 "aa......................",
6062 "aXa.....................",
6063 "aXXa....................",
6064 "aXXXa...................",
6065 "aXXXXa..................",
6066 "aXXXXXa.................",
6067 "aXXXXXXa................",
6068 "aXXXXXXXa...............",
6069 "aXXXXXXXXa..............",
6070 "aXXXXXXXXXa.............",
6071 "aXXXXXXaaaa.............",
6072 "aXXXaXXa................",
6073 "aXXaaXXa................",
6074 "aXa..aXXa...............",
6075 "aa...aXXa...............",
6076 "a.....aXXa..............",
6077 "......aXXa..............",
6078 ".......aXXa.............",
6079 ".......aXXa.............",
6080 "........aa...aaaaaaaaaaa",
6081 #else
6082 "XX......................",
6083 "XaX.....................",
6084 "XaaX....................",
6085 "XaaaX...................",
6086 "XaaaaX..................",
6087 "XaaaaaX.................",
6088 "XaaaaaaX................",
6089 "XaaaaaaaX...............",
6090 "XaaaaaaaaX..............",
6091 "XaaaaaaaaaX.............",
6092 "XaaaaaaXXXX.............",
6093 "XaaaXaaX................",
6094 "XaaXXaaX................",
6095 "XaX..XaaX...............",
6096 "XX...XaaX...............",
6097 "X.....XaaX..............",
6098 "......XaaX..............",
6099 ".......XaaX.............",
6100 ".......XaaX.............",
6101 "........XX...aaaaaaaaaaa",
6102 #endif
6103 ".............aXXXXXXXXXa",
6104 ".............aXXXXXXXXXa",
6105 ".............aXXXXaXXXXa",
6106 ".............aXXXXaXXXXa",
6107 ".............aXXaaaaaXXa",
6108 ".............aXXXXaXXXXa",
6109 ".............aXXXXaXXXXa",
6110 ".............aXXXXXXXXXa",
6111 ".............aXXXXXXXXXa",
6112 ".............aaaaaaaaaaa"};
6113 
6114 /* XPM */
6115 static const char * const link_xpm[] = {
6116 "24 30 3 1",
6117 ".        c None",
6118 "a        c #000000",
6119 "X        c #FFFFFF",
6120 #if defined(Q_WS_WIN) // Windows cursor is traditionally white
6121 "aa......................",
6122 "aXa.....................",
6123 "aXXa....................",
6124 "aXXXa...................",
6125 "aXXXXa..................",
6126 "aXXXXXa.................",
6127 "aXXXXXXa................",
6128 "aXXXXXXXa...............",
6129 "aXXXXXXXXa..............",
6130 "aXXXXXXXXXa.............",
6131 "aXXXXXXaaaa.............",
6132 "aXXXaXXa................",
6133 "aXXaaXXa................",
6134 "aXa..aXXa...............",
6135 "aa...aXXa...............",
6136 "a.....aXXa..............",
6137 "......aXXa..............",
6138 ".......aXXa.............",
6139 ".......aXXa.............",
6140 "........aa...aaaaaaaaaaa",
6141 #else
6142 "XX......................",
6143 "XaX.....................",
6144 "XaaX....................",
6145 "XaaaX...................",
6146 "XaaaaX..................",
6147 "XaaaaaX.................",
6148 "XaaaaaaX................",
6149 "XaaaaaaaX...............",
6150 "XaaaaaaaaX..............",
6151 "XaaaaaaaaaX.............",
6152 "XaaaaaaXXXX.............",
6153 "XaaaXaaX................",
6154 "XaaXXaaX................",
6155 "XaX..XaaX...............",
6156 "XX...XaaX...............",
6157 "X.....XaaX..............",
6158 "......XaaX..............",
6159 ".......XaaX.............",
6160 ".......XaaX.............",
6161 "........XX...aaaaaaaaaaa",
6162 #endif
6163 ".............aXXXXXXXXXa",
6164 ".............aXXXaaaaXXa",
6165 ".............aXXXXaaaXXa",
6166 ".............aXXXaaaaXXa",
6167 ".............aXXaaaXaXXa",
6168 ".............aXXaaXXXXXa",
6169 ".............aXXaXXXXXXa",
6170 ".............aXXXaXXXXXa",
6171 ".............aXXXXXXXXXa",
6172 ".............aaaaaaaaaaa"};
6173 
getPixmapCursor(Qt::CursorShape cshape)6174 QPixmap QApplicationPrivate::getPixmapCursor(Qt::CursorShape cshape)
6175 {
6176 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
6177     if (!move_cursor) {
6178         move_cursor = new QPixmap((const char **)move_xpm);
6179         copy_cursor = new QPixmap((const char **)copy_xpm);
6180         link_cursor = new QPixmap((const char **)link_xpm);
6181 #ifdef Q_WS_WIN
6182         ignore_cursor = new QPixmap((const char **)ignore_xpm);
6183 #endif
6184     }
6185 
6186     switch (cshape) {
6187     case Qt::DragMoveCursor:
6188         return *move_cursor;
6189     case Qt::DragCopyCursor:
6190         return *copy_cursor;
6191     case Qt::DragLinkCursor:
6192         return *link_cursor;
6193 #ifdef Q_WS_WIN
6194     case Qt::ForbiddenCursor:
6195         return *ignore_cursor;
6196 #endif
6197     default:
6198         break;
6199     }
6200 #else
6201     Q_UNUSED(cshape);
6202 #endif
6203     return QPixmap();
6204 }
6205 
6206 QT_END_NAMESPACE
6207 
6208 #include "moc_qapplication.cpp"
6209