summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel/qapplication.cpp')
-rw-r--r--src/gui/kernel/qapplication.cpp764
1 files changed, 539 insertions, 225 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index bc8ed96..a3420da 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "qplatformdefs.h"
#include "qabstracteventdispatcher.h"
#include "qaccessible.h"
#include "qapplication.h"
@@ -74,6 +75,9 @@
#ifdef Q_WS_X11
#include <private/qt_x11_p.h>
+#endif
+
+#if defined(Q_WS_X11) || defined(Q_WS_S60)
#include "qinputcontextfactory.h"
#endif
@@ -85,11 +89,12 @@
#include <stdlib.h>
#include "qapplication_p.h"
+#include "qevent_p.h"
#include "qwidget_p.h"
#include "qapplication.h"
-#ifdef Q_OS_WINCE
+#ifdef Q_WS_WINCE
#include "qdatetime.h"
#include "qguifunctions_wince.h"
extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp
@@ -97,19 +102,22 @@ extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp
extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp
#endif
+#include "qdatetime.h"
+
+#ifdef QT_MAC_USE_COCOA
+#include <private/qt_cocoa_helpers_mac_p.h>
+#endif
+
//#define ALIEN_DEBUG
static void initResources()
{
-#ifdef Q_OS_WINCE
+#ifdef Q_WS_WINCE
Q_INIT_RESOURCE(qstyle_wince);
#else
Q_INIT_RESOURCE(qstyle);
#endif
-#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN)
- Q_INIT_RESOURCE(qpaintengine_d3d);
-#endif
Q_INIT_RESOURCE(qmessagebox);
#if !defined(QT_NO_PRINTDIALOG)
Q_INIT_RESOURCE(qprintdialog);
@@ -130,9 +138,11 @@ QInputContext *QApplicationPrivate::inputContext = 0;
bool QApplicationPrivate::quitOnLastWindowClosed = true;
-#ifdef Q_OS_WINCE
+#ifdef Q_WS_WINCE
int QApplicationPrivate::autoMaximizeThreshold = -1;
bool QApplicationPrivate::autoSipEnabled = false;
+#else
+bool QApplicationPrivate::autoSipEnabled = true;
#endif
QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type)
@@ -173,16 +183,13 @@ QApplicationPrivate::~QApplicationPrivate()
\brief The QApplication class manages the GUI application's control
flow and main settings.
- \ingroup application
- \mainclass
-
QApplication contains the main event loop, where all events from the window
system and other sources are processed and dispatched. It also handles the
- application's initialization and finalization, and provides session
- management. In addition, it handles most system-wide and application-wide
- settings.
+ application's initialization, finalization, and provides session
+ management. In addition, QApplication handles most of the system-wide and
+ application-wide settings.
- For any GUI application using Qt, there is precisely one QApplication
+ For any GUI application using Qt, there is precisely \bold one QApplication
object, no matter whether the application has 0, 1, 2 or more windows at
any given time. For non-GUI Qt applications, use QCoreApplication instead,
as it does not depend on the \l QtGui library.
@@ -238,9 +245,9 @@ QApplicationPrivate::~QApplicationPrivate()
saveState() for details.
\endlist
- The QApplication object does so much initialization. Hence, it \e{must} be
+ Since the QApplication object does so much initialization, it \e{must} be
created before any other objects related to the user interface are created.
- Since QApplication also deals with common command line arguments, it is
+ QApplication also deals with common command line arguments. Hence, it is
usually a good idea to create it \e before any interpretation or
modification of \c argv is done in the application itself.
@@ -394,6 +401,7 @@ Qt::MouseButtons QApplicationPrivate::mouse_buttons = Qt::NoButton;
Qt::KeyboardModifiers QApplicationPrivate::modifier_buttons = Qt::NoModifier;
QStyle *QApplicationPrivate::app_style = 0; // default application style
+QString QApplicationPrivate::styleOverride; // style override
#ifndef QT_NO_STYLE_STYLESHEET
QString QApplicationPrivate::styleSheet; // default application stylesheet
@@ -408,7 +416,7 @@ QPalette *QApplicationPrivate::set_pal = 0; // default palette set by pro
QGraphicsSystem *QApplicationPrivate::graphics_system = 0; // default graphics system
QString QApplicationPrivate::graphics_system_name; // graphics system id - for delayed initialization
-Q_GLOBAL_STATIC(QMutex, applicationFontMutex);
+Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
QFont *QApplicationPrivate::app_font = 0; // default application font
QFont *QApplicationPrivate::sys_font = 0; // default system font
QFont *QApplicationPrivate::set_font = 0; // default font set by programmer
@@ -430,7 +438,12 @@ bool Q_GUI_EXPORT qt_tab_all_widgets = true;
bool qt_in_tab_key_event = false;
int qt_antialiasing_threshold = -1;
static int drag_time = 500;
+#ifdef Q_OS_SYMBIAN
+// The screens are a bit too small to for your thumb when using only 4 pixels drag distance.
+static int drag_distance = 8;
+#else
static int drag_distance = 4;
+#endif
static Qt::LayoutDirection layout_direction = Qt::LeftToRight;
QSize QApplicationPrivate::app_strut = QSize(0,0); // no default application strut
bool QApplicationPrivate::animate_ui = true;
@@ -441,12 +454,15 @@ bool QApplicationPrivate::animate_tooltip = false;
bool QApplicationPrivate::fade_tooltip = false;
bool QApplicationPrivate::animate_toolbox = false;
bool QApplicationPrivate::widgetCount = false;
-QString* QApplicationPrivate::styleOverride = 0;
-#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE)
bool QApplicationPrivate::inSizeMove = false;
#endif
#ifdef QT_KEYPAD_NAVIGATION
+# if defined(Q_OS_SYMBIAN)
+bool QApplicationPrivate::keypadNavigation = true;
+# else
bool QApplicationPrivate::keypadNavigation = false;
+# endif
QWidget *QApplicationPrivate::oldEditFocus = 0;
#endif
@@ -466,15 +482,12 @@ static inline bool isAlien(QWidget *widget)
// ######## move to QApplicationPrivate
// Default application palettes and fonts (per widget type)
-
-typedef QHash<QByteArray, QPalette> PaletteHash;
Q_GLOBAL_STATIC(PaletteHash, app_palettes)
PaletteHash *qt_app_palettes_hash()
{
return app_palettes();
}
-typedef QHash<QByteArray, QFont> FontHash;
Q_GLOBAL_STATIC(FontHash, app_fonts)
FontHash *qt_app_fonts_hash()
{
@@ -494,8 +507,6 @@ QWidgetList * qt_modal_stack=0; // stack of modal widgets
*/
void QApplicationPrivate::process_cmdline()
{
- Q_Q(QApplication);
- Q_UNUSED(q);// only static members being used.
// process platform-indep command line
if (!qt_is_gui_used || !argc)
return;
@@ -540,7 +551,7 @@ void QApplicationPrivate::process_cmdline()
#endif
} else if (qstrcmp(arg, "-reverse") == 0) {
force_reverse = true;
- q->setLayoutDirection(Qt::RightToLeft);
+ QApplication::setLayoutDirection(Qt::RightToLeft);
} else if (qstrcmp(arg, "-widgetcount") == 0) {
widgetCount = true;
} else if (arg == "-graphicssystem" && i < argc-1) {
@@ -553,9 +564,7 @@ void QApplicationPrivate::process_cmdline()
delete app_style;
app_style = 0;
}
- if (!styleOverride)
- styleOverride = new QString;
- *styleOverride = s;
+ styleOverride = s;
}
}
@@ -620,13 +629,6 @@ void QApplicationPrivate::process_cmdline()
and QPixmaps. Available options are \c{raster} and \c{opengl}.
\endlist
- The Windows version of Qt supports an additional command line option, if
- Direct3D support has been compiled into Qt:
- \list
- \o -direct3d will make the Direct3D paint engine the default widget
- paint engine in Qt. \bold {This functionality is experimental.}
- \endlist
-
The X11 version of Qt supports some traditional X11 command line options:
\list
\o -display \e display, sets the X display (default is $DISPLAY).
@@ -686,9 +688,9 @@ QApplication::QApplication(int &argc, char **argv, int _internal)
On X11, the window system is initialized if \a GUIenabled is true. If
\a GUIenabled is false, the application does not connect to the X server.
- On Windows and Macintosh, currently the window system is always
- initialized, regardless of the value of GUIenabled. This may change in
- future versions of Qt.
+ On Windows and Mac OS, currently the window system is always initialized,
+ regardless of the value of GUIenabled. This may change in future versions
+ of Qt.
The following example shows how to create an application that uses a
graphical interface when available.
@@ -833,6 +835,12 @@ QApplication::QApplication(Display *dpy, int &argc, char **argv,
#endif // Q_WS_X11
extern void qInitDrawhelperAsm();
+extern int qRegisterGuiVariant();
+extern int qUnregisterGuiVariant();
+#ifndef QT_NO_STATEMACHINE
+extern int qRegisterGuiStateMachine();
+extern int qUnregisterGuiStateMachine();
+#endif
/*!
\fn void QApplicationPrivate::initialize()
@@ -842,12 +850,15 @@ extern void qInitDrawhelperAsm();
void QApplicationPrivate::initialize()
{
QWidgetPrivate::mapper = new QWidgetMapper;
- QWidgetPrivate::uncreatedWidgets = new QWidgetSet;
+ QWidgetPrivate::allWidgets = new QWidgetSet;
if (qt_appType != QApplication::Tty)
(void) QApplication::style(); // trigger creation of application style
// trigger registering of QVariant's GUI types
- extern int qRegisterGuiVariant();
qRegisterGuiVariant();
+#ifndef QT_NO_STATEMACHINE
+ // trigger registering of QStateMachine's GUI types
+ qRegisterGuiStateMachine();
+#endif
is_app_running = true; // no longer starting up
@@ -860,13 +871,7 @@ void QApplicationPrivate::initialize()
if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0)
q->setAttribute(Qt::AA_NativeWindows);
-#if defined(Q_WS_WIN)
- // Alien is not currently working on Windows 98
- if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based)
- q->setAttribute(Qt::AA_NativeWindows);
-#endif
-
-#ifdef Q_OS_WINCE
+#ifdef Q_WS_WINCE
#ifdef QT_AUTO_MAXIMIZE_THRESHOLD
autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD;
#else
@@ -875,7 +880,7 @@ void QApplicationPrivate::initialize()
else
autoMaximizeThreshold = -1;
#endif //QT_AUTO_MAXIMIZE_THRESHOLD
-#endif //Q_OS_WINCE
+#endif //Q_WS_WINCE
// Set up which span functions should be used in raster engine...
qInitDrawhelperAsm();
@@ -893,6 +898,8 @@ void QApplicationPrivate::initialize()
QApplicationPrivate::wheel_scroll_lines = 3;
#endif
#endif
+
+ initializeMultitouch();
}
/*!
@@ -987,23 +994,14 @@ QApplication::~QApplication()
qt_clipboard = 0;
#endif
- // delete widget mapper
- if (QWidgetPrivate::mapper) {
- QWidgetMapper * myMapper = QWidgetPrivate::mapper;
- QWidgetPrivate::mapper = 0;
- for (QWidgetMapper::Iterator it = myMapper->begin(); it != myMapper->end(); ++it) {
- register QWidget *w = *it;
- if (!w->parent()) // window
- w->destroy(true, true);
- }
- delete myMapper;
- }
+ delete QWidgetPrivate::mapper;
+ QWidgetPrivate::mapper = 0;
- // delete uncreated widgets
- if (QWidgetPrivate::uncreatedWidgets) {
- QWidgetSet *mySet = QWidgetPrivate::uncreatedWidgets;
- QWidgetPrivate::uncreatedWidgets = 0;
- for (QWidgetSet::Iterator it = mySet->begin(); it != mySet->end(); ++it) {
+ // delete all widgets
+ if (QWidgetPrivate::allWidgets) {
+ QWidgetSet *mySet = QWidgetPrivate::allWidgets;
+ QWidgetPrivate::allWidgets = 0;
+ for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
register QWidget *w = *it;
if (!w->parent()) // window
w->destroy(true, true);
@@ -1043,6 +1041,8 @@ QApplication::~QApplication()
delete QDragManager::self();
#endif
+ d->cleanupMultitouch();
+
qt_cleanup();
if (QApplicationPrivate::widgetCount)
@@ -1069,8 +1069,11 @@ QApplication::~QApplication()
QApplicationPrivate::fade_tooltip = false;
QApplicationPrivate::widgetCount = false;
+#ifndef QT_NO_STATEMACHINE
+ // trigger unregistering of QStateMachine's GUI types
+ qUnregisterGuiStateMachine();
+#endif
// trigger unregistering of QVariant's GUI types
- extern int qUnregisterGuiVariant();
qUnregisterGuiVariant();
}
@@ -1197,21 +1200,22 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis
\since 4.4
\brief defines a threshold for auto maximizing widgets
- The auto maximize threshold is only available as part of Qt for Windows CE.
+ \bold{The auto maximize threshold is only available as part of Qt for
+ Windows CE.}
This property defines a threshold for the size of a window as a percentage
of the screen size. If the minimum size hint of a window exceeds the
- threshold, calling show() will then cause the window to be maximized
+ threshold, calling show() will cause the window to be maximized
automatically.
- Setting the threshold to be 100 or greater means that it will cause it to
- always be maximized. Setting it to be 50 means that the widget is maximized
- if the vertical minimum size hint is at least 50% of the vertical screen
- size.
+ Setting the threshold to 100 or greater means that the widget will always
+ be maximized. Alternatively, setting the threshold to 50 means that the
+ widget will be maximized only if the vertical minimum size hint is at least
+ 50% of the vertical screen size.
- If -1 is specified then this will disable the feature.
+ Setting the threshold to -1 disables the feature.
- On Windows CE the default is -1 (i.e. it is disabled).
+ On Windows CE the default is -1 (i.e., it is disabled).
On Windows Mobile the default is 40.
*/
@@ -1220,14 +1224,18 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis
\since 4.5
\brief toggles automatic SIP (software input panel) visibility
- The auto SIP property is only available as part of Qt for Windows CE.
-
- Set this property to true to automatically display the SIP when entering
+ Set this property to \c true to automatically display the SIP when entering
widgets that accept keyboard input. This property only affects widgets with
- the WA_InputMethodEnabled attribute set.
+ the WA_InputMethodEnabled attribute set, and is typically used to launch
+ a virtual keyboard on devices which have very few or no keys.
+
+ \bold{ The property only has an effect on platforms which use software input
+ panels, such as Windows CE and Symbian.}
+
+ The default is platform dependent.
*/
-#ifdef Q_OS_WINCE
+#ifdef Q_WS_WINCE
void QApplication::setAutoMaximizeThreshold(const int threshold)
{
QApplicationPrivate::autoMaximizeThreshold = threshold;
@@ -1237,6 +1245,7 @@ int QApplication::autoMaximizeThreshold() const
{
return QApplicationPrivate::autoMaximizeThreshold;
}
+#endif
void QApplication::setAutoSipEnabled(const bool enabled)
{
@@ -1247,7 +1256,6 @@ bool QApplication::autoSipEnabled() const
{
return QApplicationPrivate::autoSipEnabled;
}
-#endif
#ifndef QT_NO_STYLE_STYLESHEET
@@ -1289,44 +1297,14 @@ QStyle *QApplication::style()
return 0;
}
-#if defined(Q_WS_X11)
- if(!QApplicationPrivate::styleOverride)
- QApplicationPrivate::x11_initialize_style(); // run-time search for default style
-#endif
if (!QApplicationPrivate::app_style) {
// Compile-time search for default style
//
QString style;
- if (QApplicationPrivate::styleOverride) {
- style = *QApplicationPrivate::styleOverride;
- delete QApplicationPrivate::styleOverride;
- QApplicationPrivate::styleOverride = 0;
- } else {
-#if defined(Q_WS_WIN) && defined(Q_OS_WINCE)
- if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc())
- style = QLatin1String("WindowsMobile");
- else
- style = QLatin1String("WindowsCE");
-
-#elif defined(Q_WS_WIN)
- if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- style = QLatin1String("WindowsVista");
- else if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
- && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
- style = QLatin1String("WindowsXP");
- else
- style = QLatin1String("Windows"); // default styles for Windows
-#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS)
- style = QLatin1String("CDE"); // default style for X11 on Solaris
-#elif defined(Q_WS_X11) && defined(Q_OS_IRIX)
- style = QLatin1String("SGI"); // default style for X11 on IRIX
-#elif defined(Q_WS_X11) || defined(Q_WS_QWS)
- style = QLatin1String("Plastique"); // default style for X11 and small devices
-#elif defined(Q_WS_MAC)
- style = QLatin1String("Macintosh"); // default style for all Mac's
-#endif
- }
+ if (!QApplicationPrivate::styleOverride.isEmpty())
+ style = QApplicationPrivate::styleOverride;
+ else
+ style = QApplicationPrivate::desktopStyleKey();
QStyle *&app_style = QApplicationPrivate::app_style;
app_style = QStyleFactory::create(style);
@@ -1414,7 +1392,6 @@ void QApplication::setStyle(QStyle *style)
} else
#endif // QT_NO_STYLE_STYLESHEET
QApplicationPrivate::app_style = style;
-
QApplicationPrivate::app_style->setParent(qApp); // take ownership
// take care of possible palette requirements of certain gui
@@ -1551,7 +1528,7 @@ int QApplication::colorSpec()
strategy. Use this option if your application uses buttons, menus,
texts and pixmaps with few colors. With this option, the
application uses system global colors. This works fine for most
- applications under X11, but on Windows machines it may cause
+ applications under X11, but on the Windows platform, it may cause
dithering of non-standard colors.
\o QApplication::CustomColor. Use this option if your application
needs a small number of custom colors. On X11, this option is the
@@ -1938,6 +1915,44 @@ void QApplicationPrivate::setSystemFont(const QFont &font)
QApplication::setFont(*sys_font);
}
+/*! \internal
+*/
+QString QApplicationPrivate::desktopStyleKey()
+{
+QString desktopstyle;
+#if defined(Q_WS_WIN) && defined(Q_WS_WINCE)
+ if (qt_wince_is_smartphone() || qt_wince_is_pocket_pc())
+ desktopstyle = QLatin1String("WindowsMobile");
+ else
+ desktopstyle = QLatin1String("WindowsCE");
+
+#elif defined(Q_WS_WIN)
+ if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ desktopstyle = QLatin1String("WindowsVista");
+ else if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
+ && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
+ desktopstyle = QLatin1String("WindowsXP");
+ else
+ desktopstyle = QLatin1String("Windows"); // default styles for Windows
+#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS)
+ desktopstyle = QLatin1String("CDE"); // default style for X11 on Solaris
+#elif defined(Q_WS_S60)
+ desktopstyle = QLatin1String("S60"); // default style for Symbian with S60
+#elif defined(Q_OS_SYMBIAN)
+ desktopstyle = QLatin1String("Windows"); // default style for Symbian without S60
+#elif defined(Q_WS_X11) && defined(Q_OS_IRIX)
+ desktopstyle = QLatin1String("SGI"); // default style for X11 on IRIX
+#elif defined(Q_WS_QWS)
+ desktopstyle = QLatin1String("Plastique"); // default style for X11 and small devices
+#elif defined(Q_WS_X11)
+ desktopstyle = QApplicationPrivate::x11_desktop_style(); // default runtime dependant style for X11
+#elif defined(Q_WS_MAC)
+ desktopstyle = QLatin1String("Macintosh"); // default style for all Mac's
+#endif
+ return desktopstyle;
+}
+
/*!
\property QApplication::windowIcon
\brief the default window icon
@@ -2010,12 +2025,9 @@ QWidgetList QApplication::topLevelWidgets()
QWidgetList QApplication::allWidgets()
{
- QWidgetList list;
- if (QWidgetPrivate::mapper)
- list += QWidgetPrivate::mapper->values();
- if (QWidgetPrivate::uncreatedWidgets)
- list += QWidgetPrivate::uncreatedWidgets->toList();
- return list;
+ if (QWidgetPrivate::allWidgets)
+ return QWidgetPrivate::allWidgets->toList();
+ return QWidgetList();
}
/*!
@@ -2080,6 +2092,16 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
prev->setEditFocus(false);
}
#endif
+#ifndef QT_NO_IM
+ if (focus) {
+ QInputContext *prevIc;
+ prevIc = prev->inputContext();
+ if (prevIc && prevIc != focus->inputContext()) {
+ QEvent closeSIPEvent(QEvent::CloseSoftwareInputPanel);
+ QApplication::sendEvent(prev, &closeSIPEvent);
+ }
+ }
+#endif
QFocusEvent out(QEvent::FocusOut, reason);
QPointer<QWidget> that = prev;
QApplication::sendEvent(prev, &out);
@@ -2089,8 +2111,9 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
if(focus && QApplicationPrivate::focus_widget == focus) {
if (focus->testAttribute(Qt::WA_InputMethodEnabled)) {
QInputContext *qic = focus->inputContext();
- if (qic && focus_widget->testAttribute(Qt::WA_WState_Created))
- qic->setFocusWidget( focus_widget );
+ if (qic && focus->testAttribute(Qt::WA_WState_Created)
+ && focus->isEnabled())
+ qic->setFocusWidget(focus);
}
QFocusEvent in(QEvent::FocusIn, reason);
QPointer<QWidget> that = focus;
@@ -2309,10 +2332,6 @@ bool QApplication::event(QEvent *e)
} else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
d->toolTipFallAsleep.stop();
}
-#ifdef QT_MAC_USE_COCOA
- } else if (e->type() == QEvent::CocoaRequestModal) {
- d->_q_runAppModalWindow();
-#endif
}
return QCoreApplication::event(e);
}
@@ -2576,14 +2595,14 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
QEvent leaveEvent(QEvent::Leave);
for (int i = 0; i < leaveList.size(); ++i) {
w = leaveList.at(i);
- if (!qApp->activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
+ if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
#if defined(Q_WS_WIN) || defined(Q_WS_X11)
if (leaveAfterRelease == w)
leaveAfterRelease = 0;
#endif
QApplication::sendEvent(w, &leaveEvent);
if (w->testAttribute(Qt::WA_Hover) &&
- (!qApp->activePopupWidget() || qApp->activePopupWidget() == w->window())) {
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
Q_ASSERT(instance());
QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos));
qApp->d_func()->notify_helper(w, &he);
@@ -2594,10 +2613,10 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
QEvent enterEvent(QEvent::Enter);
for (int i = 0; i < enterList.size(); ++i) {
w = enterList.at(i);
- if (!qApp->activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
+ if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
QApplication::sendEvent(w, &enterEvent);
if (w->testAttribute(Qt::WA_Hover) &&
- (!qApp->activePopupWidget() || qApp->activePopupWidget() == w->window())) {
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
QHoverEvent he(QEvent::HoverEnter, w->mapFromGlobal(posEnter), QPoint(-1, -1));
qApp->d_func()->notify_helper(w, &he);
}
@@ -2671,7 +2690,7 @@ bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
widget = widget->window();
if (!modalState())
return false;
- if (qApp->activePopupWidget() == widget)
+ if (QApplication::activePopupWidget() == widget)
return false;
for (int i = 0; i < qt_modal_stack->size(); ++i) {
@@ -2760,7 +2779,7 @@ bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
void QApplicationPrivate::enterModal(QWidget *widget)
{
QSet<QWidget*> blocked;
- QList<QWidget*> windows = qApp->topLevelWidgets();
+ QList<QWidget*> windows = QApplication::topLevelWidgets();
for (int i = 0; i < windows.count(); ++i) {
QWidget *window = windows.at(i);
if (window->windowType() != Qt::Tool && isBlockedByModal(window))
@@ -2769,7 +2788,7 @@ void QApplicationPrivate::enterModal(QWidget *widget)
enterModal_sys(widget);
- windows = qApp->topLevelWidgets();
+ windows = QApplication::topLevelWidgets();
QEvent e(QEvent::WindowBlocked);
for (int i = 0; i < windows.count(); ++i) {
QWidget *window = windows.at(i);
@@ -2783,7 +2802,7 @@ void QApplicationPrivate::enterModal(QWidget *widget)
void QApplicationPrivate::leaveModal(QWidget *widget)
{
QSet<QWidget*> blocked;
- QList<QWidget*> windows = qApp->topLevelWidgets();
+ QList<QWidget*> windows = QApplication::topLevelWidgets();
for (int i = 0; i < windows.count(); ++i) {
QWidget *window = windows.at(i);
if (window->windowType() != Qt::Tool && isBlockedByModal(window))
@@ -2792,7 +2811,7 @@ void QApplicationPrivate::leaveModal(QWidget *widget)
leaveModal_sys(widget);
- windows = qApp->topLevelWidgets();
+ windows = QApplication::topLevelWidgets();
QEvent e(QEvent::WindowUnblocked);
for (int i = 0; i < windows.count(); ++i) {
QWidget *window = windows.at(i);
@@ -2815,7 +2834,7 @@ bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop)
*rettop = top;
// the active popup widget always gets the input event
- if (qApp->activePopupWidget())
+ if (QApplication::activePopupWidget())
return true;
#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
@@ -2849,7 +2868,7 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint
QWidget *receiver = candidate;
if (!mouseGrabber)
- mouseGrabber = buttonDown ? buttonDown : alienWidget;
+ mouseGrabber = (buttonDown && !isBlockedByModal(buttonDown)) ? buttonDown : alienWidget;
if (mouseGrabber && mouseGrabber != candidate) {
receiver = mouseGrabber;
@@ -2868,7 +2887,8 @@ QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint
*/
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
QWidget *alienWidget, QWidget *nativeWidget,
- QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver)
+ QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
+ bool spontaneous)
{
Q_ASSERT(receiver);
Q_ASSERT(event);
@@ -2881,7 +2901,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
QPointer<QWidget> receiverGuard = receiver;
QPointer<QWidget> nativeGuard = nativeWidget;
QPointer<QWidget> alienGuard = alienWidget;
- QPointer<QWidget> activePopupWidget = qApp->activePopupWidget();
+ QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
const bool graphicsWidget = nativeWidget->testAttribute(Qt::WA_DontShowOnScreen);
@@ -2921,7 +2941,11 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
// We need this quard in case someone opens a modal dialog / popup. If that's the case
// leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
- bool result = QApplication::sendSpontaneousEvent(receiver, event);
+ bool result;
+ if (spontaneous)
+ result = QApplication::sendSpontaneousEvent(receiver, event);
+ else
+ result = QApplication::sendEvent(receiver, event);
if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
&& !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
@@ -3477,6 +3501,15 @@ void QApplication::changeOverrideCursor(const QCursor &cursor)
if (qApp->d_func()->cursor_list.isEmpty())
return;
qApp->d_func()->cursor_list.removeFirst();
+#ifdef QT_MAC_USE_COCOA
+ // We use native NSCursor stacks in Cocoa. The currentCursor is the
+ // top of this stack. So to avoid flickering of cursor, we have to
+ // change the cusor instead of pop-ing the existing OverrideCursor
+ // and pushing the new one.
+ qApp->d_func()->cursor_list.prepend(cursor);
+ qt_cocoaChangeOverrideCursor(cursor);
+ return;
+#endif
setOverrideCursor(cursor);
}
#endif
@@ -3496,7 +3529,7 @@ void QApplication::changeOverrideCursor(const QCursor &cursor)
It is necessary to call this function to start event handling. The main
event loop receives events from the window system and dispatches these to
the application widgets.
-
+
Generally, no user interaction can take place before calling exec(). As a
special case, modal widgets like QMessageBox can be used before calling
exec(), because modal widgets call exec() to start a local event loop.
@@ -3507,12 +3540,12 @@ void QApplication::changeOverrideCursor(const QCursor &cursor)
We recommend that you connect clean-up code to the
\l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your
- application's \c{main()} function because on some platforms the
- QApplication::exec() call may not return. For example, on Windows when the
- user logs off, the system terminates the process after Qt closes all
- top-level windows. Hence, there is no guarantee that the application will
- have time to exit its event loop and execute code at the end of the
- \c{main()} function after the QApplication::exec() call.
+ application's \c{main()} function. This is because, on some platforms the
+ QApplication::exec() call may not return. For example, on the Windows
+ platform, when the user logs off, the system terminates the process after Qt
+ closes all top-level windows. Hence, there is \e{no guarantee} that the
+ application will have time to exit its event loop and execute code at the
+ end of the \c{main()} function, after the QApplication::exec() call.
\sa quitOnLastWindowClosed, quit(), exit(), processEvents(),
QCoreApplication::exec()
@@ -3562,20 +3595,18 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QApplicationPrivate::mouse_buttons |= me->button();
else
QApplicationPrivate::mouse_buttons &= ~me->button();
- }
+ }
#if !defined(QT_NO_WHEELEVENT) || !defined(QT_NO_TABLETEVENT)
- else if (
+ else if (false
# ifndef QT_NO_WHEELEVENT
- e->type() == QEvent::Wheel
-# else
- false
+ || e->type() == QEvent::Wheel
# endif
# ifndef QT_NO_TABLETEVENT
- || e->type() == QEvent::TabletMove
- || e->type() == QEvent::TabletPress
- || e->type() == QEvent::TabletRelease
+ || e->type() == QEvent::TabletMove
+ || e->type() == QEvent::TabletPress
+ || e->type() == QEvent::TabletRelease
# endif
- ) {
+ ) {
QInputEvent *ie = static_cast<QInputEvent*>(e);
QApplicationPrivate::modifier_buttons = ie->modifiers();
}
@@ -3594,6 +3625,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
d->toolTipFallAsleep.stop();
+ // fall-through
case QEvent::Leave:
d->toolTipWakeUp.stop();
default:
@@ -3709,19 +3741,18 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint relpos = mouse->pos();
if (e->spontaneous()) {
+#ifndef QT_NO_IM
+ QInputContext *ic = w->inputContext();
+ if (ic
+ && w->testAttribute(Qt::WA_InputMethodEnabled)
+ && ic->filterEvent(mouse))
+ return true;
+#endif
if (e->type() == QEvent::MouseButtonPress) {
- QWidget *fw = w;
- while (fw) {
- if (fw->isEnabled()
- && QApplicationPrivate::shouldSetFocus(fw, Qt::ClickFocus)) {
- fw->setFocus(Qt::MouseFocusReason);
- break;
- }
- if (fw->isWindow())
- break;
- fw = fw->parentWidget();
- }
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
+ Qt::ClickFocus,
+ Qt::MouseFocusReason);
}
// ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
@@ -3787,7 +3818,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
while (w) {
if (w->testAttribute(Qt::WA_Hover) &&
- (!qApp->activePopupWidget() || qApp->activePopupWidget() == w->window())) {
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff);
d->notify_helper(w, &he);
}
@@ -3810,17 +3841,9 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
bool eventAccepted = wheel->isAccepted();
if (e->spontaneous()) {
- QWidget *fw = w;
- while (fw) {
- if (fw->isEnabled()
- && QApplicationPrivate::shouldSetFocus(fw, Qt::WheelFocus)) {
- fw->setFocus(Qt::MouseFocusReason);
- break;
- }
- if (fw->isWindow())
- break;
- fw = fw->parentWidget();
- }
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
+ Qt::WheelFocus,
+ Qt::MouseFocusReason);
}
while (w) {
@@ -4025,7 +4048,72 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
}
break;
#endif
+ case QEvent::TouchBegin:
+ // Note: TouchUpdate and TouchEnd events are never propagated
+ {
+ QWidget *widget = static_cast<QWidget *>(receiver);
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
+ bool eventAccepted = touchEvent->isAccepted();
+ if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
+ // give the widget focus if the focus policy allows it
+ QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
+ Qt::ClickFocus,
+ Qt::MouseFocusReason);
+ }
+ while (widget) {
+ // first, try to deliver the touch event
+ bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
+ touchEvent->setWidget(widget);
+ touchEvent->setAccepted(acceptTouchEvents);
+ res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
+ eventAccepted = touchEvent->isAccepted();
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
+ touchEvent->spont = false;
+ if (res && eventAccepted) {
+ // the first widget to accept the TouchBegin gets an implicit grab.
+ for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
+ const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
+ d->widgetForTouchPointId[touchPoint.id()] = widget;
+ }
+ break;
+ } else if (widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
+ break;
+ }
+ widget = widget->parentWidget();
+ d->updateTouchPointsForWidget(widget, touchEvent);
+ }
+
+ touchEvent->setAccepted(eventAccepted);
+ break;
+ }
+ case QEvent::RequestSoftwareInputPanel:
+ case QEvent::CloseSoftwareInputPanel:
+#ifndef QT_NO_IM
+ if (receiver->isWidgetType()) {
+ QWidget *w = static_cast<QWidget *>(receiver);
+ QInputContext *ic = w->inputContext();
+ if (ic && ic->filterEvent(e)) {
+ break;
+ }
+ }
+#endif
+ res = d->notify_helper(receiver, e);
+ break;
+
+ case QEvent::NativeGesture:
+ {
+ // only propagate the first gesture event (after the GID_BEGIN)
+ QWidget *w = static_cast<QWidget *>(receiver);
+ while (w) {
+ e->ignore();
+ res = d->notify_helper(w, e);
+ if ((res && e->isAccepted()) || w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ break;
+ }
default:
res = d->notify_helper(receiver, e);
break;
@@ -4043,10 +4131,10 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
if (receiver->isWidgetType()) {
QWidget *widget = static_cast<QWidget *>(receiver);
-#if !defined(Q_OS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR))
+#if !defined(Q_WS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR))
// toggle HasMouse widget state on enter and leave
if ((e->type() == QEvent::Enter || e->type() == QEvent::DragEnter) &&
- (!qApp->activePopupWidget() || qApp->activePopupWidget() == widget->window()))
+ (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == widget->window()))
widget->setAttribute(Qt::WA_UnderMouse, true);
else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave)
widget->setAttribute(Qt::WA_UnderMouse, false);
@@ -4072,9 +4160,6 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
\class QSessionManager
\brief The QSessionManager class provides access to the session manager.
- \ingroup application
- \ingroup environment
-
A session manager in a desktop environment (in which Qt GUI applications
live) keeps track of a session, which is a group of running applications,
each of which has a particular state. The state of an application contains
@@ -4373,13 +4458,13 @@ HRESULT qt_CoCreateGuid(GUID* guid)
{
// We will use the following information to create the GUID
// 1. absolute path to application
- wchar_t tempFilename[512];
- if (!GetModuleFileNameW(0, tempFilename, 512))
+ wchar_t tempFilename[MAX_PATH];
+ if (!GetModuleFileName(0, tempFilename, MAX_PATH))
return S_FALSE;
- unsigned int hash = qHash(QString::fromUtf16((const unsigned short *) tempFilename));
+ unsigned int hash = qHash(QString::fromWCharArray(tempFilename));
guid->Data1 = hash;
// 2. creation time of file
- QFileInfo info(QString::fromUtf16((const unsigned short *) tempFilename));
+ QFileInfo info(QString::fromWCharArray(tempFilename));
guid->Data2 = qHash(info.created().toTime_t());
// 3. current system time
guid->Data3 = qHash(QDateTime::currentDateTime().toTime_t());
@@ -4413,10 +4498,10 @@ QSessionManager::QSessionManager(QApplication * app, QString &id, QString &key)
GUID guid;
CoCreateGuid(&guid);
StringFromGUID2(guid, guidstr, 40);
- id = QString::fromUtf16((ushort*)guidstr);
+ id = QString::fromWCharArray(guidstr);
CoCreateGuid(&guid);
StringFromGUID2(guid, guidstr, 40);
- key = QString::fromUtf16((ushort*)guidstr);
+ key = QString::fromWCharArray(guidstr);
#endif
d->sessionId = id;
d->sessionKey = key;
@@ -4576,9 +4661,9 @@ void QSessionManager::requestPhase2()
\oldcode
app.setWinStyleHighlightColor(color);
\newcode
- QPalette palette(qApp->palette());
+ QPalette palette(QApplication::palette());
palette.setColor(QPalette::Highlight, color);
- qApp->setPalette(palette);
+ QApplication::setPalette(palette);
\endcode
*/
@@ -4597,7 +4682,7 @@ void QSessionManager::requestPhase2()
/*!
\fn const QColor &QApplication::winStyleHighlightColor()
- Use qApp->palette().color(QPalette::Active, QPalette::Highlight) instead.
+ Use QApplication::palette().color(QPalette::Active, QPalette::Highlight) instead.
*/
/*!
@@ -4687,7 +4772,8 @@ void QApplicationPrivate::emitLastWindowClosed()
If \a enable is true, Qt::Key_Up and Qt::Key_Down are used to change focus.
- This feature is available in Qt for Embedded Linux and Windows CE only.
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
\note On Windows CE this feature is disabled by default for touch device
mkspecs. To enable keypad navigation, build Qt with
@@ -4702,9 +4788,10 @@ void QApplication::setKeypadNavigationEnabled(bool enable)
/*!
Returns true if Qt is set to use keypad navigation; otherwise returns
- false. The default is false.
+ false. The default value is true on Symbian, but false on other platforms.
- This feature is available in Qt for Embedded Linux and Windows CE only.
+ This feature is available in Qt for Embedded Linux, Symbian and Windows CE
+ only.
\note On Windows CE this feature is disabled by default for touch device
mkspecs. To enable keypad navigation, build Qt with
@@ -4732,7 +4819,7 @@ bool QApplication::keypadNavigationEnabled()
On Mac OS X, this works more at the application level and will cause the
application icon to bounce in the dock.
- On Windows this causes the window's taskbar entry to flash for a time. If
+ On Windows, this causes the window's taskbar entry to flash for a time. If
\a msec is zero, the flashing will stop and the taskbar entry will turn a
different color (currently orange).
@@ -4749,24 +4836,22 @@ bool QApplication::keypadNavigationEnabled()
caret display. Usually the text cursor is displayed for half the cursor
flash time, then hidden for the same amount of time, but this may vary.
- The default value on X11 is 1000 milliseconds. On Windows, the control
- panel value is used. Widgets should not cache this value since it may be
- changed at any time by the user changing the global desktop settings.
+ The default value on X11 is 1000 milliseconds. On Windows, the
+ \gui{Control Panel} value is used and setting this property sets the cursor
+ flash time for all applications.
- \note On Microsoft Windows, setting this property sets the cursor flash
- time for all applications.
+ We recommend that widgets do not cache this value as it may change at any
+ time if the user changes the global desktop settings.
*/
/*!
\property QApplication::doubleClickInterval
- \brief the time limit in milliseconds that distinguishes a double click from two
- consecutive mouse clicks
-
- The default value on X11 is 400 milliseconds. On Windows and Mac OS X, the
- operating system's value is used.
+ \brief the time limit in milliseconds that distinguishes a double click
+ from two consecutive mouse clicks
- On Microsoft Windows, calling this function sets the double click interval
- for all applications.
+ The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
+ operating system's value is used. However, on Windows and Symbian OS,
+ calling this function sets the double click interval for all applications.
*/
/*!
@@ -4775,7 +4860,7 @@ bool QApplication::keypadNavigationEnabled()
from two consecutive key presses
\since 4.2
- The default value on X11 is 400 milliseconds. On Windows and Mac OS X, the
+ The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
operating system's value is used.
*/
@@ -4840,7 +4925,7 @@ bool QApplication::keypadNavigationEnabled()
You need not have a main widget; connecting lastWindowClosed() to quit()
is an alternative.
- For X11, this function also resizes and moves the main widget according
+ On X11, this function also resizes and moves the main widget according
to the \e -geometry command-line option, so you should set the default
geometry (using \l QWidget::setGeometry()) before calling setMainWidget().
@@ -4869,9 +4954,10 @@ bool QApplication::keypadNavigationEnabled()
Application cursors are stored on an internal stack. setOverrideCursor()
pushes the cursor onto the stack, and restoreOverrideCursor() pops the
active cursor off the stack. changeOverrideCursor() changes the curently
- active application override cursor. Every setOverrideCursor() must
- eventually be followed by a corresponding restoreOverrideCursor(),
- otherwise the stack will never be emptied.
+ active application override cursor.
+
+ Every setOverrideCursor() must eventually be followed by a corresponding
+ restoreOverrideCursor(), otherwise the stack will never be emptied.
Example:
\snippet doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp 0
@@ -4924,8 +5010,7 @@ void QApplication::setInputContext(QInputContext *inputContext)
qWarning("QApplication::setInputContext: called with 0 input context");
return;
}
- if (d->inputContext)
- delete d->inputContext;
+ delete d->inputContext;
d->inputContext = inputContext;
}
@@ -4949,6 +5034,11 @@ QInputContext *QApplication::inputContext() const
qic = QInputContextFactory::create(QLatin1String("xim"), that);
that->d_func()->inputContext = qic;
}
+#elif defined(Q_WS_S60)
+ if (!d->inputContext) {
+ QApplication *that = const_cast<QApplication *>(this);
+ that->d_func()->inputContext = QInputContextFactory::create(QString::fromLatin1("coefep"), that);
+ }
#endif
return d->inputContext;
}
@@ -4966,6 +5056,8 @@ uint QApplicationPrivate::currentPlatform(){
platform |= KB_Gnome;
if (X11->desktopEnvironment == DE_CDE)
platform |= KB_CDE;
+#elif defined(Q_OS_SYMBIAN)
+ platform = KB_S60;
#endif
return platform;
}
@@ -5000,6 +5092,23 @@ Qt::LayoutDirection QApplication::keyboardInputDirection()
return qt_keymapper_private()->keyboardInputDirection;
}
+void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
+ Qt::FocusPolicy focusPolicy,
+ Qt::FocusReason focusReason)
+{
+ QWidget *focusWidget = widget;
+ while (focusWidget) {
+ if (focusWidget->isEnabled()
+ && QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
+ focusWidget->setFocus(focusReason);
+ break;
+ }
+ if (focusWidget->isWindow())
+ break;
+ focusWidget = focusWidget->parentWidget();
+ }
+}
+
bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
{
QWidget *f = w;
@@ -5035,19 +5144,19 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
*/
/*! \fn QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
- \overload
+ \overload
- Requests a QDecoration object for \a decoration from the QDecorationFactory.
+ Requests a QDecoration object for \a decoration from the
+ QDecorationFactory.
- The string must be one of the QDecorationFactory::keys(). Keys are
- case insensitive.
+ The string must be one of the QDecorationFactory::keys(). Keys are case
+ insensitive.
- A later call to the QApplication constructor will override the
- requested style when a "-style" option is passed in as a commandline
- parameter.
+ A later call to the QApplication constructor will override the requested
+ style when a "-style" option is passed in as a commandline parameter.
- Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object
- returned is set as the application's GUI style.
+ Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object
+ returned is set as the application's GUI style.
*/
/*!
@@ -5144,6 +5253,211 @@ bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
This normally takes some time. Does nothing on other platforms.
*/
+void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
+{
+ for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
+ QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
+
+ // preserve the sub-pixel resolution
+ QRectF rect = touchPoint.screenRect();
+ const QPointF screenPos = rect.center();
+ const QPointF delta = screenPos - screenPos.toPoint();
+
+ rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
+ touchPoint.setRect(rect);
+ touchPoint.setStartPos(widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta);
+ touchPoint.setLastPos(widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta);
+ }
+}
+
+void QApplicationPrivate::initializeMultitouch()
+{
+ widgetForTouchPointId.clear();
+ appCurrentTouchPoints.clear();
+
+ initializeMultitouch_sys();
+}
+
+void QApplicationPrivate::cleanupMultitouch()
+{
+ cleanupMultitouch_sys();
+
+ widgetForTouchPointId.clear();
+ appCurrentTouchPoints.clear();
+}
+
+int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
+{
+ int closestTouchPointId = -1;
+ qreal closestDistance = qreal(0.);
+ foreach (const QTouchEvent::TouchPoint &touchPoint, appCurrentTouchPoints) {
+ qreal distance = QLineF(screenPos, touchPoint.screenPos()).length();
+ if (closestTouchPointId == -1 || distance < closestDistance) {
+ closestTouchPointId = touchPoint.id();
+ closestDistance = distance;
+ }
+ }
+ return closestTouchPointId;
+}
+
+void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
+ QTouchEvent::DeviceType deviceType,
+ const QList<QTouchEvent::TouchPoint> &touchPoints)
+{
+ QApplicationPrivate *d = self;
+ typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
+ QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents;
+
+ for (int i = 0; i < touchPoints.count(); ++i) {
+ QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
+
+ // update state
+ QWidget *widget = 0;
+ switch (touchPoint.state()) {
+ case Qt::TouchPointPressed:
+ {
+ if (deviceType == QTouchEvent::TouchPad) {
+ // on touch-pads, send all touch points to the same widget
+ widget = d->widgetForTouchPointId.isEmpty()
+ ? 0
+ : d->widgetForTouchPointId.constBegin().value();
+ }
+
+ if (!widget) {
+ // determine which widget this event will go to
+ if (!window)
+ window = QApplication::topLevelAt(touchPoint.screenPos().toPoint());
+ if (!window)
+ continue;
+ widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
+ if (!widget)
+ widget = window;
+ }
+
+ if (deviceType == QTouchEvent::TouchScreen) {
+ int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
+ QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId);
+ if (closestWidget
+ && (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) {
+ widget = closestWidget;
+ }
+ }
+
+ d->widgetForTouchPointId[touchPoint.id()] = widget;
+ touchPoint.setStartScreenPos(touchPoint.screenPos());
+ touchPoint.setLastScreenPos(touchPoint.screenPos());
+ touchPoint.setStartNormalizedPos(touchPoint.normalizedPos());
+ touchPoint.setLastNormalizedPos(touchPoint.normalizedPos());
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.setPressure(qreal(1.));
+ d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
+ break;
+ }
+ case Qt::TouchPointReleased:
+ {
+ widget = d->widgetForTouchPointId.take(touchPoint.id());
+ if (!widget)
+ continue;
+
+ QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
+ touchPoint.setStartScreenPos(previousTouchPoint.startScreenPos());
+ touchPoint.setLastScreenPos(previousTouchPoint.screenPos());
+ touchPoint.setStartNormalizedPos(previousTouchPoint.startNormalizedPos());
+ touchPoint.setLastNormalizedPos(previousTouchPoint.normalizedPos());
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.setPressure(qreal(0.));
+ break;
+ }
+ default:
+ widget = d->widgetForTouchPointId.value(touchPoint.id());
+ if (!widget)
+ continue;
+
+ Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
+ QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
+ touchPoint.setStartScreenPos(previousTouchPoint.startScreenPos());
+ touchPoint.setLastScreenPos(previousTouchPoint.screenPos());
+ touchPoint.setStartNormalizedPos(previousTouchPoint.startNormalizedPos());
+ touchPoint.setLastNormalizedPos(previousTouchPoint.normalizedPos());
+ if (touchPoint.pressure() < qreal(0.))
+ touchPoint.setPressure(qreal(1.));
+ d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
+ break;
+ }
+ Q_ASSERT(widget != 0);
+
+ // make the *scene* functions return the same as the *screen* functions
+ touchPoint.setSceneRect(touchPoint.screenRect());
+ touchPoint.setStartScenePos(touchPoint.startScreenPos());
+ touchPoint.setLastScenePos(touchPoint.lastScreenPos());
+
+ StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget];
+ maskAndPoints.first |= touchPoint.state();
+ if (touchPoint.isPrimary())
+ maskAndPoints.first |= Qt::TouchPointPrimary;
+ maskAndPoints.second.append(touchPoint);
+ }
+
+ if (widgetsNeedingEvents.isEmpty())
+ return;
+
+ QHash<QWidget *, StatesAndTouchPoints>::ConstIterator it = widgetsNeedingEvents.constBegin();
+ const QHash<QWidget *, StatesAndTouchPoints>::ConstIterator end = widgetsNeedingEvents.constEnd();
+ for (; it != end; ++it) {
+ QWidget *widget = it.key();
+ if (!QApplicationPrivate::tryModalHelper(widget, 0))
+ continue;
+
+ QEvent::Type eventType;
+ switch (it.value().first & Qt::TouchPointStateMask) {
+ case Qt::TouchPointPressed:
+ eventType = QEvent::TouchBegin;
+ break;
+ case Qt::TouchPointReleased:
+ eventType = QEvent::TouchEnd;
+ break;
+ case Qt::TouchPointStationary:
+ // don't send the event if nothing changed
+ continue;
+ default:
+ eventType = QEvent::TouchUpdate;
+ break;
+ }
+
+ QTouchEvent touchEvent(eventType,
+ deviceType,
+ QApplication::keyboardModifiers(),
+ it.value().first,
+ it.value().second);
+ updateTouchPointsForWidget(widget, &touchEvent);
+
+ switch (touchEvent.type()) {
+ case QEvent::TouchBegin:
+ {
+ // if the TouchBegin handler recurses, we assume that means the event
+ // has been implicitly accepted and continue to send touch events
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
+ (void ) QApplication::sendSpontaneousEvent(widget, &touchEvent);
+ break;
+ }
+ default:
+ if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) {
+ if (touchEvent.type() == QEvent::TouchEnd)
+ widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
+ (void) QApplication::sendSpontaneousEvent(widget, &touchEvent);
+ }
+ break;
+ }
+ }
+}
+
+Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window,
+ QTouchEvent::DeviceType deviceType,
+ const QList<QTouchEvent::TouchPoint> &touchPoints)
+{
+ QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
+}
+
QT_END_NAMESPACE
#include "moc_qapplication.cpp"