diff options
Diffstat (limited to 'src/gui/kernel')
78 files changed, 5532 insertions, 2487 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index cb2b014..e6eff6e 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -41,7 +41,11 @@ HEADERS += \ kernel/qwidgetaction.h \ kernel/qwidgetaction_p.h \ kernel/qwindowdefs.h \ - kernel/qkeymapper_p.h + kernel/qkeymapper_p.h \ + kernel/qgesture.h \ + kernel/qgesture_p.h \ + kernel/qstandardgestures.h \ + kernel/qstandardgestures_p.h SOURCES += \ kernel/qaction.cpp \ @@ -70,7 +74,9 @@ SOURCES += \ kernel/qwhatsthis.cpp \ kernel/qwidget.cpp \ kernel/qwidgetaction.cpp \ - kernel/qkeymapper.cpp + kernel/qkeymapper.cpp \ + kernel/qgesture.cpp \ + kernel/qstandardgestures.cpp win32 { DEFINES += QT_NO_DIRECTDRAW @@ -164,24 +170,26 @@ embedded { qcocoaview_mac_p.h \ qcocoaapplication_mac_p.h \ qcocoaapplicationdelegate_mac_p.h \ + qmultitouch_mac_p.h OBJECTIVE_SOURCES += \ kernel/qcursor_mac.mm \ kernel/qdnd_mac.mm \ kernel/qsound_mac.mm \ kernel/qapplication_mac.mm \ - kernel/qwidget_mac.mm \ - kernel/qcocoapanel_mac.mm \ - kernel/qcocoaview_mac.mm \ - kernel/qcocoawindow_mac.mm \ - kernel/qcocoawindowdelegate_mac.mm \ + kernel/qwidget_mac.mm \ + kernel/qcocoapanel_mac.mm \ + kernel/qcocoaview_mac.mm \ + kernel/qcocoawindow_mac.mm \ + kernel/qcocoawindowdelegate_mac.mm \ kernel/qcocoamenuloader_mac.mm \ kernel/qcocoaapplication_mac.mm \ kernel/qcocoaapplicationdelegate_mac.mm \ kernel/qt_cocoa_helpers_mac.mm \ - kernel/qdesktopwidget_mac.mm \ + kernel/qdesktopwidget_mac.mm \ kernel/qeventdispatcher_mac.mm \ - kernel/qcocoawindowcustomthemeframe_mac.mm + kernel/qcocoawindowcustomthemeframe_mac.mm \ + kernel/qmultitouch_mac.mm \ HEADERS += \ kernel/qt_cocoa_helpers_mac_p.h \ @@ -193,7 +201,7 @@ embedded { MENU_NIB.path = Resources MENU_NIB.version = Versions QMAKE_BUNDLE_DATA += MENU_NIB - RESOURCES += mac/maccursors.qrc + RESOURCES += mac/macresources.qrc LIBS += -framework AppKit } diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index 26baad5..5952320 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -76,12 +76,12 @@ static QString qt_strippedText(QString s) s.remove(i-1,1); } return s.trimmed(); -}; +} QActionPrivate::QActionPrivate() : group(0), enabled(1), forceDisabled(0), visible(1), forceInvisible(0), checkable(0), checked(0), separator(0), fontSet(false), - menuRole(QAction::TextHeuristicRole), iconVisibleInMenu(-1) + menuRole(QAction::TextHeuristicRole), priority(QAction::NormalPriority), iconVisibleInMenu(-1) { #ifdef QT3_SUPPORT static int qt_static_action_id = -1; @@ -136,25 +136,31 @@ void QActionPrivate::redoGrab(QShortcutMap &map) void QActionPrivate::redoGrabAlternate(QShortcutMap &map) { Q_Q(QAction); - foreach (int id, alternateShortcutIds) - if (id) + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + if (const int id = alternateShortcutIds.at(i)) map.removeShortcut(id, q); + } alternateShortcutIds.clear(); if (alternateShortcuts.isEmpty()) return; - foreach (const QKeySequence& alternate, alternateShortcuts) { + for(int i = 0; i < alternateShortcuts.count(); ++i) { + const QKeySequence& alternate = alternateShortcuts.at(i); if (!alternate.isEmpty()) alternateShortcutIds.append(map.addShortcut(q, alternate, shortcutContext)); else alternateShortcutIds.append(0); } if (!enabled) { - foreach (int id, alternateShortcutIds) + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + const int id = alternateShortcutIds.at(i); map.setShortcutEnabled(false, id, q); + } } if (!autorepeat) { - foreach (int id, alternateShortcutIds) + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + const int id = alternateShortcutIds.at(i); map.setShortcutAutoRepeat(false, id, q); + } } } @@ -163,9 +169,10 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map) Q_Q(QAction); if (shortcutId) map.setShortcutEnabled(enable, shortcutId, q); - foreach (int id, alternateShortcutIds) - if (id) + for(int i = 0; i < alternateShortcutIds.count(); ++i) { + if (const int id = alternateShortcutIds.at(i)) map.setShortcutEnabled(enable, id, q); + } } #endif // QT_NO_SHORTCUT @@ -617,8 +624,10 @@ QAction::~QAction() #ifndef QT_NO_SHORTCUT if (d->shortcutId && qApp) { qApp->d_func()->shortcutMap.removeShortcut(d->shortcutId, this); - foreach (int id, d->alternateShortcutIds) + for(int i = 0; i < d->alternateShortcutIds.count(); ++i) { + const int id = d->alternateShortcutIds.at(i); qApp->d_func()->shortcutMap.removeShortcut(id, this); + } } #endif } @@ -900,6 +909,52 @@ QString QAction::whatsThis() const return d->whatsthis; } +/*! + \enum QAction::Priority + \since 4.6 + + This enum defines priorities for actions in user interface. + + \value LowPriority The action will not be prioritized in + collapsible layouts when not enough space for all actions is + available. + + \value NormalPriority + + \value HighPriority The action will be prioritized by + collapsible layouts when not enough space for all actions is + available. + + \sa priority +*/ + + +/*! + \property QAction::priority + \since 4.6 + + \brief the actions's priority in the user interface. + + This property can be set to indicate how the action should be prioritized + in a collapsible layout. For instance, when toolbars have the Qt::ToolButtonTextBesideIcon + mode set, then lower priority actions will hide text labels to preserve + horizontal space if necessary. +*/ +void QAction::setPriority(Priority priority) +{ + Q_D(QAction); + if (d->priority == priority) + return; + + d->priority = priority; + d->sendDataChanged(); +} + +QAction::Priority QAction::priority() const +{ + Q_D(const QAction); + return d->priority; +} /*! \property QAction::checkable @@ -1153,6 +1208,8 @@ void QAction::activate(ActionEvent event) // the checked action of an exclusive group cannot be unchecked if (d->checked && (d->group && d->group->isExclusive() && d->group->checkedAction() == this)) { + if (guard) + emit triggered(true); QMetaObject::removeGuard(&guard); return; } @@ -1370,7 +1427,7 @@ QAction::MenuRole QAction::menuRole() const void QAction::setIconVisibleInMenu(bool visible) { Q_D(QAction); - if (visible != (bool)d->iconVisibleInMenu) { + if (d->iconVisibleInMenu == -1 || visible != bool(d->iconVisibleInMenu)) { int oldValue = d->iconVisibleInMenu; d->iconVisibleInMenu = visible; // Only send data changed if we really need to. diff --git a/src/gui/kernel/qaction.h b/src/gui/kernel/qaction.h index 6920ec5..133fab4 100644 --- a/src/gui/kernel/qaction.h +++ b/src/gui/kernel/qaction.h @@ -67,6 +67,7 @@ class Q_GUI_EXPORT QAction : public QObject Q_DECLARE_PRIVATE(QAction) Q_ENUMS(MenuRole) + Q_ENUMS(Priority) Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable) Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) @@ -85,10 +86,14 @@ class Q_GUI_EXPORT QAction : public QObject Q_PROPERTY(bool visible READ isVisible WRITE setVisible) Q_PROPERTY(MenuRole menuRole READ menuRole WRITE setMenuRole) Q_PROPERTY(bool iconVisibleInMenu READ isIconVisibleInMenu WRITE setIconVisibleInMenu) + Q_PROPERTY(Priority priority READ priority WRITE setPriority) public: enum MenuRole { NoRole, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole, AboutRole, PreferencesRole, QuitRole }; + enum Priority { LowPriority = 0, + NormalPriority = 128, + HighPriority = 256}; explicit QAction(QObject* parent); QAction(const QString &text, QObject* parent); QAction(const QIcon &icon, const QString &text, QObject* parent); @@ -123,6 +128,9 @@ public: void setWhatsThis(const QString &what); QString whatsThis() const; + void setPriority(Priority priority); + Priority priority() const; + #ifndef QT_NO_MENU QMenu *menu() const; void setMenu(QMenu *menu); diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h index bae9bbf..4745ed1 100644 --- a/src/gui/kernel/qaction_p.h +++ b/src/gui/kernel/qaction_p.h @@ -102,6 +102,7 @@ public: uint separator : 1; uint fontSet : 1; QAction::MenuRole menuRole; + QAction::Priority priority; int iconVisibleInMenu : 3; // Only has values -1, 0, and 1 QList<QWidget *> widgets; #ifndef QT_NO_GRAPHICSVIEW diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 114ebb2..b168188 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -85,11 +85,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 +98,18 @@ extern bool qt_wince_is_mobile(); //qguifunctions_wince.cpp extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp #endif +#include "qdatetime.h" + //#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,7 +130,7 @@ QInputContext *QApplicationPrivate::inputContext = 0; bool QApplicationPrivate::quitOnLastWindowClosed = true; -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE int QApplicationPrivate::autoMaximizeThreshold = -1; bool QApplicationPrivate::autoSipEnabled = false; #endif @@ -394,6 +394,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 +409,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 @@ -441,8 +442,7 @@ 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 @@ -466,15 +466,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 +491,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 +535,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 +548,7 @@ void QApplicationPrivate::process_cmdline() delete app_style; app_style = 0; } - if (!styleOverride) - styleOverride = new QString; - *styleOverride = s; + styleOverride = s; } } @@ -620,13 +613,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). @@ -848,6 +834,11 @@ void QApplicationPrivate::initialize() // trigger registering of QVariant's GUI types extern int qRegisterGuiVariant(); qRegisterGuiVariant(); +#ifndef QT_NO_STATEMACHINE + // trigger registering of QStateMachine's GUI types + extern int qRegisterGuiStateMachine(); + qRegisterGuiStateMachine(); +#endif is_app_running = true; // no longer starting up @@ -860,13 +851,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 +860,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 +878,8 @@ void QApplicationPrivate::initialize() QApplicationPrivate::wheel_scroll_lines = 3; #endif #endif + + initializeMultitouch(); } /*! @@ -1043,6 +1030,8 @@ QApplication::~QApplication() delete QDragManager::self(); #endif + d->cleanupMultitouch(); + qt_cleanup(); if (QApplicationPrivate::widgetCount) @@ -1069,6 +1058,11 @@ QApplication::~QApplication() QApplicationPrivate::fade_tooltip = false; QApplicationPrivate::widgetCount = false; +#ifndef QT_NO_STATEMACHINE + // trigger unregistering of QStateMachine's GUI types + extern int qUnregisterGuiStateMachine(); + qUnregisterGuiStateMachine(); +#endif // trigger unregistering of QVariant's GUI types extern int qUnregisterGuiVariant(); qUnregisterGuiVariant(); @@ -1227,7 +1221,7 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis the WA_InputMethodEnabled attribute set. */ -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE void QApplication::setAutoMaximizeThreshold(const int threshold) { QApplicationPrivate::autoMaximizeThreshold = threshold; @@ -1289,44 +1283,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 +1378,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 @@ -1938,6 +1901,40 @@ 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_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 @@ -2089,8 +2086,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; @@ -2576,14 +2574,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 +2592,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 +2669,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 +2758,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 +2767,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 +2781,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 +2790,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 +2813,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) @@ -2868,7 +2866,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 +2880,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 +2920,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) { @@ -3496,7 +3499,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. @@ -3562,20 +3565,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(); } @@ -3709,19 +3710,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QPoint relpos = mouse->pos(); if (e->spontaneous()) { - 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 +3779,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 +3802,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 +4009,58 @@ 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::WinGesture: + { + // 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 +4078,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); @@ -4373,13 +4408,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 +4448,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 +4611,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 +4632,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. */ /*! @@ -4992,6 +5027,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; @@ -5136,6 +5188,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" diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 3c0e598..19ae085 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -102,7 +102,7 @@ class Q_GUI_EXPORT QApplication : public QCoreApplication #ifndef QT_NO_STYLE_STYLESHEET Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet) #endif -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE Q_PROPERTY(int autoMaximizeThreshold READ autoMaximizeThreshold WRITE setAutoMaximizeThreshold) Q_PROPERTY(bool autoSipEnabled READ autoSipEnabled WRITE setAutoSipEnabled) #endif @@ -281,7 +281,7 @@ public Q_SLOTS: #ifndef QT_NO_STYLE_STYLESHEET void setStyleSheet(const QString& sheet); #endif -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE void setAutoMaximizeThreshold(const int threshold); int autoMaximizeThreshold() const; void setAutoSipEnabled(const bool enabled); @@ -382,6 +382,9 @@ private: #if defined(Q_WS_MAC) || defined(Q_WS_X11) Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut()) #endif +#if defined(QT_RX71_MULTITOUCH) + Q_PRIVATE_SLOT(d_func(), void _q_readRX71MultiTouchEvents()) +#endif }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 0d86c8e..beccfb0 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -154,13 +154,16 @@ #define kThemeBrushAlternatePrimaryHighlightColor -5 #endif +#define kCMDeviceUnregisteredNotification CFSTR("CMDeviceUnregisteredNotification") +#define kCMDefaultDeviceNotification CFSTR("CMDefaultDeviceNotification") +#define kCMDeviceProfilesNotification CFSTR("CMDeviceProfilesNotification") +#define kCMDefaultDeviceProfileNotification CFSTR("CMDefaultDeviceProfileNotification") QT_BEGIN_NAMESPACE //for qt_mac.h QPaintDevice *qt_mac_safe_pdev = 0; QList<QMacWindowChangeEvent*> *QMacWindowChangeEvent::change_events = 0; -extern QHash<QByteArray, QFont> *qt_app_fonts_hash(); // qapplication.cpp /***************************************************************************** Internal variables and functions @@ -523,9 +526,9 @@ void qt_mac_update_os_settings() for(int i = 0; mac_widget_fonts[i].qt_class; i++) { QFont fnt = qfontForThemeFont(mac_widget_fonts[i].font_key); bool set_font = true; - QHash<QByteArray, QFont> *hash = qt_app_fonts_hash(); + FontHash *hash = qt_app_fonts_hash(); if (!hash->isEmpty()) { - QHash<QByteArray, QFont>::const_iterator it + FontHash::const_iterator it = hash->constFind(mac_widget_fonts[i].qt_class); if (it != hash->constEnd()) set_font = (fnt != *it); @@ -624,10 +627,9 @@ void QApplicationPrivate::initializeWidgetPaletteHash() } bool set_palette = true; - extern QHash<QByteArray, QPalette> *qt_app_palettes_hash(); //qapplication.cpp - QHash<QByteArray, QPalette> *phash = qt_app_palettes_hash(); + PaletteHash *phash = qt_app_palettes_hash(); if (!phash->isEmpty()) { - QHash<QByteArray, QPalette>::const_iterator it + PaletteHash::const_iterator it = phash->constFind(mac_widget_colors[i].qt_class); if (it != phash->constEnd()) set_palette = (pal != *it); @@ -1040,16 +1042,34 @@ void qt_release_app_proc_handler() #endif } +void qt_color_profile_changed(CFNotificationCenterRef, void *, CFStringRef, const void *, + CFDictionaryRef) +{ + QCoreGraphicsPaintEngine::cleanUpMacColorSpaces(); +} /* platform specific implementations */ void qt_init(QApplicationPrivate *priv, int) { if (qt_is_gui_used) { CGDisplayRegisterReconfigurationCallback(qt_mac_display_change_callbk, 0); + CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter(); + CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed, + kCMDeviceUnregisteredNotification, 0, + CFNotificationSuspensionBehaviorDeliverImmediately); + CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed, + kCMDefaultDeviceNotification, 0, + CFNotificationSuspensionBehaviorDeliverImmediately); + CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed, + kCMDeviceProfilesNotification, 0, + CFNotificationSuspensionBehaviorDeliverImmediately); + CFNotificationCenterAddObserver(center, qApp, qt_color_profile_changed, + kCMDefaultDeviceProfileNotification, 0, + CFNotificationSuspensionBehaviorDeliverImmediately); ProcessSerialNumber psn; if (GetCurrentProcess(&psn) == noErr) { // Jambi needs to transform itself since most people aren't "used" // to putting things in bundles, but other people may actually not - // want to tranform the process (running as a helper or somethng) + // want to tranform the process (running as a helper or something) // so don't do that for them. This means checking both LSUIElement // and LSBackgroundOnly. If you set them both... well, you // shouldn't do that. @@ -1196,10 +1216,6 @@ void qt_init(QApplicationPrivate *priv, int) [qtMenuLoader release]; } #endif - if (QApplication::testAttribute(Qt::AA_MacPluginApplication)) { - extern void qt_mac_set_native_menubar(bool); - qt_mac_set_native_menubar(false); - } // Register for Carbon tablet proximity events on the event monitor target. // This means that we should receive proximity events even when we aren't the active application. if (!tablet_proximity_handler) { @@ -1228,6 +1244,12 @@ void qt_release_apple_event_handler() void qt_cleanup() { CGDisplayRemoveReconfigurationCallback(qt_mac_display_change_callbk, 0); + CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter(); + CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceUnregisteredNotification, 0); + CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceNotification, 0); + CFNotificationCenterRemoveObserver(center, qApp, kCMDeviceProfilesNotification, 0); + CFNotificationCenterRemoveObserver(center, qApp, kCMDefaultDeviceProfileNotification, 0); + #ifndef QT_MAC_USE_COCOA qt_release_app_proc_handler(); if (app_proc_handlerUPP) { @@ -1355,29 +1377,6 @@ QWidget *QApplication::topLevelAt(const QPoint &p) #endif } -static QWidget *qt_mac_recursive_widgetAt(QWidget *widget, int x, int y) -{ - if (!widget) - return 0; - const QObjectList kids = widget->children(); - for(int i = kids.size()-1; i >= 0; --i) { - if ( QWidget *kid = qobject_cast<QWidget*>(kids.at(i)) ) { - if (kid->isVisible() && !kid->isTopLevel() && - !kid->testAttribute(Qt::WA_TransparentForMouseEvents)) { - const int wx=kid->x(), wy=kid->y(), - wx2=wx+kid->width(), wy2=wy+kid->height(); - if (x >= wx && y >= wy && x < wx2 && y < wy2) { - const QRegion mask = kid->mask(); - if (!mask.isEmpty() && !mask.contains(QPoint(x-wx, y-wy))) - continue; - return qt_mac_recursive_widgetAt(kid, x-wx, y-wy); - } - } - } - } - return widget; -} - /***************************************************************************** Main event loop *****************************************************************************/ @@ -1652,15 +1651,6 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event bool inNonClientArea = false; GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, 0, sizeof(where), 0, &where); - if(ekind == kEventMouseMoved && qt_mac_app_fullscreen && - QApplication::desktop()->screenNumber(QPoint(where.h, where.v)) == - QApplication::desktop()->primaryScreen()) { - if(where.v <= 0) - ShowMenuBar(); - else if(qt_mac_window_at(where.h, where.v, 0) != inMenuBar) - HideMenuBar(); - } - #if defined(DEBUG_MOUSE_MAPS) const char *edesc = 0; switch(ekind) { @@ -1757,7 +1747,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event if(window) { HIViewRef hiview; if(HIViewGetViewForMouseEvent(HIViewGetRoot(window), event, &hiview) == noErr) { - widget = QWidget::find((WId)hiview);; + widget = QWidget::find((WId)hiview); if (widget) { // Make sure we didn't pass over a widget with a "fake hole" in it. QWidget *otherWidget = QApplication::widgetAt(where.h, where.v); @@ -1874,9 +1864,10 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event tablet_button_state = new_tablet_button_state; QMacTabletHash *tabletHash = qt_mac_tablet_hash(); - if (!tabletHash->contains(tabletPointRec.deviceID)) { - qWarning("QCocoaView handleTabletEvent: This tablet device is unknown" - " (received no proximity event for it). Discarding event."); + if (!tabletHash->contains(tabletPointRec.deviceID) && t != QEvent::TabletRelease) { + // Never discard TabletRelease events as they may be delivered *after* TabletLeaveProximity events + qWarning("handleTabletEvent: This tablet device is unknown" + " (received no proximity event for it). Discarding event."); return false; } QTabletDeviceData &deviceData = tabletHash->operator[](tabletPointRec.deviceID); @@ -1918,8 +1909,13 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event tp, rotation, z, modifiers, deviceData.tabletUniqueID); QApplication::sendSpontaneousEvent(widget, &e); if (e.isAccepted()) { + if (t == QEvent::TabletPress) { + qt_button_down = widget; + } else if (t == QEvent::TabletRelease) { + qt_button_down = 0; + } #if defined(DEBUG_MOUSE_MAPS) - qDebug("Bail out early due to table acceptance"); + qDebug("Bail out early due to tablet acceptance"); #endif break; } @@ -2993,4 +2989,9 @@ void onApplicationChangedActivation( bool activated ) #endif } +void QApplicationPrivate::initializeMultitouch_sys() +{ } +void QApplicationPrivate::cleanupMultitouch_sys() +{ } + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index ddd5624..90eaba0 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -55,6 +55,7 @@ // #include "QtGui/qapplication.h" +#include "QtGui/qevent.h" #include "QtGui/qfont.h" #include "QtGui/qcursor.h" #include "QtGui/qregion.h" @@ -77,11 +78,10 @@ class QClipboard; class QGraphicsScene; class QGraphicsSystem; class QInputContext; -class QKeyEvent; -class QMouseEvent; class QObject; -class QWheelEvent; class QWidget; +class QGestureManager; +class QSocketNotifier; extern bool qt_is_gui_used; #ifndef QT_NO_CLIPBOARD @@ -158,17 +158,19 @@ inline QPointF QTabletDeviceData::scaleCoord(int coordX, int coordY, int outOriginY, int outExtentY) const { QPointF ret; + if (sign(outExtentX) == sign(maxX)) - ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX))) + outOriginX); + ret.setX(((coordX - minX) * qAbs(outExtentX) / qAbs(qreal(maxX - minX))) + outOriginX); else - ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX))) + ret.setX(((qAbs(maxX) - (coordX - minX)) * qAbs(outExtentX) / qAbs(qreal(maxX - minX))) + outOriginX); if (sign(outExtentY) == sign(maxY)) - ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY))) + outOriginY); + ret.setY(((coordY - minY) * qAbs(outExtentY) / qAbs(qreal(maxY - minY))) + outOriginY); else - ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY))) + ret.setY(((qAbs(maxY) - (coordY - minY)) * qAbs(outExtentY) / qAbs(qreal(maxY - minY))) + outOriginY); + return ret; } #endif @@ -189,6 +191,114 @@ extern "C" { } #endif +#if defined(Q_WS_WIN) +typedef BOOL (WINAPI *qt_RegisterTouchWindowPtr)(HWND, ULONG); +typedef BOOL (WINAPI *qt_GetTouchInputInfoPtr)(HANDLE, UINT, PVOID, int); +typedef BOOL (WINAPI *qt_CloseTouchInputHandlePtr)(HANDLE); + +#ifndef WM_GESTURE + +#define WM_GESTURE 0x0119 +#define WM_GESTURE_NOTIFY 0x011A + +DECLARE_HANDLE(HGESTUREINFO); + +#define GF_BEGIN 0x00000001 +#define GF_INERTIA 0x00000002 +#define GF_END 0x00000004 + +/* + * Gesture IDs + */ +#define GID_BEGIN 1 +#define GID_END 2 +#define GID_ZOOM 3 +#define GID_PAN 4 +#define GID_ROTATE 5 +#define GID_TWOFINGERTAP 6 +#define GID_ROLLOVER 7 + +typedef struct tagGESTUREINFO { + UINT cbSize; // size, in bytes, of this structure (including variable length Args field) + DWORD dwFlags; // see GF_* flags + DWORD dwID; // gesture ID, see GID_* defines + HWND hwndTarget; // handle to window targeted by this gesture + POINTS ptsLocation; // current location of this gesture + DWORD dwInstanceID; // internally used + DWORD dwSequenceID; // internally used + ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES + UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture +} GESTUREINFO, *PGESTUREINFO; +typedef GESTUREINFO const * PCGESTUREINFO; + +typedef struct tagGESTURENOTIFYSTRUCT { + UINT cbSize; // size, in bytes, of this structure + DWORD dwFlags; // unused + HWND hwndTarget; // handle to window targeted by the gesture + POINTS ptsLocation; // starting location + DWORD dwInstanceID; // internally used +} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; + +/* + * Gesture argument helpers + * - Angle should be a double in the range of -2pi to +2pi + * - Argument should be an unsigned 16-bit value + */ +#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)) +#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265) + +typedef struct tagGESTURECONFIG { + DWORD dwID; // gesture ID + DWORD dwWant; // settings related to gesture ID that are to be turned on + DWORD dwBlock; // settings related to gesture ID that are to be turned off +} GESTURECONFIG, *PGESTURECONFIG; + +#define GC_ALLGESTURES 0x00000001 +#define GC_ZOOM 0x00000001 +#define GC_PAN 0x00000001 +#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 +#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 +#define GC_PAN_WITH_GUTTER 0x00000008 +#define GC_PAN_WITH_INERTIA 0x00000010 +#define GC_ROTATE 0x00000001 +#define GC_TWOFINGERTAP 0x00000001 +#define GC_ROLLOVER 0x00000001 +#define GESTURECONFIGMAXCOUNT 256 // Maximum number of gestures that can be included + // in a single call to SetGestureConfig / GetGestureConfig + + + +#define GCF_INCLUDE_ANCESTORS 0x00000001 // If specified, GetGestureConfig returns consolidated configuration + // for the specified window and it's parent window chain + +typedef BOOL (*PtrGetGestureInfo)(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); +typedef BOOL (*PtrGetGestureExtraArgs)(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); +typedef BOOL (*PtrCloseGestureInfoHandle)(HGESTUREINFO hGestureInfo); +typedef BOOL (*PtrSetGestureConfig)(HWND hwnd, DWORD dwReserved, UINT cIDs, + PGESTURECONFIG pGestureConfig, + UINT cbSize); +typedef BOOL (*PtrGetGestureConfig)(HWND hwnd, DWORD dwReserved, + DWORD dwFlags, PUINT pcIDs, + PGESTURECONFIG pGestureConfig, + UINT cbSize); + +typedef BOOL (*PtrBeginPanningFeedback)(HWND hwnd); +typedef BOOL (*PtrUpdatePanningFeedback)(HWND hwnd, LONG, LONG, BOOL); +typedef BOOL (*PtrEndPanningFeedback)(HWND hwnd, BOOL); + +#endif // WM_GESTURE +#endif // Q_WS_WIN + +class QPanGesture; +class QPinchGesture; +struct StandardGestures +{ + QPanGesture *pan; + QPinchGesture *pinch; + StandardGestures() : pan(0), pinch(0) { } +}; + + class QScopedLoopLevelCounter { QThreadData *threadData; @@ -200,6 +310,12 @@ public: { --threadData->loopLevel; } }; +typedef QHash<QByteArray, QFont> FontHash; +FontHash *qt_app_fonts_hash(); + +typedef QHash<QByteArray, QPalette> PaletteHash; +PaletteHash *qt_app_palettes_hash(); + class Q_GUI_EXPORT QApplicationPrivate : public QCoreApplicationPrivate { Q_DECLARE_PUBLIC(QApplication) @@ -210,6 +326,7 @@ public: #if defined(Q_WS_X11) #ifndef QT_NO_SETTINGS static QString kdeHome(); + static QString x11_desktop_style(); static bool x11_apply_settings(); #endif static void reset_instance_pointer(); @@ -219,10 +336,11 @@ public: #endif static bool quitOnLastWindowClosed; static void emitLastWindowClosed(); -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE static int autoMaximizeThreshold; static bool autoSipEnabled; #endif + static QString desktopStyleKey(); static QGraphicsSystem *graphicsSystem() #if !defined(Q_WS_QWS) @@ -358,7 +476,7 @@ public: #ifdef Q_WS_MAC static bool native_modal_dialog_active; #endif -#if defined(Q_WS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_WS_WIN) && !defined(Q_WS_WINCE) static bool inSizeMove; #endif @@ -392,7 +510,7 @@ public: static QApplicationPrivate *instance() { return self; } - static QString *styleOverride; + static QString styleOverride; static int app_compile_version; @@ -419,20 +537,84 @@ public: QEvent::Type type, Qt::MouseButtons buttons, QWidget *buttonDown, QWidget *alienWidget); static bool sendMouseEvent(QWidget *receiver, QMouseEvent *event, QWidget *alienWidget, - QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver); + QWidget *native, QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver, + bool spontaneous = true); #if defined(Q_WS_WIN) || defined(Q_WS_X11) void sendSyntheticEnterLeave(QWidget *widget); #endif + QMap<int, QWidget *> widgetForTouchPointId; + QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints; + static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent); + void initializeMultitouch(); + void initializeMultitouch_sys(); + void cleanupMultitouch(); + void cleanupMultitouch_sys(); + int findClosestTouchPointId(const QPointF &screenPos); + void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint); + void removeTouchPoint(int touchPointId); + static void translateRawTouchEvent(QWidget *widget, + QTouchEvent::DeviceType deviceType, + const QList<QTouchEvent::TouchPoint> &touchPoints); + +#if defined(Q_WS_WIN) + static qt_RegisterTouchWindowPtr RegisterTouchWindow; + static qt_GetTouchInputInfoPtr GetTouchInputInfo; + static qt_CloseTouchInputHandlePtr CloseTouchInputHandle; + + QHash<DWORD, int> touchInputIDToTouchPointID; + QList<QTouchEvent::TouchPoint> appAllTouchPoints; + bool translateTouchEvent(const MSG &msg); + + typedef QMap<QWidget*, StandardGestures> WidgetStandardGesturesMap; + WidgetStandardGesturesMap widgetGestures; + ulong lastGestureId; + + PtrGetGestureInfo GetGestureInfo; + PtrGetGestureExtraArgs GetGestureExtraArgs; + PtrCloseGestureInfoHandle CloseGestureInfoHandle; + PtrSetGestureConfig SetGestureConfig; + PtrGetGestureConfig GetGestureConfig; + PtrBeginPanningFeedback BeginPanningFeedback; + PtrUpdatePanningFeedback UpdatePanningFeedback; + PtrEndPanningFeedback EndPanningFeedback; +#endif + +#ifdef QT_RX71_MULTITOUCH + bool hasRX71MultiTouch; + + struct RX71TouchPointState { + QSocketNotifier *socketNotifier; + QTouchEvent::TouchPoint touchPoint; + + int minX, maxX, scaleX; + int minY, maxY, scaleY; + int minZ, maxZ; + }; + QList<RX71TouchPointState> allRX71TouchPoints; + + bool readRX71MultiTouchEvents(int deviceNumber); + void fakeMouseEventFromRX71TouchEvent(); + void _q_readRX71MultiTouchEvents(); +#endif + private: #ifdef Q_WS_QWS QMap<const QScreen*, QRect> maxWindowRects; #endif static QApplicationPrivate *self; + + static void giveFocusAccordingToFocusPolicy(QWidget *w, + Qt::FocusPolicy focusPolicy, + Qt::FocusReason focusReason); static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy); }; +Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, + QTouchEvent::DeviceType deviceType, + const QList<QTouchEvent::TouchPoint> &touchPoints); + QT_END_NAMESPACE #endif // QAPPLICATION_P_H diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index ab2062c..347afc8 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -194,15 +194,15 @@ QString qws_dataDir() static QString result; if (!result.isEmpty()) return result; - QByteArray dataDir = QString(QLatin1String("/tmp/qtembedded-%1")).arg(qws_display_id).toLocal8Bit(); - if (mkdir(dataDir, 0700)) { + QByteArray dataDir = QString::fromLatin1("/tmp/qtembedded-%1").arg(qws_display_id).toLocal8Bit(); + if (QT_MKDIR(dataDir, 0700)) { if (errno != EEXIST) { qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData()); } } - struct stat buf; - if (lstat(dataDir, &buf)) + QT_STATBUF buf; + if (QT_LSTAT(dataDir, &buf)) qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData()); if (!S_ISDIR(buf.st_mode)) @@ -215,7 +215,7 @@ QString qws_dataDir() if ((buf.st_mode & 0677) != 0600) qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData()); #endif - dataDir += "/"; + dataDir += '/'; result = QString::fromLocal8Bit(dataDir); return result; @@ -224,7 +224,7 @@ QString qws_dataDir() // Get the filename of the pipe Qt for Embedded Linux uses for server/client comms Q_GUI_EXPORT QString qws_qtePipeFilename() { - return (qws_dataDir() + QString(QLatin1String(QTE_PIPE)).arg(qws_display_id)); + return (qws_dataDir() + QString::fromLatin1(QTE_PIPE).arg(qws_display_id)); } static void setMaxWindowRect(const QRect &rect) @@ -2015,8 +2015,8 @@ bool QApplicationPrivate::qws_apply_settings() // read new QStyle QString stylename = settings.value(QLatin1String("style")).toString(); if (QCoreApplication::startingUp()) { - if (!stylename.isEmpty() && !QApplicationPrivate::styleOverride) - QApplicationPrivate::styleOverride = new QString(stylename); + if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull()) + QApplicationPrivate::styleOverride = stylename; } else { QApplication::setStyle(stylename); } @@ -2284,7 +2284,8 @@ void qt_init(QApplicationPrivate *priv, int type) qt_appType = QApplication::Type(type); qws_single_process = true; QWSServer::startup(flags); - setenv("QWS_DISPLAY", qws_display_spec.constData(), 0); + if (!display) // if not already set + qputenv("QWS_DISPLAY", qws_display_spec); } if(qt_is_gui_used) { @@ -3749,4 +3750,9 @@ void QApplication::setArgs(int c, char **v) d->argv = v; } +void QApplicationPrivate::initializeMultitouch_sys() +{ } +void QApplicationPrivate::cleanupMultitouch_sys() +{ } + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 6fbdae2..cbcac9a 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE #include "qguifunctions_wince.h" #include "qmenubar.h" extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp @@ -48,7 +48,7 @@ extern bool qt_wince_is_smartphone(); //defined in qguifunctions_wince.c extern bool qt_wince_is_pocket_pc(); //defined in qguifunctions_wince.cpp extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.cpp #endif -#ifdef Q_OS_WINCE_WM +#ifdef Q_WS_WINCE_WM #include <windowsm.h> #include <tpcshell.h> #endif @@ -88,6 +88,9 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #include "qdebug.h" #include <private/qkeymapper_p.h> #include <private/qlocale_p.h> +#include "qevent_p.h" +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" //#define ALIEN_DEBUG @@ -104,32 +107,44 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #endif #endif // QT_NO_ACCESSIBILITY -#include <winuser.h> #if !defined(WINABLEAPI) -# if defined(Q_OS_WINCE) +# if defined(Q_WS_WINCE) # include <bldver.h> # endif # include <winable.h> #endif +#ifndef WM_TOUCH +# define WM_TOUCH 0x0240 + +# define TOUCHEVENTF_MOVE 0x0001 +# define TOUCHEVENTF_DOWN 0x0002 +# define TOUCHEVENTF_UP 0x0004 +# define TOUCHEVENTF_INRANGE 0x0008 +# define TOUCHEVENTF_PRIMARY 0x0010 +# define TOUCHEVENTF_NOCOALESCE 0x0020 +# define TOUCHEVENTF_PEN 0x0040 +# define TOUCHEVENTF_PALM 0x0080 + +# define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001 +# define TOUCHINPUTMASKF_EXTRAINFO 0x0002 +# define TOUCHINPUTMASKF_CONTACTAREA 0x0004 -#ifndef FLASHW_STOP -typedef struct { - UINT cbSize; - HWND hwnd; +typedef struct tagTOUCHINPUT +{ + LONG x; + LONG y; + HANDLE hSource; + DWORD dwID; DWORD dwFlags; - UINT uCount; - DWORD dwTimeout; -} FLASHWINFO, *PFLASHWINFO; -#define FLASHW_STOP 0 -#define FLASHW_CAPTION 0x00000001 -#define FLASHW_TRAY 0x00000002 -#define FLASHW_ALL (FLASHW_CAPTION | FLASHW_TRAY) -#define FLASHW_TIMER 0x00000004 -#define FLASHW_TIMERNOFG 0x0000000C -#endif /* FLASHW_STOP */ -typedef BOOL (WINAPI *PtrFlashWindowEx)(PFLASHWINFO pfwi); -static PtrFlashWindowEx pFlashWindowEx = 0; + DWORD dwMask; + DWORD dwTime; + ULONG_PTR dwExtraInfo; + DWORD cxContact; + DWORD cyContact; +} TOUCHINPUT, *PTOUCHINPUT; + +#endif #include <windowsx.h> #include <limits.h> @@ -155,7 +170,7 @@ static PtrFlashWindowEx pFlashWindowEx = 0; QT_BEGIN_NAMESPACE -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE #ifndef SHRG_RETURNCMD struct SHRGINFO { DWORD cbSize; @@ -240,10 +255,6 @@ QTabletDeviceData currentTabletPointer; // from qregion_win.cpp extern HRGN qt_tryCreateRegion(QRegion::RegionType type, int left, int top, int right, int bottom); -Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, - UINT wMsgFilterMax, UINT wRemoveMsg); -Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - // support for on-the-fly changes of the XP theme engine #ifndef WM_THEMECHANGED #define WM_THEMECHANGED 0x031A @@ -258,22 +269,24 @@ Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa #define WM_XBUTTONDOWN 0x020B #define WM_XBUTTONUP 0x020C #define WM_XBUTTONDBLCLK 0x020D +#endif +#ifndef GET_KEYSTATE_WPARAM #define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam)) #define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) #define XBUTTON1 0x0001 #define XBUTTON2 0x0002 +#endif +#ifndef MK_XBUTTON1 #define MK_XBUTTON1 0x0020 #define MK_XBUTTON2 0x0040 #endif -#ifdef Q_OS_WINCE -#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam)) -#endif - -// support for multi-media-keys on ME/2000/XP +// support for multi-media-keys #ifndef WM_APPCOMMAND #define WM_APPCOMMAND 0x0319 +#endif +#ifndef FAPPCOMMAND_MOUSE #define FAPPCOMMAND_MOUSE 0x8000 #define FAPPCOMMAND_KEY 0 #define FAPPCOMMAND_OEM 0x1000 @@ -341,9 +354,7 @@ Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa #define APPCOMMAND_MEDIA_CHANNEL_DOWN 52 #endif // APPCOMMAND_MICROPHONE_VOLUME_MUTE -#endif // WM_APPCOMMAND - -static UINT WM95_MOUSEWHEEL = 0; +#endif // FAPPCOMMAND_MOUSE #if (_WIN32_WINNT < 0x0400) // This struct is defined in winuser.h if the _WIN32_WINNT >= 0x0400 -- in the @@ -376,11 +387,6 @@ QRgb qt_colorref2qrgb(COLORREF col) Internal variables and functions *****************************************************************************/ -extern Q_CORE_EXPORT char theAppName[]; -extern Q_CORE_EXPORT char appFileName[]; -extern Q_CORE_EXPORT HINSTANCE appInst; // handle to app instance -extern Q_CORE_EXPORT HINSTANCE appPrevInst; // handle to prev app instance -extern Q_CORE_EXPORT int appCmdShow; // main window show command static HWND curWin = 0; // current window static HDC displayDC = 0; // display device context @@ -448,6 +454,7 @@ public: bool translateConfigEvent(const MSG &msg); bool translateCloseEvent(const MSG &msg); bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets); + bool translateGestureEvent(const MSG &msg); void repolishStyle(QStyle &style); inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); } inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); } @@ -497,7 +504,7 @@ static void qt_set_windows_color_resources() pal.setColor(QPalette::HighlightedText, QColor(qt_colorref2qrgb(GetSysColor(COLOR_HIGHLIGHTTEXT)))); -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) // ### hardcoded until I find out how to get it from the system settings. pal.setColor(QPalette::LinkVisited, pal.highlight().color().dark(150)); pal.setColor(QPalette::Link, pal.highlight().color().light(130)); @@ -516,14 +523,13 @@ static void qt_set_windows_color_resources() pal.setColor(QPalette::Inactive, QPalette::Light, pal.light().color()); pal.setColor(QPalette::Inactive, QPalette::Dark, pal.dark().color()); - if (QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95) { - if (pal.midlight() == pal.button()) - pal.setColor(QPalette::Midlight, pal.button().color().lighter(110)); - if (pal.background() != pal.base()) { - pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window)); - pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text)); - } + if (pal.midlight() == pal.button()) + pal.setColor(QPalette::Midlight, pal.button().color().lighter(110)); + if (pal.background() != pal.base()) { + pal.setColor(QPalette::Inactive, QPalette::Highlight, pal.color(QPalette::Inactive, QPalette::Window)); + pal.setColor(QPalette::Inactive, QPalette::HighlightedText, pal.color(QPalette::Inactive, QPalette::Text)); } + const QColor bg = pal.background().color(); const QColor fg = pal.foreground().color(), btn = pal.button().color(); QColor disabled((fg.red()+btn.red())/2,(fg.green()+btn.green())/2, @@ -573,36 +579,19 @@ static void qt_set_windows_color_resources() static void qt_set_windows_font_resources() { -#ifndef Q_OS_WINCE - QFont menuFont; - QFont messageFont; - QFont statusFont; - QFont titleFont; - QFont iconTitleFont; - QT_WA({ - NONCLIENTMETRICS ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONTW); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); - menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont,true); - messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont,true); - statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont,true); - titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont,true); - LOGFONTW lfIconTitleFont; - SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); - iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont,true); - } , { - // A version - NONCLIENTMETRICSA ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, lfMessageFont) + sizeof(LOGFONTA); - SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); - menuFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfMenuFont,true); - messageFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfMessageFont,true); - statusFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfStatusFont,true); - titleFont = qt_LOGFONTtoQFont((LOGFONT&)ncm.lfCaptionFont,true); - LOGFONTA lfIconTitleFont; - SystemParametersInfoA(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); - iconTitleFont = qt_LOGFONTtoQFont((LOGFONT&)lfIconTitleFont,true); - }); +#ifndef Q_WS_WINCE + NONCLIENTMETRICS ncm; + ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); + + QFont menuFont = qt_LOGFONTtoQFont(ncm.lfMenuFont, true); + QFont messageFont = qt_LOGFONTtoQFont(ncm.lfMessageFont, true); + QFont statusFont = qt_LOGFONTtoQFont(ncm.lfStatusFont, true); + QFont titleFont = qt_LOGFONTtoQFont(ncm.lfCaptionFont, true); + + LOGFONT lfIconTitleFont; + SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); + QFont iconTitleFont = qt_LOGFONTtoQFont(lfIconTitleFont, true); QApplication::setFont(menuFont, "QMenu"); QApplication::setFont(menuFont, "QMenuBar"); @@ -625,24 +614,19 @@ static void qt_set_windows_font_resources() smallerFont.setPointSize(systemFont.pointSize()-1); QApplication::setFont(smallerFont, "QTabBar"); } -#endif// Q_OS_WINCE +#endif// Q_WS_WINCE } static void qt_win_read_cleartype_settings() { - QT_WA({ - UINT result; - BOOL ok; - ok = SystemParametersInfoW(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0); - if (ok) - qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); - }, { - UINT result; - BOOL ok; - ok = SystemParametersInfoA(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0); - if (ok) - qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); - }); + UINT result = 0; +#ifdef Q_OS_WINCE + if (SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &result, 0)) + qt_cleartype_enabled = result; +#else + if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0)) + qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); +#endif } @@ -659,10 +643,10 @@ void QApplicationPrivate::initializeWidgetPaletteHash() QPalette pal = *QApplicationPrivate::sys_pal; QColor menuCol(qt_colorref2qrgb(GetSysColor(COLOR_MENU))); QColor menuText(qt_colorref2qrgb(GetSysColor(COLOR_MENUTEXT))); - BOOL isFlat = 0; + BOOL isFlat = false; if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - SystemParametersInfo(0x1022 /*SPI_GETFLATMENU*/, 0, &isFlat, 0); + SystemParametersInfo(SPI_GETFLATMENU, 0, &isFlat, 0); QPalette menu(pal); // we might need a special color group for the menu. menu.setColor(QPalette::Active, QPalette::Button, menuCol); @@ -677,8 +661,7 @@ void QApplicationPrivate::initializeWidgetPaletteHash() QColor(qt_colorref2qrgb(GetSysColor( (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based) - && isFlat ? COLOR_MENUHILIGHT - : COLOR_HIGHLIGHT)))); + && isFlat ? COLOR_MENUHILIGHT : COLOR_HIGHLIGHT)))); menu.setColor(QPalette::Disabled, QPalette::HighlightedText, disabled); menu.setColor(QPalette::Disabled, QPalette::Button, menu.color(QPalette::Active, QPalette::Button)); @@ -694,10 +677,8 @@ void QApplicationPrivate::initializeWidgetPaletteHash() menu.color(QPalette::Active, QPalette::Highlight)); menu.setColor(QPalette::Inactive, QPalette::HighlightedText, menu.color(QPalette::Active, QPalette::HighlightedText)); - - if (QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95) - menu.setColor(QPalette::Inactive, QPalette::ButtonText, - pal.color(QPalette::Inactive, QPalette::Dark)); + menu.setColor(QPalette::Inactive, QPalette::ButtonText, + pal.color(QPalette::Inactive, QPalette::Dark)); QApplication::setPalette(menu, "QMenu"); if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP @@ -714,11 +695,10 @@ void QApplicationPrivate::initializeWidgetPaletteHash() qt_init() - initializes Qt for Windows *****************************************************************************/ -typedef BOOL (WINAPI *PtrUpdateLayeredWindow)(HWND hwnd, HDC hdcDst, const POINT *pptDst, - const SIZE *psize, HDC hdcSrc, const POINT *pptSrc, COLORREF crKey, - const Q_BLENDFUNCTION *pblend, DWORD dwflags); -static PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0; - +typedef BOOL (WINAPI *PtrSetProcessDPIAware) (VOID); +static PtrSetProcessDPIAware ptrSetProcessDPIAware = 0; +PtrUpdateLayeredWindow ptrUpdateLayeredWindow = 0; +PtrUpdateLayeredWindowIndirect ptrUpdateLayeredWindowIndirect = 0; static BOOL WINAPI qt_updateLayeredWindowIndirect(HWND hwnd, const Q_UPDATELAYEREDWINDOWINFO *info) { return (*ptrUpdateLayeredWindow)(hwnd, info->hdcDst, info->pptDst, info->psize, info->hdcSrc, @@ -745,9 +725,6 @@ void qt_init(QApplicationPrivate *priv, int) appNoGrab = !appNoGrab; else #endif // QT_DEBUG - if (qstrcmp(argv[i], "-direct3d") == 0) - QApplication::setAttribute(Qt::AA_MSWindowsUseDirect3DByDefault); - else argv[j++] = argv[i]; } if(j < priv->argc) { @@ -755,21 +732,12 @@ void qt_init(QApplicationPrivate *priv, int) priv->argc = j; } - // Get the application name/instance if qWinMain() was not invoked -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE // No message boxes but important ones SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX); #endif - if (appInst == 0) { - QT_WA({ - appInst = GetModuleHandle(0); - }, { - appInst = GetModuleHandleA(0); - }); - } - -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE // Initialize OLE/COM // S_OK means success and S_FALSE means that it has already // been initialized @@ -781,7 +749,7 @@ void qt_init(QApplicationPrivate *priv, int) #endif // Misc. initialization -#if defined(QT_DEBUG) && !defined(Q_OS_WINCE) +#if defined(QT_DEBUG) && !defined(Q_WS_WINCE) GdiSetBatchLimit(1); #endif @@ -793,48 +761,32 @@ void qt_init(QApplicationPrivate *priv, int) #ifndef QT_NO_CURSOR QCursorData::initialize(); #endif - qApp->setObjectName(QLatin1String(theAppName)); + qApp->setObjectName(priv->appName()); -#if !defined(Q_OS_WINCE) // default font - HFONT hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); - QFont f(QLatin1String("MS Sans Serif"),8); - int result = 0; - QT_WA({ - LOGFONT lf; - if (result = GetObject(hfont, sizeof(lf), &lf)) - f = qt_LOGFONTtoQFont((LOGFONT&)lf,true); - } , { - LOGFONTA lf; - if (result = GetObjectA(hfont, sizeof(lf), &lf)) - f = qt_LOGFONTtoQFont((LOGFONT&)lf,true); - }); - if (result - && QSysInfo::WindowsVersion >= QSysInfo::WV_2000 - && QSysInfo::WindowsVersion <= QSysInfo::WV_NT_based - && f.family() == QLatin1String("MS Shell Dlg")) - f.setFamily(QLatin1String("MS Shell Dlg 2")); - QApplicationPrivate::setSystemFont(f); -#else //Q_OS_WINCE - LOGFONT lf; - HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT); - int result = 0; - result = GetObject(stockFont, sizeof(lf), &lf); - QFont font = qt_LOGFONTtoQFont(lf, true); - if (result) - QApplicationPrivate::setSystemFont(font); -#endif //Q_OS_WINCE +#ifndef Q_WS_WINCE + HGDIOBJ stockFont = GetStockObject(DEFAULT_GUI_FONT); +#else + HGDIOBJ stockFont = GetStockObject(SYSTEM_FONT); +#endif + + LOGFONT lf; + GetObject(stockFont, sizeof(lf), &lf); + QFont systemFont = qt_LOGFONTtoQFont(lf, true); + +#ifndef Q_WS_WINCE + if (systemFont.family() == QLatin1String("MS Shell Dlg")) { + systemFont.setFamily(QLatin1String("MS Shell Dlg 2")); + } +#endif + + QApplicationPrivate::setSystemFont(systemFont); // QFont::locale_init(); ### Uncomment when it does something on Windows if (QApplication::desktopSettingsAware()) qt_set_windows_resources(); - QT_WA({ - WM95_MOUSEWHEEL = RegisterWindowMessage(L"MSWHEEL_ROLLMSG"); - } , { - WM95_MOUSEWHEEL = RegisterWindowMessageA("MSWHEEL_ROLLMSG"); - }); initWinTabFunctions(); QApplicationPrivate::inputContext = new QWinInputContext(0); @@ -855,7 +807,40 @@ void qt_init(QApplicationPrivate *priv, int) if (ptrUpdateLayeredWindow && !ptrUpdateLayeredWindowIndirect) ptrUpdateLayeredWindowIndirect = qt_updateLayeredWindowIndirect; -#endif + + // Notify Vista and Windows 7 that we support highter DPI settings + ptrSetProcessDPIAware = (PtrSetProcessDPIAware) + QLibrary::resolve(QLatin1String("user32"), "SetProcessDPIAware"); + if (ptrSetProcessDPIAware) + ptrSetProcessDPIAware(); +#endif + + priv->lastGestureId = 0; + + priv->GetGestureInfo = + (PtrGetGestureInfo)QLibrary::resolve(QLatin1String("user32"), + "GetGestureInfo"); + priv->GetGestureExtraArgs = + (PtrGetGestureExtraArgs)QLibrary::resolve(QLatin1String("user32"), + "GetGestureExtraArgs"); + priv->CloseGestureInfoHandle = + (PtrCloseGestureInfoHandle)QLibrary::resolve(QLatin1String("user32"), + "CloseGestureInfoHandle"); + priv->SetGestureConfig = + (PtrSetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "SetGestureConfig"); + priv->GetGestureConfig = + (PtrGetGestureConfig)QLibrary::resolve(QLatin1String("user32"), + "GetGestureConfig"); + priv->BeginPanningFeedback = + (PtrBeginPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "BeginPanningFeedback"); + priv->UpdatePanningFeedback = + (PtrUpdatePanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "UpdatePanningFeedback"); + priv->EndPanningFeedback = + (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), + "EndPanningFeedback"); } /***************************************************************************** @@ -880,7 +865,7 @@ void qt_cleanup() delete QApplicationPrivate::inputContext; QApplicationPrivate::inputContext = 0; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE // Deinitialize OLE/COM OleUninitialize(); #endif @@ -891,12 +876,6 @@ void qt_cleanup() Platform specific global and internal functions *****************************************************************************/ -Q_GUI_EXPORT int qWinAppCmdShow() // get main window show command -{ - return appCmdShow; -} - - Q_GUI_EXPORT HDC qt_win_display_dc() // get display DC { Q_ASSERT(qApp && qApp->thread() == QThread::currentThread()); @@ -928,7 +907,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class if (flags & Qt::MSWindowsOwnDC) { cname = QLatin1String("QWidgetOwnDC"); style = CS_DBLCLKS; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE style |= CS_OWNDC; #endif icon = true; @@ -937,25 +916,25 @@ const QString qt_reg_winclass(QWidget *w) // register window class if (w->inherits("QTipLabel") || w->inherits("QAlphaWidget")) { if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) { - style |= 0x00020000; // CS_DROPSHADOW + style |= CS_DROPSHADOW; } cname = QLatin1String("QToolTip"); } else { cname = QLatin1String("QTool"); } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE style |= CS_SAVEBITS; #endif icon = false; } else if (type == Qt::Popup) { cname = QLatin1String("QPopup"); style = CS_DBLCLKS; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE style |= CS_SAVEBITS; #endif if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) - style |= 0x00020000; // CS_DROPSHADOW + style |= CS_DROPSHADOW; icon = false; } else { cname = QLatin1String("QWidget"); @@ -963,7 +942,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class icon = true; } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE // force CS_OWNDC when the GL graphics system is // used as the default renderer if (qt_win_owndc_required) @@ -975,11 +954,11 @@ const QString qt_reg_winclass(QWidget *w) // register window class // unique ID on WinCE to make sure we can // move the windows to the front when starting // a second instance. - wchar_t uniqueAppID[256]; - GetModuleFileNameW(0, uniqueAppID, 255); - cname = QString::number(RegisterWindowMessageW( - (const wchar_t *) QString::fromUtf16((const ushort *)uniqueAppID).toLower().replace(QString(QString::fromLatin1("\\")), - QString(QString::fromLatin1("_"))).utf16())); + wchar_t uniqueAppID[MAX_PATH]; + GetModuleFileName(0, uniqueAppID, MAX_PATH); + cname = QString::number(RegisterWindowMessage( + (const wchar_t *) QString::fromWCharArray(uniqueAppID).toLower().replace(QLatin1Char('\\'), + QLatin1Char('_')).utf16())); #endif // since multiple Qt versions can be used in one process @@ -990,15 +969,9 @@ const QString qt_reg_winclass(QWidget *w) // register window class static int classExists = -1; if (classExists == -1) { - QT_WA({ - WNDCLASS wcinfo; - classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (TCHAR*)cname.utf16(), &wcinfo); - classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; - }, { - WNDCLASSA wcinfo; - classExists = GetClassInfoA((HINSTANCE)qWinAppInst(), cname.toLatin1(), &wcinfo); - classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; - }); + WNDCLASS wcinfo; + classExists = GetClassInfo((HINSTANCE)qWinAppInst(), (wchar_t*)cname.utf16(), &wcinfo); + classExists = classExists && wcinfo.lpfnWndProc != QtWndProc; } if (classExists) @@ -1007,73 +980,37 @@ const QString qt_reg_winclass(QWidget *w) // register window class if (winclassNames()->contains(cname)) // already registered in our list return cname; - ATOM atom; -#ifndef Q_OS_WINCE - HBRUSH bgBrush = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); - QT_WA({ - WNDCLASS wc; - wc.style = style; - wc.lpfnWndProc = (WNDPROC)QtWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = (HINSTANCE)qWinAppInst(); - if (icon) { - wc.hIcon = LoadIcon(appInst, L"IDI_ICON1"); - if (!wc.hIcon) - wc.hIcon = LoadIcon(0, IDI_APPLICATION); - } else { - wc.hIcon = 0; - } - wc.hCursor = 0; - wc.hbrBackground= bgBrush; - wc.lpszMenuName = 0; - wc.lpszClassName= (TCHAR*)cname.utf16(); - atom = RegisterClass(&wc); - } , { - WNDCLASSA wc; - wc.style = style; - wc.lpfnWndProc = (WNDPROC)QtWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = (HINSTANCE)qWinAppInst(); - if (icon) { - wc.hIcon = LoadIconA(appInst, (char*)"IDI_ICON1"); - if (!wc.hIcon) - wc.hIcon = LoadIconA(0, (char*)IDI_APPLICATION); - } else { - wc.hIcon = 0; - } - wc.hCursor = 0; - wc.hbrBackground= bgBrush; - wc.lpszMenuName = 0; - QByteArray tempArray = cname.toLatin1(); - wc.lpszClassName= tempArray; - atom = RegisterClassA(&wc); - }); + WNDCLASS wc; + wc.style = style; + wc.lpfnWndProc = (WNDPROC)QtWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = qWinAppInst(); + if (icon) { + wc.hIcon = (HICON)LoadImage(qWinAppInst(), L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); +#ifndef Q_WS_WINCE + if (!wc.hIcon) + wc.hIcon = (HICON)LoadImage(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); +#endif + } else { + wc.hIcon = 0; + } + wc.hCursor = 0; +#ifndef Q_WS_WINCE + wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); #else - WNDCLASS wc; - wc.style = style; - wc.lpfnWndProc = (WNDPROC)QtWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = (HINSTANCE)qWinAppInst(); - if (icon) { - wc.hIcon = LoadIcon(appInst, L"IDI_ICON1"); -// if (!wc.hIcon) -// wc.hIcon = LoadIcon(0, IDI_APPLICATION); - } else { - wc.hIcon = 0; - } - wc.hCursor = 0; - wc.hbrBackground= 0; - wc.lpszMenuName = 0; - wc.lpszClassName= (TCHAR*)cname.utf16(); - atom = RegisterClass(&wc); + wc.hbrBackground = 0; #endif + wc.lpszMenuName = 0; + wc.lpszClassName = (wchar_t*)cname.utf16(); + + ATOM atom = RegisterClass(&wc); #ifndef QT_NO_DEBUG if (!atom) qErrnoWarning("QApplication::regClass: Registering window class failed."); +#else + Q_UNUSED(atom); #endif winclassNames()->insert(cname, 1); @@ -1091,11 +1028,7 @@ static void unregWinClasses() WinClassNameHash *hash = winclassNames(); QHash<QString, int>::ConstIterator it = hash->constBegin(); while (it != hash->constEnd()) { - QT_WA({ - UnregisterClass((TCHAR*)it.key().utf16(), (HINSTANCE)qWinAppInst()); - } , { - UnregisterClassA(it.key().toLatin1(), (HINSTANCE)qWinAppInst()); - }); + UnregisterClass((wchar_t*)it.key().utf16(), qWinAppInst()); ++it; } hash->clear(); @@ -1129,7 +1062,7 @@ void qWinRequestConfig(WId id, int req, int x, int y, int w, int h) configRequests->append(r); // store request in queue } -Q_GUI_EXPORT void qWinProcessConfigRequests() // perform requests in queue +static void qWinProcessConfigRequests() // perform requests in queue { if (!configRequests) return; @@ -1312,16 +1245,10 @@ void QApplication::beep() static void alert_widget(QWidget *widget, int duration) { - bool stopFlash = duration < 0; - - if (!pFlashWindowEx) { #ifndef Q_OS_WINCE - QLibrary themeLib(QLatin1String("user32")); - pFlashWindowEx = (PtrFlashWindowEx)themeLib.resolve("FlashWindowEx"); -#endif - } + bool stopFlash = duration < 0; - if (pFlashWindowEx && widget && (!widget->isActiveWindow() || stopFlash)) { + if (widget && (!widget->isActiveWindow() || stopFlash)) { DWORD timeOut = GetCaretBlinkTime(); if (timeOut <= 0) timeOut = 250; @@ -1339,8 +1266,9 @@ static void alert_widget(QWidget *widget, int duration) info.dwTimeout = stopFlash ? 0 : timeOut; info.uCount = stopFlash ? 0 : flashCount; - pFlashWindowEx(&info); + FlashWindowEx(&info); } +#endif } void QApplication::alert(QWidget *widget, int duration) @@ -1381,7 +1309,7 @@ void QApplication::winFocus(QWidget *widget, bool gotFocus) && (QApplicationPrivate::active_window->windowType() == Qt::Dialog)) { // raise the entire application, not just the dialog QWidget* mw = QApplicationPrivate::active_window; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE while(mw->parentWidget() && (mw->windowType() == Qt::Dialog)) mw = mw->parentWidget()->window(); if (mw->testAttribute(Qt::WA_WState_Created) && mw != QApplicationPrivate::active_window) @@ -1428,12 +1356,13 @@ static int inputcharset = CP_ACP; static bool qt_is_translatable_mouse_event(UINT message) { - return (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST || - message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK) + return (((message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) || + (message >= WM_XBUTTONDOWN && message <= WM_XBUTTONDBLCLK)) && message != WM_MOUSEWHEEL + && message != WM_MOUSEHWHEEL) -#ifndef Q_OS_WINCE - || message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK +#ifndef Q_WS_WINCE + || (message >= WM_NCMOUSEMOVE && message <= WM_NCMBUTTONDBLCLK) #endif ; } @@ -1472,7 +1401,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam msg.pt.y = GET_Y_LPARAM(lParam); // If it's a non-client-area message the coords are screen coords, otherwise they are // client coords. -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE if (message < WM_NCMOUSEMOVE || message > WM_NCMBUTTONDBLCLK) #endif ClientToScreen(msg.hwnd, &msg.pt); @@ -1502,7 +1431,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam if (imeParentWnd && QApplication::activePopupWidget() && (message == WM_MBUTTONDOWN || message == WM_XBUTTONDOWN || message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE || message == WM_NCMBUTTONDOWN || message == WM_NCLBUTTONDOWN || message == WM_NCRBUTTONDOWN)) { #else @@ -1512,7 +1441,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } switch (message) { -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE case WM_QUERYENDSESSION: { if (sm_smActive) // bogus message from windows RETURN(true); @@ -1540,13 +1469,13 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam int index = QApplication::staticMetaObject.indexOfSignal("aboutToQuit()"); qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,0); // since the process will be killed immediately quit() has no real effect - qApp->quit(); + QApplication::quit(); } RETURN(0); } case WM_DISPLAYCHANGE: - if (qApp->type() == QApplication::Tty) + if (QApplication::type() == QApplication::Tty) break; if (qt_desktopWidget) { qt_desktopWidget->move(GetSystemMetrics(76), GetSystemMetrics(77)); @@ -1563,7 +1492,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam #endif case WM_SETTINGCHANGE: -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE // CE SIP hide/show if (wParam == SPI_SETSIPINFO) { QResizeEvent re(QSize(0, 0), QSize(0, 0)); // Calculated by QDesktopWidget @@ -1572,7 +1501,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } #endif // ignore spurious XP message when user logs in again after locking - if (qApp->type() == QApplication::Tty) + if (QApplication::type() == QApplication::Tty) break; if (QApplication::desktopSettingsAware() && wParam != SPI_SETWORKAREA) { widget = (QETWidget*)QWidget::find(hwnd); @@ -1595,7 +1524,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam if (wParam == SPI_SETFONTSMOOTHINGTYPE) { qt_win_read_cleartype_settings(); - foreach (QWidget *w, qApp->topLevelWidgets()) { + foreach (QWidget *w, QApplication::topLevelWidgets()) { if (!w->isVisible()) continue; ((QETWidget *) w)->forceUpdate(); @@ -1604,7 +1533,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam break; case WM_SYSCOLORCHANGE: - if (qApp->type() == QApplication::Tty) + if (QApplication::type() == QApplication::Tty) break; if (QApplication::desktopSettingsAware()) { widget = (QETWidget*)QWidget::find(hwnd); @@ -1656,7 +1585,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam RETURN(res); if (qt_is_translatable_mouse_event(message)) { - if (qApp->activePopupWidget() != 0) { // in popup mode + if (QApplication::activePopupWidget() != 0) { // in popup mode POINT curPos = msg.pt; QWidget* w = QApplication::widgetAt(curPos.x, curPos.y); if (w) @@ -1665,10 +1594,10 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam if (!qt_tabletChokeMouse) { result = widget->translateMouseEvent(msg); // mouse event -#if defined(Q_OS_WINCE) && !defined(QT_NO_CONTEXTMENU) - if (message == WM_LBUTTONDOWN && widget != qApp->activePopupWidget()) { +#if defined(Q_WS_WINCE) && !defined(QT_NO_CONTEXTMENU) + if (message == WM_LBUTTONDOWN && widget != QApplication::activePopupWidget()) { QWidget* alienWidget = widget; - if ((alienWidget != qApp->activePopupWidget()) && (alienWidget->contextMenuPolicy() != Qt::PreventContextMenu)) { + if ((alienWidget != QApplication::activePopupWidget()) && (alienWidget->contextMenuPolicy() != Qt::PreventContextMenu)) { QPoint pos(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); QPoint globalPos(msg.pt.x, msg.pt.y); // In case we are using Alien, then the widget to @@ -1687,8 +1616,8 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION; resolveAygLibs(); if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) { - if (qApp->activePopupWidget()) - qApp->activePopupWidget()->close(); + if (QApplication::activePopupWidget()) + QApplication::activePopupWidget()->close(); QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos); result = qt_sendSpontaneousEvent(alienWidget, &e); } @@ -1700,7 +1629,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam // Sometimes we only get a WM_MOUSEMOVE message // and sometimes we get both a WM_MOUSEMOVE and // a WM_LBUTTONDOWN/UP, this creates a spurious mouse - // press/release event, using the winPeekMessage + // press/release event, using the PeekMessage // will help us fix this. This leaves us with a // question: // This effectively kills using the mouse AND the @@ -1710,18 +1639,19 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam bool is_mouse_move = (message == WM_MOUSEMOVE); if (is_mouse_move) { MSG msg1; - if (winPeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST, - WM_MOUSELAST, PM_NOREMOVE)) + if (PeekMessage(&msg1, msg.hwnd, WM_MOUSEFIRST, + WM_MOUSELAST, PM_NOREMOVE)) next_is_button = (msg1.message == WM_LBUTTONUP || msg1.message == WM_LBUTTONDOWN); } if (!is_mouse_move || (is_mouse_move && !next_is_button)) qt_tabletChokeMouse = false; } - } else if (message == WM95_MOUSEWHEEL) { - result = widget->translateWheelEvent(msg); } else { switch (message) { + case WM_TOUCH: + result = getQApplicationPrivateInternal()->translateTouchEvent(msg); + break; case WM_KEYDOWN: // keyboard event case WM_SYSKEYDOWN: qt_keymapper_private()->updateKeyMap(msg); @@ -1747,7 +1677,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam case WM_IME_KEYDOWN: case WM_CHAR: { MSG msg1; - bool anyMsg = winPeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE); + bool anyMsg = PeekMessage(&msg1, msg.hwnd, 0, 0, PM_NOREMOVE); if (anyMsg && msg1.message == WM_DEADCHAR) { result = true; // consume event since there is a dead char next break; @@ -1766,7 +1696,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam widget = (QETWidget*)QApplication::activePopupWidget()->focusWidget() ? (QETWidget*)QApplication::activePopupWidget()->focusWidget() : (QETWidget*)QApplication::activePopupWidget(); - else if (qApp->focusWidget()) + else if (QApplication::focusWidget()) widget = (QETWidget*)QApplication::focusWidget(); else if (!widget || widget->internalWinId() == GetFocus()) // We faked the message to go to exactly that widget. widget = (QETWidget*)widget->window(); @@ -1781,6 +1711,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam break; case WM_MOUSEWHEEL: + case WM_MOUSEHWHEEL: result = widget->translateWheelEvent(msg); break; @@ -1888,8 +1819,8 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam QWidget *g = QWidget::keyboardGrabber(); if (g) widget = (QETWidget*)g; - else if (qApp->focusWidget()) - widget = (QETWidget*)qApp->focusWidget(); + else if (QApplication::focusWidget()) + widget = (QETWidget*)QApplication::focusWidget(); else widget = (QETWidget*)widget->window(); if (widget->isEnabled()) { @@ -1911,17 +1842,21 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } break; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE case WM_NCHITTEST: if (widget->isWindow()) { QPoint pos = widget->mapFromGlobal(QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); // don't show resize-cursors for fixed-size widgets QRect fs = widget->frameStrut(); if (!widget->isMinimized()) { + if (widget->minimumHeight() == widget->maximumHeight()) { + if (pos.y() < -(fs.top() - fs.left())) + return HTCAPTION; + if (pos.y() >= widget->height()) + return HTBORDER; + } if (widget->minimumWidth() == widget->maximumWidth() && (pos.x() < 0 || pos.x() >= widget->width())) - break; - if (widget->minimumHeight() == widget->maximumHeight() && (pos.y() < -(fs.top() - fs.left()) || pos.y() >= widget->height())) - break; + return HTBORDER; } } @@ -1930,7 +1865,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam #endif case WM_SYSCOMMAND: { -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE bool window_state_change = false; Qt::WindowStates oldstate = Qt::WindowStates(widget->dataPtr()->window_state); // MSDN:In WM_SYSCOMMAND messages, the four low-order bits of the wParam parameter are @@ -1942,11 +1877,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam #ifndef QT_NO_WHATSTHIS QWhatsThis::enterWhatsThisMode(); #endif - QT_WA({ - DefWindowProc(hwnd, WM_NCPAINT, 1, 0); - } , { - DefWindowProcA(hwnd, WM_NCPAINT, 1, 0); - }); + DefWindowProc(hwnd, WM_NCPAINT, 1, 0); break; #if defined(QT_NON_COMMERCIAL) QT_NC_SYSCOMMAND @@ -1958,7 +1889,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam QHideEvent e; qt_sendSpontaneousEvent(widget, &e); widget->hideChildren(true); -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE const QString title = widget->windowIconText(); if (!title.isEmpty()) widget->setWindowTitle_helper(title); @@ -1981,7 +1912,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam widget->showChildren(true); QShowEvent e; qt_sendSpontaneousEvent(widget, &e); -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE const QString title = widget->windowTitle(); if (!title.isEmpty()) widget->setWindowTitle_helper(title); @@ -2004,12 +1935,11 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } case WM_SETTINGCHANGE: - if ( qApp->type() == QApplication::Tty ) + if ( QApplication::type() == QApplication::Tty ) break; if (!msg.wParam) { - QString area = QT_WA_INLINE(QString::fromUtf16((unsigned short *)msg.lParam), - QString::fromLocal8Bit((char*)msg.lParam)); + QString area = QString::fromWCharArray((wchar_t*)msg.lParam); if (area == QLatin1String("intl")) { QLocalePrivate::updateSystemPrivate(); if (!widget->testAttribute(Qt::WA_SetLocale)) @@ -2017,7 +1947,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } } else if (msg.wParam == SPI_SETICONTITLELOGFONT) { - if (qApp->desktopSettingsAware()) { + if (QApplication::desktopSettingsAware()) { widget = (QETWidget*)QWidget::find(hwnd); if (widget && !widget->parentWidget()) { qt_set_windows_font_resources(); @@ -2031,7 +1961,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam result = widget->translatePaintEvent(msg); break; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE case WM_ENTERSIZEMOVE: autoCaptureWnd = hwnd; QApplicationPrivate::inSizeMove = true; @@ -2060,7 +1990,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam break; case WM_ACTIVATE: - if ( qApp->type() == QApplication::Tty ) + if ( QApplication::type() == QApplication::Tty ) break; if (ptrWTOverlap && ptrWTEnable) { @@ -2086,9 +2016,13 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam // WM_ACTIVATEAPP handles the "true" false case, as this is only when the application // loses focus. Doing it here would result in the widget getting focus to not know // where it got it from; it would simply get a 0 value as the old focus widget. +#ifndef Q_WS_WINCE_WM if (!(widget->windowState() & Qt::WindowMinimized)) { // Ignore the activate message send by WindowsXP to a minimized window -#ifdef Q_OS_WINCE_WM +#else + { + if (widget->windowState() & Qt::WindowMinimized) + widget->dataPtr()->window_state &= ~Qt::WindowMinimized; if (widget->windowState() & Qt::WindowFullScreen) qt_wince_hide_taskbar(widget->winId()); #endif @@ -2115,7 +2049,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } break; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE case WM_MOUSEACTIVATE: if (widget->window()->windowType() == Qt::Tool) { QWidget *w = widget; @@ -2204,7 +2138,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam result = false; break; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE case WM_WINDOWPOSCHANGING: { result = false; @@ -2285,12 +2219,12 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam QWidget *fw = QWidget::keyboardGrabber(); if (!fw) { - if (qApp->activePopupWidget()) - fw = (qApp->activePopupWidget()->focusWidget() - ? qApp->activePopupWidget()->focusWidget() - : qApp->activePopupWidget()); - else if (qApp->focusWidget()) - fw = qApp->focusWidget(); + if (QApplication::activePopupWidget()) + fw = (QApplication::activePopupWidget()->focusWidget() + ? QApplication::activePopupWidget()->focusWidget() + : QApplication::activePopupWidget()); + else if (QApplication::focusWidget()) + fw = QApplication::focusWidget(); else if (widget) fw = widget->window(); } @@ -2307,7 +2241,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: { - QWidget *fw = qApp->focusWidget(); + QWidget *fw = QApplication::focusWidget(); QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0; if (fw && im) { if(message == WM_IME_STARTCOMPOSITION) @@ -2320,7 +2254,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam break; } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE case WM_CHANGECBCHAIN: case WM_DRAWCLIPBOARD: #endif @@ -2340,7 +2274,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam case WM_GETOBJECT: { // Ignoring all requests while starting up - if (qApp->startingUp() || qApp->closingDown() || (DWORD)lParam != OBJID_CLIENT) { + if (QApplication::startingUp() || QApplication::closingDown() || (DWORD)lParam != OBJID_CLIENT) { result = false; break; } @@ -2383,11 +2317,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam text = widget->objectName(); ret = qMin<int>(wParam - 1, text.size()); text.resize(ret); - QT_WA({ - memcpy((void *)lParam, text.utf16(), (text.size() + 1) * 2); - }, { - memcpy((void *)lParam, text.toLocal8Bit().data(), text.size() + 1); - }); + memcpy((void *)lParam, text.utf16(), (text.size() + 1) * sizeof(ushort)); delete acc; } if (!ret) { @@ -2427,7 +2357,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam #endif // QT_NO_TABLETEVENT } break; -#ifdef Q_OS_WINCE_WM +#ifdef Q_WS_WINCE_WM case WM_SETFOCUS: { HIMC hC; hC = ImmGetContext(hwnd); @@ -2440,7 +2370,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam case WM_KILLFOCUS: if (!QWidget::find((HWND)wParam)) { // we don't get focus, so unset it now if (!widget->hasFocus()) // work around Windows bug after minimizing/restoring - widget = (QETWidget*)qApp->focusWidget(); + widget = (QETWidget*)QApplication::focusWidget(); HWND focus = ::GetFocus(); //if there is a current widget and the new widget belongs to the same toplevel window //or if the current widget was embedded into non-qt window (i.e. we won't get WM_ACTIVATEAPP) @@ -2459,27 +2389,27 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } break; case WM_THEMECHANGED: - if ((widget->windowType() == Qt::Desktop) || !qApp || qApp->closingDown() - || qApp->type() == QApplication::Tty) + if ((widget->windowType() == Qt::Desktop) || !qApp || QApplication::closingDown() + || QApplication::type() == QApplication::Tty) break; if (widget->testAttribute(Qt::WA_WState_Polished)) - qApp->style()->unpolish(widget); + QApplication::style()->unpolish(widget); if (widget->testAttribute(Qt::WA_WState_Polished)) - qApp->style()->polish(widget); - widget->repolishStyle(*qApp->style()); + QApplication::style()->polish(widget); + widget->repolishStyle(*QApplication::style()); if (widget->isVisible()) widget->update(); break; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE case WM_INPUTLANGCHANGE: { - char info[7]; - if (!GetLocaleInfoA(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) { + wchar_t info[7]; + if (!GetLocaleInfo(MAKELCID(lParam, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, info, 6)) { inputcharset = CP_ACP; } else { - inputcharset = QString::fromLatin1(info).toInt(); + inputcharset = QString::fromWCharArray(info).toInt(); } QKeyMapper::changeKeyboard(); break; @@ -2573,6 +2503,10 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } result = false; break; + case WM_GESTURE: + widget->translateGestureEvent(msg); + result = true; + break; default: result = false; // event was not processed break; @@ -2671,19 +2605,19 @@ bool qt_try_modal(QWidget *widget, MSG *msg, int& ret) int type = msg->message; bool block_event = false; -#ifndef Q_OS_WINCE - if (type != WM_NCHITTEST) +#ifndef Q_WS_WINCE + if (type != WM_NCHITTEST) { #endif if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) || - type == WM_MOUSEWHEEL || type == (int)WM95_MOUSEWHEEL || + type == WM_MOUSEWHEEL || type == WM_MOUSEHWHEEL || type == WM_MOUSELEAVE || (type >= WM_KEYFIRST && type <= WM_KEYLAST) -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE || type == WM_NCMOUSEMOVE #endif ) { if (type == WM_MOUSEMOVE -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE || type == WM_NCMOUSEMOVE #endif ) { @@ -2701,18 +2635,19 @@ bool qt_try_modal(QWidget *widget, MSG *msg, int& ret) } else if (type == WM_CLOSE) { block_event = true; } -#ifndef Q_OS_WINCE - else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){ - if (!top->isActiveWindow()) { - top->activateWindow(); - } else { - QApplication::beep(); - } - block_event = true; - ret = MA_NOACTIVATEANDEAT; - } else if (type == WM_SYSCOMMAND) { - if (!(msg->wParam == SC_RESTORE && widget->isMinimized())) +#ifndef Q_WS_WINCE + else if (type == WM_MOUSEACTIVATE || type == WM_NCLBUTTONDOWN){ + if (!top->isActiveWindow()) { + top->activateWindow(); + } else { + QApplication::beep(); + } block_event = true; + ret = MA_NOACTIVATEANDEAT; + } else if (type == WM_SYSCOMMAND) { + if (!(msg->wParam == SC_RESTORE && widget->isMinimized())) + block_event = true; + } } #endif @@ -2756,9 +2691,9 @@ void QApplicationPrivate::openPopup(QWidget *popup) if (popup->focusWidget()) { popup->focusWidget()->setFocus(Qt::PopupFocusReason); } else if (QApplicationPrivate::popupWidgets->count() == 1) { // this was the first popup - if (QWidget *fw = q_func()->focusWidget()) { + if (QWidget *fw = QApplication::focusWidget()) { QFocusEvent e(QEvent::FocusOut, Qt::PopupFocusReason); - q_func()->sendEvent(fw, &e); + QApplication::sendEvent(fw, &e); } } } @@ -2785,13 +2720,13 @@ void QApplicationPrivate::closePopup(QWidget *popup) if (!qt_nograb()) // grabbing not disabled releaseAutoCapture(); QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget() - : q_func()->focusWidget(); + : QApplication::focusWidget(); if (fw) { - if (fw != q_func()->focusWidget()) { + if (fw != QApplication::focusWidget()) { fw->setFocus(Qt::PopupFocusReason); } else { QFocusEvent e(QEvent::FocusIn, Qt::PopupFocusReason); - q_func()->sendEvent(fw, &e); + QApplication::sendEvent(fw, &e); } } } else { @@ -2859,7 +2794,7 @@ static const ushort mouseTbl[] = { WM_XBUTTONUP, QEvent::MouseButtonRelease, Qt::XButton1, WM_XBUTTONDBLCLK, QEvent::MouseButtonDblClick, Qt::XButton1, -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE WM_NCMOUSEMOVE, QEvent::NonClientAreaMouseMove, 0, WM_NCLBUTTONDOWN, QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton, WM_NCLBUTTONUP, QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton, @@ -2914,20 +2849,11 @@ void qt_win_eatMouseMove() // remove all those messages (usually 1) and post the last one with a // reset button state - MSG msg = {0, 0, 0, 0, 0, 0, 0}; - QT_WA( { - while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - ; - if (msg.message == WM_MOUSEMOVE) - PostMessage(msg.hwnd, msg.message, 0, msg.lParam); - }, { - MSG msg; - msg.message = 0; - while (PeekMessageA(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) - ; - if (msg.message == WM_MOUSEMOVE) - PostMessageA(msg.hwnd, msg.message, 0, msg.lParam); - } ); + MSG msg = {0, 0, 0, 0, 0, {0, 0} }; + while (PeekMessage(&msg, 0, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) + ; + if (msg.message == WM_MOUSEMOVE) + PostMessage(msg.hwnd, msg.message, 0, msg.lParam); } // In DnD, the mouse release event never appears, so the @@ -2962,8 +2888,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg) // Compress mouse move events if (msg.message == WM_MOUSEMOVE) { MSG mouseMsg; - while (winPeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST, - WM_MOUSELAST, PM_NOREMOVE)) { + while (PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEFIRST, + WM_MOUSELAST, PM_NOREMOVE)) { if (mouseMsg.message == WM_MOUSEMOVE) { #define PEEKMESSAGE_IS_BROKEN 1 #ifdef PEEKMESSAGE_IS_BROKEN @@ -2974,12 +2900,12 @@ bool QETWidget::translateMouseEvent(const MSG &msg) // key release events (kls 2003-05-13): MSG keyMsg; bool done = false; - while (winPeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST, - PM_NOREMOVE)) { + while (PeekMessage(&keyMsg, 0, WM_KEYFIRST, WM_KEYLAST, + PM_NOREMOVE)) { if (keyMsg.time < mouseMsg.time) { if ((keyMsg.lParam & 0xC0000000) == 0x40000000) { - winPeekMessage(&keyMsg, 0, keyMsg.message, - keyMsg.message, PM_REMOVE); + PeekMessage(&keyMsg, 0, keyMsg.message, + keyMsg.message, PM_REMOVE); } else { done = true; break; @@ -3005,8 +2931,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg) msgPtr->wParam = mouseMsg.wParam; msgPtr->pt = mouseMsg.pt; // Remove the mouse move message - winPeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE, - WM_MOUSEMOVE, PM_REMOVE); + PeekMessage(&mouseMsg, msg.hwnd, WM_MOUSEMOVE, + WM_MOUSEMOVE, PM_REMOVE); } else { break; // there was no more WM_MOUSEMOVE event } @@ -3035,7 +2961,9 @@ bool QETWidget::translateMouseEvent(const MSG &msg) if (alienWidget && alienWidget->internalWinId()) alienWidget = 0; - if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove) { + if (type == QEvent::MouseMove || type == QEvent::NonClientAreaMouseMove + || type == QEvent::TabletMove) { + if (!(state & Qt::MouseButtonMask)) qt_button_down = 0; #ifndef QT_NO_CURSOR @@ -3055,7 +2983,7 @@ bool QETWidget::translateMouseEvent(const MSG &msg) HWND id = effectiveWinId(); QWidget *mouseGrabber = QWidget::mouseGrabber(); - QWidget *activePopupWidget = qApp->activePopupWidget(); + QWidget *activePopupWidget = QApplication::activePopupWidget(); if (mouseGrabber) { if (!activePopupWidget || (activePopupWidget == this && !rect().contains(widgetPos))) id = mouseGrabber->effectiveWinId(); @@ -3148,7 +3076,7 @@ bool QETWidget::translateMouseEvent(const MSG &msg) return false; replayPopupMouseEvent = false; - QWidget* activePopupWidget = qApp->activePopupWidget(); + QWidget* activePopupWidget = QApplication::activePopupWidget(); QWidget *target = activePopupWidget; const QPoint globalPos(gpos.x, gpos.y); @@ -3166,6 +3094,8 @@ bool QETWidget::translateMouseEvent(const MSG &msg) popupButtonFocus = popupChild; break; case QEvent::MouseButtonRelease: + case QEvent::TabletRelease: + releaseAfter = true; break; default: @@ -3176,10 +3106,7 @@ bool QETWidget::translateMouseEvent(const MSG &msg) if (popupButtonFocus) { target = popupButtonFocus; } else if (popupChild) { - // forward mouse events to the popup child. mouse move events - // are only forwarded to popup children that enable mouse tracking. - if (type != QEvent::MouseMove || popupChild->hasMouseTracking()) - target = popupChild; + target = popupChild; } pos = target->mapFromGlobal(globalPos); @@ -3209,7 +3136,7 @@ bool QETWidget::translateMouseEvent(const MSG &msg) } if (type == QEvent::MouseButtonPress - && qApp->activePopupWidget() != activePopupWidget + && QApplication::activePopupWidget() != activePopupWidget && replayPopupMouseEvent) { // the popup dissappeared. Replay the event QWidget* w = QApplication::widgetAt(gpos.x, gpos.y); @@ -3223,10 +3150,10 @@ bool QETWidget::translateMouseEvent(const MSG &msg) POINT widgetpt = gpos; ScreenToClient(hwndTarget, &widgetpt); LPARAM lParam = MAKELPARAM(widgetpt.x, widgetpt.y); - winPostMessage(hwndTarget, msg.message, msg.wParam, lParam); + PostMessage(hwndTarget, msg.message, msg.wParam, lParam); } } else if (type == QEvent::MouseButtonRelease && button == Qt::RightButton - && qApp->activePopupWidget() == activePopupWidget) { + && QApplication::activePopupWidget() == activePopupWidget) { // popup still alive and received right-button-release #if !defined(QT_NO_CONTEXTMENU) QContextMenuEvent e2(QContextMenuEvent::Mouse, pos, globalPos, @@ -3290,12 +3217,12 @@ bool QETWidget::translateWheelEvent(const MSG &msg) state = translateButtonState(GET_KEYSTATE_WPARAM(msg.wParam), 0, 0); int delta; - if (msg.message == WM_MOUSEWHEEL) + if (msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL) delta = (short) HIWORD (msg.wParam); else delta = (int) msg.wParam; - Qt::Orientation orient = (state&Qt::AltModifier + Qt::Orientation orient = (msg.message == WM_MOUSEHWHEEL || state&Qt::AltModifier #if 0 // disabled for now - Trenton's one-wheel mouse makes trouble... // "delta" for usual wheels is +-120. +-240 seems to indicate @@ -3309,6 +3236,13 @@ bool QETWidget::translateWheelEvent(const MSG &msg) #endif ) ? Qt::Horizontal : Qt::Vertical; + // according to the MSDN documentation on WM_MOUSEHWHEEL: + // a positive value indicates that the wheel was rotated to the right; + // a negative value indicates that the wheel was rotated to the left. + // Qt defines this value as the exact opposite, so we have to flip the value! + if (msg.message == WM_MOUSEHWHEEL) + delta = -delta; + QPoint globalPos; globalPos.rx() = (short)LOWORD (msg.lParam); @@ -3329,7 +3263,7 @@ bool QETWidget::translateWheelEvent(const MSG &msg) // send the event to the widget or its ancestors { - QWidget* popup = qApp->activePopupWidget(); + QWidget* popup = QApplication::activePopupWidget(); if (popup && w->window() != popup) popup->close(); #ifndef QT_NO_WHEELEVENT @@ -3345,8 +3279,8 @@ bool QETWidget::translateWheelEvent(const MSG &msg) } // send the event to the widget that has the focus or its ancestors, if different - if (w != qApp->focusWidget() && (w = qApp->focusWidget())) { - QWidget* popup = qApp->activePopupWidget(); + if (w != QApplication::focusWidget() && (w = QApplication::focusWidget())) { + QWidget* popup = QApplication::activePopupWidget(); if (popup && w->window() != popup) popup->close(); #ifndef QT_NO_WHEELEVENT @@ -3399,17 +3333,19 @@ static void tabletInit(UINT wActiveCsr, HCTX hTab) tdd.minTanPressure = int(np.axMin); tdd.maxTanPressure = int(np.axMax); - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_X, &np); - tdd.minX = int(np.axMin); - tdd.maxX = int(np.axMax); + LOGCONTEXT lcMine; - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_Y, &np); - tdd.minY = int(np.axMin); - tdd.maxY = int(np.axMax); + /* get default region */ + ptrWTInfo(WTI_DEFCONTEXT, 0, &lcMine); - ptrWTInfo(WTI_DEVICES + lc.lcDevice, DVC_Z, &np); - tdd.minZ = int(np.axMin); - tdd.maxZ = int(np.axMax); + tdd.minX = 0; + tdd.maxX = int(lcMine.lcInExtX) - int(lcMine.lcInOrgX); + + tdd.minY = 0; + tdd.maxY = int(lcMine.lcInExtY) - int(lcMine.lcInOrgY); + + tdd.minZ = 0; + tdd.maxZ = int(lcMine.lcInExtZ) - int(lcMine.lcInOrgZ); int csr_type, csr_physid; @@ -3519,13 +3455,34 @@ bool QETWidget::translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, } QPoint globalPos(qRound(hiResGlobal.x()), qRound(hiResGlobal.y())); + if (t == QEvent::TabletPress) + { + qt_button_down = QApplication::widgetAt(globalPos); + } + // make sure the tablet event get's sent to the proper widget... - QWidget *w = QApplication::widgetAt(globalPos); + QWidget *w = 0; + if (qt_button_down) w = qt_button_down; // Pass it to the thing that's grabbed it. + else + w = QApplication::widgetAt(globalPos); if (!w) w = this; + + if (t == QEvent::TabletRelease) + { + if (qt_win_ignoreNextMouseReleaseEvent) { + qt_win_ignoreNextMouseReleaseEvent = false; + if (qt_button_down && qt_button_down->internalWinId() == autoCaptureWnd) { + releaseAutoCapture(); + qt_button_down = 0; + } + } + + } + QPoint localPos = w->mapFromGlobal(globalPos); #ifndef QT_NO_TABLETEVENT if (currentTabletPointer.currentDevice == QTabletEvent::Airbrush) { @@ -3583,14 +3540,8 @@ static void initWinTabFunctions() QLibrary library(QLatin1String("wintab32")); if (library.load()) { - QT_WA({ - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); - ptrWTGet = (PtrWTGet)library.resolve("WTGetW"); - } , { - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoA"); - ptrWTGet = (PtrWTGet)library.resolve("WTGetA"); - }); - + ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); + ptrWTGet = (PtrWTGet)library.resolve("WTGetW"); ptrWTEnable = (PtrWTEnable)library.resolve("WTEnable"); ptrWTOverlap = (PtrWTEnable)library.resolve("WTOverlap"); ptrWTPacketsGet = (PtrWTPacketsGet)library.resolve("WTPacketsGet"); @@ -3661,7 +3612,7 @@ bool QETWidget::translateConfigEvent(const MSG &msg) WORD b = HIWORD(msg.lParam); QSize oldSize = size(); QSize newSize(a, b); -#ifdef Q_OS_WINCE_WM +#ifdef Q_WS_WINCE_WM if (isFullScreen() && (oldSize.width() == newSize.height()) && (oldSize.height() == newSize.width())) qt_wince_hide_taskbar(internalWinId()); #endif @@ -3673,7 +3624,7 @@ bool QETWidget::translateConfigEvent(const MSG &msg) // Capture SIZE_MINIMIZED without preceding WM_SYSCOMMAND // (like Windows+M) if (msg.wParam == SIZE_MINIMIZED && !isMinimized()) { -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE const QString title = windowIconText(); if (!title.isEmpty()) d_func()->setWindowTitle_helper(title); @@ -3685,7 +3636,7 @@ bool QETWidget::translateConfigEvent(const MSG &msg) hideChildren(true); } } else if (msg.wParam != SIZE_MINIMIZED && isMinimized()) { -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE const QString title = windowTitle(); if (!title.isEmpty()) d_func()->setWindowTitle_helper(title); @@ -3731,7 +3682,7 @@ bool QETWidget::translateConfigEvent(const MSG &msg) QPoint oldPos = geometry().topLeft(); QPoint newCPos(a, b); // Ignore silly Windows move event to wild pos after iconify. -#if !defined(Q_OS_WINCE) +#if !defined(Q_WS_WINCE) if (!IsIconic(internalWinId()) && newCPos != oldPos) { #endif cr.moveTopLeft(newCPos); @@ -3743,7 +3694,7 @@ bool QETWidget::translateConfigEvent(const MSG &msg) QMoveEvent * e = new QMoveEvent(newCPos, oldPos); QApplication::postEvent(this, e); } -#if !defined(Q_OS_WINCE) +#if !defined(Q_WS_WINCE) } #endif } @@ -3764,6 +3715,60 @@ bool QETWidget::translateCloseEvent(const MSG &) return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); } +bool QETWidget::translateGestureEvent(const MSG &msg) +{ + GESTUREINFO gi; + gi.cbSize = sizeof(GESTUREINFO); + gi.dwFlags = 0; + gi.ptsLocation.x = 0; + gi.ptsLocation.y = 0; + gi.dwID = 0; + gi.dwInstanceID = 0; + gi.dwSequenceID = 0; + + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + BOOL bResult = qAppPriv->GetGestureInfo((HGESTUREINFO)msg.lParam, &gi); + + const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); + if (alienWidget && alienWidget->internalWinId()) + alienWidget = 0; + QWidget *widget = alienWidget ? alienWidget : this; + + QWinGestureEvent event; + event.sequenceId = gi.dwSequenceID; + event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); + if (bResult) { + switch (gi.dwID) { + case GID_BEGIN: + // we are not interested in this type of event. + break; + case GID_END: + event.gestureType = QWinGestureEvent::GestureEnd; + break; + case GID_ZOOM: + event.gestureType = QWinGestureEvent::Pinch; + break; + case GID_PAN: + event.gestureType = QWinGestureEvent::Pan; + break; + case GID_ROTATE: + case GID_TWOFINGERTAP: + case GID_ROLLOVER: + default: + break; + } + if (event.gestureType != QWinGestureEvent::None) + qt_sendSpontaneousEvent(widget, &event); + } else { + DWORD dwErr = GetLastError(); + if (dwErr > 0) + qWarning() << "translateGestureEvent: error = " << dwErr; + } + qAppPriv->CloseGestureInfoHandle((HGESTUREINFO)msg.lParam); + return true; +} + void QApplication::setCursorFlashTime(int msecs) { @@ -3785,7 +3790,7 @@ int QApplication::cursorFlashTime() void QApplication::setDoubleClickInterval(int ms) { -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE SetDoubleClickTime(ms); #endif QApplicationPrivate::mouse_double_click_time = ms; @@ -3817,11 +3822,7 @@ void QApplication::setWheelScrollLines(int n) #ifdef SPI_SETWHEELSCROLLLINES if (n < 0) n = 0; - QT_WA({ - SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0); - } , { - SystemParametersInfoA(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0); - }); + SystemParametersInfo(SPI_SETWHEELSCROLLLINES, (uint)n, 0, 0); #else QApplicationPrivate::wheel_scroll_lines = n; #endif @@ -3831,11 +3832,7 @@ int QApplication::wheelScrollLines() { #ifdef SPI_GETWHEELSCROLLLINES uint i = 3; - QT_WA({ - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0); - } , { - SystemParametersInfoA(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0); - }); + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, sizeof(uint), &i, 0); if (i > INT_MAX) i = INT_MAX; return i; @@ -3880,8 +3877,7 @@ bool QApplication::isEffectEnabled(Qt::UIEffect effect) if (QColormap::instance().depth() < 16) return false; - if (!effect_override && desktopSettingsAware() - && !(QSysInfo::WindowsVersion == QSysInfo::WV_95 || QSysInfo::WindowsVersion == QSysInfo::WV_NT)) { + if (!effect_override && desktopSettingsAware()) { // we know that they can be used when we are here BOOL enabled = false; UINT api; @@ -3890,33 +3886,22 @@ bool QApplication::isEffectEnabled(Qt::UIEffect effect) api = SPI_GETMENUANIMATION; break; case Qt::UI_FadeMenu: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - return false; api = SPI_GETMENUFADE; break; case Qt::UI_AnimateCombo: api = SPI_GETCOMBOBOXANIMATION; break; case Qt::UI_AnimateTooltip: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - api = SPI_GETMENUANIMATION; - else - api = SPI_GETTOOLTIPANIMATION; + api = SPI_GETTOOLTIPANIMATION; break; case Qt::UI_FadeTooltip: - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - return false; api = SPI_GETTOOLTIPFADE; break; default: api = SPI_GETUIEFFECTS; break; } - QT_WA({ - SystemParametersInfo(api, 0, &enabled, 0); - } , { - SystemParametersInfoA(api, 0, &enabled, 0); - }); + SystemParametersInfo(api, 0, &enabled, 0); return enabled; } @@ -3965,4 +3950,90 @@ void QSessionManager::cancel() #endif //QT_NO_SESSIONMANAGER + +qt_RegisterTouchWindowPtr QApplicationPrivate::RegisterTouchWindow = 0; +qt_GetTouchInputInfoPtr QApplicationPrivate::GetTouchInputInfo = 0; +qt_CloseTouchInputHandlePtr QApplicationPrivate::CloseTouchInputHandle = 0; + +void QApplicationPrivate::initializeMultitouch_sys() +{ + QLibrary library(QLatin1String("user32")); + // MinGW (g++ 3.4.5) accepts only C casts. + RegisterTouchWindow = (qt_RegisterTouchWindowPtr)(library.resolve("RegisterTouchWindow")); + GetTouchInputInfo = (qt_GetTouchInputInfoPtr)(library.resolve("GetTouchInputInfo")); + CloseTouchInputHandle = (qt_CloseTouchInputHandlePtr)(library.resolve("CloseTouchInputHandle")); + + touchInputIDToTouchPointID.clear(); +} + +void QApplicationPrivate::cleanupMultitouch_sys() +{ + touchInputIDToTouchPointID.clear(); +} + +bool QApplicationPrivate::translateTouchEvent(const MSG &msg) +{ + QWidget *widgetForHwnd = QWidget::find(msg.hwnd); + if (!widgetForHwnd) + return false; + + QRect screenGeometry = QApplication::desktop()->screenGeometry(widgetForHwnd); + + QList<QTouchEvent::TouchPoint> touchPoints; + + QVector<TOUCHINPUT> winTouchInputs(msg.wParam); + memset(winTouchInputs.data(), 0, sizeof(TOUCHINPUT) * winTouchInputs.count()); + Qt::TouchPointStates allStates = 0; + QApplicationPrivate::GetTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT)); + for (int i = 0; i < winTouchInputs.count(); ++i) { + const TOUCHINPUT &touchInput = winTouchInputs.at(i); + + int touchPointID = touchInputIDToTouchPointID.value(touchInput.dwID, -1); + if (touchPointID == -1) { + touchPointID = touchInputIDToTouchPointID.count(); + touchInputIDToTouchPointID.insert(touchInput.dwID, touchPointID); + } + + QTouchEvent::TouchPoint touchPoint(touchPointID); + + // update state + QPointF screenPos(qreal(touchInput.x) / qreal(100.), qreal(touchInput.y) / qreal(100.)); + QRectF screenRect; + if (touchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA) + screenRect.setSize(QSizeF(qreal(touchInput.cxContact) / qreal(100.), + qreal(touchInput.cyContact) / qreal(100.))); + screenRect.moveCenter(screenPos); + + Qt::TouchPointStates state; + if (touchInput.dwFlags & TOUCHEVENTF_DOWN) { + state = Qt::TouchPointPressed; + } else if (touchInput.dwFlags & TOUCHEVENTF_UP) { + state = Qt::TouchPointReleased; + } else { + state = (screenPos == touchPoint.screenPos() + ? Qt::TouchPointStationary + : Qt::TouchPointMoved); + } + if (touchInput.dwFlags & TOUCHEVENTF_PRIMARY) + state |= Qt::TouchPointPrimary; + touchPoint.setState(state); + touchPoint.setScreenRect(screenRect); + touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(), + screenPos.y() / screenGeometry.height())); + + allStates |= state; + + touchPoints.append(touchPoint); + } + QApplicationPrivate::CloseTouchInputHandle((HANDLE) msg.lParam); + + if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) { + // all touch points released, forget the ids we've seen, they may not be reused + touchInputIDToTouchPointID.clear(); + } + + translateRawTouchEvent(widgetForHwnd, QTouchEvent::TouchScreen, touchPoints); + return true; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 163ceb6..76138f8 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -117,7 +117,9 @@ extern "C" { #define XK_MISCELLANY #include <X11/keysymdef.h> +#if !defined(QT_NO_XINPUT) #include <X11/extensions/XI.h> +#endif #include <stdlib.h> #include <string.h> @@ -128,6 +130,16 @@ extern "C" { #include <private/qbackingstore_p.h> +#ifdef QT_RX71_MULTITOUCH +# include <qsocketnotifier.h> +# include <linux/input.h> +# include <errno.h> +#endif + +#if _POSIX_VERSION+0 < 200112L && !defined(Q_OS_BSD4) +# define QT_NO_UNSETENV +#endif + QT_BEGIN_NAMESPACE //#define X_NOT_BROKEN @@ -157,6 +169,8 @@ static const char * x11_atomnames = { "WM_TAKE_FOCUS\0" "_NET_WM_PING\0" "_NET_WM_CONTEXT_HELP\0" + "_NET_WM_SYNC_REQUEST\0" + "_NET_WM_SYNC_REQUEST_COUNTER\0" // ICCCM window state "WM_STATE\0" @@ -294,6 +308,10 @@ static const char * x11_atomnames = { // XEMBED "_XEMBED\0" "_XEMBED_INFO\0" + + "Wacom Stylus\0" + "Wacom Cursor\0" + "Wacom Eraser\0" }; Q_GUI_EXPORT QX11Data *qt_x11Data = 0; @@ -504,6 +522,7 @@ static Bool qt_xfixes_scanner(Display*, XEvent *event, XPointer arg) class QETWidget : public QWidget // event translator widget { public: + QWidgetPrivate* d_func() { return QWidget::d_func(); } bool translateMouseEvent(const XEvent *); void translatePaintEvent(const XEvent *); bool translateConfigEvent(const XEvent *); @@ -638,11 +657,13 @@ static int qt_x_errhandler(Display *dpy, XErrorEvent *err) break; default: +#if !defined(QT_NO_XINPUT) if (err->request_code == X11->xinput_major && err->error_code == (X11->xinput_errorbase + XI_BadDevice) && err->minor_code == 3 /* X_OpenDevice */) { return 0; } +#endif break; } @@ -714,6 +735,44 @@ static int qt_xio_errhandler(Display *) } #endif +#ifndef QT_NO_XSYNC +struct qt_sync_request_event_data +{ + WId window; +}; + +#if defined(Q_C_CALLBACKS) +extern "C" { +#endif + +static Bool qt_sync_request_scanner(Display*, XEvent *event, XPointer arg) +{ + qt_sync_request_event_data *data = + reinterpret_cast<qt_sync_request_event_data*>(arg); + if (event->type == ClientMessage && + event->xany.window == data->window && + event->xclient.message_type == ATOM(WM_PROTOCOLS) && + (Atom)event->xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST)) { + QWidget *w = QWidget::find(event->xany.window); + if (QTLWExtra *tlw = ((QETWidget*)w)->d_func()->maybeTopData()) { + const ulong timestamp = (const ulong) event->xclient.data.l[1]; + if (timestamp > X11->time) + X11->time = timestamp; + if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) { + tlw->syncRequestTimestamp = timestamp; + tlw->newCounterValueLo = event->xclient.data.l[2]; + tlw->newCounterValueHi = event->xclient.data.l[3]; + } + } + return true; + } + return false; +} + +#if defined(Q_C_CALLBACKS) +} +#endif +#endif // QT_NO_XSYNC static void qt_x11_create_intern_atoms() { @@ -754,6 +813,14 @@ Q_GUI_EXPORT void qt_x11_apply_settings_in_all_apps() PropModeReplace, (unsigned char *)stamp.data(), stamp.size()); } +static int kdeSessionVersion() +{ + static int kdeVersion = 0; + if (!kdeVersion) + kdeVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); + return kdeVersion; +} + /*! \internal Gets the current KDE 3 or 4 home path */ @@ -763,10 +830,9 @@ QString QApplicationPrivate::kdeHome() if (kdeHomePath.isEmpty()) { kdeHomePath = QString::fromLocal8Bit(qgetenv("KDEHOME")); if (kdeHomePath.isEmpty()) { - int kdeSessionVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); QDir homeDir(QDir::homePath()); QString kdeConfDir(QLatin1String("/.kde")); - if (4 == kdeSessionVersion && homeDir.exists(QLatin1String(".kde4"))) + if (4 == kdeSessionVersion() && homeDir.exists(QLatin1String(".kde4"))) kdeConfDir = QLatin1String("/.kde4"); kdeHomePath = QDir::homePath() + kdeConfDir; } @@ -835,13 +901,11 @@ bool QApplicationPrivate::x11_apply_settings() QApplicationPrivate::setSystemPalette(pal); } - int kdeSessionVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); - if (!appFont) { QFont font(QApplication::font()); QString fontDescription; // Override Qt font if KDE4 settings can be used - if (4 == kdeSessionVersion) { + if (4 == kdeSessionVersion()) { QSettings kdeSettings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); fontDescription = kdeSettings.value(QLatin1String("font")).toString(); if (fontDescription.isEmpty()) { @@ -871,29 +935,16 @@ bool QApplicationPrivate::x11_apply_settings() // read new QStyle QString stylename = settings.value(QLatin1String("style")).toString(); - if (stylename.isEmpty() && !QApplicationPrivate::styleOverride && X11->use_xrender) { - QStringList availableStyles = QStyleFactory::keys(); - // Override Qt style if KDE4 settings can be used - if (4 == kdeSessionVersion) { - QSettings kdeSettings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); - QString kde4Style = kdeSettings.value(QLatin1String("widgetStyle"), - QLatin1String("Oxygen")).toString(); - foreach (const QString &style, availableStyles) { - if (style.toLower() == kde4Style.toLower()) - stylename = kde4Style; - } - // Set QGtkStyle for GNOME - } else if (X11->desktopEnvironment == DE_GNOME) { - QString gtkStyleKey = QString::fromLatin1("GTK+"); - if (availableStyles.contains(gtkStyleKey)) - stylename = gtkStyleKey; - } + + + if (stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull() && X11->use_xrender) { + stylename = x11_desktop_style(); } static QString currentStyleName = stylename; if (QCoreApplication::startingUp()) { - if (!stylename.isEmpty() && !QApplicationPrivate::styleOverride) - QApplicationPrivate::styleOverride = new QString(stylename); + if (!stylename.isEmpty() && QApplicationPrivate::styleOverride.isNull()) + QApplicationPrivate::styleOverride = stylename; } else { if (currentStyleName != stylename) { currentStyleName = stylename; @@ -1044,10 +1095,8 @@ static void qt_set_input_encoding() } // Reads a KDE color setting -static QColor kdeColor(const QString &key) +static QColor kdeColor(const QString &key, const QSettings &kdeSettings) { - QSettings kdeSettings(QApplicationPrivate::kdeHome() + - QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); QVariant variant = kdeSettings.value(key); if (variant.isValid()) { QStringList values = variant.toStringList(); @@ -1266,36 +1315,40 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, } if (kdeColors) { + const QSettings theKdeSettings( + QApplicationPrivate::kdeHome() + + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); + // Setup KDE palette QColor color; - color = kdeColor(QLatin1String("buttonBackground")); + color = kdeColor(QLatin1String("buttonBackground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Button/BackgroundNormal")); + color = kdeColor(QLatin1String("Colors:Button/BackgroundNormal"), theKdeSettings); if (color.isValid()) btn = color; - color = kdeColor(QLatin1String("background")); + color = kdeColor(QLatin1String("background"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Window/BackgroundNormal")); + color = kdeColor(QLatin1String("Colors:Window/BackgroundNormal"), theKdeSettings); if (color.isValid()) bg = color; - color = kdeColor(QLatin1String("foreground")); + color = kdeColor(QLatin1String("foreground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/ForegroundNormal")); + color = kdeColor(QLatin1String("Colors:View/ForegroundNormal"), theKdeSettings); if (color.isValid()) { fg = color; } - color = kdeColor(QLatin1String("windowForeground")); + color = kdeColor(QLatin1String("windowForeground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Window/ForegroundNormal")); + color = kdeColor(QLatin1String("Colors:Window/ForegroundNormal"), theKdeSettings); if (color.isValid()) wfg = color; - color = kdeColor(QLatin1String("windowBackground")); + color = kdeColor(QLatin1String("windowBackground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/BackgroundNormal")); + color = kdeColor(QLatin1String("Colors:View/BackgroundNormal"), theKdeSettings); if (color.isValid()) base = color; } @@ -1314,31 +1367,47 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, } // Use KDE3 or KDE4 color settings if present if (kdeColors) { - QColor color = kdeColor(QLatin1String("selectBackground")); + const QSettings theKdeSettings( + QApplicationPrivate::kdeHome() + + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); + + QColor color = kdeColor(QLatin1String("selectBackground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Selection/BackgroundNormal")); + color = kdeColor(QLatin1String("Colors:Selection/BackgroundNormal"), theKdeSettings); if (color.isValid()) highlight = color; - color = kdeColor(QLatin1String("selectForeground")); + color = kdeColor(QLatin1String("selectForeground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Selection/ForegroundNormal")); + color = kdeColor(QLatin1String("Colors:Selection/ForegroundNormal"), theKdeSettings); if (color.isValid()) highlightText = color; - color = kdeColor(QLatin1String("alternateBackground")); + color = kdeColor(QLatin1String("alternateBackground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:View/BackgroundAlternate")); + color = kdeColor(QLatin1String("Colors:View/BackgroundAlternate"), theKdeSettings); if (color.isValid()) pal.setColor(QPalette::AlternateBase, color); else pal.setBrush(QPalette::AlternateBase, pal.base().color().darker(110)); - color = kdeColor(QLatin1String("buttonForeground")); + color = kdeColor(QLatin1String("buttonForeground"), theKdeSettings); if (!color.isValid()) - color = kdeColor(QLatin1String("Colors:Button/ForegroundNormal")); + color = kdeColor(QLatin1String("Colors:Button/ForegroundNormal"), theKdeSettings); if (color.isValid()) pal.setColor(QPalette::ButtonText, color); + + color = kdeColor(QLatin1String("linkColor"), theKdeSettings); + if (!color.isValid()) + color = kdeColor(QLatin1String("Colors:View/ForegroundLink"), theKdeSettings); + if (color.isValid()) + pal.setColor(QPalette::Link, color); + + color = kdeColor(QLatin1String("visitedLinkColor"), theKdeSettings); + if (!color.isValid()) + color = kdeColor(QLatin1String("Colors:View/ForegroundVisited"), theKdeSettings); + if (color.isValid()) + pal.setColor(QPalette::LinkVisited, color); } if (highlight.isValid() && highlightText.isValid()) { @@ -1579,6 +1648,7 @@ static PtrWacomConfigOpenDevice ptrWacomConfigOpenDevice = 0; static PtrWacomConfigGetRawParam ptrWacomConfigGetRawParam = 0; static PtrWacomConfigCloseDevice ptrWacomConfigCloseDevice = 0; static PtrWacomConfigTerm ptrWacomConfigTerm = 0; +Q_GLOBAL_STATIC(QByteArray, wacomDeviceName) #endif #endif @@ -1719,7 +1789,7 @@ void qt_init(QApplicationPrivate *priv, int, X11->pattern_fills[i].screen = -1; #endif - X11->startupId = X11->originalStartupId = 0; + X11->startupId = 0; int argc = priv->argc; char **argv = priv->argv; @@ -2077,6 +2147,13 @@ void qt_init(QApplicationPrivate *priv, int, #endif // QT_RUNTIME_XCURSOR #endif // QT_NO_XCURSOR +#ifndef QT_NO_XSYNC + int xsync_evbase, xsync_errbase; + int major, minor; + if (XSyncQueryExtension(X11->display, &xsync_evbase, &xsync_errbase)) + XSyncInitialize(X11->display, &major, &minor); +#endif // QT_NO_XSYNC + #ifndef QT_NO_XINERAMA #ifdef QT_RUNTIME_XINERAMA X11->ptrXineramaQueryExtension = 0; @@ -2348,13 +2425,6 @@ void qt_init(QApplicationPrivate *priv, int, XAxisInfoPtr a; XDevice *dev = 0; -#if !defined(Q_OS_IRIX) - // XFree86 divides a stylus and eraser into 2 devices, so we must do for both... - const QString XFREENAMESTYLUS = QLatin1String("stylus"); - const QString XFREENAMEPEN = QLatin1String("pen"); - const QString XFREENAMEERASER = QLatin1String("eraser"); -#endif - if (X11->ptrXListInputDevices) { devices = X11->ptrXListInputDevices(X11->display, &ndev); if (!devices) @@ -2369,18 +2439,19 @@ void qt_init(QApplicationPrivate *priv, int, gotStylus = false; gotEraser = false; - QString devName = QString::fromLocal8Bit(devs->name).toLower(); #if defined(Q_OS_IRIX) + QString devName = QString::fromLocal8Bit(devs->name).toLower(); if (devName == QLatin1String(WACOM_NAME)) { deviceType = QTabletEvent::Stylus; gotStylus = true; } #else - if (devName.startsWith(XFREENAMEPEN) - || devName.startsWith(XFREENAMESTYLUS)) { + if (devs->type == ATOM(XWacomStylus)) { deviceType = QTabletEvent::Stylus; + if (wacomDeviceName()->isEmpty()) + wacomDeviceName()->append(devs->name); gotStylus = true; - } else if (devName.startsWith(XFREENAMEERASER)) { + } else if (devs->type == ATOM(XWacomEraser)) { deviceType = QTabletEvent::XFreeEraser; gotEraser = true; } @@ -2516,10 +2587,15 @@ void qt_init(QApplicationPrivate *priv, int, #endif // QT_NO_TABLET X11->startupId = getenv("DESKTOP_STARTUP_ID"); - X11->originalStartupId = X11->startupId; - static char desktop_startup_id[] = "DESKTOP_STARTUP_ID="; - putenv(desktop_startup_id); - + if (X11->startupId) { +#ifndef QT_NO_UNSETENV + unsetenv("DESKTOP_STARTUP_ID"); +#else + // it's a small memory leak, however we won't crash if Qt is + // unloaded and someones tries to use the envoriment. + putenv(strdup("DESKTOP_STARTUP_ID=")); +#endif + } } else { // read some non-GUI settings when not using the X server... @@ -2578,31 +2654,49 @@ void qt_init(QApplicationPrivate *priv, int, /*! \internal */ -void QApplicationPrivate::x11_initialize_style() +QString QApplicationPrivate::x11_desktop_style() { - if (QApplicationPrivate::app_style) - return; + QString stylename; + QStringList availableStyles = QStyleFactory::keys(); + // Override Qt style if KDE4 settings can be used + if (4 == kdeSessionVersion()) { + QSettings kdeSettings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat); + QString kde4Style = kdeSettings.value(QLatin1String("widgetStyle"), + QLatin1String("Oxygen")).toString(); + foreach (const QString &style, availableStyles) { + if (style.toLower() == kde4Style.toLower()) + stylename = kde4Style; + } + // Set QGtkStyle for GNOME + } else if (X11->desktopEnvironment == DE_GNOME) { + QString gtkStyleKey = QString::fromLatin1("GTK+"); + if (availableStyles.contains(gtkStyleKey)) + stylename = gtkStyleKey; + } - switch(X11->desktopEnvironment) { + if (stylename.isEmpty()) { + switch(X11->desktopEnvironment) { case DE_KDE: if (X11->use_xrender) - QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("plastique")); + stylename = QLatin1String("plastique"); else - QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("windows")); + stylename = QLatin1String("windows"); break; case DE_GNOME: if (X11->use_xrender) - QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("cleanlooks")); + stylename = QLatin1String("cleanlooks"); else - QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("windows")); + stylename = QLatin1String("windows"); break; case DE_CDE: - QApplicationPrivate::app_style = QStyleFactory::create(QLatin1String("cde")); + stylename = QLatin1String("cde"); break; default: // Don't do anything break; + } } + return stylename; } void QApplicationPrivate::initializeWidgetPaletteHash() @@ -2633,10 +2727,6 @@ void qt_cleanup() #endif } - // restore original value back. This is also done in QWidgetPrivate::show_sys. - if (X11->originalStartupId) - putenv(X11->originalStartupId); - #ifndef QT_NO_XRENDER for (int i = 0; i < X11->solid_fill_count; ++i) { if (X11->solid_fills[i].picture) @@ -2971,7 +3061,7 @@ QWidget *QApplication::topLevelAt(const QPoint &p) void QApplication::syncX() { if (X11->display) - XSync(X11->display, False); // don't discard events + XSync(X11->display, False); // don't discard events } @@ -3109,6 +3199,19 @@ int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only) XSendEvent(event->xclient.display, event->xclient.window, False, SubstructureNotifyMask|SubstructureRedirectMask, event); } +#ifndef QT_NO_XSYNC + } else if (a == ATOM(_NET_WM_SYNC_REQUEST)) { + const ulong timestamp = (const ulong) event->xclient.data.l[1]; + if (timestamp > X11->time) + X11->time = timestamp; + if (QTLWExtra *tlw = w->d_func()->maybeTopData()) { + if (timestamp == CurrentTime || timestamp > tlw->syncRequestTimestamp) { + tlw->syncRequestTimestamp = timestamp; + tlw->newCounterValueLo = event->xclient.data.l[2]; + tlw->newCounterValueHi = event->xclient.data.l[3]; + } + } +#endif } } else if (event->xclient.message_type == ATOM(_QT_SCROLL_DONE)) { widget->translateScrollDoneEvent(event); @@ -3139,6 +3242,7 @@ int QApplication::x11ProcessEvent(XEvent* event) { Q_D(QApplication); QScopedLoopLevelCounter loopLevelCounter(d->threadData); + #ifdef ALIEN_DEBUG //qDebug() << "QApplication::x11ProcessEvent:" << event->type; #endif @@ -3349,19 +3453,10 @@ int QApplication::x11ProcessEvent(XEvent* event) QSize oldSize(w->size()); w->data->crect.setWidth(DisplayWidth(X11->display, scr)); w->data->crect.setHeight(DisplayHeight(X11->display, scr)); - QVarLengthArray<QRect> oldSizes(desktop->numScreens()); - for (int i = 0; i < desktop->numScreens(); ++i) - oldSizes[i] = desktop->screenGeometry(i); QResizeEvent e(w->size(), oldSize); QApplication::sendEvent(w, &e); - for (int i = 0; i < qMin(oldSizes.count(), desktop->numScreens()); ++i) { - if (oldSizes[i] != desktop->screenGeometry(i)) - emit desktop->resized(i); - } - for (int i = oldSizes.count(); i < desktop->numScreens(); ++i) - emit desktop->resized(i); // added - for (int i = desktop->numScreens(); i < oldSizes.count(); ++i) - emit desktop->resized(i); // removed + if (w != desktop) + QApplication::sendEvent(desktop, &e); } #endif // QT_NO_XRANDR @@ -4137,7 +4232,9 @@ bool QETWidget::translateMouseEvent(const XEvent *event) || ((nextEvent.type == EnterNotify || nextEvent.type == LeaveNotify) && qt_button_down == this) || (nextEvent.type == ClientMessage - && nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE))) { + && (nextEvent.xclient.message_type == ATOM(_QT_SCROLL_DONE) || + (nextEvent.xclient.message_type == ATOM(WM_PROTOCOLS) && + (Atom)nextEvent.xclient.data.l[0] == ATOM(_NET_WM_SYNC_REQUEST))))) { qApp->x11ProcessEvent(&nextEvent); continue; } else if (nextEvent.type != MotionNotify || @@ -4407,7 +4504,6 @@ bool QETWidget::translateMouseEvent(const XEvent *event) QMouseEvent e(type, pos, globalPos, button, buttons, modifiers); QApplicationPrivate::sendMouseEvent(widget, &e, alienWidget, this, &qt_button_down, qt_last_mouse_receiver); - if (type == QEvent::MouseButtonPress && button == Qt::RightButton && (openPopupCount == oldOpenPopupCount)) { @@ -4476,8 +4572,7 @@ void fetchWacomToolId(int &deviceType, qint64 &serialId) WACOMCONFIG *config = ptrWacomConfigInit(X11->display, 0); if (config == 0) return; - const char *name = "stylus"; // TODO get this from the X config instead (users may have called it differently) - WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, name); + WACOMDEVICE *device = ptrWacomConfigOpenDevice (config, wacomDeviceName()->constData()); if (device == 0) return; unsigned keys[1]; @@ -4535,6 +4630,46 @@ void fetchWacomToolId(int &deviceType, qint64 &serialId) } #endif +struct qt_tablet_motion_data +{ + Time timestamp; + int tabletMotionType; + bool error; // found a reason to stop searching +}; + +static Bool qt_mouseMotion_scanner(Display *, XEvent *event, XPointer arg) +{ + qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg; + if (data->error) + return false; + + if (event->type == MotionNotify) + return true; + + data->error = event->type != data->tabletMotionType; // we stop compression when another event gets in between. + return false; +} + +static Bool qt_tabletMotion_scanner(Display *, XEvent *event, XPointer arg) +{ + qt_tablet_motion_data *data = (qt_tablet_motion_data *) arg; + if (data->error) + return false; + + if (event->type == data->tabletMotionType) { + if (data->timestamp > 0) { + if ((reinterpret_cast<const XDeviceMotionEvent*>(event))->time > data->timestamp) { + data->error = true; + return false; + } + } + return true; + } + + data->error = event->type != MotionNotify; // we stop compression when another event gets in between. + return false; +} + bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet) { #if defined (Q_OS_IRIX) @@ -4561,7 +4696,6 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet qreal rotation = 0; int deviceType = QTabletEvent::NoDevice; int pointerType = QTabletEvent::UnknownPointer; - XEvent xinputMotionEvent; XEvent mouseMotionEvent; const XDeviceMotionEvent *motion = 0; XDeviceButtonEvent *button = 0; @@ -4569,8 +4703,6 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet QEvent::Type t; Qt::KeyboardModifiers modifiers = 0; bool reinsertMouseEvent = false; - bool neverFoundMouseEvent = true; - XEvent xinputMotionEventNext; XEvent mouseMotionEventSave; #if !defined (Q_OS_IRIX) XID device_id; @@ -4578,72 +4710,41 @@ bool QETWidget::translateXinputEvent(const XEvent *ev, QTabletDeviceData *tablet if (ev->type == tablet->xinput_motion) { motion = reinterpret_cast<const XDeviceMotionEvent*>(ev); - for (;;) { - // get the corresponding mouseMotionEvent for motion - if (XCheckTypedWindowEvent(X11->display, internalWinId(), MotionNotify, &mouseMotionEvent)) { + + // Do event compression. Skip over tablet+mouse move events if there are newer ones. + qt_tablet_motion_data tabletMotionData; + tabletMotionData.tabletMotionType = tablet->xinput_motion; + while (true) { + // Find first mouse event since we expect them in pairs inside Qt + tabletMotionData.error =false; + tabletMotionData.timestamp = 0; + if (XCheckIfEvent(X11->display, &mouseMotionEvent, &qt_mouseMotion_scanner, (XPointer) &tabletMotionData)) { mouseMotionEventSave = mouseMotionEvent; reinsertMouseEvent = true; - neverFoundMouseEvent = false; - - if (mouseMotionEvent.xmotion.time > motion->time) { - XEvent xinputMotionEventLoop = *ev; - - // xinput event is older than the mouse event --> search for the corresponding xinput event for the given mouse event - while (mouseMotionEvent.xmotion.time > (reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEventLoop))->time) { - if (XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventLoop)) { - xinputMotionEvent = xinputMotionEventLoop; - } - else { - break; - } - } - motion = reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent); - } - - // get the next xinputMotionEvent, for the next loop run - if (!XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventNext)) { - XPutBackEvent(X11->display, &mouseMotionEvent); - reinsertMouseEvent = false; - break; - } - - if (mouseMotionEvent.xmotion.time != motion->time) { - // reinsert in order - if (mouseMotionEvent.xmotion.time >= motion->time) { - XPutBackEvent(X11->display, &mouseMotionEvent); - XPutBackEvent(X11->display, &xinputMotionEventNext); - // next entry in queue is xinputMotionEventNext - } - else { - XPutBackEvent(X11->display, &xinputMotionEventNext); - XPutBackEvent(X11->display, &mouseMotionEvent); - // next entry in queue is mouseMotionEvent - } - reinsertMouseEvent = false; - break; - } - } - else { + } else { break; } - xinputMotionEvent = xinputMotionEventNext; - motion = (reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent)); - } + // Now discard any duplicate tablet events. + XEvent dummy; + tabletMotionData.error = false; + tabletMotionData.timestamp = mouseMotionEvent.xmotion.time; + while (XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) { + motion = reinterpret_cast<const XDeviceMotionEvent*>(&dummy); + } - if (reinsertMouseEvent) { - XPutBackEvent(X11->display, &mouseMotionEventSave); + // now check if there are more recent tablet motion events since we'll compress the current one with + // newer ones in that case + tabletMotionData.error = false; + tabletMotionData.timestamp = 0; + if (! XCheckIfEvent(X11->display, &dummy, &qt_tabletMotion_scanner, (XPointer) &tabletMotionData)) { + break; // done with compression + } + motion = reinterpret_cast<const XDeviceMotionEvent*>(&dummy); } - if (neverFoundMouseEvent) { - XEvent xinputMotionEventLoop; - bool eventFound = false; - // xinput event without mouseMotionEvent --> search the newest xinputMotionEvent - while (XCheckTypedWindowEvent(X11->display, internalWinId(), tablet->xinput_motion, &xinputMotionEventLoop)) { - xinputMotionEvent = xinputMotionEventLoop; - eventFound = true; - } - if (eventFound) motion = reinterpret_cast<const XDeviceMotionEvent*>(&xinputMotionEvent); + if (reinsertMouseEvent) { + XPutBackEvent(X11->display, &mouseMotionEventSave); } t = QEvent::TabletMove; @@ -5016,6 +5117,7 @@ bool QETWidget::translatePropertyEvent(const XEvent *event) return true; } + // // Paint event translation // @@ -5194,6 +5296,14 @@ bool QETWidget::translateConfigEvent(const XEvent *event) otherEvent.xconfigure.border_width; } } +#ifndef QT_NO_XSYNC + qt_sync_request_event_data sync_event; + sync_event.window = internalWinId(); + for (XEvent ev;;) { + if (!XCheckIfEvent(X11->display, &ev, &qt_sync_request_scanner, (XPointer)&sync_event)) + break; + } +#endif // QT_NO_XSYNC } QRect cr (geometry()); @@ -5279,6 +5389,20 @@ bool QETWidget::translateConfigEvent(const XEvent *event) if (d->extra && d->extra->topextra) d->extra->topextra->inTopLevelResize = false; } +#ifndef QT_NO_XSYNC + if (QTLWExtra *tlwExtra = d->maybeTopData()) { + if (tlwExtra->newCounterValueLo != 0 || tlwExtra->newCounterValueHi != 0) { + XSyncValue value; + XSyncIntsToValue(&value, + tlwExtra->newCounterValueLo, + tlwExtra->newCounterValueHi); + + XSyncSetCounter(X11->display, tlwExtra->syncUpdateCounter, value); + tlwExtra->newCounterValueHi = 0; + tlwExtra->newCounterValueLo = 0; + } + } +#endif return true; } @@ -5895,4 +6019,225 @@ void QSessionManager::requestPhase2() #endif // QT_NO_SESSIONMANAGER +#if defined(QT_RX71_MULTITOUCH) + +static inline int testBit(const char *array, int bit) +{ + return (array[bit/8] & (1<<(bit%8))); +} + +static int openRX71Device(const QByteArray &deviceName) +{ + int fd = open(deviceName, O_RDONLY | O_NONBLOCK); + if (fd == -1) { + fd = -errno; + return fd; + } + + // fetch the event type mask and check that the device reports absolute coordinates + char eventTypeMask[(EV_MAX + sizeof(char) - 1) * sizeof(char) + 1]; + memset(eventTypeMask, 0, sizeof(eventTypeMask)); + if (ioctl(fd, EVIOCGBIT(0, sizeof(eventTypeMask)), eventTypeMask) < 0) { + close(fd); + return -1; + } + if (!testBit(eventTypeMask, EV_ABS)) { + close(fd); + return -1; + } + + // make sure that we can get the absolute X and Y positions from the device + char absMask[(ABS_MAX + sizeof(char) - 1) * sizeof(char) + 1]; + memset(absMask, 0, sizeof(absMask)); + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absMask)), absMask) < 0) { + close(fd); + return -1; + } + if (!testBit(absMask, ABS_X) || !testBit(absMask, ABS_Y)) { + close(fd); + return -1; + } + + return fd; +} + +void QApplicationPrivate::initializeMultitouch_sys() +{ + Q_Q(QApplication); + + QByteArray deviceName = QByteArray("/dev/input/event"); + int currentDeviceNumber = 0; + for (;;) { + int fd = openRX71Device(QByteArray(deviceName + QByteArray::number(currentDeviceNumber++))); + if (fd == -ENOENT) { + // no more devices + break; + } + if (fd < 0) { + // not a touch device + continue; + } + + struct input_absinfo abs_x, abs_y, abs_z; + ioctl(fd, EVIOCGABS(ABS_X), &abs_x); + ioctl(fd, EVIOCGABS(ABS_Y), &abs_y); + ioctl(fd, EVIOCGABS(ABS_Z), &abs_z); + + int deviceNumber = allRX71TouchPoints.count(); + + QSocketNotifier *socketNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, q); + QObject::connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(_q_readRX71MultiTouchEvents())); + + RX71TouchPointState touchPointState = { + socketNotifier, + QTouchEvent::TouchPoint(deviceNumber), + + abs_x.minimum, abs_x.maximum, q->desktop()->screenGeometry().width(), + abs_y.minimum, abs_y.maximum, q->desktop()->screenGeometry().height(), + abs_z.minimum, abs_z.maximum + }; + allRX71TouchPoints.append(touchPointState); + } + + hasRX71MultiTouch = allRX71TouchPoints.count() > 1; + if (!hasRX71MultiTouch) { + for (int i = 0; i < allRX71TouchPoints.count(); ++i) { + QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier; + close(socketNotifier->socket()); + delete socketNotifier; + } + allRX71TouchPoints.clear(); + } +} + +void QApplicationPrivate::cleanupMultitouch_sys() +{ + hasRX71MultiTouch = false; + for (int i = 0; i < allRX71TouchPoints.count(); ++i) { + QSocketNotifier *socketNotifier = allRX71TouchPoints.at(i).socketNotifier; + close(socketNotifier->socket()); + delete socketNotifier; + } + allRX71TouchPoints.clear(); +} + +bool QApplicationPrivate::readRX71MultiTouchEvents(int deviceNumber) +{ + RX71TouchPointState &touchPointState = allRX71TouchPoints[deviceNumber]; + QSocketNotifier *socketNotifier = touchPointState.socketNotifier; + int fd = socketNotifier->socket(); + + QTouchEvent::TouchPoint &touchPoint = touchPointState.touchPoint; + + bool down = touchPoint.state() != Qt::TouchPointReleased; + if (down) + touchPoint.setState(Qt::TouchPointStationary); + + bool changed = false; + for (;;) { + struct input_event inputEvent; + int bytesRead = read(fd, &inputEvent, sizeof(inputEvent)); + if (bytesRead <= 0) + break; + if (bytesRead != sizeof(inputEvent)) { + qWarning("Qt: INTERNAL ERROR: short read in readRX71MultiTouchEvents()"); + return false; + } + + switch (inputEvent.type) { + case EV_SYN: + changed = true; + switch (touchPoint.state()) { + case Qt::TouchPointPressed: + case Qt::TouchPointReleased: + // make sure we don't compress pressed and releases with any other events + return changed; + default: + break; + } + continue; + case EV_KEY: + case EV_ABS: + break; + default: + qWarning("Qt: WARNING: unknown event type %d on multitouch device", inputEvent.type); + continue; + } + + QPointF screenPos = touchPoint.screenPos(); + switch (inputEvent.code) { + case BTN_TOUCH: + if (!down && inputEvent.value != 0) + touchPoint.setState(Qt::TouchPointPressed); + else if (down && inputEvent.value == 0) + touchPoint.setState(Qt::TouchPointReleased); + break; + case ABS_TOOL_WIDTH: + case ABS_VOLUME: + case ABS_PRESSURE: + // ignore for now + break; + case ABS_X: + { + qreal newValue = ((qreal(inputEvent.value - touchPointState.minX) + / qreal(touchPointState.maxX - touchPointState.minX)) + * touchPointState.scaleX); + screenPos.rx() = newValue; + touchPoint.setScreenPos(screenPos); + break; + } + case ABS_Y: + { + qreal newValue = ((qreal(inputEvent.value - touchPointState.minY) + / qreal(touchPointState.maxY - touchPointState.minY)) + * touchPointState.scaleY); + screenPos.ry() = newValue; + touchPoint.setScreenPos(screenPos); + break; + } + case ABS_Z: + { + // map Z (signal strength) to pressure for now + qreal newValue = (qreal(inputEvent.value - touchPointState.minZ) + / qreal(touchPointState.maxZ - touchPointState.minZ)); + touchPoint.setPressure(newValue); + break; + } + default: + qWarning("Qt: WARNING: unknown event code %d on multitouch device", inputEvent.code); + continue; + } + } + + if (down && touchPoint.state() != Qt::TouchPointReleased) + touchPoint.setState(changed ? Qt::TouchPointMoved : Qt::TouchPointStationary); + + return changed; +} + +void QApplicationPrivate::_q_readRX71MultiTouchEvents() +{ + // read touch events from all devices + bool changed = false; + for (int i = 0; i < allRX71TouchPoints.count(); ++i) + changed = readRX71MultiTouchEvents(i) || changed; + if (!changed) + return; + + QList<QTouchEvent::TouchPoint> touchPoints; + for (int i = 0; i < allRX71TouchPoints.count(); ++i) + touchPoints.append(allRX71TouchPoints.at(i).touchPoint); + + translateRawTouchEvent(0, QTouchEvent::TouchScreen, touchPoints); +} + +#else // !QT_RX71_MULTITOUCH + +void QApplicationPrivate::initializeMultitouch_sys() +{ } +void QApplicationPrivate::cleanupMultitouch_sys() +{ } + +#endif // QT_RX71_MULTITOUCH + QT_END_NAMESPACE diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 9e14a3c..d2b9991 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -50,6 +50,7 @@ #include "qvariant.h" #include "qbuffer.h" #include "qimage.h" +#include "qtextcodec.h" QT_BEGIN_NAMESPACE @@ -276,11 +277,12 @@ QClipboard::~QClipboard() */ QString QClipboard::text(QString &subtype, Mode mode) const { - const QMimeData *data = mimeData(mode); + const QMimeData *const data = mimeData(mode); if (!data) return QString(); + + const QStringList formats = data->formats(); if (subtype.isEmpty()) { - QStringList formats = data->formats(); if (formats.contains(QLatin1String("text/plain"))) subtype = QLatin1String("plain"); else { @@ -289,13 +291,21 @@ QString QClipboard::text(QString &subtype, Mode mode) const subtype = formats.at(i).mid(5); break; } + if (subtype.isEmpty()) + return QString(); } - } - if (subtype.isEmpty()) + } else if (!formats.contains(QLatin1String("text/") + subtype)) { return QString(); - if (subtype == QLatin1String("plain")) - return data->text(); - return QString::fromUtf8(data->data(QLatin1String("text/") + subtype)); + } + + const QByteArray rawData = data->data(QLatin1String("text/") + subtype); + + QTextCodec* codec = QTextCodec::codecForMib(106); // utf-8 is default + if (subtype == QLatin1String("html")) + codec = QTextCodec::codecForHtml(rawData, codec); + else + codec = QTextCodec::codecForUtfText(rawData, codec); + return codec->toUnicode(rawData); } /*! diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp index b7b57b8..45050b2 100644 --- a/src/gui/kernel/qclipboard_mac.cpp +++ b/src/gui/kernel/qclipboard_mac.cpp @@ -50,6 +50,7 @@ #include "qurl.h" #include <stdlib.h> #include <string.h> +#include "qt_cocoa_helpers_mac_p.h" QT_BEGIN_NAMESPACE @@ -525,8 +526,17 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const QString c_flavor = c->flavorFor(format); if(!c_flavor.isEmpty()) { // Handle text/plain a little differently. Try handling Unicode first. - if((c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") || c_flavor == QLatin1String("public.utf8-plain-text")) && - hasFlavor(QLatin1String("public.utf16-plain-text"))) + bool checkForUtf16 = (c_flavor == QLatin1String("com.apple.traditional-mac-plain-text") + || c_flavor == QLatin1String("public.utf8-plain-text")); + if (checkForUtf16 || c_flavor == QLatin1String("public.utf16-plain-text")) { + // Try to get the NSStringPboardType from NSPasteboard, newlines are mapped + // correctly (as '\n') in this data. The 'public.utf16-plain-text' type + // usually maps newlines to '\r' instead. + QString str = qt_mac_get_pasteboardString(); + if (!str.isEmpty()) + return str; + } + if (checkForUtf16 && hasFlavor(QLatin1String("public.utf16-plain-text"))) c_flavor = QLatin1String("public.utf16-plain-text"); QVariant ret; diff --git a/src/gui/kernel/qclipboard_win.cpp b/src/gui/kernel/qclipboard_win.cpp index 09b5448..f5aa088 100644 --- a/src/gui/kernel/qclipboard_win.cpp +++ b/src/gui/kernel/qclipboard_win.cpp @@ -200,7 +200,7 @@ HRESULT QtCeGetClipboard(IDataObject** obj) if (clipData == 0) { clipData = GetClipboardData(CF_UNICODETEXT); if (clipData != 0) - clipText = QString::fromUtf16((unsigned short *)clipData); + clipText = QString::fromWCharArray((wchar_t *)clipData); } else { clipText = QString::fromLatin1((const char*)clipData); } @@ -325,13 +325,7 @@ bool QClipboard::event(QEvent *e) } if (propagate && d->nextClipboardViewer) { - QT_WA({ - SendMessage(d->nextClipboardViewer, m->message, - m->wParam, m->lParam); - } , { - SendMessageA(d->nextClipboardViewer, m->message, - m->wParam, m->lParam); - }); + SendMessage(d->nextClipboardViewer, m->message, m->wParam, m->lParam); } return true; diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp index bbf8cdd..1ebc764 100644 --- a/src/gui/kernel/qclipboard_x11.cpp +++ b/src/gui/kernel/qclipboard_x11.cpp @@ -800,7 +800,7 @@ static Atom send_selection(QClipboardData *d, Atom target, Window window, Atom p QByteArray data; QByteArray fmt = X11->xdndAtomToString(target); - if (fmt.isEmpty() || !QInternalMimeData::hasFormatHelper(QString::fromAscii(fmt), d->source())) { // Not a MIME type we have + if (fmt.isEmpty()) { // Not a MIME type we have DEBUG("QClipboard: send_selection(): converting to type '%s' is not supported", fmt.data()); return XNone; } diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index bdc7ecb..1e0bbdf 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -85,6 +85,12 @@ QT_USE_NAMESPACE last resort (i.e., this is code that can potentially be removed). */ +- (void)toggleToolbarShown:(id)sender +{ + macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super toggleToolbarShown:sender]; +} + - (void)keyDown:(NSEvent *)theEvent { bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index e3ec30a..3e5bfb6 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -49,6 +49,7 @@ #include <private/qt_cocoa_helpers_mac_p.h> #include <private/qdnd_p.h> #include <private/qmacinputcontext_p.h> +#include <private/qmultitouch_mac_p.h> #include <qscrollarea.h> #include <qhash.h> @@ -196,6 +197,7 @@ extern "C" { if (self) { [self finishInitWithQWidget:widget widgetPrivate:widgetprivate]; } + composingText = new QString(); composing = false; sendKeyEvents = true; currentCustomTypes = 0; @@ -453,6 +455,7 @@ extern "C" { - (void)dealloc { + delete composingText; [[NSNotificationCenter defaultCenter] removeObserver:self]; delete currentCustomTypes; [self unregisterDraggedTypes]; @@ -547,15 +550,7 @@ extern "C" { qwidget->objectName().local8Bit().data()); #endif QPainter p(qwidget); - QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(qwidget->parent()); - QPoint scrollAreaOffset; - if (scrollArea && scrollArea->viewport() == qwidget) { - QAbstractScrollAreaPrivate *priv - = static_cast<QAbstractScrollAreaPrivate *>(qt_widget_private(scrollArea)); - scrollAreaOffset = priv->contentsOffset(); - p.translate(-scrollAreaOffset); - } - qwidgetprivate->paintBackground(&p, qrgn, scrollAreaOffset, + qwidgetprivate->paintBackground(&p, qrgn, qwidget->isWindow() ? QWidgetPrivate::DrawAsRoot : 0); p.end(); } @@ -696,7 +691,7 @@ extern "C" { } - (void)rightMouseDown:(NSEvent *)theEvent -{ +{ bool mouseOK = qt_mac_handleMouseEvent(self, theEvent, QEvent::MouseButtonPress, Qt::RightButton); if (!mouseOK) @@ -845,6 +840,62 @@ extern "C" { [super tabletPoint:tabletEvent]; } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +- (void)touchesBeganWithEvent:(NSEvent *)event; +{ + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); +} + +- (void)touchesMovedWithEvent:(NSEvent *)event; +{ + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); +} + +- (void)touchesEndedWithEvent:(NSEvent *)event; +{ + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); +} + +- (void)touchesCancelledWithEvent:(NSEvent *)event; +{ + bool all = qwidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + qt_translateRawTouchEvent(qwidget, QTouchEvent::TouchPad, QCocoaTouch::getCurrentTouchPointList(event, all)); +} + +- (void)magnifyWithEvent:(NSEvent *)event; +{ + Q_UNUSED(event); +// qDebug() << "magnifyWithEvent"; +} + +- (void)rotateWithEvent:(NSEvent *)event; +{ + Q_UNUSED(event); +// qDebug() << "rotateWithEvent"; +} + +- (void)swipeWithEvent:(NSEvent *)event; +{ + Q_UNUSED(event); +// qDebug() << "swipeWithEvent"; +} + +- (void)beginGestureWithEvent:(NSEvent *)event; +{ + Q_UNUSED(event); +// qDebug() << "beginGestureWithEvent"; +} + +- (void)endGestureWithEvent:(NSEvent *)event; +{ + Q_UNUSED(event); +// qDebug() << "endGestureWithEvent"; +} +#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + - (void)frameDidChange:(NSNotification *)note { Q_UNUSED(note); @@ -988,7 +1039,7 @@ extern "C" { - (void) insertText:(id)aString { - if (composing) { + if ([aString length]) { // Send the commit string to the widget. QString commitText; if ([aString isKindOfClass:[NSAttributedString class]]) { @@ -1002,6 +1053,7 @@ extern "C" { e.setCommitString(commitText); qt_sendSpontaneousEvent(qwidget, &e); } + composingText->clear(); } - (void) setMarkedText:(id)aString selectedRange:(NSRange)selRange @@ -1055,12 +1107,21 @@ extern "C" { attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, composingLength, format); } + *composingText = qtText; QInputMethodEvent e(qtText, attrs); qt_sendSpontaneousEvent(qwidget, &e); + if (!composingLength) + composing = false; } - (void) unmarkText { + if (composing) { + QInputMethodEvent e; + e.setCommitString(*composingText); + qt_sendSpontaneousEvent(qwidget, &e); + } + composingText->clear(); composing = false; } diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 24040ba..4762b17 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -85,6 +85,7 @@ Q_GUI_EXPORT bool composing; int composingLength; bool sendKeyEvents; + QString *composingText; QStringList *currentCustomTypes; NSInteger dragEnterSequence; } diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 7084416..eb08982 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -104,6 +104,12 @@ QT_USE_NAMESPACE last resort (i.e., this is code that can potentially be removed). */ +- (void)toggleToolbarShown:(id)sender +{ + macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); + [super toggleToolbarShown:sender]; +} + - (void)keyDown:(NSEvent *)theEvent { bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index 6fb5f5a..9cca0d6 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -403,7 +403,7 @@ void QCursorData::initialize() QCursor::QCursor() { if (!QCursorData::initialized) { - if (qApp->startingUp()) { + if (QApplication::startingUp()) { d = 0; return; } diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp index a81a857..26e395c 100644 --- a/src/gui/kernel/qcursor_win.cpp +++ b/src/gui/kernel/qcursor_win.cpp @@ -66,7 +66,7 @@ QCursorData::~QCursorData() { delete bm; delete bmm; -#if !defined(Q_OS_WINCE) || defined(GWES_ICONCURS) +#if !defined(Q_WS_WINCE) || defined(GWES_ICONCURS) if (hcurs) DestroyCursor(hcurs); #endif @@ -129,7 +129,7 @@ extern HBITMAP qt_createIconMask(const QBitmap &bitmap); static HCURSOR create32BitCursor(const QPixmap &pixmap, int hx, int hy) { HCURSOR cur = 0; -#if !defined(Q_OS_WINCE) +#if !defined(Q_WS_WINCE) QBitmap mask = pixmap.mask(); if (mask.isNull()) { mask = QBitmap(pixmap.size()); @@ -317,54 +317,50 @@ void QCursorData::update() phand_bits, phandm_bits }; - unsigned short *sh; + wchar_t *sh = 0; switch (cshape) { // map to windows cursor case Qt::ArrowCursor: - sh = (unsigned short*)IDC_ARROW; + sh = IDC_ARROW; break; case Qt::UpArrowCursor: - sh = (unsigned short*)IDC_UPARROW; + sh = IDC_UPARROW; break; case Qt::CrossCursor: - sh = (unsigned short*)IDC_CROSS; + sh = IDC_CROSS; break; case Qt::WaitCursor: - sh = (unsigned short*)IDC_WAIT; + sh = IDC_WAIT; break; case Qt::IBeamCursor: - sh = (unsigned short*)IDC_IBEAM; + sh = IDC_IBEAM; break; case Qt::SizeVerCursor: - sh = (unsigned short*)IDC_SIZENS; + sh = IDC_SIZENS; break; case Qt::SizeHorCursor: - sh = (unsigned short*)IDC_SIZEWE; + sh = IDC_SIZEWE; break; case Qt::SizeBDiagCursor: - sh = (unsigned short*)IDC_SIZENESW; + sh = IDC_SIZENESW; break; case Qt::SizeFDiagCursor: - sh = (unsigned short*)IDC_SIZENWSE; + sh = IDC_SIZENWSE; break; case Qt::SizeAllCursor: - sh = (unsigned short*)IDC_SIZEALL; + sh = IDC_SIZEALL; break; case Qt::ForbiddenCursor: - sh = (unsigned short*)IDC_NO; + sh = IDC_NO; break; case Qt::WhatsThisCursor: - sh = (unsigned short*)IDC_HELP; + sh = IDC_HELP; break; case Qt::BusyCursor: - sh = (unsigned short*)IDC_APPSTARTING; + sh = IDC_APPSTARTING; break; case Qt::PointingHandCursor: - if ((QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) > QSysInfo::WV_95 || - (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) > QSysInfo::WV_NT) { - sh = (unsigned short*)IDC_HAND; - break; - } - // fall through + sh = IDC_HAND; + break; case Qt::BlankCursor: case Qt::SplitVCursor: case Qt::SplitHCursor: @@ -407,7 +403,7 @@ void QCursorData::update() } int n = qMax(1, bbits.width() / 8); int h = bbits.height(); -#if !defined(Q_OS_WINCE) +#if !defined(Q_WS_WINCE) uchar* xBits = new uchar[h * n]; uchar* xMask = new uchar[h * n]; int x = 0; @@ -430,7 +426,7 @@ void QCursorData::update() xBits, xMask); delete [] xBits; delete [] xMask; -#elif defined(GWES_ICONCURS) // Q_OS_WINCE +#elif defined(GWES_ICONCURS) // Q_WS_WINCE // Windows CE only supports fixed cursor size. int sysW = GetSystemMetrics(SM_CXCURSOR); int sysH = GetSystemMetrics(SM_CYCURSOR); @@ -480,13 +476,11 @@ void QCursorData::update() qWarning("QCursor::update: Invalid cursor shape %d", cshape); return; } - // ### From MSDN: - // ### LoadCursor has been superseded by the LoadImage function. - QT_WA({ - hcurs = LoadCursorW(0, reinterpret_cast<const TCHAR *>(sh)); - } , { - hcurs = LoadCursorA(0, reinterpret_cast<const char*>(sh)); - }); +#ifdef Q_WS_WINCE + hcurs = LoadCursor(0, sh); +#else + hcurs = (HCURSOR)LoadImage(0, sh, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); +#endif } QT_END_NAMESPACE diff --git a/src/gui/kernel/qdesktopwidget.h b/src/gui/kernel/qdesktopwidget.h index 470f10a..a21ae9d 100644 --- a/src/gui/kernel/qdesktopwidget.h +++ b/src/gui/kernel/qdesktopwidget.h @@ -56,6 +56,9 @@ class QDesktopWidgetPrivate; class Q_GUI_EXPORT QDesktopWidget : public QWidget { Q_OBJECT + Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop) + Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged) + Q_PROPERTY(int primaryScreen READ primaryScreen) public: QDesktopWidget(); ~QDesktopWidget(); @@ -63,6 +66,7 @@ public: bool isVirtualDesktop() const; int numScreens() const; + int screenCount() const; int primaryScreen() const; int screenNumber(const QWidget *widget = 0) const; @@ -85,6 +89,7 @@ public: Q_SIGNALS: void resized(int); void workAreaResized(int); + void screenCountChanged(int); protected: void resizeEvent(QResizeEvent *e); @@ -97,6 +102,9 @@ private: friend class QApplicationPrivate; }; +inline int QDesktopWidget::screenCount() const +{ return numScreens(); } + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qdesktopwidget_mac.mm b/src/gui/kernel/qdesktopwidget_mac.mm index 2489fe4..705387d 100644 --- a/src/gui/kernel/qdesktopwidget_mac.mm +++ b/src/gui/kernel/qdesktopwidget_mac.mm @@ -97,15 +97,13 @@ QT_USE_NAMESPACE Q_GLOBAL_STATIC(QDesktopWidgetImplementation, qdesktopWidgetImplementation) QDesktopWidgetImplementation::QDesktopWidgetImplementation() - : appScreen(0), displays(0) + : appScreen(0) { onResize(); } QDesktopWidgetImplementation::~QDesktopWidgetImplementation() { - if (displays) - [displays release]; } QDesktopWidgetImplementation *QDesktopWidgetImplementation::instance() @@ -118,13 +116,7 @@ QRect QDesktopWidgetImplementation::availableRect(int screenIndex) const if (screenIndex < 0 || screenIndex >= screenCount) screenIndex = appScreen; - NSRect r = [[displays objectAtIndex:screenIndex] visibleFrame]; - NSRect primaryRect = [[displays objectAtIndex:0] frame]; - - const int flippedY = - r.origin.y + // account for position offset and - primaryRect.size.height - r.size.height; // height difference. - return QRectF(r.origin.x, flippedY, - r.size.width, r.size.height).toRect(); + return availableRects[screenIndex].toRect(); } QRect QDesktopWidgetImplementation::screenRect(int screenIndex) const @@ -132,22 +124,28 @@ QRect QDesktopWidgetImplementation::screenRect(int screenIndex) const if (screenIndex < 0 || screenIndex >= screenCount) screenIndex = appScreen; - NSRect r = [[displays objectAtIndex:screenIndex] frame]; - NSRect primaryRect = [[displays objectAtIndex:0] frame]; - - const int flippedY = - r.origin.y + // account for position offset and - primaryRect.size.height - r.size.height; // height difference. - return QRectF(r.origin.x, flippedY, - r.size.width, r.size.height).toRect(); + return screenRects[screenIndex].toRect(); } void QDesktopWidgetImplementation::onResize() { - if (displays) - [displays release]; - - displays = [[NSScreen screens] retain]; - screenCount = [displays count]; + QMacCocoaAutoReleasePool pool; + NSArray *displays = [NSScreen screens]; + screenCount = [displays count]; + + screenRects.clear(); + availableRects.clear(); + NSRect primaryRect = [[displays objectAtIndex:0] frame]; + for (int i = 0; i<screenCount; i++) { + NSRect r = [[displays objectAtIndex:i] frame]; + const int flippedY = - r.origin.y + // account for position offset and + primaryRect.size.height - r.size.height; // height difference. + screenRects.append(QRectF(r.origin.x, flippedY, + r.size.width, r.size.height)); + r = [[displays objectAtIndex:i] visibleFrame]; + availableRects.append(QRectF(r.origin.x, flippedY, + r.size.width, r.size.height)); + } } @@ -195,7 +193,7 @@ const QRect QDesktopWidget::screenGeometry(int screen) const int QDesktopWidget::screenNumber(const QWidget *widget) const { - QDesktopWidgetImplementation *d = qdesktopWidgetImplementation(); + QDesktopWidgetImplementation *d = qdesktopWidgetImplementation(); if (!widget) return d->appScreen; QRect frame = widget->frameGeometry(); @@ -216,7 +214,7 @@ int QDesktopWidget::screenNumber(const QWidget *widget) const int QDesktopWidget::screenNumber(const QPoint &point) const { - QDesktopWidgetImplementation *d = qdesktopWidgetImplementation(); + QDesktopWidgetImplementation *d = qdesktopWidgetImplementation(); int closestScreen = -1; int shortestDistance = INT_MAX; for (int i = 0; i < d->screenCount; ++i) { @@ -232,13 +230,25 @@ int QDesktopWidget::screenNumber(const QPoint &point) const void QDesktopWidget::resizeEvent(QResizeEvent *) { - QDesktopWidgetImplementation *d = qdesktopWidgetImplementation(); + QDesktopWidgetImplementation *d = qdesktopWidgetImplementation(); + + const int oldScreenCount = d->screenCount; + const QVector<QRectF> oldRects(d->screenRects); + const QVector<QRectF> oldWorks(d->availableRects); d->onResize(); - for (int i = 0; i < d->screenCount; ++i) { - emit resized(i); + for (int i = 0; i < qMin(oldScreenCount, d->screenCount); ++i) { + if (oldRects.at(i) != d->screenRects.at(i)) + emit resized(i); + } + for (int i = 0; i < qMin(oldScreenCount, d->screenCount); ++i) { + if (oldWorks.at(i) != d->availableRects.at(i)) + emit workAreaResized(i); } + + if (oldScreenCount != d->screenCount) + emit screenCountChanged(d->screenCount); } QT_END_NAMESPACE diff --git a/src/gui/kernel/qdesktopwidget_mac_p.h b/src/gui/kernel/qdesktopwidget_mac_p.h index 0fdc455..e9d5d9f 100644 --- a/src/gui/kernel/qdesktopwidget_mac_p.h +++ b/src/gui/kernel/qdesktopwidget_mac_p.h @@ -64,7 +64,8 @@ public: int appScreen; int screenCount; - NSArray *displays; + QVector<QRectF> availableRects; + QVector<QRectF> screenRects; QRect availableRect(int screenIndex) const; QRect screenRect(int screenIndex) const; diff --git a/src/gui/kernel/qdesktopwidget_win.cpp b/src/gui/kernel/qdesktopwidget_win.cpp index 115b4c5..a89e08f 100644 --- a/src/gui/kernel/qdesktopwidget_win.cpp +++ b/src/gui/kernel/qdesktopwidget_win.cpp @@ -45,7 +45,7 @@ #include "qlibrary.h" #include <qvector.h> #include <limits.h> -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE #include <sipapi.h> #endif #include "qwidget_p.h" @@ -92,7 +92,7 @@ QVector<QRect> *QDesktopWidgetPrivate::rects = 0; QVector<QRect> *QDesktopWidgetPrivate::workrects = 0; static int screen_number = 0; int QDesktopWidgetPrivate::refcount = 0; -#ifdef Q_OS_WINCE_WM +#ifdef Q_WS_WINCE_WM // Use SIP information, if available // SipGetInfo is not supported by SSDK (no definition!). static inline void qt_get_sip_info(QRect &rect) @@ -152,41 +152,27 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that) rects = new QVector<QRect>(); workrects = new QVector<QRect>(); + screenCount = 0; #ifndef Q_OS_WINCE - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - screenCount = 0; - // Trying to get the function pointers to Win98/2000 only functions - QLibrary user32Lib(QLatin1String("user32")); - if (!user32Lib.load()) - return; + QLibrary user32Lib(QLatin1String("user32")); + if (user32Lib.load()) { enumDisplayMonitors = (EnumFunc)user32Lib.resolve("EnumDisplayMonitors"); - QT_WA({ - getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW"); - } , { - getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoA"); - }); - - if (!enumDisplayMonitors || !getMonitorInfo) { - screenCount = GetSystemMetrics(80); // SM_CMONITORS - rects->resize(screenCount); - for (int i = 0; i < screenCount; ++i) - rects->replace(i, that->rect()); - return; - } - // Calls enumCallback - enumDisplayMonitors(0, 0, enumCallback, 0); - enumDisplayMonitors = 0; - getMonitorInfo = 0; - } else { - rects->resize(1); - rects->replace(0, that->rect()); - workrects->resize(1); - workrects->replace(0, that->rect()); + getMonitorInfo = (InfoFunc)user32Lib.resolve("GetMonitorInfoW"); } -#else - screenCount = 0; + if (!enumDisplayMonitors || !getMonitorInfo) { + screenCount = GetSystemMetrics(80); // SM_CMONITORS + rects->resize(screenCount); + for (int i = 0; i < screenCount; ++i) + rects->replace(i, that->rect()); + return; + } + // Calls enumCallback + enumDisplayMonitors(0, 0, enumCallback, 0); + enumDisplayMonitors = 0; + getMonitorInfo = 0; +#else QLibrary coreLib(QLatin1String("coredll")); if (coreLib.load()) { // CE >= 4.0 case @@ -208,7 +194,7 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that) SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); QRect qr = QRect(QPoint(r.left, r.top), QPoint(r.right - 1, r.bottom - 1)); -#if defined(Q_OS_WINCE_WM) +#if defined(Q_WS_WINCE_WM) qt_get_sip_info(qr); #endif @@ -222,7 +208,7 @@ void QDesktopWidgetPrivate::init(QDesktopWidget *that) enumDisplayMonitors(0, 0, enumCallback, 0); enumDisplayMonitors = 0; getMonitorInfo = 0; -#endif // Q_OS_WINCE +#endif // Q_WS_WINCE } QDesktopWidgetPrivate::~QDesktopWidgetPrivate() @@ -303,106 +289,99 @@ QWidget *QDesktopWidget::screen(int /* screen */) const QRect QDesktopWidget::availableGeometry(int screen) const { Q_D(const QDesktopWidget); -#ifdef Q_OS_WINCE_WM +#ifdef Q_WS_WINCE_WM for(int i=0; i < d->workrects->size(); ++i) qt_get_sip_info((*d->workrects)[i]); #endif - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - if (screen < 0 || screen >= d->screenCount) - screen = d->primaryScreen; + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; - return d->workrects->at(screen); - } else { - return d->workrects->at(d->primaryScreen); - } + return d->workrects->at(screen); } const QRect QDesktopWidget::screenGeometry(int screen) const { const QDesktopWidgetPrivate *d = d_func(); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - if (screen < 0 || screen >= d->screenCount) - screen = d->primaryScreen; + if (screen < 0 || screen >= d->screenCount) + screen = d->primaryScreen; - return d->rects->at(screen); - } else { - return d->rects->at(d->primaryScreen); - } + return d->rects->at(screen); } int QDesktopWidget::screenNumber(const QWidget *widget) const { Q_D(const QDesktopWidget); - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - if (!widget) - return d->primaryScreen; - QRect frame = widget->frameGeometry(); - if (!widget->isWindow()) - frame.moveTopLeft(widget->mapToGlobal(QPoint(0,0))); - - int maxSize = -1; - int maxScreen = -1; - - for (int i = 0; i < d->screenCount; ++i) { - QRect sect = d->rects->at(i).intersected(frame); - int size = sect.width() * sect.height(); - if (size > maxSize && sect.width() > 0 && sect.height() > 0) { - maxSize = size; - maxScreen = i; - } - } - return maxScreen; - } else { + if (!widget) return d->primaryScreen; + + QRect frame = widget->frameGeometry(); + if (!widget->isWindow()) + frame.moveTopLeft(widget->mapToGlobal(QPoint(0,0))); + + int maxSize = -1; + int maxScreen = -1; + + for (int i = 0; i < d->screenCount; ++i) { + QRect sect = d->rects->at(i).intersected(frame); + int size = sect.width() * sect.height(); + if (size > maxSize && sect.width() > 0 && sect.height() > 0) { + maxSize = size; + maxScreen = i; + } } + + return maxScreen; } int QDesktopWidget::screenNumber(const QPoint &point) const { Q_D(const QDesktopWidget); + int closestScreen = -1; - if (QSysInfo::WindowsVersion != QSysInfo::WV_95 && QSysInfo::WindowsVersion != QSysInfo::WV_NT) { - int shortestDistance = INT_MAX; - for (int i = 0; i < d->screenCount; ++i) { - int thisDistance = d->pointToRect(point, d->rects->at(i)); - if (thisDistance < shortestDistance) { - shortestDistance = thisDistance; - closestScreen = i; - } + int shortestDistance = INT_MAX; + + for (int i = 0; i < d->screenCount; ++i) { + int thisDistance = d->pointToRect(point, d->rects->at(i)); + if (thisDistance < shortestDistance) { + shortestDistance = thisDistance; + closestScreen = i; } } + return closestScreen; } void QDesktopWidget::resizeEvent(QResizeEvent *) { Q_D(QDesktopWidget); - QVector<QRect> oldrects; - oldrects = *d->rects; - QVector<QRect> oldworkrects; - oldworkrects = *d->workrects; + const QVector<QRect> oldrects(*d->rects); + const QVector<QRect> oldworkrects(*d->workrects); int oldscreencount = d->screenCount; QDesktopWidgetPrivate::cleanup(); QDesktopWidgetPrivate::init(this); -#ifdef Q_OS_WINCE_WM +#ifdef Q_WS_WINCE_WM for(int i=0; i < d->workrects->size(); ++i) qt_get_sip_info((*d->workrects)[i]); #endif for (int i = 0; i < qMin(oldscreencount, d->screenCount); ++i) { - QRect oldrect = oldrects[i]; - QRect newrect = d->rects->at(i); + const QRect oldrect = oldrects[i]; + const QRect newrect = d->rects->at(i); if (oldrect != newrect) emit resized(i); } for (int j = 0; j < qMin(oldscreencount, d->screenCount); ++j) { - QRect oldrect = oldworkrects[j]; - QRect newrect = d->workrects->at(j); + const QRect oldrect = oldworkrects[j]; + const QRect newrect = d->workrects->at(j); if (oldrect != newrect) emit workAreaResized(j); } + + if (oldscreencount != d->screenCount) { + emit screenCountChanged(d->screenCount); + } } #ifdef Q_CC_MSVC diff --git a/src/gui/kernel/qdesktopwidget_x11.cpp b/src/gui/kernel/qdesktopwidget_x11.cpp index 59d3239..1555fc0 100644 --- a/src/gui/kernel/qdesktopwidget_x11.cpp +++ b/src/gui/kernel/qdesktopwidget_x11.cpp @@ -372,7 +372,32 @@ int QDesktopWidget::screenNumber(const QPoint &point) const void QDesktopWidget::resizeEvent(QResizeEvent *event) { Q_D(QDesktopWidget); + int oldScreenCount = d->screenCount; + QVector<QRect> oldRects(oldScreenCount); + QVector<QRect> oldWorks(oldScreenCount); + for (int i = 0; i < oldScreenCount; ++i) { + oldRects[i] = d->rects[i]; + oldWorks[i] = d->workareas[i]; + } + d->init(); + + for (int i = 0; i < qMin(oldScreenCount, d->screenCount); ++i) { + if (oldRects.at(i) != d->rects[i]) + emit resized(i); + } + + // ### workareas are just reset by init, not filled with new values + // ### so this will not work correctly + for (int j = 0; j < qMin(oldScreenCount, d->screenCount); ++j) { + if (oldWorks.at(j) != d->workareas[j]) + emit workAreaResized(j); + } + + if (oldScreenCount != d->screenCount) { + emit screenCountChanged(d->screenCount); + } + qt_desktopwidget_workarea_dirty = true; QWidget::resizeEvent(event); } diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index 6e8b440..0622de2 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -368,7 +368,7 @@ QDragManager::~QDragManager() QDragManager *QDragManager::self() { - if (!instance && qApp && !qApp->closingDown()) + if (!instance && !QApplication::closingDown()) instance = new QDragManager; return instance; } diff --git a/src/gui/kernel/qdnd_mac.mm b/src/gui/kernel/qdnd_mac.mm index b244d84..99399da 100644 --- a/src/gui/kernel/qdnd_mac.mm +++ b/src/gui/kernel/qdnd_mac.mm @@ -405,12 +405,12 @@ bool QWidgetPrivate::qt_mac_dnd_event(uint kind, DragRef dragRef) SetDragDropAction(dragRef, qt_mac_dnd_map_qt_actions(qDEEvent.dropAction())); if (!qDEEvent.isAccepted()) - // The widget is simply not interrested in this + // The widget is simply not interested in this // drag. So tell carbon this by returning 'false'. We will then // not receive any further move, drop or leave events for this widget. return false; else { - // Documentation states that a drag move event is sendt immidiatly after + // Documentation states that a drag move event is sent immediately after // a drag enter event. So we do that. This will honor widgets overriding // 'dragMoveEvent' only, and not 'dragEnterEvent' QDragMoveEvent qDMEvent(q->mapFromGlobal(QPoint(mouse.h, mouse.v)), qtAllowed, dropdata, diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h index 0ca08b4..852c86c 100644 --- a/src/gui/kernel/qdnd_p.h +++ b/src/gui/kernel/qdnd_p.h @@ -65,7 +65,7 @@ #endif #if defined(Q_WS_WIN) -# include <windows.h> +# include <qt_windows.h> # include <objidl.h> #endif @@ -202,7 +202,7 @@ public: #endif }; -class Q_GUI_EXPORT QDragManager: public QObject { +class QDragManager: public QObject { Q_OBJECT QDragManager(); diff --git a/src/gui/kernel/qdnd_win.cpp b/src/gui/kernel/qdnd_win.cpp index d27dca8..70f89d2 100644 --- a/src/gui/kernel/qdnd_win.cpp +++ b/src/gui/kernel/qdnd_win.cpp @@ -154,9 +154,9 @@ QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) #ifdef QDND_DEBUG qDebug("QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)"); #ifndef Q_OS_WINCE - char buf[256] = {0}; - GetClipboardFormatNameA(pformatetc->cfFormat, buf, 255); - qDebug("CF = %d : %s", pformatetc->cfFormat, buf); + wchar_t buf[256] = {0}; + GetClipboardFormatName(pformatetc->cfFormat, buf, 255); + qDebug("CF = %d : %s", pformatetc->cfFormat, QString::fromWCharArray(buf)); #endif #endif @@ -398,52 +398,47 @@ void QOleDropSource::createCursors() int h = cpm.height(); if (!pm.isNull()) { - int x1 = qMin(-hotSpot.x(),0); - int x2 = qMax(pm.width()-hotSpot.x(),cpm.width()); - int y1 = qMin(-hotSpot.y(),0); - int y2 = qMax(pm.height()-hotSpot.y(),cpm.height()); + int x1 = qMin(-hotSpot.x(), 0); + int x2 = qMax(pm.width() - hotSpot.x(), cpm.width()); + int y1 = qMin(-hotSpot.y(), 0); + int y2 = qMax(pm.height() - hotSpot.y(), cpm.height()); - w = x2-x1+1; - h = y2-y1+1; + w = x2 - x1 + 1; + h = y2 - y1 + 1; } QRect srcRect = pm.rect(); QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y())); QPoint newHotSpot = hotSpot; -#if !defined(Q_OS_WINCE) || defined(GWES_ICONCURS) - bool limitedCursorSize = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) - || (QSysInfo::WindowsVersion == QSysInfo::WV_NT) - || (QSysInfo::WindowsVersion == QSysInfo::WV_CE); - - if (limitedCursorSize) { - // Limited cursor size - int reqw = GetSystemMetrics(SM_CXCURSOR); - int reqh = GetSystemMetrics(SM_CYCURSOR); - - QPoint hotspotInPM = newHotSpot - pmDest; - if (reqw < w) { - // Not wide enough - move objectpm right - qreal r = qreal(newHotSpot.x()) / w; - newHotSpot = QPoint(int(r * reqw), newHotSpot.y()); - if (newHotSpot.x() + cpm.width() > reqw) - newHotSpot.setX(reqw - cpm.width()); - - srcRect = QRect(QPoint(hotspotInPM.x() - newHotSpot.x(), srcRect.top()), QSize(reqw, srcRect.height())); - } - if (reqh < h) { - qreal r = qreal(newHotSpot.y()) / h; - newHotSpot = QPoint(newHotSpot.x(), int(r * reqh)); - if (newHotSpot.y() + cpm.height() > reqh) - newHotSpot.setY(reqh - cpm.height()); - - srcRect = QRect(QPoint(srcRect.left(), hotspotInPM.y() - newHotSpot.y()), QSize(srcRect.width(), reqh)); - } - // Always use system cursor size - w = reqw; - h = reqh; +#if defined(Q_OS_WINCE) + // Limited cursor size + int reqw = GetSystemMetrics(SM_CXCURSOR); + int reqh = GetSystemMetrics(SM_CYCURSOR); + + QPoint hotspotInPM = newHotSpot - pmDest; + if (reqw < w) { + // Not wide enough - move objectpm right + qreal r = qreal(newHotSpot.x()) / w; + newHotSpot = QPoint(int(r * reqw), newHotSpot.y()); + if (newHotSpot.x() + cpm.width() > reqw) + newHotSpot.setX(reqw - cpm.width()); + + srcRect = QRect(QPoint(hotspotInPM.x() - newHotSpot.x(), srcRect.top()), QSize(reqw, srcRect.height())); } + if (reqh < h) { + qreal r = qreal(newHotSpot.y()) / h; + newHotSpot = QPoint(newHotSpot.x(), int(r * reqh)); + if (newHotSpot.y() + cpm.height() > reqh) + newHotSpot.setY(reqh - cpm.height()); + + srcRect = QRect(QPoint(srcRect.left(), hotspotInPM.y() - newHotSpot.y()), QSize(srcRect.width(), reqh)); + } + // Always use system cursor size + w = reqw; + h = reqh; #endif + QPixmap newCursor(w, h); if (!pm.isNull()) { newCursor.fill(QColor(0, 0, 0, 0)); @@ -549,7 +544,7 @@ QOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) return ResultFromScode(DRAGDROP_S_DROP); } #endif - qApp->processEvents(); + QApplication::processEvents(); return NOERROR; } } diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index a15c20f..7b445ea 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -542,6 +542,8 @@ bool QX11Data::xdndMimeDataForAtom(Atom a, QMimeData *mimeData, QByteArray *data dm->xdndMimeTransferedPixmapIndex = (dm->xdndMimeTransferedPixmapIndex + 1) % 2; } + } else { + DEBUG("QClipboard: xdndMimeDataForAtom(): converting to type '%s' is not supported", qPrintable(atomName)); } } return data; @@ -622,28 +624,12 @@ QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const if (format == QLatin1String("image/ppm")) { if (a == XA_PIXMAP && data.size() == sizeof(Pixmap)) { Pixmap xpm = *((Pixmap*)data.data()); - Display *dpy = display; - Window r; - int x,y; - uint w,h,bw,d; if (!xpm) return QByteArray(); - XGetGeometry(dpy,xpm, &r,&x,&y,&w,&h,&bw,&d); + QPixmap qpm = QPixmap::fromX11Pixmap(xpm); QImageWriter imageWriter; - GC gc = XCreateGC(dpy, xpm, 0, 0); - QImage imageToWrite; - if (d == 1) { - QBitmap qbm(w,h); - XCopyArea(dpy,xpm,qbm.handle(),gc,0,0,w,h,0,0); - imageWriter.setFormat("PBMRAW"); - imageToWrite = qbm.toImage(); - } else { - QPixmap qpm(w,h); - XCopyArea(dpy,xpm,qpm.handle(),gc,0,0,w,h,0,0); - imageWriter.setFormat("PPMRAW"); - imageToWrite = qpm.toImage(); - } - XFreeGC(dpy,gc); + imageWriter.setFormat("PPMRAW"); + QImage imageToWrite = qpm.toImage(); QBuffer buf; buf.open(QIODevice::WriteOnly); imageWriter.setDevice(&buf); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index de4b2b9..4fc3643 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -49,6 +49,7 @@ #include "qmime.h" #include "qdnd_p.h" #include "qevent_p.h" +#include "qgesture.h" QT_BEGIN_NAMESPACE @@ -83,6 +84,13 @@ QInputEvent::~QInputEvent() \sa QApplication::keyboardModifiers() */ +/*! \fn void QInputEvent::setModifiers(Qt::KeyboardModifiers modifiers) + + \internal + + Sets the keyboard modifiers flags for this event. +*/ + /*! \class QMouseEvent \ingroup events @@ -106,6 +114,10 @@ QInputEvent::~QInputEvent() propagated up the parent widget chain until a widget accepts it with accept(), or an event filter consumes it. + \note If a mouse event is propagated to a \l{QWidget}{widget} for + which Qt::WA_NoMousePropagation has been set, that mouse event + will not be propagated further up the parent widget chain. + The state of the keyboard modifier keys can be found by calling the \l{QInputEvent::modifiers()}{modifiers()} function, inhertied from QInputEvent. @@ -861,6 +873,17 @@ bool QKeyEvent::matches(QKeySequence::StandardKey matchKey) const uint searchkey = (modifiers() | key()) & ~(Qt::KeypadModifier); //The keypad modifier should not make a difference uint platform = QApplicationPrivate::currentPlatform(); +#ifdef Q_WS_MAC + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + uint oldSearchKey = searchkey; + searchkey &= ~(Qt::ControlModifier | Qt::MetaModifier); + if (oldSearchKey & Qt::ControlModifier) + searchkey |= Qt::MetaModifier; + if (oldSearchKey & Qt::MetaModifier) + searchkey |= Qt::ControlModifier; + } +#endif + uint N = QKeySequencePrivate::numberOfKeyBindings; int first = 0; int last = N - 1; @@ -3070,7 +3093,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { << ", " << me->button() << ", " << hex << (int)me->buttons() << ", " << hex << (int)me->modifiers() - << ")"; + << ')'; } return dbg.space(); @@ -3091,7 +3114,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: dbg.nospace() << "QWheelEvent(" << static_cast<const QWheelEvent *>(e)->delta() - << ")"; + << ')'; return dbg.space(); #endif case QEvent::KeyPress: @@ -3117,7 +3140,7 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { << ", \"" << ke->text() << "\", " << ke->isAutoRepeat() << ", " << ke->count() - << ")"; + << ')'; } return dbg.space(); case QEvent::FocusIn: @@ -3507,4 +3530,504 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar) #endif +/*! \class QTouchEvent + \brief The QTouchEvent class contains parameters that describe a touch event +. + \since 4.6 + \ingroup events + + Touch events occur when pressing, releasing, or moving one or more + touch points on a touch device (such as a touch-screen or + track-pad), and if the widget has the Qt::WA_AcceptTouchEvents + attribute. + + All touch events are of type QEvent::TouchBegin, + QEvent::TouchUpdate, or QEvent::TouchEnd. The touchPoints() + function returns a list of all touch points contained in the event. + Information about each touch point can be retreived using the + QTouchEvent::TouchPoint class. + + Similar to QMouseEvent, Qt automatically grabs each touch point on + the first press inside a widget; the widget will receive all + updates for the touch point until it is released. Note that it is + possible for a widget to receive events for multiple touch points, + and that multiple widgets may be receiving touch events at the same + time. + + A touch event contains a special accept flag that indicates + whether the receiver wants the event. By default, the event is + accepted. You should call ignore() if the touch event is not handled by + your widget. A QEvent::TouchBegin event is propagated up the parent widget + chain until a widget accepts it with accept(), or an event filter + consumes it. If the QEvent::TouchBegin event is neither accepted nor consumed, + then mouse events are simulated from the state of the first touch + point. + + The Qt::TouchPointState enum describes the different states that a + touch point may have. + + QTouchEvent::TouchPoint Qt::TouchPointState Qt::WA_AcceptTouchEvents +*/ + +/*! \enum Qt::TouchPointState + \since 4.6 + + This enum represents the state of a touch point at the time the + QTouchEvent occurred. + + \value TouchPointPressed The touch point is now pressed. + \value TouchPointMoved The touch point moved. + \value TouchPointStationary The touch point did not move. + \value TouchPointReleased The touch point was released. + + \omitvalue TouchPointStateMask + \omitvalue TouchPointPrimary +*/ + +/*! \class QTouchEvent::TouchPoint + \brief The QTouchEvent::TouchPoint class provide information about a touch point in a QTouchEvent. + \since 4.6 +*/ + +/*! \enum QTouchEvent::DeviceType + \since 4.6 + + This enum represents the type of device that generated a QTouchEvent. + + \value TouchScreen In this type of device, the touch surface and display are integrated. This + means the surface and display typically have the same size, such that there + is a direct relationship between the touch points' physical positions and the + coordinate reported by QTouchEvent::TouchPoint. As a result, Qt allows the + user to interact directly with multiple QWidgets and QGraphicsItems at the + same time. + + \value TouchPad In this type of device, the touch surface is separate from the display. There + is not a direct relationship between the physical touch location and the + on-screen coordinates. Instead, they are calculated relative to the current + mouse position, and the user must use the touch-pad to move this reference + point. Unlike touch-screens, Qt allows users to only interact with a single + QWidget or QGraphicsItem at a time. +*/ + +/*! + Constructs a QTouchEvent with the given \a eventType, \a deviceType, and \a touchPoints. + The \a touchPointStates and \a modifiers are the current touch point states and keyboard + modifiers at the time of the event. +*/ +QTouchEvent::QTouchEvent(QEvent::Type eventType, + QTouchEvent::DeviceType deviceType, + Qt::KeyboardModifiers modifiers, + Qt::TouchPointStates touchPointStates, + const QList<QTouchEvent::TouchPoint> &touchPoints) + : QInputEvent(eventType, modifiers), + _widget(0), + _deviceType(deviceType), + _touchPointStates(touchPointStates), + _touchPoints(touchPoints) +{ } + +/*! + Destroys the QTouchEvent. +*/ +QTouchEvent::~QTouchEvent() +{ } + +/*! \fn QWidget *QTouchEvent::widget() const + + Returns the widget on which the event occurred. +*/ + + +/*! \fn Qt::TouchPointStates QTouchEvent::touchPointStates() const + + Returns a bitwise OR of all the touch point states for this event. +*/ + +/*! \fn const QList<QTouchEvent::TouchPoint> &QTouchEvent::touchPoints() const + + Returns the list of touch points contained in the touch event. +*/ + +/*! \fn void QTouchEvent::setWidget(QWidget *widget) + + \internal + + Sets the widget for this event. +*/ + +/*! \fn void QTouchEvent::setTouchPointStates(Qt::TouchPointStates touchPointStates) + + \internal + + Sets a bitwise OR of all the touch point states for this event. +*/ + +/*! \fn void QTouchEvent::setTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints) + + \internal + + Sets the list of touch points for this event. +*/ + +/*! \internal + + Constructs a QTouchEvent::TouchPoint for use in a QTouchEvent. +*/ +QTouchEvent::TouchPoint::TouchPoint(int id) + : d(new QTouchEventTouchPointPrivate(id)) +{ } + +/*! \internal + + Constructs a copy of \a other. +*/ +QTouchEvent::TouchPoint::TouchPoint(const QTouchEvent::TouchPoint &other) + : d(other.d) +{ + d->ref.ref(); +} + +/*! \internal + + Destroys the QTouchEvent::TouchPoint. +*/ +QTouchEvent::TouchPoint::~TouchPoint() +{ + if (!d->ref.deref()) + delete d; +} + +/*! + Returns the id number of this touch point. + + Id numbers are globally sequential, starting at zero, meaning the + first touch point in the application has id 0, the second has id 1, + and so on. +*/ +int QTouchEvent::TouchPoint::id() const +{ + return d->id; +} + +/*! + Returns the current state of this touch point. +*/ +Qt::TouchPointState QTouchEvent::TouchPoint::state() const +{ + return Qt::TouchPointState(int(d->state) & Qt::TouchPointStateMask); +} + +/*! + Returns true if this touch point is the primary touch point. The primary touch point is the + point for which the windowing system generates mouse events. +*/ +bool QTouchEvent::TouchPoint::isPrimary() const +{ + return (d->state & Qt::TouchPointPrimary) != 0; +} + +/*! + Returns the position of this touch point, relative to the widget + or item that received the event. +*/ +QPointF QTouchEvent::TouchPoint::pos() const +{ + return d->rect.center(); +} + +/*! + Returns the scene position of this touch point. +*/ +QPointF QTouchEvent::TouchPoint::scenePos() const +{ + return d->sceneRect.center(); +} + +/*! + Returns the screen position of this touch point. +*/ +QPointF QTouchEvent::TouchPoint::screenPos() const +{ + return d->screenRect.center(); +} + +/*! + Returns the position of this touch point. The coordinates are normalized to size of the touch + device, i.e. (0,0) is the top-left corner and (1,1) is the bottom-right corner. +*/ +QPointF QTouchEvent::TouchPoint::normalizedPos() const +{ + return d->normalizedPos; +} + +/*! + Returns the starting position of this touch point, relative to the + widget that received the event. +*/ +QPointF QTouchEvent::TouchPoint::startPos() const +{ + return d->startPos; +} + +/*! + Returns the starting scene position of this touch point. +*/ +QPointF QTouchEvent::TouchPoint::startScenePos() const +{ + return d->startScenePos; +} + +/*! + Returns the starting screen position of this touch point. +*/ +QPointF QTouchEvent::TouchPoint::startScreenPos() const +{ + return d->startScreenPos; +} + +/*! + Returns the starting position of this touch point. The coordinates are normalized to size of + the touch device, i.e. (0,0) is the top-left corner and (1,1) is the bottom-right corner. +*/ +QPointF QTouchEvent::TouchPoint::startNormalizedPos() const +{ + return d->startNormalizedPos; +} + +/*! + Returns the position of this touch point from the previous touch + event, relative to the widget that received the event. +*/ +QPointF QTouchEvent::TouchPoint::lastPos() const +{ + return d->lastPos; +} + +/*! + Returns the scene position of this touch point from the previous + touch event. +*/ +QPointF QTouchEvent::TouchPoint::lastScenePos() const +{ + return d->lastScenePos; +} + +/*! + Returns the screen position of this touch point from the previous + touch event. +*/ +QPointF QTouchEvent::TouchPoint::lastScreenPos() const +{ + return d->lastScreenPos; +} + +/*! + Returns the position of this touch point from the previous touch event. The coordinates are + normalized to size of the touch device, i.e. (0,0) is the top-left corner and (1,1) is the + bottom-right corner. +*/ +QPointF QTouchEvent::TouchPoint::lastNormalizedPos() const +{ + return d->lastNormalizedPos; +} + +/*! + Returns the rect for this touch point. The rect is centered around the point returned by pos(). + Note this function returns an empty rect if the device does not report touch point sizes. +*/ +QRectF QTouchEvent::TouchPoint::rect() const +{ + return d->rect; +} + +/*! + Returns the rect for this touch point in scene coordinates. +*/ +QRectF QTouchEvent::TouchPoint::sceneRect() const +{ + return d->sceneRect; +} + +/*! + Returns the rect for this touch point in screen coordinates. +*/ +QRectF QTouchEvent::TouchPoint::screenRect() const +{ + return d->screenRect; +} + +/*! + Returns the pressure of this touch point. The return value is in + the range 0.0 to 1.0. +*/ +qreal QTouchEvent::TouchPoint::pressure() const +{ + return d->pressure; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setId(int id) +{ + if (d->ref != 1) + d = d->detach(); + d->id = id; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setState(Qt::TouchPointStates state) +{ + if (d->ref != 1) + d = d->detach(); + d->state = state; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setPos(const QPointF &pos) +{ + if (d->ref != 1) + d = d->detach(); + d->rect.moveCenter(pos); +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setScenePos(const QPointF &scenePos) +{ + if (d->ref != 1) + d = d->detach(); + d->sceneRect.moveCenter(scenePos); +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setScreenPos(const QPointF &screenPos) +{ + if (d->ref != 1) + d = d->detach(); + d->screenRect.moveCenter(screenPos); +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setNormalizedPos(const QPointF &normalizedPos) +{ + if (d->ref != 1) + d = d->detach(); + d->normalizedPos = normalizedPos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setStartPos(const QPointF &startPos) +{ + if (d->ref != 1) + d = d->detach(); + d->startPos = startPos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setStartScenePos(const QPointF &startScenePos) +{ + if (d->ref != 1) + d = d->detach(); + d->startScenePos = startScenePos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setStartScreenPos(const QPointF &startScreenPos) +{ + if (d->ref != 1) + d = d->detach(); + d->startScreenPos = startScreenPos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setStartNormalizedPos(const QPointF &startNormalizedPos) +{ + if (d->ref != 1) + d = d->detach(); + d->startNormalizedPos = startNormalizedPos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setLastPos(const QPointF &lastPos) +{ + if (d->ref != 1) + d = d->detach(); + d->lastPos = lastPos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setLastScenePos(const QPointF &lastScenePos) +{ + if (d->ref != 1) + d = d->detach(); + d->lastScenePos = lastScenePos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setLastScreenPos(const QPointF &lastScreenPos) +{ + if (d->ref != 1) + d = d->detach(); + d->lastScreenPos = lastScreenPos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setLastNormalizedPos(const QPointF &lastNormalizedPos) +{ + if (d->ref != 1) + d = d->detach(); + d->lastNormalizedPos = lastNormalizedPos; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setRect(const QRectF &rect) +{ + if (d->ref != 1) + d = d->detach(); + d->rect = rect; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setSceneRect(const QRectF &sceneRect) +{ + if (d->ref != 1) + d = d->detach(); + d->sceneRect = sceneRect; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setScreenRect(const QRectF &screenRect) +{ + if (d->ref != 1) + d = d->detach(); + d->screenRect = screenRect; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setPressure(qreal pressure) +{ + if (d->ref != 1) + d = d->detach(); + d->pressure = pressure; +} + +/*! \internal */ +QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::TouchPoint &other) +{ + other.d->ref.ref(); + if (!d->ref.deref()) + delete d; + d = other.d; + return *this; +} + +/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const + Returns the touch device Type, which is of type + \l {QTouchEvent::DeviceType} {DeviceType}. + */ + +/*! \fn void QTouchEvent::setDeviceType(DeviceType deviceType) + Sets the device type to \a deviceType, which is of type + \l {QTouchEvent::DeviceType} {DeviceType}. + */ + + QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index c2cb05f..11843cb 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -52,6 +52,8 @@ #include <QtGui/qmime.h> #include <QtGui/qdrag.h> #include <QtCore/qvariant.h> +#include <QtCore/qmap.h> +#include <QtCore/qset.h> QT_BEGIN_HEADER @@ -60,6 +62,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) class QAction; +class QGesture; class Q_GUI_EXPORT QInputEvent : public QEvent { @@ -67,6 +70,7 @@ public: QInputEvent(Type type, Qt::KeyboardModifiers modifiers = Qt::NoModifier); ~QInputEvent(); inline Qt::KeyboardModifiers modifiers() const { return modState; } + inline void setModifiers(Qt::KeyboardModifiers modifiers) { modState = modifiers; } protected: Qt::KeyboardModifiers modState; }; @@ -719,6 +723,101 @@ inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ? inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);} #endif // QT_NO_SHORTCUT +class QTouchEventTouchPointPrivate; +class Q_GUI_EXPORT QTouchEvent : public QInputEvent +{ +public: + class Q_GUI_EXPORT TouchPoint + { + public: + TouchPoint(int id = -1); + TouchPoint(const QTouchEvent::TouchPoint &other); + ~TouchPoint(); + + int id() const; + + Qt::TouchPointState state() const; + bool isPrimary() const; + + QPointF pos() const; + QPointF startPos() const; + QPointF lastPos() const; + + QPointF scenePos() const; + QPointF startScenePos() const; + QPointF lastScenePos() const; + + QPointF screenPos() const; + QPointF startScreenPos() const; + QPointF lastScreenPos() const; + + QPointF normalizedPos() const; + QPointF startNormalizedPos() const; + QPointF lastNormalizedPos() const; + + QRectF rect() const; + QRectF sceneRect() const; + QRectF screenRect() const; + + qreal pressure() const; + + // internal + void setId(int id); + void setState(Qt::TouchPointStates state); + void setPos(const QPointF &pos); + void setScenePos(const QPointF &scenePos); + void setScreenPos(const QPointF &screenPos); + void setNormalizedPos(const QPointF &normalizedPos); + void setStartPos(const QPointF &startPos); + void setStartScenePos(const QPointF &startScenePos); + void setStartScreenPos(const QPointF &startScreenPos); + void setStartNormalizedPos(const QPointF &startNormalizedPos); + void setLastPos(const QPointF &lastPos); + void setLastScenePos(const QPointF &lastScenePos); + void setLastScreenPos(const QPointF &lastScreenPos); + void setLastNormalizedPos(const QPointF &lastNormalizedPos); + void setRect(const QRectF &rect); + void setSceneRect(const QRectF &sceneRect); + void setScreenRect(const QRectF &screenRect); + void setPressure(qreal pressure); + QTouchEvent::TouchPoint &operator=(const QTouchEvent::TouchPoint &other); + + private: + QTouchEventTouchPointPrivate *d; + }; + + enum DeviceType { + TouchScreen, + TouchPad + }; + + QTouchEvent(QEvent::Type eventType, + QTouchEvent::DeviceType deviceType = TouchScreen, + Qt::KeyboardModifiers modifiers = Qt::NoModifier, + Qt::TouchPointStates touchPointStates = 0, + const QList<QTouchEvent::TouchPoint> &touchPoints = QList<QTouchEvent::TouchPoint>()); + ~QTouchEvent(); + + inline QWidget *widget() const { return _widget; } + inline QTouchEvent::DeviceType deviceType() const { return _deviceType; } + inline Qt::TouchPointStates touchPointStates() const { return _touchPointStates; } + inline const QList<QTouchEvent::TouchPoint> &touchPoints() const { return _touchPoints; } + + // internal + inline void setWidget(QWidget *widget) { _widget = widget; } + inline void setDeviceType(DeviceType deviceType) { _deviceType = deviceType; } + inline void setTouchPointStates(Qt::TouchPointStates touchPointStates) { _touchPointStates = touchPointStates; } + inline void setTouchPoints(const QList<QTouchEvent::TouchPoint> &touchPoints) { _touchPoints = touchPoints; } + +protected: + QWidget *_widget; + QTouchEvent::DeviceType _deviceType; + Qt::TouchPointStates _touchPointStates; + QList<QTouchEvent::TouchPoint> _touchPoints; + + friend class QApplicationPrivate; +}; + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 77f7c4b..67441ea 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -43,6 +43,7 @@ #define QEVENT_P_H #include <QtCore/qglobal.h> +#include <QtGui/qevent.h> QT_BEGIN_NAMESPACE @@ -58,7 +59,7 @@ QT_BEGIN_NAMESPACE // // ### Qt 5: remove -class Q_GUI_EXPORT QKeyEventEx : public QKeyEvent +class QKeyEventEx : public QKeyEvent { public: QKeyEventEx(Type type, int key, Qt::KeyboardModifiers modifiers, @@ -76,7 +77,7 @@ protected: }; // ### Qt 5: remove -class Q_GUI_EXPORT QMouseEventEx : public QMouseEvent +class QMouseEventEx : public QMouseEvent { public: QMouseEventEx(Type type, const QPointF &pos, const QPoint &globalPos, @@ -89,6 +90,51 @@ protected: friend class QMouseEvent; }; +class QTouchEventTouchPointPrivate +{ +public: + inline QTouchEventTouchPointPrivate(int id) + : ref(1), + id(id), + state(Qt::TouchPointReleased), + pressure(qreal(-1.)) + { } + + inline QTouchEventTouchPointPrivate *detach() + { + QTouchEventTouchPointPrivate *d = new QTouchEventTouchPointPrivate(*this); + d->ref = 1; + if (!this->ref.deref()) + delete this; + return d; + } + + QAtomicInt ref; + int id; + Qt::TouchPointStates state; + QRectF rect, sceneRect, screenRect; + QPointF normalizedPos, + startPos, startScenePos, startScreenPos, startNormalizedPos, + lastPos, lastScenePos, lastScreenPos, lastNormalizedPos; + qreal pressure; +}; + +class QWinGestureEvent : public QEvent +{ +public: + enum Type { + None, + GestureEnd, + Pan, + Pinch + }; + + QWinGestureEvent() : QEvent(QEvent::WinGesture), gestureType(None), sequenceId(0) { } + Type gestureType; + QPoint position; + ulong sequenceId; +}; + QT_END_NAMESPACE #endif // QEVENT_P_H diff --git a/src/gui/kernel/qformlayout.cpp b/src/gui/kernel/qformlayout.cpp index de33f93..0b7656f 100644 --- a/src/gui/kernel/qformlayout.cpp +++ b/src/gui/kernel/qformlayout.cpp @@ -689,12 +689,16 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width) // are split. maxLabelWidth = 0; if (!wrapAllRows) { + int maxFieldMinWidth = 0; //the maximum minimum size of the field for (int i = 0; i < rr; ++i) { const QFormLayoutItem *label = m_matrix(i, 0); const QFormLayoutItem *field = m_matrix(i, 1); - if (label && (label->sizeHint.width() + (field ? field->minSize.width() : 0) <= width)) + if (label && field && label->sideBySide) maxLabelWidth = qMax(maxLabelWidth, label->sizeHint.width()); + if (field) + maxFieldMinWidth = qMax(maxFieldMinWidth, field->minSize.width() + field->sbsHSpace); } + maxLabelWidth = qMin(maxLabelWidth, width - maxFieldMinWidth); } else { maxLabelWidth = width; } diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp new file mode 100644 index 0000000..d53b419 --- /dev/null +++ b/src/gui/kernel/qgesture.cpp @@ -0,0 +1,296 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgesture.h" +#include <private/qgesture_p.h> +#include "qgraphicsitem.h" + +QT_BEGIN_NAMESPACE + + +class QEventFilterProxyGraphicsItem : public QGraphicsItem +{ +public: + QEventFilterProxyGraphicsItem(QGesture *g) + : gesture(g) + { + } + bool sceneEventFilter(QGraphicsItem *, QEvent *event) + { + return gesture ? gesture->filterEvent(event) : false; + } + QRectF boundingRect() const { return QRectF(); } + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) { } + +private: + QGesture *gesture; +}; + +/*! + \class QGesture + \since 4.6 + + \brief The QGesture class is the base class for implementing custom + gestures. + + This class represents both an object that recognizes a gesture out of a set + of input events (a gesture recognizer), and a gesture object itself that + can be used to get extended information about the triggered gesture. + + The class has a list of properties that can be queried by the user to get + some gesture-specific parameters (for example, an offset of a Pan gesture). + + Usually gesture recognizer implements a state machine, storing its state + internally in the recognizer object. The recognizer receives input events + through the \l{QGesture::}{filterEvent()} virtual function and decides + whether the event should change the state of the recognizer by emitting an + appropriate signal. + + Input events should be either fed to the recognizer one by one with a + filterEvent() function, or the gesture recognizer should be attached to an + object it filters events for by specifying it as a parent object. The + QGesture object installs itself as an event filter to the parent object + automatically, the unsetObject() function should be used to remove an event + filter from the parent object. To make a + gesture that operates on a QGraphicsItem, both the appropriate QGraphicsView + should be passed as a parent object and setGraphicsItem() functions should + be used to attach a gesture to a graphics item. + + This is a base class, to create a custom gesture type, you should subclass + it and implement its pure virtual functions. + + \sa QPanGesture, QTapAndHoldGesture +*/ + +/*! \fn bool QGesture::filterEvent(QEvent *event) + + Parses input \a event and emits a signal when detects a gesture. + + In your reimplementation of this function, if you want to filter the \a + event out, i.e. stop it being handled further, return true; otherwise + return false; + + This is a pure virtual function that needs to be implemented in subclasses. +*/ + +/*! \fn void QGesture::started() + + The signal is emitted when the gesture is started. Extended information + about the gesture is contained in the signal sender object. + + In addition to started(), a triggered() signal should also be emitted. +*/ + +/*! \fn void QGesture::triggered() + + The signal is emitted when the gesture is detected. Extended information + about the gesture is contained in the signal sender object. +*/ + +/*! \fn void QGesture::finished() + + The signal is emitted when the gesture is finished. Extended information + about the gesture is contained in the signal sender object. +*/ + +/*! \fn void QGesture::cancelled() + + The signal is emitted when the gesture is cancelled, for example the reset() + function is called while the gesture was in the process of emitting a + triggered() signal. Extended information about the gesture is contained in + the sender object. +*/ + + +/*! + Creates a new gesture handler object and marks it as a child of \a parent. + + The \a parent object is also the default event source for the gesture, + meaning that the gesture installs itself as an event filter for the \a + parent. + + \sa setGraphicsItem() +*/ +QGesture::QGesture(QObject *parent) + : QObject(*new QGesturePrivate, parent) +{ + if (parent) + installEventFilter(parent); +} + +/*! \internal + */ +QGesture::QGesture(QGesturePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + if (parent) + installEventFilter(parent); +} + +/*! + Destroys the gesture object. +*/ +QGesture::~QGesture() +{ +} + +/*! \internal + */ +bool QGesture::eventFilter(QObject *receiver, QEvent *event) +{ + Q_D(QGesture); + if (d->graphicsItem && receiver == parent()) + return false; + return filterEvent(event); +} + +/*! + \property QGesture::state + + \brief The current state of the gesture. +*/ + +/*! + Returns the gesture recognition state. + */ +Qt::GestureState QGesture::state() const +{ + return d_func()->state; +} + +/*! + Sets this gesture's recognition state to \a state. + */ +void QGesture::setState(Qt::GestureState state) +{ + d_func()->state = state; +} + +/*! + \property QGesture::startPos + + \brief The start position of the gesture (if relevant). +*/ +QPoint QGesture::startPos() const +{ + return d_func()->startPos; +} + +void QGesture::setStartPos(const QPoint &point) +{ + d_func()->startPos = point; +} + +/*! + \property QGesture::lastPos + + \brief The last recorded position of the gesture (if relevant). +*/ +QPoint QGesture::lastPos() const +{ + return d_func()->lastPos; +} + +void QGesture::setLastPos(const QPoint &point) +{ + d_func()->lastPos = point; +} + +/*! + \property QGesture::pos + + \brief The current position of the gesture (if relevant). +*/ +QPoint QGesture::pos() const +{ + return d_func()->pos; +} + +void QGesture::setPos(const QPoint &point) +{ + d_func()->pos = point; +} + +/*! + Sets the \a graphicsItem the gesture is filtering events for. + + The gesture will install an event filter to the \a graphicsItem and + redirect them to the filterEvent() function. + + \sa graphicsItem() +*/ +void QGesture::setGraphicsItem(QGraphicsItem *graphicsItem) +{ + Q_D(QGesture); + if (d->graphicsItem && d->eventFilterProxyGraphicsItem) + d->graphicsItem->removeSceneEventFilter(d->eventFilterProxyGraphicsItem); + d->graphicsItem = graphicsItem; + if (!d->eventFilterProxyGraphicsItem) + d->eventFilterProxyGraphicsItem = new QEventFilterProxyGraphicsItem(this); + if (graphicsItem) + graphicsItem->installSceneEventFilter(d->eventFilterProxyGraphicsItem); +} + +/*! + Returns the graphics item the gesture is filtering events for. + + \sa setGraphicsItem() +*/ +QGraphicsItem* QGesture::graphicsItem() const +{ + return d_func()->graphicsItem; +} + +/*! \fn void QGesture::reset() + + Resets the internal state of the gesture. This function might be called by + the filterEvent() implementation in a derived class, or by the user to + cancel a gesture. The base class implementation emits the cancelled() + signal if the state() of the gesture wasn't empty. +*/ +void QGesture::reset() +{ + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h new file mode 100644 index 0000000..cc46916 --- /dev/null +++ b/src/gui/kernel/qgesture.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGESTURE_H +#define QGESTURE_H + +#include "qobject.h" +#include "qlist.h" +#include "qdatetime.h" +#include "qpoint.h" +#include "qrect.h" +#include "qmetatype.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QGraphicsItem; +class QGesturePrivate; +class Q_GUI_EXPORT QGesture : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QGesture) + + Q_PROPERTY(Qt::GestureState state READ state) + + Q_PROPERTY(QPoint startPos READ startPos WRITE setStartPos) + Q_PROPERTY(QPoint lastPos READ lastPos WRITE setLastPos) + Q_PROPERTY(QPoint pos READ pos WRITE setPos) + +public: + explicit QGesture(QObject *parent = 0); + ~QGesture(); + + virtual bool filterEvent(QEvent *event) = 0; + + void setGraphicsItem(QGraphicsItem *); + QGraphicsItem *graphicsItem() const; + + virtual void reset(); + + Qt::GestureState state() const; + void setState(Qt::GestureState state); + + QPoint startPos() const; + void setStartPos(const QPoint &point); + QPoint lastPos() const; + void setLastPos(const QPoint &point); + QPoint pos() const; + void setPos(const QPoint &point); + +protected: + QGesture(QGesturePrivate &dd, QObject *parent); + bool eventFilter(QObject*, QEvent*); + +Q_SIGNALS: + void started(); + void triggered(); + void finished(); + void cancelled(); + +private: + friend class QWidget; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGESTURE_H diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h new file mode 100644 index 0000000..99f572f --- /dev/null +++ b/src/gui/kernel/qgesture_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGESTURE_P_H +#define QGESTURE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qrect.h" +#include "qpoint.h" +#include "qdatetime.h" +#include "qgesture.h" +#include "private/qobject_p.h" + +QT_BEGIN_NAMESPACE + +class QObject; +class QGraphicsItem; +class QGesturePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QGesture) + +public: + QGesturePrivate() + : graphicsItem(0), eventFilterProxyGraphicsItem(0), state(Qt::NoGesture) + { + } + + void init(const QPoint &startPos, const QPoint &lastPos, + const QPoint &pos) + { + this->startPos = startPos; + this->lastPos = lastPos; + this->pos = pos; + } + + QGraphicsItem *graphicsItem; + QGraphicsItem *eventFilterProxyGraphicsItem; + + Qt::GestureState state; + + QPoint startPos; + QPoint lastPos; + QPoint pos; +}; + +QT_END_NAMESPACE + +#endif // QGESTURE_P_H diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp index c986117..011c726 100644 --- a/src/gui/kernel/qguifunctions_wince.cpp +++ b/src/gui/kernel/qguifunctions_wince.cpp @@ -215,13 +215,7 @@ int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID l return ret; } -bool qt_wince_TextOutW(HDC hdc, int x, int y, LPWSTR lpString, UINT c) -{ - return ExtTextOutW(hdc, x, y, 0, NULL, lpString, c, NULL); -} - - -HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCTSTR, LPCTSTR file, LPCTSTR params, LPCTSTR dir, int showCmd) +HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd) { SHELLEXECUTEINFO info; info.hwnd = hwnd; @@ -253,17 +247,11 @@ COLORREF qt_wince_PALETTEINDEX( WORD /*wPaletteIndex*/) return 0; } -BOOL qt_wince_TextOut( HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString ) -{ - return ExtTextOut( hdc, nXStart, nYStart - 16, 0, NULL, lpString, cbString, NULL ); -} - // Internal Qt ----------------------------------------------------- bool qt_wince_is_platform(const QString &platformString) { - TCHAR tszPlatform[64]; - if (SystemParametersInfo(SPI_GETPLATFORMTYPE, - sizeof(tszPlatform)/sizeof(*tszPlatform),tszPlatform,0)) - if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform)) + wchar_t tszPlatform[64]; + if (SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(tszPlatform) / sizeof(wchar_t), tszPlatform, 0)) + if (0 == _tcsicmp(reinterpret_cast<const wchar_t *> (platformString.utf16()), tszPlatform)) return true; return false; } @@ -316,8 +304,8 @@ void qt_wince_maximize(QWidget *widget) void qt_wince_minimize(HWND hwnd) { - uint exstyle = GetWindowLongW(hwnd, GWL_EXSTYLE); - uint style = GetWindowLongW(hwnd, GWL_STYLE); + uint exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); + uint style = GetWindowLong(hwnd, GWL_STYLE); RECT rect; RECT crect = {0,0,0,0}; GetWindowRect(hwnd, &rect); diff --git a/src/gui/kernel/qguifunctions_wince.h b/src/gui/kernel/qguifunctions_wince.h index bcf2004..234c8c6 100644 --- a/src/gui/kernel/qguifunctions_wince.h +++ b/src/gui/kernel/qguifunctions_wince.h @@ -73,10 +73,6 @@ int qt_wince_GetDIBits(HDC, HBITMAP, uint, uint, void*, LPBITMAPINFO, uint); // QWidget #define SW_SHOWMINIMIZED SW_MINIMIZE -// QPaintEngine -bool qt_wince_TextOutW(HDC, int, int, LPWSTR, UINT); -#define TextOutW(a,b,c,d,e) qt_wince_TextOutW(a,b,c,d,e) - // QRegion #define ALTERNATE 0 #define WINDING 1 @@ -128,7 +124,7 @@ typedef struct tagTTPOLYCURVE #define TT_PRIM_CSPLINE 3 #define ANSI_VAR_FONT 12 -HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCTSTR operation, LPCTSTR file, LPCTSTR params, LPCTSTR dir, int showCmd); +HINSTANCE qt_wince_ShellExecute(HWND hwnd, LPCWSTR operation, LPCWSTR file, LPCWSTR params, LPCWSTR dir, int showCmd); #define ShellExecute(a,b,c,d,e,f) qt_wince_ShellExecute(a,b,c,d,e,f) @@ -150,8 +146,6 @@ HWND qt_wince_SetClipboardViewer( // Graphics --------------------------------------------------------- COLORREF qt_wince_PALETTEINDEX( WORD wPaletteIndex ); #define PALETTEINDEX(a) qt_wince_PALETTEINDEX(a) -BOOL qt_wince_TextOut( HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString ); -#define TextOut(a,b,c,d,e) qt_wince_TextOut(a,b,c,d,e) #endif // Q_OS_WINCE #endif // QGUIFUNCTIONS_WCE_H diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp index fd177e3..ca631a6 100644 --- a/src/gui/kernel/qkeymapper.cpp +++ b/src/gui/kernel/qkeymapper.cpp @@ -116,6 +116,4 @@ QKeyMapperPrivate *qt_keymapper_private() return QKeyMapper::instance()->d_func(); } -Q_GUI_EXPORT QList<int> qt_keymapper_possibleKeys(QKeyEvent *e) { return QKeyMapper::instance()->possibleKeys(e); } - QT_END_NAMESPACE diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index 4868daf..017c13c 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -48,6 +48,7 @@ #include <qinputcontext.h> #include <private/qkeymapper_p.h> #include <private/qapplication_p.h> +#include <private/qmacinputcontext_p.h> QT_BEGIN_NAMESPACE @@ -160,6 +161,14 @@ Qt::KeyboardModifiers qt_mac_get_modifiers(int keys) ret |= Qt::KeyboardModifier(qt_mac_modifier_symbols[i].qt_code); } } + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + Qt::KeyboardModifiers oldModifiers = ret; + ret &= ~(Qt::MetaModifier | Qt::ControlModifier); + if (oldModifiers & Qt::ControlModifier) + ret |= Qt::MetaModifier; + if (oldModifiers & Qt::MetaModifier) + ret |= Qt::ControlModifier; + } return ret; } static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys) @@ -176,6 +185,15 @@ static int qt_mac_get_mac_modifiers(Qt::KeyboardModifiers keys) ret |= qt_mac_modifier_symbols[i].mac_code; } } + + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + int oldModifiers = ret; + ret &= ~(controlKeyBit | cmdKeyBit); + if (oldModifiers & controlKeyBit) + ret |= cmdKeyBit; + if (oldModifiers & cmdKeyBit) + ret |= controlKeyBit; + } return ret; } void qt_mac_send_modifiers_changed(quint32 modifiers, QObject *object) @@ -480,7 +498,8 @@ static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, #ifdef QT_MAC_USE_COCOA if (outHandled) { qt_mac_eat_unicode_key = false; - CallNextEventHandler(er, keyEvent); + if (er) + CallNextEventHandler(er, keyEvent); *outHandled = qt_mac_eat_unicode_key; } #endif @@ -692,8 +711,14 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e return true; } - if (qApp->inputContext() && qApp->inputContext()->isComposing()) + if (qApp->inputContext() && qApp->inputContext()->isComposing()) { + if (ekind == kEventRawKeyDown) { + QMacInputContext *context = qobject_cast<QMacInputContext*>(qApp->inputContext()); + if (context) + context->setLastKeydownEvent(event); + } return false; + } //get modifiers Qt::KeyboardModifiers modifiers; int qtKey; @@ -721,7 +746,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e //is it of use to text services? If so we won't bother //with a QKeyEvent. qt_mac_eat_unicode_key = false; - CallNextEventHandler(er, event); + if (er) + CallNextEventHandler(er, event); extern bool qt_mac_menubar_is_open(); if (qt_mac_eat_unicode_key || qt_mac_menubar_is_open()) { return true; diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp index e40dfa0..0998631 100644 --- a/src/gui/kernel/qkeymapper_win.cpp +++ b/src/gui/kernel/qkeymapper_win.cpp @@ -41,7 +41,7 @@ #include "qkeymapper_p.h" -#include <windows.h> +#include <qt_windows.h> #include <qdebug.h> #include <private/qevent_p.h> #include <private/qlocale_p.h> @@ -57,9 +57,7 @@ QT_BEGIN_NAMESPACE // Implemented elsewhere extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); -Q_CORE_EXPORT bool winPostMessage(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -Q_CORE_EXPORT bool winPeekMessage(MSG* msg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, - UINT wRemoveMsg); + extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); #ifndef LANG_PASHTO #define LANG_PASHTO 0x63 @@ -467,12 +465,7 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, Q_ASSERT(vk > 0 && vk < 256); int code = 0; QChar unicodeBuffer[5]; - int res = 0; - if (QSysInfo::WindowsVersion < QSysInfo::WV_NT) - res = ToAscii(vk, scancode, kbdBuffer, reinterpret_cast<LPWORD>(unicodeBuffer), 0); - else - res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0); - + int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0); if (res) code = unicodeBuffer[0].toUpper().unicode(); @@ -504,38 +497,6 @@ static inline int asciiToKeycode(char a, int state) return a & 0xff; } -static int inputcharset = CP_ACP; -static inline QChar wmchar_to_unicode(DWORD c) -{ - // qt_winMB2QString is the generalization of this function. - QT_WA({ - return QChar((ushort)c); - } , { - char mb[2]; - mb[0] = c & 0xff; - mb[1] = 0; - WCHAR wc[1]; - MultiByteToWideChar(inputcharset, MB_PRECOMPOSED, mb, -1, wc, 1); - return QChar(wc[0]); - }); -} - -static inline QChar imechar_to_unicode(DWORD c) -{ - // qt_winMB2QString is the generalization of this function. - QT_WA({ - return QChar((ushort)c); - } , { - char mb[3]; - mb[0] = (c >> 8) & 0xff; - mb[1] = c & 0xff; - mb[2] = 0; - WCHAR wc[1]; - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mb, -1, wc, 1); - return QChar(wc[0]); - }); -} - static inline bool isModifierKey(int code) { return (code >= Qt::Key_Shift) && (code <= Qt::Key_ScrollLock); @@ -635,43 +596,15 @@ void QKeyMapperPrivate::clearMappings() /* MAKELCID()'s first argument is a WORD, and GetKeyboardLayout() * returns a DWORD. */ -// LCID newLCID = MAKELCID(DWORD(GetKeyboardLayout(0)), SORT_DEFAULT); + + LCID newLCID = MAKELCID((DWORD)GetKeyboardLayout(0), SORT_DEFAULT); // keyboardInputLocale = qt_localeFromLCID(newLCID); - LCID newLCID = MAKELCID( - reinterpret_cast<long>(GetKeyboardLayout(0)), - SORT_DEFAULT - ); - keyboardInputLocale = qt_localeFromLCID(newLCID); + bool bidi = false; -#ifdef UNICODE - if (QSysInfo::WindowsVersion >= QSysInfo::WV_2000) { - WCHAR wchLCIDFontSig[16]; - if (GetLocaleInfoW(newLCID, - LOCALE_FONTSIGNATURE, - &wchLCIDFontSig[0], - (sizeof(wchLCIDFontSig)/sizeof(WCHAR))) - && (wchLCIDFontSig[7] & (WCHAR)0x0800)) + wchar_t LCIDFontSig[16]; + if (GetLocaleInfo(newLCID, LOCALE_FONTSIGNATURE, LCIDFontSig, sizeof(LCIDFontSig) / sizeof(wchar_t)) + && (LCIDFontSig[7] & (wchar_t)0x0800)) bidi = true; - } else -#endif //UNICODE - { - if (newLCID == 0x0859 || //Sindhi (Arabic script) - newLCID == 0x0460) //Kashmiri (Arabic script) - bidi = true;; - - switch (PRIMARYLANGID(newLCID)) - { - case LANG_ARABIC: - case LANG_HEBREW: - case LANG_URDU: - case LANG_FARSI: - case LANG_PASHTO: - //case LANG_UIGHUR: - case LANG_SYRIAC: - case LANG_DIVEHI: - bidi = true; - } - } keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight; } @@ -760,7 +693,7 @@ void QKeyMapperPrivate::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 keyLayout[vk_key]->qtKey[8] = fallbackKey; // If this vk_key a Dead Key - if (MapVirtualKey(vk_key, 2) & 0x80008000) { // (High-order dead key on Win 95 is 0x8000) + if (MapVirtualKey(vk_key, 2) & 0x80000000) { // Push a Space, then the original key through the low-level ToAscii functions. // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of // the keyboard driver By doing the following, we set the keyboard driver state back to what @@ -837,13 +770,13 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9); quint32 nModifiers = 0; - if (QSysInfo::WindowsVersion < QSysInfo::WV_NT || QSysInfo::WindowsVersion & QSysInfo::WV_CE_based) { +#if defined(QT_OS_WINCE) nModifiers |= (GetKeyState(VK_SHIFT ) < 0 ? ShiftAny : 0); nModifiers |= (GetKeyState(VK_CONTROL) < 0 ? ControlAny : 0); nModifiers |= (GetKeyState(VK_MENU ) < 0 ? AltAny : 0); nModifiers |= (GetKeyState(VK_LWIN ) < 0 ? MetaLeft : 0); nModifiers |= (GetKeyState(VK_RWIN ) < 0 ? MetaRight : 0); - } else { +#else // Map native modifiers to some bit representation nModifiers |= (GetKeyState(VK_LSHIFT ) & 0x80 ? ShiftLeft : 0); nModifiers |= (GetKeyState(VK_RSHIFT ) & 0x80 ? ShiftRight : 0); @@ -857,7 +790,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool nModifiers |= (GetKeyState(VK_CAPITAL ) & 0x01 ? CapsLock : 0); nModifiers |= (GetKeyState(VK_NUMLOCK ) & 0x01 ? NumLock : 0); nModifiers |= (GetKeyState(VK_SCROLL ) & 0x01 ? ScrollLock : 0); - } +#endif // QT_OS_WINCE + if (msg.lParam & ExtendedKey) nModifiers |= msg.lParam & ExtendedKey; @@ -870,12 +804,12 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey bool isDeadKey = isADeadKey(msg.wParam, state) - || MapVirtualKey(msg.wParam, 2) & 0x80008000; // High-order on 95 is 0x8000 + || MapVirtualKey(msg.wParam, 2) & 0x80000000; // A multi-character key not found by our look-ahead if (msgType == WM_CHAR) { QString s; - QChar ch = wmchar_to_unicode(msg.wParam); + QChar ch = QChar((ushort)msg.wParam); if (!ch.isNull()) s += ch; @@ -886,7 +820,7 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool // Input method characters not found by our look-ahead else if (msgType == WM_IME_CHAR) { QString s; - QChar ch = imechar_to_unicode(msg.wParam); + QChar ch = QChar((ushort)msg.wParam); if (!ch.isNull()) s += ch; @@ -917,8 +851,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool } } else if (msgType == WM_KEYUP) { if (dirStatus == VK_LSHIFT - && (msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL) - || msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT))) { + && ((msg.wParam == VK_SHIFT && GetKeyState(VK_LCONTROL)) + || (msg.wParam == VK_CONTROL && GetKeyState(VK_LSHIFT)))) { k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_L, 0, QString(), false, 0, scancode, msg.wParam, nModifiers); @@ -927,8 +861,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool scancode, msg.wParam, nModifiers); dirStatus = 0; } else if (dirStatus == VK_RSHIFT - && (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL) - || msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT))) { + && ( (msg.wParam == VK_SHIFT && GetKeyState(VK_RCONTROL)) + || (msg.wParam == VK_CONTROL && GetKeyState(VK_RSHIFT)))) { k0 = q->sendKeyEvent(widget, grab, QEvent::KeyPress, Qt::Key_Direction_R, 0, QString(), false, 0, scancode, msg.wParam, nModifiers); @@ -1050,11 +984,9 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool : msgType == WM_IME_KEYDOWN ? WM_IME_CHAR : WM_SYSCHAR); QChar uch; - if (winPeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { + if (PeekMessage(&wm_char, 0, charType, charType, PM_REMOVE)) { // Found a ?_CHAR - uch = charType == WM_IME_CHAR - ? imechar_to_unicode(wm_char.wParam) - : wmchar_to_unicode(wm_char.wParam); + uch = QChar((ushort)wm_char.wParam); if (msgType == WM_SYSKEYDOWN && uch.isLetter() && (msg.lParam & KF_ALTDOWN)) uch = uch.toLower(); // (See doc of WM_SYSCHAR) Alt-letter if (!code && !uch.row()) @@ -1067,7 +999,7 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool // to find the correct key using the current message parameters & keyboard state. if (uch.isNull() && msgType == WM_IME_KEYDOWN) { BYTE keyState[256]; - WCHAR newKey[3] = {0}; + wchar_t newKey[3] = {0}; GetKeyboardState(keyState); int val = ToUnicode(vk_key, scancode, keyState, newKey, 2, 0); if (val == 1) { @@ -1085,18 +1017,10 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool uch = QChar(QLatin1Char(0x7f)); // Windows doesn't know this one. } else { if (msgType != WM_SYSKEYDOWN || !code) { - UINT map; - QT_WA({ - map = MapVirtualKey(msg.wParam, 2); - } , { - map = MapVirtualKeyA(msg.wParam, 2); - // High-order bit is 0x8000 on '95 - if (map & 0x8000) - map = (map^0x8000)|0x80000000; - }); + UINT map = MapVirtualKey(msg.wParam, 2); // If the high bit of the return value is set, it's a deadkey if (!(map & 0x80000000)) - uch = wmchar_to_unicode((DWORD)map); + uch = QChar((ushort)map); } } if (!code && !uch.row()) @@ -1237,6 +1161,8 @@ bool QKeyMapper::sendKeyEvent(QWidget *widget, bool grab, if (QApplicationPrivate::instance()->qt_tryAccelEvent(widget, &a)) return true; } +#else + Q_UNUSED(grab); #endif if (!widget->isEnabled()) return false; diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 22dd30b..d27eacd 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -105,20 +105,39 @@ static bool operator<(int key, const MacSpecialKey &entry) static const MacSpecialKey * const MacSpecialKeyEntriesEnd = entries + NumEntries; -static QChar macSymbolForQtKey(int key) +QChar qt_macSymbolForQtKey(int key) { const MacSpecialKey *i = qBinaryFind(entries, MacSpecialKeyEntriesEnd, key); if (i == MacSpecialKeyEntriesEnd) return QChar(); - return QChar(i->macSymbol); + ushort macSymbol = i->macSymbol; + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) + && (macSymbol == kControlUnicode || macSymbol == kCommandUnicode)) { + if (macSymbol == kControlUnicode) + macSymbol = kCommandUnicode; + else + macSymbol = kControlUnicode; + } + + return QChar(macSymbol); } static int qtkeyForMacSymbol(const QChar ch) { + const ushort unicode = ch.unicode(); for (int i = 0; i < NumEntries; ++i) { const MacSpecialKey &entry = entries[i]; - if (entry.macSymbol == ch.unicode()) - return entry.key; + if (entry.macSymbol == unicode) { + int key = entry.key; + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) + && (unicode == kControlUnicode || unicode == kCommandUnicode)) { + if (unicode == kControlUnicode) + key = Qt::Key_Control; + else + key = Qt::Key_Meta; + } + return key; + } } return -1; } @@ -126,7 +145,7 @@ static int qtkeyForMacSymbol(const QChar ch) #else static bool qt_sequence_no_mnemonics = false; #endif -void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; } +void Q_AUTOTEST_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemonics = !b; } /*! \class QKeySequence @@ -213,12 +232,14 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni \row \i Open \i Ctrl+O \i Ctrl+O \i Ctrl+O \i Ctrl+O \row \i Close \i Ctrl+F4, Ctrl+W \i Ctrl+W, Ctrl+F4 \i Ctrl+W \i Ctrl+W \row \i Save \i Ctrl+S \i Ctrl+S \i Ctrl+S \i Ctrl+S + \row \i Quit \i \i Ctrl+Q \i Qtrl+Q \i Qtrl+Q \row \i SaveAs \i \i Ctrl+Shift+S \i \i Ctrl+Shift+S \row \i New \i Ctrl+N \i Ctrl+N \i Ctrl+N \i Ctrl+N \row \i Delete \i Del \i Del, Meta+D \i Del, Ctrl+D \i Del, Ctrl+D \row \i Cut \i Ctrl+X, Shift+Del \i Ctrl+X \i Ctrl+X, F20, Shift+Del \i Ctrl+X, F20, Shift+Del \row \i Copy \i Ctrl+C, Ctrl+Ins \i Ctrl+C \i Ctrl+C, F16, Ctrl+Ins \i Ctrl+C, F16, Ctrl+Ins \row \i Paste \i Ctrl+V, Shift+Ins \i Ctrl+V \i Ctrl+V, F18, Shift+Ins \i Ctrl+V, F18, Shift+Ins + \row \i Preferences \i \i Ctrl+, \i \i \row \i Undo \i Ctrl+Z, Alt+Backspace \i Ctrl+Z \i Ctrl+Z, F14 \i Ctrl+Z, F14 \row \i Redo \i Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \i Ctrl+Shift+Z, Ctrl+Y \i Ctrl+Shift+Z \i Ctrl+Shift+Z \row \i Back \i Alt+Left, Backspace \i Ctrl+[ \i Alt+Left \i Alt+Left @@ -521,6 +542,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = { {QKeySequence::FindPrevious, 1, Qt::SHIFT | Qt::Key_F3, QApplicationPrivate::KB_Win}, {QKeySequence::ZoomIn, 1, Qt::CTRL | Qt::Key_Plus, QApplicationPrivate::KB_All}, {QKeySequence::NextChild, 0, Qt::CTRL | Qt::Key_Comma, QApplicationPrivate::KB_KDE}, + {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, QApplicationPrivate::KB_Mac}, {QKeySequence::ZoomOut, 1, Qt::CTRL | Qt::Key_Minus, QApplicationPrivate::KB_All}, {QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::Key_Period, QApplicationPrivate::KB_KDE}, {QKeySequence::HelpContents, 1, Qt::CTRL | Qt::Key_Question, QApplicationPrivate::KB_Mac}, @@ -538,6 +560,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = { {QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, QApplicationPrivate::KB_All}, {QKeySequence::Open, 1, Qt::CTRL | Qt::Key_O, QApplicationPrivate::KB_All}, {QKeySequence::Print, 1, Qt::CTRL | Qt::Key_P, QApplicationPrivate::KB_All}, + {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_KDE | QApplicationPrivate::KB_Mac}, {QKeySequence::Refresh, 1, Qt::CTRL | Qt::Key_R, QApplicationPrivate::KB_Gnome | QApplicationPrivate::KB_Mac}, {QKeySequence::Replace, 0, Qt::CTRL | Qt::Key_R, QApplicationPrivate::KB_KDE}, {QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, QApplicationPrivate::KB_All}, @@ -669,12 +692,14 @@ const uint QKeySequencePrivate::numberOfKeyBindings = sizeof(QKeySequencePrivate \value NextChild Navigate to next tab or child window. \value Open Open document. \value Paste Paste. + \value Preferences Open the preferences dialog. \value PreviousChild Navigate to previous tab or child window. \value Print Print document. + \value Quit Quit the application. \value Redo Redo. \value Refresh Refresh or reload current document. \value Replace Find and replace. - \value SaveAs Save document after prompting the user for a file name. + \value SaveAs Save document after prompting the user for a file name. \value Save Save document. \value SelectAll Select all text. \value SelectEndOfBlock Extend selection to the end of a text block. This shortcut is only used on OS X. @@ -780,6 +805,21 @@ QKeySequence::QKeySequence(const QKeySequence& keysequence) d->ref.ref(); } +#ifdef Q_WS_MAC +static inline int maybeSwapShortcut(int shortcut) +{ + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + uint oldshortcut = shortcut; + shortcut &= ~(Qt::CTRL | Qt::META); + if (oldshortcut & Qt::CTRL) + shortcut |= Qt::META; + if (oldshortcut & Qt::META) + shortcut |= Qt::CTRL; + } + return shortcut; +} +#endif + /*! \since 4.2 @@ -796,10 +836,16 @@ QList<QKeySequence> QKeySequence::keyBindings(StandardKey key) for (uint i = 0; i < QKeySequencePrivate::numberOfKeyBindings ; ++i) { QKeyBinding keyBinding = QKeySequencePrivate::keyBindings[i]; if (keyBinding.standardKey == key && (keyBinding.platform & platform)) { - if (keyBinding.priority > 0) - list.prepend(QKeySequence(QKeySequencePrivate::keyBindings[i].shortcut)); - else - list.append(QKeySequence(QKeySequencePrivate::keyBindings[i].shortcut)); + uint shortcut = +#ifdef Q_WS_MAC + maybeSwapShortcut(QKeySequencePrivate::keyBindings[i].shortcut); +#else + QKeySequencePrivate::keyBindings[i].shortcut; +#endif + if (keyBinding.priority > 0) + list.prepend(QKeySequence(shortcut)); + else + list.append(QKeySequence(shortcut)); } } return list; @@ -967,9 +1013,16 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence gmodifs = globalModifs(); if (gmodifs->isEmpty()) { #ifdef Q_WS_MAC - *gmodifs << QModifKeyName(Qt::CTRL, QChar(kCommandUnicode)); + const bool dontSwap = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta); + if (dontSwap) + *gmodifs << QModifKeyName(Qt::META, QChar(kCommandUnicode)); + else + *gmodifs << QModifKeyName(Qt::CTRL, QChar(kCommandUnicode)); *gmodifs << QModifKeyName(Qt::ALT, QChar(kOptionUnicode)); - *gmodifs << QModifKeyName(Qt::META, QChar(kControlUnicode)); + if (dontSwap) + *gmodifs << QModifKeyName(Qt::CTRL, QChar(kControlUnicode)); + else + *gmodifs << QModifKeyName(Qt::META, QChar(kControlUnicode)); *gmodifs << QModifKeyName(Qt::SHIFT, QChar(kShiftUnicode)); #endif *gmodifs << QModifKeyName(Qt::CTRL, QLatin1String("ctrl+")) @@ -1067,8 +1120,6 @@ int QKeySequencePrivate::decodeString(const QString &str, QKeySequence::Sequence if (found) break; } -#ifdef Q_WS_MAC -#endif } return ret; } @@ -1097,15 +1148,30 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat QString s; #if defined(Q_WS_MAC) if (nativeText) { - // On MAC the order is Meta, Alt, Shift, Control. - if ((key & Qt::META) == Qt::META) - s += macSymbolForQtKey(Qt::Key_Meta); - if ((key & Qt::ALT) == Qt::ALT) - s += macSymbolForQtKey(Qt::Key_Alt); - if ((key & Qt::SHIFT) == Qt::SHIFT) - s += macSymbolForQtKey(Qt::Key_Shift); - if ((key & Qt::CTRL) == Qt::CTRL) - s += macSymbolForQtKey(Qt::Key_Control); + // On Mac OS X the order (by default) is Meta, Alt, Shift, Control. + // If the AA_MacDontSwapCtrlAndMeta is enabled, then the order + // is Ctrl, Alt, Shift, Meta. The macSymbolForQtKey does this swap + // for us, which means that we have to adjust our order here. + // The upshot is a lot more infrastructure to keep the number of + // if tests down and the code relatively clean. + static const int ModifierOrder[] = { Qt::META, Qt::ALT, Qt::SHIFT, Qt::CTRL, 0 }; + static const int QtKeyOrder[] = { Qt::Key_Meta, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Control, 0 }; + static const int DontSwapModifierOrder[] = { Qt::CTRL, Qt::ALT, Qt::SHIFT, Qt::META, 0 }; + static const int DontSwapQtKeyOrder[] = { Qt::Key_Control, Qt::Key_Alt, Qt::Key_Shift, Qt::Key_Meta, 0 }; + const int *modifierOrder; + const int *qtkeyOrder; + if (qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { + modifierOrder = DontSwapModifierOrder; + qtkeyOrder = DontSwapQtKeyOrder; + } else { + modifierOrder = ModifierOrder; + qtkeyOrder = QtKeyOrder; + } + + for (int i = 0; modifierOrder[i] != 0; ++i) { + if (key & modifierOrder[i]) + s += qt_macSymbolForQtKey(qtkeyOrder[i]); + } } else #endif { @@ -1138,7 +1204,7 @@ QString QKeySequencePrivate::encodeString(int key, QKeySequence::SequenceFormat int i=0; #if defined(Q_WS_MAC) if (nativeText) { - QChar ch = macSymbolForQtKey(key); + QChar ch = qt_macSymbolForQtKey(key); if (!ch.isNull()) p = ch; else diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index 5337a00..c45b0f0 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -136,7 +136,9 @@ public: DeleteEndOfLine, InsertParagraphSeparator, InsertLineSeparator, - SaveAs + SaveAs, + Preferences, + Quit }; QKeySequence(); diff --git a/src/gui/kernel/qlayout.cpp b/src/gui/kernel/qlayout.cpp index d09c1c5..e750088 100644 --- a/src/gui/kernel/qlayout.cpp +++ b/src/gui/kernel/qlayout.cpp @@ -61,7 +61,10 @@ static int menuBarHeightForWidth(QWidget *menubar, int w) int result = menubar->heightForWidth(qMax(w, menubar->minimumWidth())); if (result != -1) return result; - result = menubar->sizeHint().height(); + result = menubar->sizeHint() + .expandedTo(menubar->minimumSize()) + .expandedTo(menubar->minimumSizeHint()) + .boundedTo(menubar->maximumSize()).height(); if (result != -1) return result; } @@ -1583,8 +1586,6 @@ QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy) { return stream >> policy.data; } - -#endif - +#endif // QT_NO_DATASTREAM QT_END_NAMESPACE diff --git a/src/gui/kernel/qlayoutengine.cpp b/src/gui/kernel/qlayoutengine.cpp index 0268463..b428884 100644 --- a/src/gui/kernel/qlayoutengine.cpp +++ b/src/gui/kernel/qlayoutengine.cpp @@ -329,7 +329,7 @@ void qGeomCalc(QVector<QLayoutStruct> &chain, int start, int count, qDebug() << "qGeomCalc" << "start" << start << "count" << count << "pos" << pos << "space" << space << "spacer" << spacer; for (i = start; i < start + count; ++i) { - qDebug() << i << ":" << chain[i].minimumSize << chain[i].smartSizeHint() + qDebug() << i << ':' << chain[i].minimumSize << chain[i].smartSizeHint() << chain[i].maximumSize << "stretch" << chain[i].stretch << "empty" << chain[i].empty << "expansive" << chain[i].expansive << "spacing" << chain[i].spacing; diff --git a/src/gui/kernel/qlayoutitem.cpp b/src/gui/kernel/qlayoutitem.cpp index a4f92ef..7196b4a 100644 --- a/src/gui/kernel/qlayoutitem.cpp +++ b/src/gui/kernel/qlayoutitem.cpp @@ -54,7 +54,8 @@ QT_BEGIN_NAMESPACE inline static QRect fromLayoutItemRect(QWidgetPrivate *priv, const QRect &rect) { - return priv->fromOrToLayoutItemRect(rect, -1); + return rect.adjusted(priv->leftLayoutItemMargin, priv->topLayoutItemMargin, + -priv->rightLayoutItemMargin, -priv->bottomLayoutItemMargin); } inline static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size) @@ -64,7 +65,8 @@ inline static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size) inline static QRect toLayoutItemRect(QWidgetPrivate *priv, const QRect &rect) { - return priv->fromOrToLayoutItemRect(rect, +1); + return rect.adjusted(-priv->leftLayoutItemMargin, -priv->topLayoutItemMargin, + priv->rightLayoutItemMargin, priv->bottomLayoutItemMargin); } inline static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size) diff --git a/src/gui/kernel/qmime_mac.cpp b/src/gui/kernel/qmime_mac.cpp index 76b9dba..903b677 100644 --- a/src/gui/kernel/qmime_mac.cpp +++ b/src/gui/kernel/qmime_mac.cpp @@ -68,11 +68,6 @@ #include "qmap.h" #include <private/qt_mac_p.h> -#ifdef Q_WS_MAC32 -#include <QuickTime/QuickTime.h> -#include "qlibrary.h" -#endif - QT_BEGIN_NAMESPACE extern CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0); // qpaintengine_mac.cpp @@ -127,32 +122,44 @@ CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker"); /*! \class QMacPasteboardMime - \brief The QMacPasteboardMime class maps open-standard MIME to Mac flavors. + \brief The QMacPasteboardMime class converts between a MIME type and a + \l{http://developer.apple.com/macosx/uniformtypeidentifiers.html}{Uniform + Type Identifier (UTI)} format. \since 4.2 \ingroup io \ingroup draganddrop \ingroup misc - Qt's drag and drop support and clipboard facilities use the MIME - standard. On X11, this maps trivially to the Xdnd protocol, but on - Mac although some applications use MIME types to describe clipboard - formats, others use arbitrary non-standardized naming conventions, - or unnamed built-in Mac formats. + Qt's drag and drop and clipboard facilities use the MIME + standard. On X11, this maps trivially to the Xdnd protocol. On + Mac, although some applications use MIME to describe clipboard + contents, it is more common to use Apple's UTI format. + + QMacPasteboardMime's role is to bridge the gap between MIME and UTI; + By subclasses this class, one can extend Qt's drag and drop + and clipboard handling to convert to and from unsupported, or proprietary, UTI formats. - By instantiating subclasses of QMacPasteboardMime that provide conversions - between Mac flavors and MIME formats, you can convert proprietary - clipboard formats to MIME formats. + A subclass of QMacPasteboardMime will automatically be registered, and active, upon instantiation. - Qt has predefined support for the following Mac flavors: + Qt has predefined support for the following UTIs: \list - \i kScrapFlavorTypeUnicode - converted to "text/plain;charset=ISO-10646-UCS-2" - \i kScrapFlavorTypeText - converted to "text/plain;charset=system" or "text/plain" - \i kScrapFlavorTypePicture - converted to "application/x-qt-image" - \i typeFileURL - converted to "text/uri-list" + \i public.utf8-plain-text - converts to "text/plain" + \i public.utf16-plain-text - converts to "text/plain" + \i public.html - converts to "text/html" + \i public.url - converts to "text/uri-list" + \i public.file-url - converts to "text/uri-list" + \i public.tiff - converts to "application/x-qt-image" + \i com.apple.traditional-mac-plain-text - converts to "text/plain" + \i com.apple.pict - converts to "application/x-qt-image" \endlist - You can check if a MIME type is convertible using canConvert() and - can perform conversions with convertToMime() and convertFromMime(). + When working with MIME data, Qt will interate through all instances of QMacPasteboardMime to + find an instance that can convert to, or from, a specific MIME type. It will do this by calling + canConvert() on each instance, starting with (and choosing) the last created instance first. + The actual conversions will be done by using convertToMime() and convertFromMime(). + + \note The API uses the term "flavor" in some cases. This is for backwards + compatibility reasons, and should now be understood as UTIs. */ /*! \enum QMacPasteboardMime::QMacPasteboardMimeType @@ -206,7 +213,7 @@ QString QMacPasteboardMimeAny::flavorFor(const QString &mime) if(mime == QLatin1String("application/x-qt-mime-type-name")) return QString(); QString ret = QLatin1String("com.trolltech.anymime.") + mime; - return ret.replace(QLatin1String("/"), QLatin1String("--")); + return ret.replace(QLatin1Char('/'), QLatin1String("--")); } QString QMacPasteboardMimeAny::mimeFor(QString flav) @@ -382,7 +389,7 @@ QString QMacPasteboardMimeUnicodeText::flavorFor(const QString &mime) int i = mime.indexOf(QLatin1String("charset=")); if (i >= 0) { QString cs(mime.mid(i+8).toLower()); - i = cs.indexOf(QLatin1String(";")); + i = cs.indexOf(QLatin1Char(';')); if (i>=0) cs = cs.left(i); if (cs == QLatin1String("system")) @@ -495,6 +502,11 @@ QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mim #ifdef Q_WS_MAC32 +// This can be removed once 10.6 is the minimum (or we have to require 64-bit) whichever comes first. + +#include <QuickTime/QuickTime.h> +#include <qlibrary.h> + typedef ComponentResult (*PtrGraphicsImportSetDataHandle)(GraphicsImportComponent, Handle); typedef ComponentResult (*PtrGraphicsImportCreateCGImage)(GraphicsImportComponent, CGImageRef*, UInt32); typedef ComponentResult (*PtrGraphicsExportSetInputCGImage)(GraphicsExportComponent, CGImageRef); @@ -672,33 +684,11 @@ QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteA return ret; const QByteArray &a = data.first(); QCFType<CGImageRef> image; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - QCFType<CFDataRef> data = CFDataCreateWithBytesNoCopy(0, - reinterpret_cast<const UInt8 *>(a.constData()), - a.size(), kCFAllocatorNull); - QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(data, 0); - image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0); - } else -#endif - { -#ifdef Q_WS_MAC32 - if (resolveMimeQuickTimeSymbols()) { - Handle tiff = NewHandle(a.size()); - memcpy(*tiff, a.constData(), a.size()); - GraphicsImportComponent graphicsImporter; - ComponentResult result = OpenADefaultComponent(GraphicsImporterComponentType, - kQTFileTypeTIFF, &graphicsImporter); - if (!result) - result = ptrGraphicsImportSetDataHandle(graphicsImporter, tiff); - if (!result) - result = ptrGraphicsImportCreateCGImage(graphicsImporter, &image, - kGraphicsImportCreateCGImageUsingCurrentSettings); - CloseComponent(graphicsImporter); - DisposeHandle(tiff); - } -#endif - } + QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0, + reinterpret_cast<const UInt8 *>(a.constData()), + a.size(), kCFAllocatorNull); + QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0); + image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0); if (image != 0) ret = QVariant(QPixmap::fromMacCGImageRef(image).toImage()); @@ -841,6 +831,80 @@ QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime return ret; } +class QMacPasteboardMimeUrl : public QMacPasteboardMime { +public: + QMacPasteboardMimeUrl() : QMacPasteboardMime(MIME_ALL) { } + QString convertorName(); + + QString flavorFor(const QString &mime); + QString mimeFor(QString flav); + bool canConvert(const QString &mime, QString flav); + QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); + QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimeUrl::convertorName() +{ + return QLatin1String("URL"); +} + +QString QMacPasteboardMimeUrl::flavorFor(const QString &mime) +{ + if(mime.startsWith(QLatin1String("text/uri-list"))) + return QLatin1String("public.url"); + return QString(); +} + +QString QMacPasteboardMimeUrl::mimeFor(QString flav) +{ + if(flav == QLatin1String("public.url")) + return QLatin1String("text/uri-list"); + return QString(); +} + +bool QMacPasteboardMimeUrl::canConvert(const QString &mime, QString flav) +{ + return flav == QLatin1String("public.url") + && mime == QLatin1String("text/uri-list"); +} + +QVariant QMacPasteboardMimeUrl::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) +{ + if(!canConvert(mime, flav)) + return QVariant(); + + QList<QVariant> ret; + for (int i=0; i<data.size(); ++i) { + QUrl url = QUrl::fromEncoded(data.at(i)); + if (url.host().toLower() == QLatin1String("localhost")) + url.setHost(QString()); + url.setPath(url.path().normalized(QString::NormalizationForm_C)); + ret.append(url); + } + return QVariant(ret); +} + +QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QVariant data, QString flav) +{ + QList<QByteArray> ret; + if (!canConvert(mime, flav)) + return ret; + + QList<QVariant> urls = data.toList(); + for(int i=0; i<urls.size(); ++i) { + QUrl url = urls.at(i).toUrl(); + if (url.scheme().isEmpty()) + url.setScheme(QLatin1String("file")); + if (url.scheme().toLower() == QLatin1String("file")) { + if (url.host().isEmpty()) + url.setHost(QLatin1String("localhost")); + url.setPath(url.path().normalized(QString::NormalizationForm_D)); + } + ret.append(url.toEncoded()); + } + return ret; +} + #ifdef QT3_SUPPORT class QMacPasteboardMimeQt3Any : public QMacPasteboardMime { private: @@ -1037,12 +1101,16 @@ void QMacPasteboardMime::initialize() //standard types that we wrap new QMacPasteboardMimeTiff; #ifdef Q_WS_MAC32 - new QMacPasteboardMimePict; + // 10.6 does automatic synthesis to and from PICT to standard image types (like TIFF), + // so don't bother doing it ourselves, especially since it's not available in 64-bit. + if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6) + new QMacPasteboardMimePict; #endif new QMacPasteboardMimeUnicodeText; new QMacPasteboardMimePlainText; new QMacPasteboardMimeHTMLText; new QMacPasteboardMimeFileUri; + new QMacPasteboardMimeUrl; new QMacPasteboardMimeTypeName; //make sure our "non-standard" types are always last! --Sam new QMacPasteboardMimeAny; diff --git a/src/gui/kernel/qmime_win.cpp b/src/gui/kernel/qmime_win.cpp index a7dce99..acd7cfc 100644 --- a/src/gui/kernel/qmime_win.cpp +++ b/src/gui/kernel/qmime_win.cpp @@ -170,7 +170,7 @@ static QByteArray getData(int cf, IDataObject *pDataObj) if (pDataObj->GetData(&formatetc, &s) == S_OK) { char szBuffer[4096]; ULONG actualRead = 0; - LARGE_INTEGER pos = {0, 0}; + LARGE_INTEGER pos = {{0, 0}}; //Move to front (can fail depending on the data model implemented) HRESULT hr = s.pstm->Seek(pos, STREAM_SEEK_SET, NULL); while(SUCCEEDED(hr)){ @@ -281,11 +281,7 @@ QWindowsMime::~QWindowsMime() */ int QWindowsMime::registerMimeType(const QString &mime) { -#ifdef Q_OS_WINCE int f = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (mime.utf16())); -#else - int f = RegisterClipboardFormatA(mime.toLocal8Bit()); -#endif if (!f) qErrnoWarning("QWindowsMime::registerMimeType: Failed to register clipboard format"); @@ -401,9 +397,9 @@ QStringList QWindowsMime::allMimesForFormats(IDataObject *pDataObj) while (S_OK == fmtenum->Next(1, &fmtetc, 0)) { #if defined(QMIME_DEBUG) && !defined(Q_OS_WINCE) qDebug("QWindowsMime::allMimesForFormats()"); - char buf[256] = {0}; - GetClipboardFormatNameA(fmtetc.cfFormat, buf, 255); - qDebug("CF = %d : %s", fmtetc.cfFormat, buf); + wchar_t buf[256] = {0}; + GetClipboardFormatName(fmtetc.cfFormat, buf, 255); + qDebug("CF = %d : %s", fmtetc.cfFormat, QString::fromWCharArray(buf)); #endif for (int i=mimes.size()-1; i>=0; --i) { QString format = mimes.at(i)->mimeForFormat(fmtetc); @@ -504,7 +500,7 @@ bool QWindowsMimeText::convertFromMime(const FORMATETC &formatetc, const QMimeDa ++u; } res.truncate(ri); - const int byteLength = res.length()*2; + const int byteLength = res.length() * sizeof(ushort); QByteArray r(byteLength + 2, '\0'); memcpy(r.data(), res.unicode(), byteLength); r[byteLength] = 0; @@ -549,7 +545,7 @@ QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pData QString str; QByteArray data = getData(CF_UNICODETEXT, pDataObj); if (!data.isEmpty()) { - str = QString::fromUtf16((const unsigned short *)data.data()); + str = QString::fromWCharArray((const wchar_t *)data.data()); str.replace(QLatin1String("\r\n"), QLatin1String("\n")); } else { data = getData(CF_TEXT, pDataObj); @@ -620,11 +616,7 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat for (int i=0; i<urls.size(); i++) { QString fn = QDir::toNativeSeparators(urls.at(i).toLocalFile()); if (!fn.isEmpty()) { - QT_WA({ - size += sizeof(TCHAR)*(fn.length()+1); - } , { - size += fn.toLocal8Bit().length()+1; - }); + size += sizeof(ushort) * (fn.length() + 1); fileNames.append(fn); } } @@ -636,36 +628,22 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat d->fNC = true; char* files = ((char*)d) + d->pFiles; - QT_WA({ - d->fWide = true; - TCHAR* f = (TCHAR*)files; - for (int i=0; i<fileNames.size(); i++) { - int l = fileNames.at(i).length(); - memcpy(f, fileNames.at(i).utf16(), l*sizeof(TCHAR)); - f += l; - *f++ = 0; - } - *f = 0; - } , { - d->fWide = false; - char* f = files; - for (int i=0; i<fileNames.size(); i++) { - QByteArray c = fileNames.at(i).toLocal8Bit(); - if (!c.isEmpty()) { - int l = c.length(); - memcpy(f, c.constData(), l); - f += l; - *f++ = 0; - } - } - *f = 0; - }); + d->fWide = true; + wchar_t* f = (wchar_t*)files; + for (int i=0; i<fileNames.size(); i++) { + int l = fileNames.at(i).length(); + memcpy(f, fileNames.at(i).utf16(), l * sizeof(ushort)); + f += l; + *f++ = 0; + } + *f = 0; + return setData(result, pmedium); } else if (getCf(formatetc) == CF_INETURL_W) { QList<QUrl> urls = mimeData->urls(); QByteArray result; QString url = urls.at(0).toString(); - result = QByteArray((const char *)url.utf16(), url.length() * 2); + result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort)); result.append('\0'); result.append('\0'); return setData(result, pmedium); @@ -720,15 +698,15 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD LPDROPFILES hdrop = (LPDROPFILES)data.data(); if (hdrop->fWide) { - const ushort* filesw = (const ushort*)(data.data() + hdrop->pFiles); - int i=0; + const wchar_t* filesw = (const wchar_t *)(data.data() + hdrop->pFiles); + int i = 0; while (filesw[i]) { - QString fileurl = QString::fromUtf16(filesw+i); + QString fileurl = QString::fromWCharArray(filesw + i); urls += QUrl::fromLocalFile(fileurl); i += fileurl.length()+1; } } else { - const char* files = (const char*)data.data() + hdrop->pFiles; + const char* files = (const char *)data.data() + hdrop->pFiles; int i=0; while (files[i]) { urls += QUrl::fromLocalFile(QString::fromLocal8Bit(files+i)); @@ -744,7 +722,7 @@ QVariant QWindowsMimeURI::convertToMime(const QString &mimeType, LPDATAOBJECT pD QByteArray data = getData(CF_INETURL_W, pDataObj); if (data.isEmpty()) return QVariant(); - return QUrl(QString::fromUtf16((const unsigned short *)data.constData())); + return QUrl(QString::fromWCharArray((const wchar_t *)data.constData())); } else if (canGetData(CF_INETURL, pDataObj)) { QByteArray data = getData(CF_INETURL, pDataObj); if (data.isEmpty()) @@ -852,7 +830,7 @@ QVariant QWindowsMimeHtml::convertToMime(const QString &mime, IDataObject *pData if (end > start && start > 0) { html = "<!--StartFragment-->" + html.mid(start, end - start); html += "<!--EndFragment-->"; - html.replace("\r", ""); + html.replace('\r', ""); result = QString::fromUtf8(html); } } @@ -913,11 +891,7 @@ private: QWindowsMimeImage::QWindowsMimeImage() { -#ifdef Q_OS_WINCE - CF_PNG = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (QString::fromLatin1("PNG").utf16())); -#else - CF_PNG = RegisterClipboardFormatA("PNG"); -#endif + CF_PNG = RegisterClipboardFormat(L"PNG"); } QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, const QMimeData *mimeData) const @@ -1114,7 +1088,7 @@ bool QBuiltInMimes::convertFromMime(const FORMATETC &formatetc, const QMimeData ++u; } res.truncate(ri); - const int byteLength = res.length()*2; + const int byteLength = res.length() * sizeof(ushort); QByteArray r(byteLength + 2, '\0'); memcpy(r.data(), res.unicode(), byteLength); r[byteLength] = 0; @@ -1154,8 +1128,8 @@ QVariant QBuiltInMimes::convertToMime(const QString &mimeType, IDataObject *pDat qDebug("QBuiltInMimes::convertToMime()"); #endif if (mimeType == QLatin1String("text/html") && preferredType == QVariant::String) { - // text/html is in wide chars on windows (compatible with mozillia) - val = QString::fromUtf16((const unsigned short *)data.data()); + // text/html is in wide chars on windows (compatible with Mozilla) + val = QString::fromWCharArray((const wchar_t *)data.data()); } else { val = data; // it should be enough to return the data and let QMimeData do the rest. } @@ -1262,16 +1236,16 @@ QVector<FORMATETC> QLastResortMimes::formatsForMime(const QString &mimeType, con } return formatetcs; } -static const char *x_qt_windows_mime = "application/x-qt-windows-mime;value=\""; +static const char x_qt_windows_mime[] = "application/x-qt-windows-mime;value=\""; -bool isCustomMimeType(const QString &mimeType) +static bool isCustomMimeType(const QString &mimeType) { return mimeType.startsWith(QLatin1String(x_qt_windows_mime), Qt::CaseInsensitive); } -QString customMimeType(const QString &mimeType) +static QString customMimeType(const QString &mimeType) { - int len = QString(QLatin1String(x_qt_windows_mime)).length(); + int len = sizeof(x_qt_windows_mime) - 1; int n = mimeType.lastIndexOf(QLatin1Char('\"'))-len; return mimeType.mid(len, n); } @@ -1280,11 +1254,7 @@ bool QLastResortMimes::canConvertToMime(const QString &mimeType, IDataObject *pD { if (isCustomMimeType(mimeType)) { QString clipFormat = customMimeType(mimeType); -#ifdef Q_OS_WINCE int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); -#else - int cf = RegisterClipboardFormatA(clipFormat.toLocal8Bit()); -#endif return canGetData(cf, pDataObj); } else if (formats.keys(mimeType).isEmpty()) { // if it is not in there then register it an see if we can get it @@ -1304,11 +1274,7 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p QByteArray data; if (isCustomMimeType(mimeType)) { QString clipFormat = customMimeType(mimeType); -#ifdef Q_OS_WINCE int cf = RegisterClipboardFormat(reinterpret_cast<const wchar_t *> (clipFormat.utf16())); -#else - int cf = RegisterClipboardFormatA(clipFormat.toLocal8Bit()); -#endif data = getData(cf, pDataObj); } else if (formats.keys(mimeType).isEmpty()) { int cf = QWindowsMime::registerMimeType(mimeType); @@ -1325,46 +1291,38 @@ QVariant QLastResortMimes::convertToMime(const QString &mimeType, IDataObject *p QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const { QString format = formats.value(getCf(formatetc)); - if (format.isEmpty()) { - QByteArray ba; - QString clipFormat; - int len; - QT_WA({ - ba.resize(256*2); - len = GetClipboardFormatNameW(getCf(formatetc), (TCHAR*)ba.data(), 255); - if (len) - clipFormat = QString::fromUtf16((ushort *)ba.data(), len); - } , { - ba.resize(256); - len = GetClipboardFormatNameA(getCf(formatetc), ba.data(), 255); - if (len) - clipFormat = QString::fromLocal8Bit(ba.data(), len); - }); - if (len) { + if (!format.isEmpty()) + return format; + + wchar_t buffer[256]; + int len = GetClipboardFormatName(getCf(formatetc), buffer, 256); + + if (len) { + QString clipFormat = QString::fromWCharArray(buffer, len); #ifndef QT_NO_DRAGANDDROP - if (QInternalMimeData::canReadData(clipFormat)) - format = clipFormat; - else if((formatetc.cfFormat >= 0xC000)){ - //create the mime as custom. not registered. - if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) { - //check if this is a mime type - bool ianaType = false; - int sz = ianaTypes.size(); - for (int i = 0; i < sz; i++) { - if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) { - ianaType = true; - break; - } + if (QInternalMimeData::canReadData(clipFormat)) + format = clipFormat; + else if((formatetc.cfFormat >= 0xC000)){ + //create the mime as custom. not registered. + if (!excludeList.contains(clipFormat, Qt::CaseInsensitive)) { + //check if this is a mime type + bool ianaType = false; + int sz = ianaTypes.size(); + for (int i = 0; i < sz; i++) { + if (clipFormat.startsWith(ianaTypes[i], Qt::CaseInsensitive)) { + ianaType = true; + break; } - if (!ianaType) - format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"'); - else - format = clipFormat; } + if (!ianaType) + format = QLatin1String(x_qt_windows_mime) + clipFormat + QLatin1Char('\"'); + else + format = clipFormat; } -#endif //QT_NO_DRAGANDDROP } +#endif //QT_NO_DRAGANDDROP } + return format; } diff --git a/src/gui/kernel/qmultitouch_mac.mm b/src/gui/kernel/qmultitouch_mac.mm new file mode 100644 index 0000000..3d2eae6 --- /dev/null +++ b/src/gui/kernel/qmultitouch_mac.mm @@ -0,0 +1,219 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qmultitouch_mac_p.h> +#include <qcursor.h> + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +QT_BEGIN_NAMESPACE + +#ifdef QT_MAC_USE_COCOA + +QHash<qint64, QCocoaTouch*> QCocoaTouch::_currentTouches; +QPointF QCocoaTouch::_screenReferencePos; +QPointF QCocoaTouch::_trackpadReferencePos; +int QCocoaTouch::_idAssignmentCount = 0; +int QCocoaTouch::_touchCount = 0; +bool QCocoaTouch::_updateInternalStateOnly = true; + +QCocoaTouch::QCocoaTouch(NSTouch *nstouch) +{ + if (_currentTouches.size() == 0) + _idAssignmentCount = 0; + + _touchPoint.setId(_idAssignmentCount++); + _touchPoint.setPressure(1.0); + _identity = qint64([nstouch identity]); + _currentTouches.insert(_identity, this); + updateTouchData(nstouch, NSTouchPhaseBegan); +} + +QCocoaTouch::~QCocoaTouch() +{ + _currentTouches.remove(_identity); +} + +void QCocoaTouch::updateTouchData(NSTouch *nstouch, NSTouchPhase phase) +{ + if (_touchCount == 1) + _touchPoint.setState(toTouchPointState(phase) | Qt::TouchPointPrimary); + else + _touchPoint.setState(toTouchPointState(phase)); + + // From the normalized position on the trackpad, calculate + // where on screen the touchpoint should be according to the + // reference position: + NSPoint npos = [nstouch normalizedPosition]; + QPointF qnpos = QPointF(npos.x, 1 - npos.y); + _touchPoint.setNormalizedPos(qnpos); + + if (_touchPoint.id() == 0 && phase == NSTouchPhaseBegan) { + _trackpadReferencePos = qnpos; + _screenReferencePos = QCursor::pos(); + } + + NSSize dsize = [nstouch deviceSize]; + float ppiX = (qnpos.x() - _trackpadReferencePos.x()) * dsize.width; + float ppiY = (qnpos.y() - _trackpadReferencePos.y()) * dsize.height; + QPointF relativePos = _trackpadReferencePos - QPointF(ppiX, ppiY); + _touchPoint.setScreenPos(_screenReferencePos - relativePos); +} + +QCocoaTouch *QCocoaTouch::findQCocoaTouch(NSTouch *nstouch) +{ + qint64 identity = qint64([nstouch identity]); + if (_currentTouches.contains(identity)) + return _currentTouches.value(identity); + return 0; +} + +Qt::TouchPointState QCocoaTouch::toTouchPointState(NSTouchPhase nsState) +{ + Qt::TouchPointState qtState = Qt::TouchPointReleased; + switch (nsState) { + case NSTouchPhaseBegan: + qtState = Qt::TouchPointPressed; + break; + case NSTouchPhaseMoved: + qtState = Qt::TouchPointMoved; + break; + case NSTouchPhaseStationary: + qtState = Qt::TouchPointStationary; + break; + case NSTouchPhaseEnded: + case NSTouchPhaseCancelled: + qtState = Qt::TouchPointReleased; + break; + default: + break; + } + return qtState; +} + +QList<QTouchEvent::TouchPoint> +QCocoaTouch::getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch) +{ + QMap<int, QTouchEvent::TouchPoint> touchPoints; + NSSet *ended = [event touchesMatchingPhase:NSTouchPhaseEnded | NSTouchPhaseCancelled inView:nil]; + NSSet *active = [event + touchesMatchingPhase:NSTouchPhaseBegan | NSTouchPhaseMoved | NSTouchPhaseStationary + inView:nil]; + _touchCount = [active count]; + + // First: remove touches that were ended by the user. If we are + // currently not accepting single touches, a corresponding 'begin' + // has never been send to the app for these events. + // So should therefore not send the following removes either. + + for (int i=0; i<int([ended count]); ++i) { + NSTouch *touch = [[ended allObjects] objectAtIndex:i]; + QCocoaTouch *qcocoaTouch = findQCocoaTouch(touch); + if (qcocoaTouch) { + qcocoaTouch->updateTouchData(touch, [touch phase]); + if (!_updateInternalStateOnly) + touchPoints.insert(qcocoaTouch->_touchPoint.id(), qcocoaTouch->_touchPoint); + delete qcocoaTouch; + } + } + + bool wasUpdateInternalStateOnly = _updateInternalStateOnly; + _updateInternalStateOnly = !acceptSingleTouch && _touchCount < 2; + + // Next: update, or create, existing touches. + // We always keep track of all touch points, even + // when not accepting single touches. + + for (int i=0; i<int([active count]); ++i) { + NSTouch *touch = [[active allObjects] objectAtIndex:i]; + QCocoaTouch *qcocoaTouch = findQCocoaTouch(touch); + if (!qcocoaTouch) + qcocoaTouch = new QCocoaTouch(touch); + else + qcocoaTouch->updateTouchData(touch, wasUpdateInternalStateOnly ? NSTouchPhaseBegan : [touch phase]); + if (!_updateInternalStateOnly) + touchPoints.insert(qcocoaTouch->_touchPoint.id(), qcocoaTouch->_touchPoint); + } + + // Next: sadly, we need to check that our touch hash is in + // sync with cocoa. This is typically not the case after a system + // gesture happend (like a four-finger-swipe to show expose). + + if (_touchCount != _currentTouches.size()) { + // Remove all instances, and basically start from scratch: + touchPoints.clear(); + QList<QCocoaTouch *> list = _currentTouches.values(); + foreach (QCocoaTouch *qcocoaTouch, _currentTouches.values()) { + if (!_updateInternalStateOnly) { + qcocoaTouch->_touchPoint.setState(Qt::TouchPointReleased); + touchPoints.insert(qcocoaTouch->_touchPoint.id(), qcocoaTouch->_touchPoint); + } + delete qcocoaTouch; + } + _currentTouches.clear(); + _updateInternalStateOnly = !acceptSingleTouch; + return touchPoints.values(); + } + + // Finally: If this call _started_ to reject single + // touches, we need to fake a relase for the remaining + // touch now (and refake a begin for it later, if needed). + + if (_updateInternalStateOnly && !wasUpdateInternalStateOnly && !_currentTouches.isEmpty()) { + QCocoaTouch *qcocoaTouch = _currentTouches.values().first(); + qcocoaTouch->_touchPoint.setState(Qt::TouchPointReleased); + touchPoints.insert(qcocoaTouch->_touchPoint.id(), qcocoaTouch->_touchPoint); + // Since this last touch also will end up beeing the first + // touch (if the user adds a second finger without lifting + // the first), we promote it to be the primary touch: + qcocoaTouch->_touchPoint.setId(0); + _idAssignmentCount = 1; + } + + return touchPoints.values(); +} + +#endif + +QT_END_NAMESPACE + +#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + diff --git a/src/gui/kernel/qmultitouch_mac_p.h b/src/gui/kernel/qmultitouch_mac_p.h new file mode 100644 index 0000000..618e9ca --- /dev/null +++ b/src/gui/kernel/qmultitouch_mac_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#ifndef QMULTITOUCH_MAC_P_H +#define QMULTITOUCH_MAC_P_H + +#ifdef QT_MAC_USE_COCOA +#import <Cocoa/Cocoa.h> +#endif + +#include <qevent.h> +#include <qhash.h> +#include <QtCore> + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +QT_BEGIN_NAMESPACE + +#ifdef QT_MAC_USE_COCOA + +class QCocoaTouch +{ + public: + static QList<QTouchEvent::TouchPoint> getCurrentTouchPointList(NSEvent *event, bool acceptSingleTouch); + static void setMouseInDraggingState(bool inDraggingState); + + private: + static QHash<qint64, QCocoaTouch*> _currentTouches; + static QPointF _screenReferencePos; + static QPointF _trackpadReferencePos; + static int _idAssignmentCount; + static int _touchCount; + static bool _updateInternalStateOnly; + + QTouchEvent::TouchPoint _touchPoint; + qint64 _identity; + + QCocoaTouch(NSTouch *nstouch); + ~QCocoaTouch(); + + void updateTouchData(NSTouch *nstouch, NSTouchPhase phase); + static QCocoaTouch *findQCocoaTouch(NSTouch *nstouch); + static Qt::TouchPointState toTouchPointState(NSTouchPhase nsState); +}; + +#endif // QT_MAC_USE_COCOA + +QT_END_NAMESPACE + +#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + +#endif // QMULTITOUCH_MAC_P_H + diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index e0c80ba..50b70c3 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -125,7 +125,7 @@ QDataStream &operator>>(QDataStream &s, QColorGroup &g) { return qt_stream_in_qcolorgroup(s, g); } -#endif +#endif // QT_NO_DATASTREAM /*! Constructs a palette with the specified \a active, \a disabled and @@ -158,7 +158,7 @@ void QPalette::setColorGroup(ColorGroup cg, const QColorGroup &g) g.brush(LinkVisited), g.brush(ToolTipBase), g.brush(ToolTipText)); } -#endif +#endif // QT3_SUPPORT /*! \fn const QColor &QPalette::color(ColorRole role) const diff --git a/src/gui/kernel/qshortcut.cpp b/src/gui/kernel/qshortcut.cpp index fd6b4e8..1a601ed 100644 --- a/src/gui/kernel/qshortcut.cpp +++ b/src/gui/kernel/qshortcut.cpp @@ -163,7 +163,6 @@ public: void QShortcutPrivate::redoGrab(QShortcutMap &map) { Q_Q(QShortcut); - QWidget *parent = q->parentWidget(); if (!parent) { qWarning("QShortcut: No widget parent defined"); return; diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index 16c07fb..5d56580 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -61,8 +61,6 @@ QT_BEGIN_NAMESPACE -extern bool qt_mac_no_native_menubar; // qmenu_mac.cpp - // To enable verbose output uncomment below //#define DEBUG_QSHORTCUTMAP @@ -111,7 +109,7 @@ QDebug &operator<<(QDebug &dbg, const QShortcutEntry *se) { dbg.nospace() << "QShortcutEntry(" << se->keyseq << "), id(" << se->id << "), enabled(" << se->enabled << "), autorepeat(" << se->autorepeat - << "), owner(" << se->owner << ")"; + << "), owner(" << se->owner << ')'; return dbg.space(); } #endif // QT_NO_DEBUGSTREAM @@ -630,13 +628,13 @@ QKeySequence::SequenceMatch QShortcutMap::matches(const QKeySequence &seq1, bool QShortcutMap::correctContext(const QShortcutEntry &item) const { Q_ASSERT_X(item.owner, "QShortcutMap", "Shortcut has no owner. Illegal map state!"); - QWidget *active_window = qApp->activeWindow(); + QWidget *active_window = QApplication::activeWindow(); // popups do not become the active window, // so we fake it here to get the correct context // for the shortcut system. - if (qApp->activePopupWidget()) - active_window = qApp->activePopupWidget(); + if (QApplication::activePopupWidget()) + active_window = QApplication::activePopupWidget(); if (!active_window) return false; @@ -660,7 +658,7 @@ bool QShortcutMap::correctWidgetContext(Qt::ShortcutContext context, QWidget *w, { bool visible = w->isVisible(); #ifdef Q_WS_MAC - if (!qt_mac_no_native_menubar && qobject_cast<QMenuBar *>(w)) + if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w)) visible = true; #endif @@ -723,7 +721,7 @@ bool QShortcutMap::correctGraphicsWidgetContext(Qt::ShortcutContext context, QGr { bool visible = w->isVisible(); #ifdef Q_WS_MAC - if (!qt_mac_no_native_menubar && qobject_cast<QMenuBar *>(w)) + if (!qApp->testAttribute(Qt::AA_DontUseNativeMenuBar) && qobject_cast<QMenuBar *>(w)) visible = true; #endif @@ -878,7 +876,7 @@ void QShortcutMap::dispatchEvent(QKeyEvent *e) qDebug().nospace() << "QShortcutMap::dispatchEvent(): Sending QShortcutEvent(\"" << (QString)next->keyseq << "\", " << next->id << ", " - << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ")"; + << (bool)(enabledShortcuts>1) << ") to object(" << next->owner << ')'; #endif QShortcutEvent se(next->keyseq, next->id, enabledShortcuts>1); QApplication::sendEvent(const_cast<QObject *>(next->owner), &se); diff --git a/src/gui/kernel/qsizepolicy.h b/src/gui/kernel/qsizepolicy.h index 77ab05b..a651f9b 100644 --- a/src/gui/kernel/qsizepolicy.h +++ b/src/gui/kernel/qsizepolicy.h @@ -203,9 +203,11 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes) +#ifndef QT_NO_DATASTREAM // implemented in qlayout.cpp Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &); +#endif inline void QSizePolicy::transpose() { Policy hData = horizontalPolicy(); diff --git a/src/gui/kernel/qsound_qws.cpp b/src/gui/kernel/qsound_qws.cpp index 2a09a39..b989843 100644 --- a/src/gui/kernel/qsound_qws.cpp +++ b/src/gui/kernel/qsound_qws.cpp @@ -279,7 +279,7 @@ QAuBucketQWS::QAuBucketQWS( QAuServerQWS *server, QSound *sound, QObject* parent sound->setObjectName( m_id.toString() ); - m_channel = new QCopChannel(QString( QLatin1String("QPE/QSound/") ).append( m_id ), this ); + m_channel = new QCopChannel(QLatin1String("QPE/QSound/") + m_id ), this ); connect( m_channel, SIGNAL(received(QString,QByteArray)), this, SLOT(processMessage(QString,QByteArray)) ); diff --git a/src/gui/kernel/qsound_win.cpp b/src/gui/kernel/qsound_win.cpp index 7330d4b..82854ae 100644 --- a/src/gui/kernel/qsound_win.cpp +++ b/src/gui/kernel/qsound_win.cpp @@ -77,13 +77,8 @@ public: QAuServerWindows::QAuServerWindows(QObject* parent) : QAuServer(parent), current(0) { - QT_WA({ - mutex = CreateMutexW(0, 0, 0); - event = CreateEventW(0, FALSE, FALSE, 0); - } , { - mutex = CreateMutexA(0, 0, 0); - event = CreateEventA(0, FALSE, FALSE, 0); - }); + mutex = CreateMutex(0, 0, 0); + event = CreateEvent(0, FALSE, FALSE, 0); } QAuServerWindows::~QAuServerWindows() @@ -133,13 +128,9 @@ DWORD WINAPI SoundPlayProc(LPVOID param) if (loops == -1) flags |= SND_LOOP; - QT_WA({ - PlaySoundW((TCHAR*)filename.utf16(), 0, flags); - } , { - PlaySoundA(QFile::encodeName(filename).data(), 0, flags); - }); - if (sound && loops == 1) - server->decLoop(sound); + PlaySound((wchar_t*)filename.utf16(), 0, flags); + if (sound && loops == 1) + server->decLoop(sound); // GUI thread continues, but we are done as well. SetEvent(event); @@ -148,18 +139,13 @@ DWORD WINAPI SoundPlayProc(LPVOID param) QPointer<QSound> guarded_sound = sound; SetEvent(event); - for (int l = 0; l < loops && server->current; ++l) { - QT_WA( { - PlaySoundW( (TCHAR*)filename.utf16(), 0, SND_FILENAME|SND_SYNC ); - } , { - PlaySoundA( QFile::encodeName(filename).data(), 0, - SND_FILENAME|SND_SYNC ); - } ); - - if (guarded_sound) - server->decLoop(guarded_sound); - } - server->current = 0; + for (int l = 0; l < loops && server->current; ++l) { + PlaySound((wchar_t*)filename.utf16(), 0, SND_FILENAME | SND_SYNC); + + if (guarded_sound) + server->decLoop(guarded_sound); + } + server->current = 0; } ReleaseMutex(mutex); @@ -169,7 +155,7 @@ DWORD WINAPI SoundPlayProc(LPVOID param) void QAuServerWindows::playHelper(const QString &filename, int loop, QSound *snd) { if (loop == 0) - return; + return; // busy? if (WaitForSingleObject(mutex, 0) == WAIT_TIMEOUT) return; diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp new file mode 100644 index 0000000..c8b11c5 --- /dev/null +++ b/src/gui/kernel/qstandardgestures.cpp @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" + +#include <qabstractscrollarea.h> +#include <qscrollbar.h> +#include <private/qapplication_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QPanGesture + \since 4.6 + + \brief The QPanGesture class represents a Pan gesture, + providing additional information related to panning. +*/ + +/*! + Creates a new Pan gesture handler object and marks it as a child of \a + parent. + + On some platform like Windows it's necessary to provide a non-null widget + as \a parent to get native gesture support. +*/ +QPanGesture::QPanGesture(QWidget *parent) + : QGesture(*new QPanGesturePrivate, parent) +{ +#ifdef Q_WS_WIN + if (parent) { + QApplicationPrivate* getQApplicationPrivateInternal(); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + qAppPriv->widgetGestures[parent].pan = this; + } +#endif +} + +/*! \internal */ +bool QPanGesture::event(QEvent *event) +{ +#ifdef Q_WS_WIN + QApplicationPrivate* getQApplicationPrivateInternal(); + switch (event->type()) { + case QEvent::ParentAboutToChange: + if (QWidget *w = qobject_cast<QWidget*>(parent())) + getQApplicationPrivateInternal()->widgetGestures[w].pan = 0; + break; + case QEvent::ParentChange: + if (QWidget *w = qobject_cast<QWidget*>(parent())) + getQApplicationPrivateInternal()->widgetGestures[w].pan = this; + break; + default: + break; + } +#endif + return QObject::event(event); +} + +/*! \internal */ +bool QPanGesture::filterEvent(QEvent *event) +{ + Q_D(QPanGesture); + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); + if (event->type() == QEvent::TouchBegin) { + d->touchPoints = ev->touchPoints(); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + setStartPos(p); + setLastPos(p); + setPos(p); + return false; + } else if (event->type() == QEvent::TouchEnd) { + if (state() != Qt::NoGesture) { + setState(Qt::GestureFinished); + setLastPos(pos()); + setPos(ev->touchPoints().at(0).pos().toPoint()); + emit triggered(); + emit finished(); + } + setState(Qt::NoGesture); + reset(); + } else if (event->type() == QEvent::TouchUpdate) { + d->touchPoints = ev->touchPoints(); + QPointF pt = d->touchPoints.at(0).pos() - d->touchPoints.at(0).startPos(); + setLastPos(pos()); + setPos(ev->touchPoints().at(0).pos().toPoint()); + if (pt.x() > 10 || pt.y() > 10 || pt.x() < -10 || pt.y() < -10) { + if (state() == Qt::NoGesture) + setState(Qt::GestureStarted); + else + setState(Qt::GestureUpdated); + emit triggered(); + } + } + return false; +} + +/*! \internal */ +void QPanGesture::reset() +{ + Q_D(QPanGesture); + d->touchPoints.clear(); +} + +/*! + \property QPanGesture::totalOffset + + Specifies a total pan offset since the start of the gesture. +*/ +QSize QPanGesture::totalOffset() const +{ + QPoint pt = pos() - startPos(); + return QSize(pt.x(), pt.y()); +} + +/*! + \property QPanGesture::lastOffset + + Specifies a pan offset since the last time the gesture was + triggered. +*/ +QSize QPanGesture::lastOffset() const +{ + QPoint pt = pos() - lastPos(); + return QSize(pt.x(), pt.y()); +} + +/*! + \class QTapAndHoldGesture + \since 4.6 + + \brief The QTapAndHoldGesture class represents a Tap-and-Hold gesture, + providing additional information. +*/ + +const int QTapAndHoldGesturePrivate::iterationCount = 40; +const int QTapAndHoldGesturePrivate::iterationTimeout = 50; + +/*! + Creates a new Tap and Hold gesture handler object and marks it as a child + of \a parent. + + On some platforms like Windows there is a system-wide tap and hold gesture + that cannot be overriden, hence the gesture might never trigger and default + context menu will be shown instead. +*/ +QTapAndHoldGesture::QTapAndHoldGesture(QWidget *parent) + : QGesture(*new QTapAndHoldGesturePrivate, parent) +{ +} + +/*! \internal */ +bool QTapAndHoldGesture::filterEvent(QEvent *event) +{ + Q_D(QTapAndHoldGesture); + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); + switch (event->type()) { + case QEvent::TouchBegin: { + if (d->timer.isActive()) + d->timer.stop(); + d->timer.start(QTapAndHoldGesturePrivate::iterationTimeout, this); + const QPoint p = ev->touchPoints().at(0).pos().toPoint(); + setStartPos(p); + setLastPos(p); + setPos(p); + break; + } + case QEvent::TouchUpdate: + if (ev->touchPoints().size() != 1) + reset(); + else if ((startPos() - ev->touchPoints().at(0).pos().toPoint()).manhattanLength() > 15) + reset(); + break; + case QEvent::TouchEnd: + reset(); + break; + default: + break; + } + return false; +} + +/*! \internal */ +void QTapAndHoldGesture::timerEvent(QTimerEvent *event) +{ + Q_D(QTapAndHoldGesture); + if (event->timerId() != d->timer.timerId()) + return; + if (d->iteration == QTapAndHoldGesturePrivate::iterationCount) { + d->timer.stop(); + setState(Qt::GestureFinished); + emit triggered(); + } else { + setState(Qt::GestureStarted); + emit triggered(); + } + ++d->iteration; +} + +/*! \internal */ +void QTapAndHoldGesture::reset() +{ + Q_D(QTapAndHoldGesture); + if (state() != Qt::NoGesture) + emit cancelled(); + setState(Qt::NoGesture); + d->timer.stop(); + d->iteration = 0; +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h new file mode 100644 index 0000000..db96ef6 --- /dev/null +++ b/src/gui/kernel/qstandardgestures.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTANDARDGESTURES_H +#define QSTANDARDGESTURES_H + +#include "qevent.h" +#include "qbasictimer.h" +#include "qdebug.h" + +#include "qgesture.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QPanGesturePrivate; +class Q_GUI_EXPORT QPanGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPanGesture) + + Q_PROPERTY(QSize totalOffset READ totalOffset) + Q_PROPERTY(QSize lastOffset READ lastOffset) + +public: + QPanGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + + QSize totalOffset() const; + QSize lastOffset() const; + +protected: + bool event(QEvent *event); + +private: + friend class QWidget; +}; + +class QTapAndHoldGesturePrivate; +class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QTapAndHoldGesture) + +public: + QTapAndHoldGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + +protected: + void timerEvent(QTimerEvent *event); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSTANDARDGESTURES_H diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h new file mode 100644 index 0000000..bb11c9f --- /dev/null +++ b/src/gui/kernel/qstandardgestures_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTANDARDGESTURES_P_H +#define QSTANDARDGESTURES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qevent.h" +#include "qbasictimer.h" +#include "qdebug.h" + +#include "qgesture.h" +#include "qgesture_p.h" + +QT_BEGIN_NAMESPACE + +class QPanGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QPanGesture) + +public: + QPanGesturePrivate() { } + + QList<QTouchEvent::TouchPoint> touchPoints; +}; + +class QTapAndHoldGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QTapAndHoldGesture) + +public: + QTapAndHoldGesturePrivate() + : iteration(0) { } + + QBasicTimer timer; + int iteration; + static const int iterationCount; + static const int iterationTimeout; +}; + +QT_END_NAMESPACE + +#endif // QSTANDARDGESTURES_P_H diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index 241ea44..223e36b 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -77,6 +77,7 @@ #include <qwidget.h> #include <qdesktopwidget.h> #include <qevent.h> +#include <qpixmapcache.h> #include <private/qevent_p.h> #include <private/qt_cocoa_helpers_mac_p.h> #include <private/qt_mac_p.h> @@ -88,6 +89,52 @@ QT_BEGIN_NAMESPACE +Q_GLOBAL_STATIC(QMacWindowFader, macwindowFader); + +QMacWindowFader::QMacWindowFader() + : m_duration(0.250) +{ +} + +QMacWindowFader *QMacWindowFader::currentFader() +{ + return macwindowFader(); +} + +void QMacWindowFader::registerWindowToFade(QWidget *window) +{ + m_windowsToFade.append(window); +} + +void QMacWindowFader::performFade() +{ + const QWidgetList myWidgetsToFade = m_windowsToFade; + const int widgetCount = myWidgetsToFade.count(); +#if QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + [NSAnimationContext beginGrouping]; + [[NSAnimationContext currentContext] setDuration:NSTimeInterval(m_duration)]; +#endif + + for (int i = 0; i < widgetCount; ++i) { + QWidget *widget = m_windowsToFade.at(i); + OSWindowRef window = qt_mac_window_for(widget); +#if QT_MAC_USE_COCOA + [[window animator] setAlphaValue:0.0]; + QTimer::singleShot(qRound(m_duration * 1000), widget, SLOT(hide())); +#else + TransitionWindowOptions options = {0, m_duration, 0, 0}; + TransitionWindowWithOptions(window, kWindowFadeTransitionEffect, kWindowHideTransitionAction, + 0, 1, &options); +#endif + } +#if QT_MAC_USE_COCOA + [NSAnimationContext endGrouping]; +#endif + m_duration = 0.250; + m_windowsToFade.clear(); +} + extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp; extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm extern QWidget * mac_mouse_grabber; @@ -95,29 +142,26 @@ extern QWidget * mac_mouse_grabber; void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds) { OSWindowRef wnd = static_cast<OSWindowRef>(window); - if( wnd ) { + if (wnd) { + QWidget *widget; #if QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; - [NSAnimationContext beginGrouping]; - [[wnd animator] setAlphaValue:0.0]; - if (durationSeconds > 0) { - [[NSAnimationContext currentContext] setDuration:NSTimeInterval(durationSeconds)]; - } else { - durationSeconds = [[NSAnimationContext currentContext] duration]; - } - [NSAnimationContext endGrouping]; - QTimer::singleShot(qRound(durationSeconds * 1000), [wnd QT_MANGLE_NAMESPACE(qt_qwidget)], SLOT(hide())); + widget = [wnd QT_MANGLE_NAMESPACE(qt_qwidget)]; #else - if (durationSeconds <= 0) - durationSeconds = 0.15; - TransitionWindowOptions options = {0, durationSeconds, 0, 0}; - TransitionWindowWithOptions(wnd, kWindowFadeTransitionEffect, kWindowHideTransitionAction, 0, 1, &options); + const UInt32 kWidgetCreatorQt = kEventClassQt; + enum { + kWidgetPropertyQWidget = 'QWId' //QWidget * + }; + if (GetWindowProperty(static_cast<WindowRef>(window), kWidgetCreatorQt, kWidgetPropertyQWidget, sizeof(widget), 0, &widget) != noErr) + widget = 0; #endif - } + if (widget) { + QMacWindowFader::currentFader()->setFadeDuration(durationSeconds); + QMacWindowFader::currentFader()->registerWindowToFade(widget); + QMacWindowFader::currentFader()->performFade(); + } + } } - - bool macWindowIsTextured( void * /*OSWindowRef*/ window ) { OSWindowRef wnd = static_cast<OSWindowRef>(window); @@ -134,11 +178,10 @@ void macWindowToolbarShow(const QWidget *widget, bool show ) { OSWindowRef wnd = qt_mac_window_for(widget); #if QT_MAC_USE_COCOA - NSToolbar *toolbar = [wnd toolbar]; - if (toolbar) { + if (NSToolbar *toolbar = [wnd toolbar]) { QMacCocoaAutoReleasePool pool; if (show != [toolbar isVisible]) { - [wnd toggleToolbarShown:wnd]; + [toolbar setVisible:show]; } else { // The toolbar may be in sync, but we are not, update our framestrut. qt_widget_private(const_cast<QWidget *>(widget))->updateFrameStrut(); @@ -154,22 +197,21 @@ void macWindowToolbarSet( void * /*OSWindowRef*/ window, void *toolbarRef ) { OSWindowRef wnd = static_cast<OSWindowRef>(window); #if QT_MAC_USE_COCOA - [wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)]; + [wnd setToolbar:static_cast<NSToolbar *>(toolbarRef)]; #else SetWindowToolbar(wnd, static_cast<HIToolbarRef>(toolbarRef)); #endif } -bool macWindowToolbarVisible( void * /*OSWindowRef*/ window ) +bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ) { OSWindowRef wnd = static_cast<OSWindowRef>(window); #if QT_MAC_USE_COCOA - NSToolbar *toolbar = [wnd toolbar]; - if (toolbar) + if (NSToolbar *toolbar = [wnd toolbar]) return [toolbar isVisible]; return false; #else - return IsWindowToolbarVisible(wnd); + return IsWindowToolbarVisible(wnd); #endif } @@ -177,12 +219,12 @@ void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ) { OSWindowRef wnd = static_cast<OSWindowRef>(window); #if QT_MAC_USE_COCOA - [wnd setHasShadow:BOOL(hasShadow)]; + [wnd setHasShadow:BOOL(hasShadow)]; #else - if (hasShadow) - ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute); - else - ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0); + if (hasShadow) + ChangeWindowAttributes(wnd, 0, kWindowNoShadowAttribute); + else + ChangeWindowAttributes(wnd, kWindowNoShadowAttribute, 0); #endif } @@ -190,9 +232,9 @@ void macWindowFlush(void * /*OSWindowRef*/ window) { OSWindowRef wnd = static_cast<OSWindowRef>(window); #if QT_MAC_USE_COCOA - [wnd flushWindowIfNeeded]; + [wnd flushWindowIfNeeded]; #else - HIWindowFlush(wnd); + HIWindowFlush(wnd); #endif } @@ -309,6 +351,12 @@ Qt::MouseButton qt_mac_get_button(EventMouseButton button) return Qt::NoButton; } +void macSendToolbarChangeEvent(QWidget *widget) +{ + QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey)); + qt_sendSpontaneousEvent(widget, &ev); +} + Q_GLOBAL_STATIC(QMacTabletHash, tablet_hash) QMacTabletHash *qt_mac_tablet_hash() { @@ -1079,4 +1127,70 @@ CGContextRef qt_mac_graphicsContextFor(QWidget *widget) return context; } +CGFloat qt_mac_get_scalefactor() +{ +#ifndef QT_MAC_USE_COCOA + return HIGetScaleFactor(); +#else + return [[NSScreen mainScreen] userSpaceScaleFactor]; +#endif +} + +QString qt_mac_get_pasteboardString() +{ + QMacCocoaAutoReleasePool pool; + NSPasteboard *pb = [NSPasteboard generalPasteboard]; + NSString *text = [pb stringForType:NSStringPboardType]; + if (text) { + return qt_mac_NSStringToQString(text); + } else { + return QString(); + } +} + +QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height) +{ + QPixmap ret(width, height); + ret.fill(QColor(0, 0, 0, 0)); + + CGRect rect = CGRectMake(0, 0, width, height); + + CGContextRef ctx = qt_mac_cg_context(&ret); + CGAffineTransform old_xform = CGContextGetCTM(ctx); + CGContextConcatCTM(ctx, CGAffineTransformInvert(old_xform)); + CGContextConcatCTM(ctx, CGAffineTransformIdentity); + + ::RGBColor b; + b.blue = b.green = b.red = 255*255; + PlotIconRefInContext(ctx, &rect, kAlignNone, kTransformNone, &b, kPlotIconRefNormalFlags, icon); + CGContextRelease(ctx); + return ret; +} + +void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayIcon, QIcon *retIcon, QStyle::StandardPixmap standardIcon) +{ + int size = 16; + while (size <= 128) { + + const QString cacheKey = QLatin1String("qt_mac_constructQIconFromIconRef") + QString::number(standardIcon) + QString::number(size); + QPixmap mainIcon; + if (standardIcon >= QStyle::SP_CustomBase) { + mainIcon = qt_mac_convert_iconref(icon, size, size); + } else if (QPixmapCache::find(cacheKey, mainIcon) == false) { + mainIcon = qt_mac_convert_iconref(icon, size, size); + QPixmapCache::insert(cacheKey, mainIcon); + } + + if (overlayIcon) { + int littleSize = size / 2; + QPixmap overlayPix = qt_mac_convert_iconref(overlayIcon, littleSize, littleSize); + QPainter painter(&mainIcon); + painter.drawPixmap(size - littleSize, size - littleSize, overlayPix); + } + + retIcon->addPixmap(mainIcon); + size += size; // 16 -> 32 -> 64 -> 128 + } +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 5156b9c..99f058b 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -118,9 +118,10 @@ void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds = 0); bool macWindowIsTextured(void * /*OSWindowRef*/ window); void macWindowToolbarShow(const QWidget *widget, bool show ); void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef ); -bool macWindowToolbarVisible( void * /*OSWindowRef*/ window ); +bool macWindowToolbarIsVisible( void * /*OSWindowRef*/ window ); void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ); void macWindowFlush(void * /*OSWindowRef*/ window); +void macSendToolbarChangeEvent(QWidget *widget); struct HIContentBorderMetrics; void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics); void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm); @@ -142,6 +143,9 @@ struct ::TabletProximityRec; void qt_dispatchTabletProximityEvent(const ::TabletProximityRec &proxRec); Qt::KeyboardModifiers qt_cocoaModifiers2QtModifiers(ulong modifierFlags); Qt::KeyboardModifiers qt_cocoaDragOperation2QtModifiers(uint dragOperations); +QPixmap qt_mac_convert_iconref(const IconRef icon, int width, int height); +void qt_mac_constructQIconFromIconRef(const IconRef icon, const IconRef overlayIcon, QIcon *retIcon, + QStyle::StandardPixmap standardIcon = QStyle::SP_CustomBase); inline int flipYCoordinate(int y) { return QApplication::desktop()->screenGeometry(0).height() - y; @@ -161,6 +165,9 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list); void qt_syncCocoaTitleBarButtons(OSWindowRef window, QWidget *widgetForWindow); +CGFloat qt_mac_get_scalefactor(); +QString qt_mac_get_pasteboardString(); + #ifdef __OBJC__ inline NSMutableArray *qt_mac_QStringListToNSMutableArray(const QStringList &qstrlist) { return reinterpret_cast<NSMutableArray *>(qt_mac_QStringListToNSMutableArrayVoid(qstrlist)); } diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h index 892cb7f..cca527a 100644 --- a/src/gui/kernel/qt_mac_p.h +++ b/src/gui/kernel/qt_mac_p.h @@ -120,6 +120,21 @@ public: } }; +// Class for chaining to gether a bunch of fades. It pretty much is only used for qmenu fading. +class QMacWindowFader +{ + QWidgetList m_windowsToFade; + float m_duration; + Q_DISABLE_COPY(QMacWindowFader) +public: + QMacWindowFader(); // PLEASE DON'T CALL THIS. + static QMacWindowFader *currentFader(); + void registerWindowToFade(QWidget *window); + void setFadeDuration(float durationInSecs) { m_duration = durationInSecs; } + float fadeDuration() const { return m_duration; } + void performFade(); +}; + class Q_GUI_EXPORT QMacCocoaAutoReleasePool { private: diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index b36b3f4..1c8394b 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -154,6 +154,10 @@ extern "C" { # include <X11/extensions/Xrender.h> #endif // QT_NO_XRENDER +#ifndef QT_NO_XSYNC +# include "X11/extensions/sync.h" +#endif + // #define QT_NO_XKB #ifndef QT_NO_XKB # include <X11/XKBlib.h> @@ -502,7 +506,6 @@ struct QX11Data int fc_hint_style; char *startupId; - char *originalStartupId; DesktopEnvironment desktopEnvironment; @@ -514,6 +517,8 @@ struct QX11Data WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_CONTEXT_HELP, + _NET_WM_SYNC_REQUEST, + _NET_WM_SYNC_REQUEST_COUNTER, // ICCCM window state WM_STATE, @@ -652,6 +657,10 @@ struct QX11Data _XEMBED, _XEMBED_INFO, + XWacomStylus, + XWacomCursor, + XWacomEraser, + NPredefinedAtoms, _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms, diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp index 870bd21..3131c40 100644 --- a/src/gui/kernel/qtooltip.cpp +++ b/src/gui/kernel/qtooltip.cpp @@ -126,14 +126,15 @@ public: bool eventFilter(QObject *, QEvent *); - QBasicTimer hideTimer; + QBasicTimer hideTimer, expireTimer; + bool fadingOut; void reuseTip(const QString &text); void hideTip(); void hideTipImmediately(); void setTipRect(QWidget *w, const QRect &r); - void restartHideTimer(); + void restartExpireTimer(); bool tipChanged(const QPoint &pos, const QString &text, QObject *o); void placeTip(const QPoint &pos, QWidget *w); @@ -190,16 +191,17 @@ QTipLabel::QTipLabel(const QString &text, QWidget *w) reuseTip(text); } -void QTipLabel::restartHideTimer() +void QTipLabel::restartExpireTimer() { int time = 10000 + 40 * qMax(0, text().length()-100); - hideTimer.start(time, this); + expireTimer.start(time, this); + hideTimer.stop(); } void QTipLabel::reuseTip(const QString &text) { #ifndef QT_NO_STYLE_STYLESHEET - if (styleSheetParent) { + if (styleSheetParent){ disconnect(styleSheetParent, SIGNAL(destroyed()), QTipLabel::instance, SLOT(styleSheetParentDestroyed())); styleSheetParent = 0; @@ -213,7 +215,7 @@ void QTipLabel::reuseTip(const QString &text) if (fm.descent() == 2 && fm.ascent() >= 11) ++extra.rheight(); resize(sizeHint() + extra); - restartHideTimer(); + restartExpireTimer(); } void QTipLabel::paintEvent(QPaintEvent *ev) @@ -257,7 +259,8 @@ QTipLabel::~QTipLabel() void QTipLabel::hideTip() { - hideTimer.start(300, this); + if (!hideTimer.isActive()) + hideTimer.start(300, this); } void QTipLabel::hideTipImmediately() @@ -278,8 +281,10 @@ void QTipLabel::setTipRect(QWidget *w, const QRect &r) void QTipLabel::timerEvent(QTimerEvent *e) { - if (e->timerId() == hideTimer.timerId()){ + if (e->timerId() == hideTimer.timerId() + || e->timerId() == expireTimer.timerId()){ hideTimer.stop(); + expireTimer.stop(); #if defined(Q_WS_MAC) && !defined(QT_NO_EFFECTS) if (QApplication::isEffectEnabled(Qt::UI_FadeTooltip)){ // Fade out tip on mac (makes it invisible). diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp index 067c783..62b5863 100644 --- a/src/gui/kernel/qwhatsthis.cpp +++ b/src/gui/kernel/qwhatsthis.cpp @@ -226,7 +226,9 @@ QWhatsThat::QWhatsThat(const QString& txt, QWidget* parent, QWidget *showTextFor text); } #if defined(Q_WS_WIN) - if ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_2000) { + if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP + && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) + { BOOL shadow; SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0); shadowWidth = shadow ? 0 : 6; @@ -302,7 +304,9 @@ void QWhatsThat::paintEvent(QPaintEvent*) { bool drawShadow = true; #if defined(Q_WS_WIN) - if ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_2000) { + if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP + && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based)) + { BOOL shadow; SystemParametersInfo(SPI_GETDROPSHADOW, 0, &shadow, 0); drawShadow = !shadow; @@ -347,6 +351,7 @@ void QWhatsThat::paintEvent(QPaintEvent*) rect.translate(-r.x(), -r.y()); p.setClipRect(rect); QAbstractTextDocumentLayout::PaintContext context; + context.palette.setBrush(QPalette::Text, context.palette.toolTipText()); doc->documentLayout()->draw(&p, context); } else diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fb9084e..7026525 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -82,6 +82,8 @@ #include "private/qstyle_p.h" #include "private/qinputcontext_p.h" #include "qfileinfo.h" +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" #if defined (Q_WS_WIN) # include <private/qwininputcontext_p.h> @@ -107,6 +109,7 @@ #include "private/qgraphicsproxywidget_p.h" #include "QtGui/qabstractscrollarea.h" #include "private/qabstractscrollarea_p.h" +#include "private/qevent_p.h" #include "private/qgraphicssystem_p.h" @@ -167,39 +170,48 @@ static inline bool bypassGraphicsProxyWidget(QWidget *p) extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp -QWidgetPrivate::QWidgetPrivate(int version) : - QObjectPrivate(version), extra(0), focus_child(0) - ,layout(0), widgetItem(0) - ,leftmargin(0), topmargin(0), rightmargin(0), bottommargin(0) - ,leftLayoutItemMargin(0), topLayoutItemMargin(0), rightLayoutItemMargin(0) - ,bottomLayoutItemMargin(0) - ,fg_role(QPalette::NoRole) - ,bg_role(QPalette::NoRole) - ,hd(0) - ,dirty(0) - ,needsFlush(0) - ,dirtyOpaqueChildren(1) - ,isOpaque(0) - ,inDirtyList(0) - ,isScrolled(0) - ,isMoved(0) - ,usesDoubleBufferedGLContext(0) -#ifdef Q_WS_WIN - ,noPaintOnScreen(0) -#endif - ,inheritedFontResolveMask(0) - ,inheritedPaletteResolveMask(0) +QWidgetPrivate::QWidgetPrivate(int version) + : QObjectPrivate(version) + , extra(0) + , focus_next(0) + , focus_prev(0) + , focus_child(0) + , layout(0) + , needsFlush(0) + , redirectDev(0) + , widgetItem(0) + , extraPaintEngine(0) + , polished(0) + , inheritedFontResolveMask(0) + , inheritedPaletteResolveMask(0) + , leftmargin(0) + , topmargin(0) + , rightmargin(0) + , bottommargin(0) + , leftLayoutItemMargin(0) + , topLayoutItemMargin(0) + , rightLayoutItemMargin(0) + , bottomLayoutItemMargin(0) + , hd(0) + , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred) + , fg_role(QPalette::NoRole) + , bg_role(QPalette::NoRole) + , dirtyOpaqueChildren(1) + , isOpaque(0) + , inDirtyList(0) + , isScrolled(0) + , isMoved(0) + , usesDoubleBufferedGLContext(0) #if defined(Q_WS_X11) - ,picture(0) + , picture(0) +#elif defined(Q_WS_WIN) + , noPaintOnScreen(0) +#elif defined(Q_WS_MAC) + , needWindowChange(0) + , isGLWidget(0) + , window_event(0) + , qd_hd(0) #endif -#ifdef Q_WS_MAC - ,needWindowChange(0) - ,isGLWidget(0) -#endif - ,polished(0) - - , size_policy(QSizePolicy::Preferred, QSizePolicy::Preferred) - , redirectDev(0) { if (!qApp) { qFatal("QWidget: Must construct a QApplication before a QPaintDevice"); @@ -851,8 +863,8 @@ void QWidget::setAutoFillBackground(bool enabled) \list \o X11: This feature relies on the use of an X server that supports ARGB visuals and a compositing window manager. - \o Windows: This feature requires Windows 2000 or later. The widget needs to have - the Qt::FramelessWindowHint window flag set for the translucency to work. + \o Windows: The widget needs to have the Qt::FramelessWindowHint window flag set + for the translucency to work. \endlist @@ -1027,7 +1039,7 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w) if (customize) ; // don't modify window flags if the user explicitely set them. else if (type == Qt::Dialog || type == Qt::Sheet) -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint; #else flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint; @@ -1043,7 +1055,7 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w) void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) { Q_Q(QWidget); - if (qApp->type() == QApplication::Tty) + if (QApplication::type() == QApplication::Tty) qFatal("QWidget: Cannot create a QWidget when no GUI is being used"); Q_ASSERT(uncreatedWidgets); @@ -1058,7 +1070,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) q->data = &data; #ifndef QT_NO_THREAD - if (!q->parent()) { + if (!parent) { Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget", "Widgets must be created in the GUI thread."); } @@ -1094,7 +1106,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) if (f & Qt::MSWindowsOwnDC) q->setAttribute(Qt::WA_NativeWindow); -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE data.window_state_internal = 0; #endif @@ -1336,7 +1348,7 @@ QWidget::~QWidget() #ifdef QT3_SUPPORT if (QApplicationPrivate::main_widget == this) { // reset main widget QApplicationPrivate::main_widget = 0; - qApp->quit(); + QApplication::quit(); } #endif @@ -1345,7 +1357,7 @@ QWidget::~QWidget() d->setDirtyOpaqueRegion(); if (isWindow() && isVisible() && internalWinId()) - hide(); + d->close_helper(QWidgetPrivate::CloseNoEvent); #if defined(Q_WS_WIN) || defined(Q_WS_X11) else if (!internalWinId() && isVisible()) qApp->d_func()->sendSyntheticEnterLeave(this); @@ -1412,36 +1424,26 @@ void QWidgetPrivate::createTLExtra() createExtra(); if (!extra->topextra) { QTLWExtra* x = extra->topextra = new QTLWExtra; + x->icon = 0; + x->iconPixmap = 0; + x->backingStore = 0; x->windowSurface = 0; + x->sharedPainter = 0; + x->incw = x->inch = 0; + x->basew = x->baseh = 0; + x->frameStrut.setCoords(0, 0, 0, 0); + x->normalGeometry = QRect(0,0,-1,-1); + x->savedFlags = 0; x->opacity = 255; x->posFromMove = false; x->sizeAdjusted = false; x->inTopLevelResize = false; x->inRepaint = false; - x->backingStore = 0; - x->icon = 0; - x->iconPixmap = 0; - x->frameStrut.setCoords(0, 0, 0, 0); - x->incw = x->inch = 0; - x->basew = x->baseh = 0; - x->normalGeometry = QRect(0,0,-1,-1); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) x->embedded = 0; -#endif -#if defined(Q_WS_X11) - x->parentWinId = 0; - x->spont_unmapped = 0; - x->dnd = 0; -#endif - x->savedFlags = 0; -#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) - x->qwsManager = 0; -#endif - x->sharedPainter = 0; createTLSysExtra(); #ifdef QWIDGET_EXTRA_DEBUG - static int count = 0; - qDebug() << "tlextra" << ++count; + static int count = 0; + qDebug() << "tlextra" << ++count; #endif } } @@ -1455,27 +1457,28 @@ void QWidgetPrivate::createExtra() { if (!extra) { // if not exists extra = new QWExtra; - extra->minw = extra->minh = 0; - extra->maxw = extra->maxh = QWIDGETSIZE_MAX; + extra->glContext = 0; + extra->topextra = 0; + extra->proxyWidget = 0; +#ifndef QT_NO_CURSOR + extra->curs = 0; +#endif + extra->minw = 0; + extra->minh = 0; + extra->maxw = QWIDGETSIZE_MAX; + extra->maxh = QWIDGETSIZE_MAX; + extra->customDpiX = 0; + extra->customDpiY = 0; extra->explicitMinSize = 0; extra->explicitMaxSize = 0; extra->autoFillBackground = 0; extra->nativeChildrenForced = 0; extra->inRenderWithPainter = 0; extra->hasMask = 0; -#ifndef QT_NO_CURSOR - extra->curs = 0; -#endif - extra->style = 0; - extra->topextra = 0; - extra->proxyWidget = 0; - extra->glContext = 0; - extra->customDpiX = 0; - extra->customDpiY = 0; createSysExtra(); #ifdef QWIDGET_EXTRA_DEBUG - static int count = 0; - qDebug() << "extra" << ++count; + static int count = 0; + qDebug() << "extra" << ++count; #endif } } @@ -1516,45 +1519,6 @@ void QWidgetPrivate::deleteExtra() } /* - Returns true if the background is inherited; otherwise returns - false. - - Mainly used in the paintOnScreen case. -*/ - -bool QWidgetPrivate::isBackgroundInherited() const -{ - Q_Q(const QWidget); - - // windows do not inherit their background - if (q->isWindow() || q->windowType() == Qt::SubWindow) - return false; - - if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent)) - return false; - - const QPalette &pal = q->palette(); - QPalette::ColorRole bg = q->backgroundRole(); - QBrush brush = pal.brush(bg); - - // non opaque brushes leaves us no choice, we must inherit - if (!q->autoFillBackground() || !brush.isOpaque()) - return true; - - if (brush.style() == Qt::SolidPattern) { - // the background is just a solid color. If there is no - // propagated contents, then we claim as performance - // optimization that it was not inheritet. This is the normal - // case in standard Windows or Motif style. - const QWidget *w = q->parentWidget(); - if (!w->d_func()->isBackgroundInherited()) - return false; - } - - return true; -} - -/* Returns true if there are widgets above this which overlap with \a rect, which is in parent's coordinate system (same as crect). */ @@ -1900,24 +1864,6 @@ void QWidgetPrivate::clipToEffectiveMask(QRegion ®ion) const } } -bool QWidgetPrivate::hasBackground() const -{ - Q_Q(const QWidget); - if (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_PaintOnScreen)) - return true; - if (q->testAttribute(Qt::WA_PaintOnScreen)) - return true; - if (!q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) { - const QPalette &pal = q->palette(); - QPalette::ColorRole bg = q->backgroundRole(); - QBrush bgBrush = pal.brush(bg); - return (bgBrush.style() != Qt::NoBrush && - ((q->isWindow() || q->windowType() == Qt::SubWindow) - || (QPalette::ColorRole(bg_role) != QPalette::NoRole || (pal.resolve() & (1<<bg))))); - } - return false; -} - bool QWidgetPrivate::paintOnScreen() const { #if defined(Q_WS_QWS) @@ -2020,10 +1966,9 @@ void QPixmap::fill( const QWidget *widget, const QPoint &off ) QPainter p(this); p.translate(-off); widget->d_func()->paintBackground(&p, QRect(off, size())); - } -static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush) +static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QBrush &brush) { Q_ASSERT(painter); @@ -2032,26 +1977,39 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoin // Optimize pattern filling on mac by using HITheme directly // when filling with the standard widget background. // Defined in qmacstyle_mac.cpp - extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush); - qt_mac_fill_background(painter, rgn, offset, brush); + extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QBrush &brush); + qt_mac_fill_background(painter, rgn, brush); #else - const QRegion translated = rgn.translated(offset); - const QRect rect(translated.boundingRect()); - painter->setClipRegion(translated); + const QRect rect(rgn.boundingRect()); + painter->setClipRegion(rgn); painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); #endif } else { const QVector<QRect> &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) - painter->fillRect(rects.at(i).translated(offset), brush); + painter->fillRect(rects.at(i), brush); } } - -void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, const QPoint &offset, int flags) const +void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, int flags) const { Q_Q(const QWidget); +#ifndef QT_NO_SCROLLAREA + bool resetBrushOrigin = false; + QPointF oldBrushOrigin; + //If we are painting the viewport of a scrollarea, we must apply an offset to the brush in case we are drawing a texture + QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent); + if (scrollArea && scrollArea->viewport() == q) { + QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr; + QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate); + oldBrushOrigin = painter->brushOrigin(); + resetBrushOrigin = true; + painter->setBrushOrigin(-priv->contentsOffset()); + + } +#endif // QT_NO_SCROLLAREA + const QBrush autoFillBrush = q->palette().brush(q->backgroundRole()); if ((flags & DrawAsRoot) && !(q->autoFillBackground() && autoFillBrush.isOpaque())) { @@ -2060,18 +2018,24 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, cons if (!(flags & DontSetCompositionMode) && painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in #endif - fillRegion(painter, rgn, offset, bg); + fillRegion(painter, rgn, bg); } if (q->autoFillBackground()) - fillRegion(painter, rgn, offset, autoFillBrush); + fillRegion(painter, rgn, autoFillBrush); + if (q->testAttribute(Qt::WA_StyledBackground)) { - painter->setClipRegion(rgn.translated(offset)); + painter->setClipRegion(rgn); QStyleOption opt; opt.initFrom(q); q->style()->drawPrimitive(QStyle::PE_Widget, &opt, painter, q); } + +#ifndef QT_NO_SCROLLAREA + if (resetBrushOrigin) + painter->setBrushOrigin(oldBrushOrigin); +#endif // QT_NO_SCROLLAREA } /* @@ -2091,8 +2055,8 @@ void QWidgetPrivate::deactivateWidgetCleanup() { Q_Q(QWidget); // If this was the active application window, reset it - if (qApp->activeWindow() == q) - qApp->setActiveWindow(0); + if (QApplication::activeWindow() == q) + QApplication::setActiveWindow(0); // If the is the active mouse press widget, reset it if (q == qt_button_down) qt_button_down = 0; @@ -2293,7 +2257,7 @@ QStyle *QWidget::style() const if (d->extra && d->extra->style) return d->extra->style; - return qApp->style(); + return QApplication::style(); } /*! @@ -2969,10 +2933,15 @@ void QWidgetPrivate::setEnabled_helper(bool enable) #if defined(Q_WS_MAC) setEnabled_helper_sys(enable); #endif -#if defined (Q_WS_WIN) - if (q->hasFocus()) - QInputContextPrivate::updateImeStatus(q, true); -#endif + if (q->testAttribute(Qt::WA_InputMethodEnabled) && q->hasFocus()) { + QInputContext *qic = inputContext(); + if (enable) { + qic->setFocusWidget(q); + } else { + qic->reset(); + qic->setFocusWidget(0); + } + } QEvent e(QEvent::EnabledChange); QApplication::sendEvent(q, &e); #ifdef QT3_SUPPORT @@ -4209,7 +4178,7 @@ const QPalette &QWidget::palette() const if (!isEnabled()) { data->pal.setCurrentColorGroup(QPalette::Disabled); } else if ((!isVisible() || isActiveWindow()) -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) +#if defined(Q_OS_WIN) && !defined(Q_WS_WINCE) && !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this)) #endif ) { @@ -4802,7 +4771,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, } const qreal opacity = painter->opacity(); - if (qFuzzyCompare(opacity + 1, qreal(1.0))) + if (qFuzzyIsNull(opacity)) return; // Fully transparent. Q_D(QWidget); @@ -5047,19 +5016,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP && !q->testAttribute(Qt::WA_OpaquePaintEvent) && !q->testAttribute(Qt::WA_NoSystemBackground)) { QPainter p(q); - QPoint scrollAreaOffset; - -#ifndef QT_NO_SCROLLAREA - QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(q->parent()); - if (scrollArea && scrollArea->viewport() == q) { - QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr; - QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate); - scrollAreaOffset = priv->contentsOffset(); - p.translate(-scrollAreaOffset); - } -#endif // QT_NO_SCROLLAREA - - paintBackground(&p, toBePainted, scrollAreaOffset, (asRoot || onScreen) ? flags | DrawAsRoot : 0); + paintBackground(&p, toBePainted, (asRoot || onScreen) ? flags | DrawAsRoot : 0); } if (!sharedPainter) @@ -5293,7 +5250,7 @@ static QString constructWindowTitleFromFilePath(const QString &filePath) #ifndef Q_WS_MAC QString appName = QApplication::applicationName(); if (!appName.isEmpty()) - windowTitle += QLatin1String(" ") + QChar(0x2014) + QLatin1String(" ") + appName; + windowTitle += QLatin1Char(' ') + QChar(0x2014) + QLatin1Char(' ') + appName; #endif return windowTitle; } @@ -5357,7 +5314,7 @@ QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widg && widget->style()->styleHint(QStyle::SH_TitleBar_ModifyNotification, 0, widget)) cap.replace(lastIndex, 3, QWidget::tr("*")); else - cap.replace(lastIndex, 3, QLatin1String("")); + cap.remove(lastIndex, 3); } index = cap.indexOf(placeHolder, index); @@ -5429,7 +5386,7 @@ QIcon QWidget::windowIcon() const return *d->extra->topextra->icon; w = w->parentWidget(); } - return qApp->windowIcon(); + return QApplication::windowIcon(); } void QWidgetPrivate::setWindowIcon_helper() @@ -5492,8 +5449,6 @@ QString QWidget::windowIconText() const \list \o The file name of the specified path, obtained using QFileInfo::fileName(). - \o An optional \c{*} character, if the \l windowModified property is set, - as per the Apple Human Interface Guidelines. \endlist On Windows and X11: @@ -5542,7 +5497,7 @@ void QWidgetPrivate::setWindowFilePath_helper(const QString &filePath) { if (extra->topextra && extra->topextra->caption.isEmpty()) { #ifdef Q_WS_MAC - setWindowTitle_helper(filePath); + setWindowTitle_helper(QFileInfo(filePath).fileName()); #else Q_Q(QWidget); Q_UNUSED(filePath); @@ -5692,7 +5647,7 @@ bool QWidget::hasFocus() const called from focusOutEvent() or focusInEvent(), you may get an infinite recursion. - \sa focus(), hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(), + \sa hasFocus(), clearFocus(), focusInEvent(), focusOutEvent(), setFocusPolicy(), focusWidget(), QApplication::focusWidget(), grabKeyboard(), grabMouse(), {Keyboard Focus} */ @@ -5913,6 +5868,8 @@ QWidget *QWidget::focusWidget() const /*! Returns the next widget in this widget's focus chain. + + \sa previousInFocusChain() */ QWidget *QWidget::nextInFocusChain() const { @@ -5920,6 +5877,18 @@ QWidget *QWidget::nextInFocusChain() const } /*! + Returns the previous widget in this widget's focus chain. + + \sa nextInFocusChain() + + \since 4.6 +*/ +QWidget *QWidget::previousInFocusChain() const +{ + return const_cast<QWidget *>(d_func()->focus_prev); +} + +/*! \property QWidget::isActiveWindow \brief whether this widget's window is the active window @@ -5937,7 +5906,7 @@ QWidget *QWidget::nextInFocusChain() const bool QWidget::isActiveWindow() const { QWidget *tlw = window(); - if(tlw == qApp->activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup))) + if(tlw == QApplication::activeWindow() || (isVisible() && (tlw->windowType() == Qt::Popup))) return true; #ifndef QT_NO_GRAPHICSVIEW @@ -5958,7 +5927,7 @@ bool QWidget::isActiveWindow() const !tlw->isModal() && (!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow())) return true; - QWidget *w = qApp->activeWindow(); + QWidget *w = QApplication::activeWindow(); while(w && tlw->windowType() == Qt::Tool && !w->isModal() && w->parentWidget()) { w = w->parentWidget()->window(); @@ -6157,14 +6126,6 @@ int QWidgetPrivate::pointToRect(const QPoint &p, const QRect &r) return dx + dy; } -QRect QWidgetPrivate::fromOrToLayoutItemRect(const QRect &rect, int sign) const -{ - QRect r = rect; - r.adjust(-sign * leftLayoutItemMargin, -sign * topLayoutItemMargin, - +sign * rightLayoutItemMargin, +sign * bottomLayoutItemMargin); - return r; -} - /*! \property QWidget::frameSize \brief the size of the widget including any window frame @@ -7136,7 +7097,7 @@ bool QWidgetPrivate::close_helper(CloseMode mode) #ifdef QT3_SUPPORT if (isMain) - qApp->quit(); + QApplication::quit(); #endif // Attempt to close the application only if this widget has the // WA_QuitOnClose flag set set and has a non-visible parent @@ -7319,10 +7280,10 @@ QSize QWidgetPrivate::adjustedSize() const if (q->isWindow()) { Qt::Orientations exp; - if (QLayout *l = q->layout()) { - if (l->hasHeightForWidth()) - s.setHeight(l->totalHeightForWidth(s.width())); - exp = l->expandingDirections(); + if (layout) { + if (layout->hasHeightForWidth()) + s.setHeight(layout->totalHeightForWidth(s.width())); + exp = layout->expandingDirections(); } else { if (q->sizePolicy().hasHeightForWidth()) @@ -7338,7 +7299,7 @@ QSize QWidgetPrivate::adjustedSize() const #else // all others QRect screen = QApplication::desktop()->screenGeometry(q->pos()); #endif -#if defined (Q_OS_WINCE) +#if defined (Q_WS_WINCE) s.setWidth(qMin(s.width(), screen.width())); s.setHeight(qMin(s.height(), screen.height())); #else @@ -7525,6 +7486,9 @@ bool QWidget::event(QEvent *event) case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: case QEvent::ContextMenu: #ifndef QT_NO_WHEELEVENT case QEvent::Wheel: @@ -7646,16 +7610,10 @@ bool QWidget::event(QEvent *event) } break; case QEvent::FocusIn: -#if defined(Q_WS_WIN) - QInputContextPrivate::updateImeStatus(this, true); -#endif focusInEvent((QFocusEvent*)event); break; case QEvent::FocusOut: -#if defined(Q_WS_WIN) - QInputContextPrivate::updateImeStatus(this, false); -#endif focusOutEvent((QFocusEvent*)event); break; @@ -7841,7 +7799,7 @@ bool QWidget::event(QEvent *event) QList<QObject*> childList = d->children; for (int i = 0; i < childList.size(); ++i) { QObject *o = childList.at(i); - if (o != qApp->activeModalWidget()) { + if (o != QApplication::activeModalWidget()) { if (qobject_cast<QWidget *>(o) && static_cast<QWidget *>(o)->isWindow()) { // do not forward the event to child windows, // QApplication does this for us @@ -7930,6 +7888,96 @@ bool QWidget::event(QEvent *event) d->needWindowChange = false; break; #endif + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + { + QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event); + const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first(); + if (touchPoint.isPrimary()) + break; + + // fake a mouse event! + QEvent::Type eventType = QEvent::None; + switch (touchEvent->type()) { + case QEvent::TouchBegin: + eventType = QEvent::MouseButtonPress; + break; + case QEvent::TouchUpdate: + eventType = QEvent::MouseMove; + break; + case QEvent::TouchEnd: + eventType = QEvent::MouseButtonRelease; + break; + default: + Q_ASSERT(!true); + break; + } + if (eventType == QEvent::None) + break; + + QMouseEvent mouseEvent(eventType, + touchPoint.pos().toPoint(), + touchPoint.screenPos().toPoint(), + Qt::LeftButton, + Qt::LeftButton, + touchEvent->modifiers()); + (void) QApplication::sendEvent(this, &mouseEvent); + break; + } +#ifdef Q_WS_WIN + case QEvent::WinGesture: { + QWinGestureEvent *ev = static_cast<QWinGestureEvent*>(event); + QApplicationPrivate *qAppPriv = qApp->d_func(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(this); + if (it != qAppPriv->widgetGestures.end()) { + Qt::GestureState state = Qt::GestureUpdated; + if (qAppPriv->lastGestureId == 0) + state = Qt::GestureStarted; + QWinGestureEvent::Type type = ev->gestureType; + if (ev->gestureType == QWinGestureEvent::GestureEnd) { + type = (QWinGestureEvent::Type)qAppPriv->lastGestureId; + state = Qt::GestureFinished; + } + + QGesture *gesture = 0; + switch (type) { + case QWinGestureEvent::Pan: { + QPanGesture *pan = it.value().pan; + gesture = pan; + if (state == Qt::GestureStarted) { + gesture->setStartPos(ev->position); + gesture->setLastPos(ev->position); + } else { + gesture->setLastPos(gesture->pos()); + } + gesture->setPos(ev->position); + break; + } + case QWinGestureEvent::Pinch: + break; + default: + break; + } + if (gesture) { + gesture->setState(state); + if (state == Qt::GestureStarted) + emit gesture->started(); + emit gesture->triggered(); + if (state == Qt::GestureFinished) + emit gesture->finished(); + event->accept(); + } + if (ev->gestureType == QWinGestureEvent::GestureEnd) { + qAppPriv->lastGestureId = 0; + } else { + qAppPriv->lastGestureId = type; + } + } + break; + } +#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName(); @@ -8064,9 +8112,9 @@ void QWidget::mousePressEvent(QMouseEvent *event) if ((windowType() == Qt::Popup)) { event->accept(); QWidget* w; - while ((w = qApp->activePopupWidget()) && w != this){ + while ((w = QApplication::activePopupWidget()) && w != this){ w->close(); - if (qApp->activePopupWidget() == w) // widget does not want to dissappear + if (QApplication::activePopupWidget() == w) // widget does not want to dissappear w->hide(); // hide at least } if (!rect().contains(event->pos())){ @@ -9261,11 +9309,12 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) d->resolveLayoutDirection(); d->resolveLocale(); - // Note: GL widgets under Windows will always need a ParentChange - // event to handle recreation/rebinding of the GL context, hence - // the (f & Qt::MSWindowsOwnDC) clause + // Note: GL widgets under WGL or EGL will always need a ParentChange + // event to handle recreation/rebinding of the GL context, hence the + // (f & Qt::MSWindowsOwnDC) clause (which is set on QGLWidgets on all + // platforms). if (newParent -#ifdef Q_WS_WIN +#if defined(Q_WS_WIN) || defined(QT_OPENGL_ES) || (f & Qt::MSWindowsOwnDC) #endif ) { @@ -9811,27 +9860,6 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) QEvent e(QEvent::MouseTrackingChange); QApplication::sendEvent(this, &e); break; } -#if !defined(QT_NO_DIRECT3D) && defined(Q_WS_WIN) - case Qt::WA_MSWindowsUseDirect3D: - if (!qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault)) { - if (on) { - if (!d->extra) - d->createExtra(); - d->extra->had_auto_fill_bg = d->extra->autoFillBackground; - d->extra->had_no_system_bg = testAttribute(Qt::WA_NoSystemBackground); - d->extra->had_paint_on_screen = testAttribute(Qt::WA_PaintOnScreen); - // enforce the opaque widget state D3D needs - d->extra->autoFillBackground = true; - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - } else if (d->extra) { - d->extra->autoFillBackground = d->extra->had_auto_fill_bg; - setAttribute(Qt::WA_PaintOnScreen, d->extra->had_paint_on_screen); - setAttribute(Qt::WA_NoSystemBackground, d->extra->had_no_system_bg); - } - } - break; -#endif case Qt::WA_NativeWindow: { QInputContext *ic = 0; if (on && !internalWinId() && testAttribute(Qt::WA_InputMethodEnabled) && hasFocus()) { @@ -9843,7 +9871,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) parentWidget()->d_func()->enforceNativeChildren(); if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created)) d->createWinId(); - if (ic) + if (ic && isEnabled()) ic->setFocusWidget(this); break; } @@ -9874,15 +9902,11 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) #endif break; case Qt::WA_InputMethodEnabled: { -#if defined(Q_WS_WIN) || (defined(Q_WS_QWS) && !defined(QT_NO_QWS_INPUTMETHODS)) - if (hasFocus()) - QInputContextPrivate::updateImeStatus(this, true); -#endif QInputContext *ic = d->ic; if (!ic && (!on || hasFocus())) ic = d->inputContext(); if (ic) { - if (on && hasFocus() && ic->focusWidget() != this) { + if (on && hasFocus() && ic->focusWidget() != this && isEnabled()) { ic->setFocusWidget(this); } else if (!on && ic->focusWidget() == this) { ic->reset(); @@ -9959,6 +9983,12 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) } break; + case Qt::WA_AcceptTouchEvents: +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) + if (on) + d->registerTouchWindow(); +#endif + break; default: break; } @@ -9989,8 +10019,8 @@ bool QWidget::testAttribute_helper(Qt::WidgetAttribute attribute) const By default the value of this property is 1.0. - This feature is available on Embedded Linux, Mac OS X, X11 platforms that - support the Composite extension, and Windows 2000 and later. + This feature is available on Embedded Linux, Mac OS X, Windows, + and X11 platforms that support the Composite extension. This feature is not available on Windows CE. diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 40ff671..bc9952c 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -95,6 +95,7 @@ class QIcon; class QWindowSurface; class QLocale; class QGraphicsProxyWidget; +class QGestureManager; #if defined(Q_WS_X11) class QX11Info; #endif @@ -130,7 +131,7 @@ public: int alloc_region_index; // int alloc_region_revision; #endif -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) uint window_state_internal : 4; #endif QRect wrect; @@ -469,7 +470,7 @@ public Q_SLOTS: virtual void setVisible(bool visible); inline void setHidden(bool hidden) { setVisible(!hidden); } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE inline void show() { setVisible(true); } #else void show(); @@ -539,6 +540,7 @@ public: QWidget *focusWidget() const; QWidget *nextInFocusChain() const; + QWidget *previousInFocusChain() const; // drag and drop bool acceptDrops() const; diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index f96d061..1717fbd 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -83,6 +83,7 @@ #include "qcursor.h" #include "qdesktopwidget.h" #include "qevent.h" +#include "qfileinfo.h" #include "qimage.h" #include "qlayout.h" #include "qmenubar.h" @@ -390,21 +391,15 @@ QWidget *qt_mac_find_window(OSWindowRef window) inline static void qt_mac_set_fullscreen_mode(bool b) { - extern bool qt_mac_app_fullscreen; //qapplication_mac.cpp + extern bool qt_mac_app_fullscreen; //qapplication_mac.mm if(qt_mac_app_fullscreen == b) return; qt_mac_app_fullscreen = b; -#if QT_MAC_USE_COCOA - if(b) - SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); - else + if (b) { + SetSystemUIMode(kUIModeAllSuppressed, 0); + } else { SetSystemUIMode(kUIModeNormal, 0); -#else - if(b) - HideMenuBar(); - else - ShowMenuBar(); -#endif + } } Q_GUI_EXPORT OSViewRef qt_mac_nativeview_for(const QWidget *w) @@ -511,16 +506,9 @@ static void qt_mac_release_window_group(WindowGroupRef group) SInt32 qt_mac_get_group_level(WindowClass wclass) { SInt32 group_level; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - CGWindowLevel tmpLevel; - GetWindowGroupLevelOfType(GetWindowGroupOfClass(wclass), kWindowGroupLevelActive, &tmpLevel); - group_level = tmpLevel; - } else -#endif - { - GetWindowGroupLevel(GetWindowGroupOfClass(wclass), &group_level); - } + CGWindowLevel tmpLevel; + GetWindowGroupLevelOfType(GetWindowGroupOfClass(wclass), kWindowGroupLevelActive, &tmpLevel); + group_level = tmpLevel; return group_level; } #endif @@ -734,6 +722,7 @@ static OSWindowRef qt_mac_create_window(QWidget *, WindowClass wclass, WindowAtt static EventTypeSpec window_events[] = { { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowExpanded }, + { kEventClassWindow, kEventWindowHidden }, { kEventClassWindow, kEventWindowZoomed }, { kEventClassWindow, kEventWindowCollapsed }, { kEventClassWindow, kEventWindowToolbarSwitchMode }, @@ -741,11 +730,8 @@ static EventTypeSpec window_events[] = { { kEventClassWindow, kEventWindowProxyEndDrag }, { kEventClassWindow, kEventWindowResizeCompleted }, { kEventClassWindow, kEventWindowBoundsChanging }, - { kEventClassWindow, kEventWindowBoundsChanged }, { kEventClassWindow, kEventWindowGetRegion }, -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 { kEventClassWindow, kEventWindowGetClickModality }, -#endif { kEventClassWindow, kEventWindowTransitionCompleted }, { kEventClassMouse, kEventMouseDown } }; @@ -775,7 +761,6 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, QWidget *widget = qt_mac_find_window(wid); if(!widget) { handled_event = false; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 } else if(ekind == kEventWindowGetClickModality) { // Carbon will send us kEventWindowGetClickModality before every // mouse press / release event. By returning 'true', we tell Carbon @@ -786,7 +771,6 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, // By also setting the current modal window back into the event, we // help Carbon determining which window is supposed to be raised. handled_event = qApp->activePopupWidget() ? true : false; -#endif } else if(ekind == kEventWindowClose) { widget->d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); QMenuBar::macUpdateMenuBar(); @@ -860,8 +844,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp qt_button_down = 0; } else if(ekind == kEventWindowToolbarSwitchMode) { - QToolBarChangeEvent ev(!(GetCurrentKeyModifiers() & cmdKey)); - QApplication::sendSpontaneousEvent(widget, &ev); + macSendToolbarChangeEvent(widget); HIToolbarRef toolbar; if (GetWindowToolbar(wid, &toolbar) == noErr) { if (toolbar) { @@ -909,90 +892,94 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, SetEventParameter(mouseUpEvent, kEventParamMouseLocation, typeQDPoint, sizeof(pos), &pos); SendEventToApplication(mouseUpEvent); ReleaseEvent(mouseUpEvent); - } else if(ekind == kEventWindowBoundsChanging || ekind == kEventWindowBoundsChanged) { - // Panther doesn't send Changing for sheets, only changed, so only - // bother handling Changed event if we are on 10.3 and we are a - // sheet. - if (ekind == kEventWindowBoundsChanged - && (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4 - || !(widget->windowFlags() & Qt::Sheet))) { - handled_event = false; + } else if(ekind == kEventWindowBoundsChanging) { + UInt32 flags = 0; + GetEventParameter(event, kEventParamAttributes, typeUInt32, 0, + sizeof(flags), 0, &flags); + Rect nr; + GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, 0, + sizeof(nr), 0, &nr); + + QRect newRect(nr.left, nr.top, nr.right - nr.left, nr.bottom - nr.top); + + QTLWExtra * const tlwExtra = widget->d_func()->maybeTopData(); + if (tlwExtra && tlwExtra->isSetGeometry == 1) { + widget->d_func()->setGeometry_sys_helper(newRect.left(), newRect.top(), newRect.width(), newRect.height(), tlwExtra->isMove); } else { - UInt32 flags = 0; - GetEventParameter(event, kEventParamAttributes, typeUInt32, 0, - sizeof(flags), 0, &flags); - Rect nr; - GetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, 0, - sizeof(nr), 0, &nr); - - QRect newRect(nr.left, nr.top, nr.right - nr.left, nr.bottom - nr.top); - - QTLWExtra * const tlwExtra = widget->d_func()->maybeTopData(); - if (tlwExtra && tlwExtra->isSetGeometry == 1) { - widget->d_func()->setGeometry_sys_helper(newRect.left(), newRect.top(), newRect.width(), newRect.height(), tlwExtra->isMove); - } else { - //implicitly removes the maximized bit - if((widget->data->window_state & Qt::WindowMaximized) && - IsWindowInStandardState(wid, 0, 0)) { - widget->data->window_state &= ~Qt::WindowMaximized; - QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state - | Qt::WindowMaximized)); - QApplication::sendSpontaneousEvent(widget, &e); + //implicitly removes the maximized bit + if((widget->data->window_state & Qt::WindowMaximized) && + IsWindowInStandardState(wid, 0, 0)) { + widget->data->window_state &= ~Qt::WindowMaximized; + QWindowStateChangeEvent e(Qt::WindowStates(widget->data->window_state + | Qt::WindowMaximized)); + QApplication::sendSpontaneousEvent(widget, &e); - } + } - handled_event = false; - const QRect oldRect = widget->data->crect; - if((flags & kWindowBoundsChangeOriginChanged)) { - if(nr.left != oldRect.x() || nr.top != oldRect.y()) { - widget->data->crect.moveTo(nr.left, nr.top); - QMoveEvent qme(widget->data->crect.topLeft(), oldRect.topLeft()); - QApplication::sendSpontaneousEvent(widget, &qme); - } + handled_event = false; + const QRect oldRect = widget->data->crect; + if((flags & kWindowBoundsChangeOriginChanged)) { + if(nr.left != oldRect.x() || nr.top != oldRect.y()) { + widget->data->crect.moveTo(nr.left, nr.top); + QMoveEvent qme(widget->data->crect.topLeft(), oldRect.topLeft()); + QApplication::sendSpontaneousEvent(widget, &qme); } - if((flags & kWindowBoundsChangeSizeChanged)) { - if (widget->isWindow()) { - QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size()); - int dh = newSize.height() - newRect.height(); - int dw = newSize.width() - newRect.width(); - if (dw != 0 || dh != 0) { - handled_event = true; // We want to change the bounds, so we handle the event - - // set the rect, so we can also do the resize down below (yes, we need to resize). - newRect.setBottom(newRect.bottom() + dh); - newRect.setRight(newRect.right() + dw); - - nr.left = newRect.x(); - nr.top = newRect.y(); - nr.right = nr.left + newRect.width(); - nr.bottom = nr.top + newRect.height(); - SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &nr); - } + } + if((flags & kWindowBoundsChangeSizeChanged)) { + if (widget->isWindow()) { + QSize newSize = QLayout::closestAcceptableSize(widget, newRect.size()); + int dh = newSize.height() - newRect.height(); + int dw = newSize.width() - newRect.width(); + if (dw != 0 || dh != 0) { + handled_event = true; // We want to change the bounds, so we handle the event + + // set the rect, so we can also do the resize down below (yes, we need to resize). + newRect.setBottom(newRect.bottom() + dh); + newRect.setRight(newRect.right() + dw); + + nr.left = newRect.x(); + nr.top = newRect.y(); + nr.right = nr.left + newRect.width(); + nr.bottom = nr.top + newRect.height(); + SetEventParameter(event, kEventParamCurrentBounds, typeQDRectangle, sizeof(Rect), &nr); } + } - if (oldRect.width() != newRect.width() || oldRect.height() != newRect.height()) { - widget->data->crect.setSize(newRect.size()); - HIRect bounds = CGRectMake(0, 0, newRect.width(), newRect.height()); - - // If the WA_StaticContents attribute is set we can optimize the resize - // by only repainting the newly exposed area. We do this by disabling - // painting when setting the size of the view. The OS will invalidate - // the newly exposed area for us. - const bool staticContents = widget->testAttribute(Qt::WA_StaticContents); - const HIViewRef view = qt_mac_nativeview_for(widget); - if (staticContents) - HIViewSetDrawingEnabled(view, false); - HIViewSetFrame(view, &bounds); - if (staticContents) - HIViewSetDrawingEnabled(view, true); - - QResizeEvent qre(newRect.size(), oldRect.size()); - QApplication::sendSpontaneousEvent(widget, &qre); - qt_event_request_window_change(widget); - } + if (oldRect.width() != newRect.width() || oldRect.height() != newRect.height()) { + widget->data->crect.setSize(newRect.size()); + HIRect bounds = CGRectMake(0, 0, newRect.width(), newRect.height()); + + // If the WA_StaticContents attribute is set we can optimize the resize + // by only repainting the newly exposed area. We do this by disabling + // painting when setting the size of the view. The OS will invalidate + // the newly exposed area for us. + const bool staticContents = widget->testAttribute(Qt::WA_StaticContents); + const HIViewRef view = qt_mac_nativeview_for(widget); + if (staticContents) + HIViewSetDrawingEnabled(view, false); + HIViewSetFrame(view, &bounds); + if (staticContents) + HIViewSetDrawingEnabled(view, true); + + QResizeEvent qre(newRect.size(), oldRect.size()); + QApplication::sendSpontaneousEvent(widget, &qre); + qt_event_request_window_change(widget); } } } + } else if (ekind == kEventWindowHidden) { + // Make sure that we also hide any visible sheets on our window. + // Cocoa does the right thing for us. + const QObjectList children = widget->children(); + const int childCount = children.count(); + for (int i = 0; i < childCount; ++i) { + QObject *obj = children.at(i); + if (obj->isWidgetType()) { + QWidget *widget = static_cast<QWidget *>(obj); + if (qt_mac_is_macsheet(widget) && widget->isVisible()) + widget->hide(); + } + } } else { handled_event = false; } @@ -1211,22 +1198,13 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, p.setClipping(false); if(was_unclipped) widget->setAttribute(Qt::WA_PaintUnclipped); - - QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(widget->parent()); - QPoint scrollAreaOffset; - if (scrollArea && scrollArea->viewport() == widget) { - QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(static_cast<QWidget *>(scrollArea)->d_ptr); - scrollAreaOffset = priv->contentsOffset(); - p.translate(-scrollAreaOffset); - } - - widget->d_func()->paintBackground(&p, qrgn, scrollAreaOffset, widget->isWindow() ? DrawAsRoot : 0); + widget->d_func()->paintBackground(&p, qrgn, widget->isWindow() ? DrawAsRoot : 0); if (widget->testAttribute(Qt::WA_TintedBackground)) { QColor tint = widget->palette().window().color(); tint.setAlphaF(.6); const QVector<QRect> &rects = qrgn.rects(); for (int i = 0; i < rects.size(); ++i) - p.fillRect(rects.at(i).translated(scrollAreaOffset), tint); + p.fillRect(rects.at(i), tint); } p.end(); if (!redirectionOffset.isNull()) @@ -1382,6 +1360,14 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, // Set dropWidget to zero, so qt_mac_dnd_event // doesn't get called a second time below: dropWidget = 0; + } else if (ekind == kEventControlDragLeave) { + dropWidget = QDragManager::self()->currentTarget(); + if (dropWidget) { + dropWidget->d_func()->qt_mac_dnd_event(kEventControlDragLeave, drag); + } + // Set dropWidget to zero, so qt_mac_dnd_event + // doesn't get called a second time below: + dropWidget = 0; } } } @@ -1598,24 +1584,6 @@ bool QWidgetPrivate::qt_create_root_win() return true; } -bool QWidgetPrivate::qt_recreate_root_win() -{ - if(!qt_root_win) //sanity check - return false; - //store old - OSWindowRef old_root_win = qt_root_win; - //recreate - qt_root_win = 0; - qt_create_root_win(); - //cleanup old window -#ifdef QT_MAC_USE_COCOA - [old_root_win release]; -#else - CFRelease(old_root_win); -#endif - return true; -} - bool QWidgetPrivate::qt_widget_rgn(QWidget *widget, short wcode, RgnHandle rgn, bool force = false) { bool ret = false; @@ -1716,17 +1684,11 @@ void QWidgetPrivate::determineWindowClass() bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint))); if (framelessWindow) { if(wclass == kDocumentWindowClass) { - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) - wattr |= kWindowNoTitleBarAttribute; - else - wclass = kPlainWindowClass; + wattr |= kWindowNoTitleBarAttribute; } else if(wclass == kFloatingWindowClass) { - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) - wattr |= kWindowNoTitleBarAttribute; - else - wclass = kToolbarWindowClass; + wattr |= kWindowNoTitleBarAttribute; } else if (wclass == kMovableModalWindowClass) { - wclass = kModalWindowClass; + wclass = kModalWindowClass; } } else { if(wclass != kModalWindowClass) @@ -2024,14 +1986,10 @@ void QWidgetPrivate::finishCreateWindow_sys_Carbon(OSWindowRef windowRef) if (!desktop) SetAutomaticControlDragTrackingEnabledForWindow(windowRef, true); HIWindowChangeFeatures(windowRef, kWindowCanCollapse, 0); -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - if (wattr & kWindowHideOnSuspendAttribute) - HIWindowChangeAvailability(windowRef, kHIWindowExposeHidden, 0); - else - HIWindowChangeAvailability(windowRef, 0, kHIWindowExposeHidden); - } -#endif + if (wattr & kWindowHideOnSuspendAttribute) + HIWindowChangeAvailability(windowRef, kHIWindowExposeHidden, 0); + else + HIWindowChangeAvailability(windowRef, 0, kHIWindowExposeHidden); if ((flags & Qt::WindowStaysOnTopHint)) ChangeWindowAttributes(windowRef, kWindowNoAttributes, kWindowHideOnSuspendAttribute); if (qt_mac_is_macdrawer(q) && parentWidget) @@ -2524,9 +2482,10 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO setFocus_sys(); if (!topLevel && initializeWindow) setWSGeometry(); - if (destroyid) qt_mac_destructView(destroyid); + if (q->testAttribute(Qt::WA_AcceptTouchEvents)) + registerTouchWindow(); } /*! @@ -2897,8 +2856,7 @@ void QWidgetPrivate::setWindowTitle_sys(const QString &caption) SetWindowTitleWithCFString(qt_mac_window_for(q), QCFString(caption)); #else QMacCocoaAutoReleasePool pool; - [qt_mac_window_for(q) - setTitle:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(caption)))]; + [qt_mac_window_for(q) setTitle:qt_mac_QStringToNSString(caption)]; #endif } } @@ -2920,7 +2878,8 @@ void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath) Q_Q(QWidget); #ifdef QT_MAC_USE_COCOA QMacCocoaAutoReleasePool pool; - [qt_mac_window_for(q) setRepresentedFilename:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(filePath)))]; + QFileInfo fi(filePath); + [qt_mac_window_for(q) setRepresentedFilename:fi.exists() ? qt_mac_QStringToNSString(filePath) : @""]; #else bool validRef = false; FSRef ref; @@ -2933,21 +2892,10 @@ void QWidgetPrivate::setWindowFilePath_sys(const QString &filePath) } // Set the proxy regardless, since this is our way of clearing it as well, but ignore the // return value as well. - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - if (validRef) { - status = HIWindowSetProxyFSRef(qt_mac_window_for(q), &ref); - } else { - status = RemoveWindowProxy(qt_mac_window_for(q)); - } + if (validRef) { + status = HIWindowSetProxyFSRef(qt_mac_window_for(q), &ref); } else { - // Convert to an FSSpec and set it. It's deprecated but it works for where we don't have the other call. - if (validRef) { - FSSpec fsspec; - FSGetCatalogInfo(&ref, kFSCatInfoNone, 0, 0, &fsspec, 0); - status = SetWindowProxyFSSpec(qt_mac_window_for(q), &fsspec); - } else { - status = RemoveWindowProxy(qt_mac_window_for(q)); - } + status = RemoveWindowProxy(qt_mac_window_for(q)); } if (status != noErr) qWarning("QWidget::setWindowFilePath: Error setting proxyicon for path (%s):%ld", @@ -3021,8 +2969,7 @@ void QWidgetPrivate::setWindowIconText_sys(const QString &iconText) SetWindowAlternateTitle(qt_mac_window_for(q), QCFString(iconText)); #else QMacCocoaAutoReleasePool pool; - [qt_mac_window_for(q) - setMiniwindowTitle:reinterpret_cast<const NSString *>(static_cast<CFStringRef>(QCFString(iconText)))]; + [qt_mac_window_for(q) setMiniwindowTitle:qt_mac_QStringToNSString(iconText)]; #endif } } @@ -3155,16 +3102,9 @@ void QWidgetPrivate::update_sys(const QRect &r) if (updateRedirectedToGraphicsProxyWidget(q, updateRect)) return; #ifndef QT_MAC_USE_COCOA -# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - dirtyOnWidget += updateRect; - HIRect r = CGRectMake(x, y, w, h); - HIViewSetNeedsDisplayInRect(qt_mac_nativeview_for(q), &r, true); - } else - #endif - { - q->update(QRegion(updateRect)); - } + dirtyOnWidget += updateRect; + HIRect r = CGRectMake(x, y, w, h); + HIViewSetNeedsDisplayInRect(qt_mac_nativeview_for(q), &r, true); #else [qt_mac_nativeview_for(q) setNeedsDisplayInRect:NSMakeRect(x, y, w, h)]; #endif @@ -3876,8 +3816,6 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) Qt coordinate system for parent X coordinate system for parent (relative to parent's wrect). */ - QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX); - QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); QRect wrect; //xrect is the X geometry of my X widget. (starts out in parent's Qt coord sys, and ends up in parent's X coord sys) QRect xrect = data.crect; @@ -3899,6 +3837,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) parentWRect = QRect(tmpRect.origin.x, tmpRect.origin.y, tmpRect.size.width, tmpRect.size.height); } else { + const QRect wrectRange(-WRECT_MAX,-WRECT_MAX, 2*WRECT_MAX, 2*WRECT_MAX); parentWRect = wrectRange; } } else { @@ -3954,15 +3893,24 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) } } + const QRect validRange(-XCOORD_MAX,-XCOORD_MAX, 2*XCOORD_MAX, 2*XCOORD_MAX); if (!validRange.contains(xrect)) { // we are too big, and must clip - xrect &=wrectRange; + QPoint screenOffset(0, 0); // offset of the part being on screen + const QWidget *parentWidget = q->parentWidget(); + while (parentWidget && !parentWidget->isWindow()) { + screenOffset -= parentWidget->data->crect.topLeft(); + parentWidget = parentWidget->parentWidget(); + } + QRect cropRect(screenOffset.x() - WRECT_MAX, + screenOffset.y() - WRECT_MAX, + 2*WRECT_MAX, + 2*WRECT_MAX); + + xrect &=cropRect; wrect = xrect; - wrect.translate(-data.crect.topLeft()); - //parent's X coord system is equal to parent's Qt coord - //sys, so we don't need to map xrect. + wrect.translate(-data.crect.topLeft()); // translate wrect in my Qt coordinates } - } // unmap if we are outside the valid window system coord system @@ -4002,10 +3950,9 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect) qt_mac_update_widget_posisiton(q, oldRect, xrect); - if (jump) { - updateSystemBackground(); + if (jump) q->update(); - } + if (mapWindow && !dontShow) { q->setAttribute(Qt::WA_Mapped); #ifndef QT_MAC_USE_COCOA @@ -4326,32 +4273,14 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) OSViewRef view = qt_mac_nativeview_for(q); #ifndef QT_MAC_USE_COCOA HIRect scrollrect = CGRectMake(r.x(), r.y(), r.width(), r.height()); -# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { - OSStatus err = _HIViewScrollRectWithOptions(view, valid_rect ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid); - if (err) { - // The only parameter that can go wrong, is the rect. - qWarning("QWidget::scroll: Your rectangle was too big for the widget, clipping rect"); - scrollrect = CGRectMake(qMax(r.x(), 0), qMax(r.y(), 0), - qMin(r.width(), q->width()), qMin(r.height(), q->height())); - _HIViewScrollRectWithOptions(view, valid_rect ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid); - } - } else { - if (HIViewGetNeedsDisplay(view)) { - q->update(valid_rect ? r : q->rect()); - return; - } - HIRect scrollrect = CGRectMake(r.x(), r.y(), r.width(), r.height()); - OSStatus err = HIViewScrollRect(view, valid_rect ? &scrollrect : 0, dx, dy); - if (err) { - // The only parameter that can go wrong, is the rect. - qWarning("QWidget::scroll: Your rectangle was too big for the widget, clipping rect"); - scrollrect = CGRectMake(qMax(r.x(), 0), qMax(r.y(), 0), - qMin(r.width(), q->width()), qMin(r.height(), q->height())); - HIViewScrollRect(view, valid_rect ? &scrollrect : 0, dx, dy); - } + OSStatus err = _HIViewScrollRectWithOptions(view, valid_rect ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid); + if (err) { + // The only parameter that can go wrong, is the rect. + qWarning("QWidget::scroll: Your rectangle was too big for the widget, clipping rect"); + scrollrect = CGRectMake(qMax(r.x(), 0), qMax(r.y(), 0), + qMin(r.width(), q->width()), qMin(r.height(), q->height())); + _HIViewScrollRectWithOptions(view, valid_rect ? &scrollrect : 0, dx, dy, kHIViewScrollRectAdjustInvalid); } -# endif #else NSRect scrollRect = valid_rect ? NSMakeRect(r.x(), r.y(), r.width(), r.height()) : NSMakeRect(0, 0, q->width(), q->height()); @@ -4379,20 +4308,9 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &r) } } - // ### Scroll the dirty regions as well, the following is not correct. - QRegion displayRegion = r.isNull() ? dirtyOnWidget : (dirtyOnWidget & r); - const QVector<QRect> &rects = dirtyOnWidget.rects(); - const QVector<QRect>::const_iterator end = rects.end(); - QVector<QRect>::const_iterator it = rects.begin(); - while (it != end) { - const QRect rect = *it; - const NSRect dirtyRect = NSMakeRect(rect.x() + dx, rect.y() + dy, - rect.width(), rect.height()); - [view setNeedsDisplayInRect:dirtyRect]; - ++it; - } - [view scrollRect:scrollRect by:NSMakeSize(dx, dy)]; - // Yes, we potentially send a duplicate area, but I think Cocoa can handle it. + NSSize deltaSize = NSMakeSize(dx, dy); + [view translateRectsNeedingDisplayInRect:scrollRect by:deltaSize]; + [view scrollRect:scrollRect by:deltaSize]; [view setNeedsDisplayInRect:deltaXRect]; [view setNeedsDisplayInRect:deltaYRect]; #endif // QT_MAC_USE_COCOA @@ -4462,11 +4380,13 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::createTLSysExtra() { + extra->topextra->resizer = 0; + extra->topextra->isSetGeometry = 0; + extra->topextra->isMove = 0; + extra->topextra->wattr = 0; extra->topextra->wclass = 0; extra->topextra->group = 0; extra->topextra->windowIcon = 0; - extra->topextra->resizer = 0; - extra->topextra->isSetGeometry = 0; extra->topextra->savedWindowAttributesFromMaximized = 0; } @@ -4521,6 +4441,23 @@ void QWidgetPrivate::registerDropSite(bool on) #endif } +void QWidgetPrivate::registerTouchWindow() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_6) + return; + Q_Q(QWidget); + if (!q->testAttribute(Qt::WA_WState_Created)) + return; +#ifndef QT_MAC_USE_COCOA + // Needs implementation! +#else + NSView *view = qt_mac_nativeview_for(q); + [view setAcceptsTouchEvents:YES]; +#endif +#endif +} + void QWidgetPrivate::setMask_sys(const QRegion ®ion) { Q_UNUSED(region); @@ -4541,14 +4478,6 @@ void QWidgetPrivate::setMask_sys(const QRegion ®ion) #endif } -extern "C" { - typedef struct CGSConnection *CGSConnectionRef; - typedef struct CGSWindow *CGSWindowRef; - extern OSStatus CGSSetWindowAlpha(CGSConnectionRef, CGSWindowRef, float); - extern CGSWindowRef GetNativeWindowFromWindowRef(WindowRef); - extern CGSConnectionRef _CGSDefaultConnection(); -} - void QWidgetPrivate::setWindowOpacity_sys(qreal level) { Q_Q(QWidget); @@ -4561,12 +4490,11 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) if (!q->testAttribute(Qt::WA_WState_Created)) return; -#if QT_MAC_USE_COCOA OSWindowRef oswindow = qt_mac_window_for(q); +#if QT_MAC_USE_COCOA [oswindow setAlphaValue:level]; #else - CGSSetWindowAlpha(_CGSDefaultConnection(), - GetNativeWindowFromWindowRef(qt_mac_window_for(q)), level); + SetWindowAlpha(oswindow, level); #endif } @@ -4910,11 +4838,9 @@ void QWidgetPrivate::macUpdateMetalAttribute() if (layout) layout->updateHIToolBarStatus(); ChangeWindowAttributes(qt_mac_window_for(q), kWindowMetalAttribute, 0); - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) - ChangeWindowAttributes(qt_mac_window_for(q), kWindowMetalNoContentSeparatorAttribute, 0); + ChangeWindowAttributes(qt_mac_window_for(q), kWindowMetalNoContentSeparatorAttribute, 0); } else { - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) - ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowMetalNoContentSeparatorAttribute); + ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowMetalNoContentSeparatorAttribute); ChangeWindowAttributes(qt_mac_window_for(q), 0, kWindowMetalAttribute); if (layout) layout->updateHIToolBarStatus(); diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index d6cc4f7..998181e 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -57,6 +57,7 @@ #include "private/qobject_p.h" #include "QtCore/qrect.h" #include "QtCore/qlocale.h" +#include "QtCore/qset.h" #include "QtGui/qregion.h" #include "QtGui/qsizepolicy.h" #include "QtGui/qstyle.h" @@ -99,93 +100,98 @@ class QWidgetItemV2; class QStyle; struct QTLWExtra { + // *************************** Cross-platform variables ***************************** + + // Regular pointers (keep them together to avoid gaps on 64 bits architectures). + QIcon *icon; // widget icon + QPixmap *iconPixmap; + QWidgetBackingStore *backingStore; + QWindowSurface *windowSurface; + QPainter *sharedPainter; + + // Implicit pointers (shared_null). QString caption; // widget caption QString iconText; // widget icon text QString role; // widget role QString filePath; // widget file path - QIcon *icon; // widget icon - QPixmap *iconPixmap; + + // Other variables. short incw, inch; // size increments + short basew, baseh; // base sizes // frame strut, don't use these directly, use QWidgetPrivate::frameStrut() instead. QRect frameStrut; + QRect normalGeometry; // used by showMin/maximized/FullScreen + Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen + + // *************************** Cross-platform bit fields **************************** uint opacity : 8; uint posFromMove : 1; uint sizeAdjusted : 1; uint inTopLevelResize : 1; uint inRepaint : 1; - QWidgetBackingStore *backingStore; -#if defined(Q_WS_WIN) - ulong savedFlags; // Save window flags while showing fullscreen - uint embedded : 1; // window is embedded in another application -#else - Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen -#endif - short basew, baseh; // base sizes -#if defined(Q_WS_X11) - WId parentWinId; // parent window Id (valid after reparenting) - uint embedded : 1; // window is embedded in another Qt application + uint embedded : 1; + + // *************************** Platform specific values (bit fields first) ********** +#if defined(Q_WS_X11) // <----------------------------------------------------------- X11 uint spont_unmapped: 1; // window was spontaneously unmapped uint dnd : 1; // DND properties installed uint validWMState : 1; // is WM_STATE valid? uint waitingForMapNotify : 1; // show() has been called, haven't got the MapNotify yet + WId parentWinId; // parent window Id (valid after reparenting) WId userTimeWindow; // window id that contains user-time timestamp when WM supports a _NET_WM_USER_TIME_WINDOW atom QPoint fullScreenOffset; +#ifndef QT_NO_XSYNC + WId syncUpdateCounter; + ulong syncRequestTimestamp; + qint32 newCounterValueHi; + quint32 newCounterValueLo; #endif -#if defined(Q_WS_MAC) +#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN + HICON winIconBig; // internal big Windows icon + HICON winIconSmall; // internal small Windows icon +#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC + uint resizer : 4; + uint isSetGeometry : 1; + uint isMove : 1; quint32 wattr; quint32 wclass; WindowGroupRef group; IconRef windowIcon; // the current window icon, if set with setWindowIcon_sys. quint32 savedWindowAttributesFromMaximized; // Saved attributes from when the calling updateMaximizeButton_sys() - uint resizer : 4; - uint isSetGeometry : 1; - uint isMove : 1; - uint embedded : 1; -#endif -#if defined(Q_WS_QWS) && !defined (QT_NO_QWS_MANAGER) +#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS +#ifndef QT_NO_QWS_MANAGER QWSManager *qwsManager; #endif -#if defined(Q_WS_WIN) - HICON winIconBig; // internal big Windows icon - HICON winIconSmall; // internal small Windows icon #endif - QRect normalGeometry; // used by showMin/maximized/FullScreen - QWindowSurface *windowSurface; - QPainter *sharedPainter; }; struct QWExtra { - qint32 minw, minh; // minimum size - qint32 maxw, maxh; // maximum size - QPointer<QWidget> focus_proxy; -#ifndef QT_NO_CURSOR - QCursor *curs; -#endif + // *************************** Cross-platform variables ***************************** + + // Regular pointers (keep them together to avoid gaps on 64 bits architectures). + void *glContext; // if the widget is hijacked by QGLWindowSurface QTLWExtra *topextra; // only useful for TLWs QGraphicsProxyWidget *proxyWidget; // if the widget is embedded - void *glContext; // if the widget is hijacked by QGLWindowSurface -#if defined(Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP) - QOleDropTarget *dropTarget; // drop target - QList<QPointer<QWidget> > oleDropWidgets; -#endif -#if defined(Q_WS_X11) - WId xDndProxy; // XDND forwarding to embedded windows +#ifndef QT_NO_CURSOR + QCursor *curs; #endif + QPointer<QStyle> style; + QPointer<QWidget> focus_proxy; + + // Implicit pointers (shared_empty/shared_null). QRegion mask; // widget mask + QString styleSheet; + + // Other variables. + qint32 minw; + qint32 minh; // minimum size + qint32 maxw; + qint32 maxh; // maximum size + quint16 customDpiX; + quint16 customDpiY; QSize staticContentsSize; -//bit flags at the end to improve packing -#if defined(Q_WS_WIN) - uint shown_mode : 8; // widget show mode -#ifndef QT_NO_DIRECT3D - uint had_paint_on_screen : 1; - uint had_no_system_bg : 1; - uint had_auto_fill_bg : 1; -#endif -#endif -#if defined(Q_WS_X11) - uint compress_events : 1; -#endif + // *************************** Cross-platform bit fields **************************** uint explicitMinSize : 2; uint explicitMaxSize : 2; uint autoFillBackground : 1; @@ -193,16 +199,22 @@ struct QWExtra { uint inRenderWithPainter : 1; uint hasMask : 1; - QPointer<QStyle> style; - QString styleSheet; - - quint16 customDpiX; - quint16 customDpiY; -#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA) + // *************************** Platform specific values (bit fields first) ********** +#if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN +#ifndef QT_NO_DRAGANDDROP + QOleDropTarget *dropTarget; // drop target + QList<QPointer<QWidget> > oleDropWidgets; +#endif +#elif defined(Q_WS_X11) // <--------------------------------------------------------- X11 + uint compress_events : 1; + WId xDndProxy; // XDND forwarding to embedded windows +#elif defined(Q_WS_MAC) // <------------------------------------------------------ MAC +#ifdef QT_MAC_USE_COCOA // Cocoa Mask stuff QImage maskBits; CGImageRef imageMask; #endif +#endif }; class Q_GUI_EXPORT QWidgetPrivate : public QObjectPrivate @@ -210,6 +222,24 @@ class Q_GUI_EXPORT QWidgetPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QWidget) public: + // *************************** Cross-platform *************************************** + enum DrawWidgetFlags { + DrawAsRoot = 0x01, + DrawPaintOnScreen = 0x02, + DrawRecursive = 0x04, + DrawInvisible = 0x08, + DontSubtractOpaqueChildren = 0x10, + DontSetCompositionMode = 0x20, + DontDrawOpaqueChildren = 0x40 + }; + + enum CloseMode { + CloseNoEvent, + CloseWithEvent, + CloseWithSpontaneousEvent + }; + + // Functions. explicit QWidgetPrivate(int version = QObjectPrivateVersion); ~QWidgetPrivate(); @@ -219,10 +249,6 @@ public: QPainter *sharedPainter() const; void setSharedPainter(QPainter *painter); QWidgetBackingStore *maybeBackingStore() const; -#ifdef Q_WS_QWS - void setMaxWindowState_helper(); - void setFullScreenSize_helper(); -#endif void init(QWidget *desktopWidget, Qt::WindowFlags f); void create_sys(WId window, bool initializeWindow, bool destroyOldWindow); void createRecursively(); @@ -243,24 +269,6 @@ public: QPalette naturalWidgetPalette(uint inheritedMask) const; void setMask_sys(const QRegion &); -#ifdef Q_WS_WIN - bool shouldShowMaximizeButton(); - void winUpdateIsOpaque(); -#endif - -#ifdef Q_WS_MAC - void macUpdateSizeAttribute(); - void macUpdateHideOnSuspend(); - void macUpdateOpaqueSizeGrip(); - void macUpdateIgnoreMouseEvents(); - void macUpdateMetalAttribute(); - void macUpdateIsOpaque(); - void setEnabled_helper_sys(bool enable); - bool isRealWindow() const; - void adjustWithinMaxAndMinSize(int &w, int &h); - void applyMaxAndMinSizeOnWindow(); -#endif - void raise_sys(); void lower_sys(); void stackUnder_sys(QWidget *); @@ -285,20 +293,9 @@ public: void setStyle_helper(QStyle *newStyle, bool propagate, bool metalHack = false); void inheritStyle(); - bool isBackgroundInherited() const; - void setUpdatesEnabled_helper(bool ); - void paintBackground(QPainter *, const QRegion &, const QPoint & = QPoint(), int flags = DrawAsRoot) const; - enum DrawWidgetFlags { - DrawAsRoot = 0x01, - DrawPaintOnScreen = 0x02, - DrawRecursive = 0x04, - DrawInvisible = 0x08, - DontSubtractOpaqueChildren = 0x10, - DontSetCompositionMode = 0x20, - DontDrawOpaqueChildren = 0x40 - }; + void paintBackground(QPainter *, const QRegion &, int flags = DrawAsRoot) const; bool isAboutToShow() const; QRegion prepareToRender(const QRegion ®ion, QWidget::RenderFlags renderFlags); void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion, @@ -321,10 +318,6 @@ public: QWindowSurface *createDefaultWindowSurface(); QWindowSurface *createDefaultWindowSurface_sys(); void repaint_sys(const QRegion &rgn); -#ifdef Q_WS_MAC - void update_sys(const QRect &rect); - void update_sys(const QRegion &rgn); -#endif QRect clipRect() const; QRegion clipRegion() const; @@ -335,42 +328,20 @@ public: void updateIsOpaque(); void setOpaque(bool opaque); void updateIsTranslucent(); - bool hasBackground() const; bool paintOnScreen() const; QRegion getOpaqueRegion() const; const QRegion &getOpaqueChildren() const; void setDirtyOpaqueRegion(); - QRegion opaqueChildren; - - enum CloseMode { - CloseNoEvent, - CloseWithEvent, - CloseWithSpontaneousEvent - }; bool close_helper(CloseMode mode); - bool compositeEvent(QEvent *e); void setWindowIcon_helper(); void setWindowIcon_sys(bool forceReset = false); void setWindowOpacity_sys(qreal opacity); - void adjustQuitOnCloseAttribute(); -#if defined(Q_WS_X11) - void setWindowRole(); - void sendStartupMessage(const char *message) const; - void setNetWmWindowTypes(); - void x11UpdateIsOpaque(); -#endif - -#if defined (Q_WS_WIN) - void reparentChildren(); -#endif - void scrollChildren(int dx, int dy); - void moveRect(const QRect &, int dx, int dy); void scrollRect(const QRect &, int dx, int dy); void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize); @@ -384,7 +355,6 @@ public: void reparentFocusWidgets(QWidget *oldtlw); static int pointToRect(const QPoint &p, const QRect &r); - QRect fromOrToLayoutItemRect(const QRect &rect, int sign) const; void setWinId(WId); void showChildren(bool spontaneous); @@ -394,9 +364,6 @@ public: void scroll_sys(int dx, int dy, const QRect &r); void deactivateWidgetCleanup(); void setGeometry_sys(int, int, int, int, bool); -#ifdef Q_WS_MAC - void setGeometry_sys_helper(int, int, int, int, bool); -#endif void sendPendingMoveAndResizeEvents(bool recursive = false, bool disableUpdates = false); void activateChildLayoutsRecursively(); void show_recursive(); @@ -408,10 +375,6 @@ public: void setEnabled_helper(bool); void registerDropSite(bool); -#if defined(Q_WS_WIN) && !defined(QT_NO_DRAGANDDROP) - QOleDropTarget *registerOleDnd(QWidget *widget); - void unregisterOleDnd(QWidget *widget, QOleDropTarget *target); -#endif static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0); void updateFrameStrut(); @@ -421,32 +384,11 @@ public: void setWindowIconText_helper(const QString &cap); void setWindowTitle_sys(const QString &cap); -#ifdef Q_OS_WIN - void grabMouseWhileInWindow(); -#endif - #ifndef QT_NO_CURSOR void setCursor_sys(const QCursor &cursor); void unsetCursor_sys(); #endif -#ifdef Q_WS_MAC - void setWindowModified_sys(bool b); - void updateMaximizeButton_sys(); - void setWindowFilePath_sys(const QString &filePath); - void createWindow_sys(); - void recreateMacWindow(); -#ifndef QT_MAC_USE_COCOA - void initWindowPtr(); - void finishCreateWindow_sys_Carbon(OSWindowRef windowRef); -#else - void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef); - void syncCocoaMask(); - void finishCocoaMaskSetup(); -#endif - void determineWindowClass(); - void transferChildren(); -#endif void setWindowTitle_helper(const QString &cap); void setWindowFilePath_helper(const QString &filePath); @@ -462,59 +404,89 @@ public: QInputContext *inputContext() const; -#if defined(Q_WS_QWS) - void moveSurface(QWindowSurface *surface, const QPoint &offset); + void setModal_sys(); - QRegion localRequestedRegion() const; - QRegion localAllocatedRegion() const; + inline void setRedirected(QPaintDevice *replacement, const QPoint &offset) + { + Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent)); + redirectDev = replacement; + redirectOffset = offset; + } - void blitToScreen(const QRegion &globalrgn); -#ifndef QT_NO_CURSOR - void updateCursor() const; -#endif + inline QPaintDevice *redirected(QPoint *offset) const + { + if (offset) + *offset = redirectDev ? redirectOffset : QPoint(); + return redirectDev; + } - QScreen* getScreen() const; + inline void restoreRedirected() + { redirectDev = 0; } - friend class QWSManager; - friend class QWSManagerPrivate; - friend class QDecoration; -#endif + inline void enforceNativeChildren() + { + if (!extra) + createExtra(); - static int instanceCounter; // Current number of widget instances - static int maxInstances; // Maximum number of widget instances + if (extra->nativeChildrenForced) + return; + extra->nativeChildrenForced = 1; -#ifdef QT_KEYPAD_NAVIGATION - static QPointer<QWidget> editingWidget; -#endif + for (int i = 0; i < children.size(); ++i) { + if (QWidget *child = qobject_cast<QWidget *>(children.at(i))) + child->setAttribute(Qt::WA_NativeWindow); + } + } - QWidgetData data; + inline bool nativeChildrenForced() const + { + return extra ? extra->nativeChildrenForced : false; + } + + QSize adjustedSize() const; + +#ifndef Q_WS_QWS // Almost cross-platform :-) + void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect()); + + inline QPoint mapToWS(const QPoint &p) const + { return p - data.wrect.topLeft(); } + + inline QPoint mapFromWS(const QPoint &p) const + { return p + data.wrect.topLeft(); } + + inline QRect mapToWS(const QRect &r) const + { QRect rr(r); rr.translate(-data.wrect.topLeft()); return rr; } + + inline QRect mapFromWS(const QRect &r) const + { QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; } +#endif + // Variables. + // Regular pointers (keep them together to avoid gaps on 64 bit architectures). QWExtra *extra; QWidget *focus_next; QWidget *focus_prev; QWidget *focus_child; -#ifndef QT_NO_ACTION - QList<QAction*> actions; -#endif QLayout *layout; + QRegion *needsFlush; + QPaintDevice *redirectDev; QWidgetItemV2 *widgetItem; -#if !defined(QT_NO_IM) - QPointer<QInputContext> ic; -#endif + QPaintEngine *extraPaintEngine; + mutable const QMetaObject *polished; // All widgets are initially added into the uncreatedWidgets set. Once // they receive a window id they are removed and added to the mapper static QWidgetMapper *mapper; static QWidgetSet *uncreatedWidgets; +#if !defined(QT_NO_IM) + QPointer<QInputContext> ic; +#endif +#ifdef QT_KEYPAD_NAVIGATION + static QPointer<QWidget> editingWidget; +#endif - short leftmargin, topmargin, rightmargin, bottommargin; - - signed char leftLayoutItemMargin; - signed char topLayoutItemMargin; - signed char rightLayoutItemMargin; - signed char bottomLayoutItemMargin; - - // ### TODO: reorganize private/extra/topextra to save memory - QPointer<QWidget> compositeChildGrab; + // Implicit pointers (shared_null/shared_empty). + QRegion opaqueChildren; + QRegion dirty; #ifndef QT_NO_TOOLTIP QString toolTip; #endif @@ -524,14 +496,37 @@ public: #ifndef QT_NO_WHATSTHIS QString whatsThis; #endif - QString accessibleName, accessibleDescription; +#ifndef QT_NO_ACCESSIBILITY + QString accessibleName; + QString accessibleDescription; +#endif + + // Other variables. + uint inheritedFontResolveMask; + uint inheritedPaletteResolveMask; + short leftmargin; + short topmargin; + short rightmargin; + short bottommargin; + signed char leftLayoutItemMargin; + signed char topLayoutItemMargin; + signed char rightLayoutItemMargin; + signed char bottomLayoutItemMargin; + static int instanceCounter; // Current number of widget instances + static int maxInstances; // Maximum number of widget instances + Qt::HANDLE hd; + QWidgetData data; + QSizePolicy size_policy; + QLocale locale; + QPoint redirectOffset; +#ifndef QT_NO_ACTION + QList<QAction*> actions; +#endif + // Bit fields. + uint high_attributes[3]; // the low ones are in QWidget::widget_attributes QPalette::ColorRole fg_role : 8; QPalette::ColorRole bg_role : 8; - uint high_attributes[3]; // the low ones are in QWidget::widget_attributes - Qt::HANDLE hd; - QRegion dirty; - QRegion *needsFlush; uint dirtyOpaqueChildren : 1; uint isOpaque : 1; uint inDirtyList : 1; @@ -539,35 +534,34 @@ public: uint isMoved : 1; uint usesDoubleBufferedGLContext : 1; -#ifdef Q_WS_WIN - uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() -#endif - - uint inheritedFontResolveMask; - uint inheritedPaletteResolveMask; -#if defined(Q_WS_X11) + // *************************** Platform specific ************************************ +#if defined(Q_WS_X11) // <----------------------------------------------------------- X11 QX11Info xinfo; Qt::HANDLE picture; + static QWidget *mouseGrabber; + static QWidget *keyboardGrabber; + + void setWindowRole(); + void sendStartupMessage(const char *message) const; + void setNetWmWindowTypes(); + void x11UpdateIsOpaque(); + bool isBackgroundInherited() const; +#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN + uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() + + bool shouldShowMaximizeButton(); + void winUpdateIsOpaque(); + void reparentChildren(); +#ifndef QT_NO_DRAGANDDROP + QOleDropTarget *registerOleDnd(QWidget *widget); + void unregisterOleDnd(QWidget *widget, QOleDropTarget *target); #endif -#if defined(Q_WS_MAC) - enum PaintChildrenOPs { - PC_None = 0x00, - PC_Now = 0x01, - PC_NoPaint = 0x04, - PC_Later = 0x10 - }; - EventHandlerRef window_event; - bool qt_mac_dnd_event(uint, DragRef); - void toggleDrawers(bool); - //mac event functions - static bool qt_create_root_win(); - static void qt_clean_root_win(); - static bool qt_recreate_root_win(); - static bool qt_mac_update_sizer(QWidget *, int up = 0); - static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *); - static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *); - static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool); - static bool qt_widget_shape(QWidget *, short, HIMutableShapeRef, bool); + void grabMouseWhileInWindow(); + void registerTouchWindow(); +#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC + // This is new stuff + uint needWindowChange : 1; + uint isGLWidget : 1; // Each wiget keeps a list of all its child and grandchild OpenGL widgets. // This list is used to update the gl context whenever a parent and a granparent @@ -580,95 +574,71 @@ public: QWidget * widget; QWidget * lastUpdateWidget; }; - QList<GlWidgetInfo> glWidgets; // dirtyOnWidget contains the areas in the widget that needs to be repained, // in the same way as dirtyOnScreen does for the window. Areas are added in // dirtyWidget_sys and cleared in the paint event. In scroll_sys we then use // this information repaint invalid areas when widgets are scrolled. QRegion dirtyOnWidget; + EventHandlerRef window_event; + QList<GlWidgetInfo> glWidgets; //these are here just for code compat (HIViews) Qt::HANDLE qd_hd; - // This is new stuff - uint needWindowChange : 1; - uint isGLWidget : 1; -#endif - -#if defined(Q_WS_X11) || defined (Q_WS_WIN) || defined(Q_WS_MAC) -#ifdef Q_WS_MAC - void setWSGeometry(bool dontShow=false, const QRect &oldRect = QRect()); + void macUpdateSizeAttribute(); + void macUpdateHideOnSuspend(); + void macUpdateOpaqueSizeGrip(); + void macUpdateIgnoreMouseEvents(); + void macUpdateMetalAttribute(); + void macUpdateIsOpaque(); + void setEnabled_helper_sys(bool enable); + bool isRealWindow() const; + void adjustWithinMaxAndMinSize(int &w, int &h); + void applyMaxAndMinSizeOnWindow(); + void update_sys(const QRect &rect); + void update_sys(const QRegion &rgn); + void setGeometry_sys_helper(int, int, int, int, bool); + void setWindowModified_sys(bool b); + void updateMaximizeButton_sys(); + void setWindowFilePath_sys(const QString &filePath); + void createWindow_sys(); + void recreateMacWindow(); +#ifndef QT_MAC_USE_COCOA + void initWindowPtr(); + void finishCreateWindow_sys_Carbon(OSWindowRef windowRef); #else - void setWSGeometry(bool dontShow=false); + void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef); + void syncCocoaMask(); + void finishCocoaMaskSetup(); #endif + void determineWindowClass(); + void transferChildren(); + bool qt_mac_dnd_event(uint, DragRef); + void toggleDrawers(bool); + //mac event functions + static bool qt_create_root_win(); + static void qt_clean_root_win(); + static bool qt_mac_update_sizer(QWidget *, int up = 0); + static OSStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *); + static OSStatus qt_widget_event(EventHandlerCallRef er, EventRef event, void *); + static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool); + void registerTouchWindow(); +#elif defined(Q_WS_QWS) // <--------------------------------------------------------- QWS + void setMaxWindowState_helper(); + void setFullScreenSize_helper(); + void moveSurface(QWindowSurface *surface, const QPoint &offset); + QRegion localRequestedRegion() const; + QRegion localAllocatedRegion() const; - inline QPoint mapToWS(const QPoint &p) const - { return p - data.wrect.topLeft(); } - - inline QPoint mapFromWS(const QPoint &p) const - { return p + data.wrect.topLeft(); } - - inline QRect mapToWS(const QRect &r) const - { QRect rr(r); rr.translate(-data.wrect.topLeft()); return rr; } - - inline QRect mapFromWS(const QRect &r) const - { QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; } + friend class QWSManager; + friend class QWSManagerPrivate; + friend class QDecoration; +#ifndef QT_NO_CURSOR + void updateCursor() const; #endif - - QPaintEngine *extraPaintEngine; - - mutable const QMetaObject *polished; - - void setModal_sys(); - QSizePolicy size_policy; - QLocale locale; - -#ifdef Q_WS_X11 - static QWidget *mouseGrabber; - static QWidget *keyboardGrabber; + QScreen* getScreen() const; #endif - QPaintDevice *redirectDev; - QPoint redirectOffset; - - inline void setRedirected(QPaintDevice *replacement, const QPoint &offset) - { - Q_ASSERT(q_func()->testAttribute(Qt::WA_WState_InPaintEvent)); - redirectDev = replacement; - redirectOffset = offset; - } - - inline QPaintDevice *redirected(QPoint *offset) const - { - if (offset) - *offset = redirectDev ? redirectOffset : QPoint(); - return redirectDev; - } - - inline void restoreRedirected() - { redirectDev = 0; } - - inline void enforceNativeChildren() - { - if (!extra) - createExtra(); - - if (extra->nativeChildrenForced) - return; - extra->nativeChildrenForced = 1; - - for (int i = 0; i < children.size(); ++i) { - if (QWidget *child = qobject_cast<QWidget *>(children.at(i))) - child->setAttribute(Qt::WA_NativeWindow); - } - } - - inline bool nativeChildrenForced() const - { - return extra ? extra->nativeChildrenForced : false; - } - - QSize adjustedSize() const; }; inline QWExtra *QWidgetPrivate::extraData() const diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp index d61cf0c..299ed73 100644 --- a/src/gui/kernel/qwidget_qws.cpp +++ b/src/gui/kernel/qwidget_qws.cpp @@ -565,20 +565,6 @@ void QWidget::activateWindow() } } -/* - Should we require that q is a toplevel window ??? - - Used by QWSManager - */ -void QWidgetPrivate::blitToScreen(const QRegion &globalrgn) -{ - Q_Q(QWidget); - QWidget *win = q->window(); - QBrush bgBrush = win->palette().brush(win->backgroundRole()); - bool opaque = bgBrush.style() == Qt::NoBrush || bgBrush.isOpaque(); - QWidget::qwsDisplay()->repaintRegion(win->data->winid, win->windowFlags(), opaque, globalrgn); -} - void QWidgetPrivate::show_sys() { Q_Q(QWidget); @@ -1037,6 +1023,9 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::createTLSysExtra() { +#ifndef QT_NO_QWS_MANAGER + extra->topextra->qwsManager = 0; +#endif } void QWidgetPrivate::deleteTLSysExtra() diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 3ab1ccb..46fa3be 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -56,19 +56,13 @@ #include "private/qbackingstore_p.h" #include "private/qwindowsurface_raster_p.h" -#ifndef QT_NO_DIRECT3D -#include "private/qpaintengine_d3d_p.h" -#include "private/qwindowsurface_d3d_p.h" -#endif - - #include <qdebug.h> #include <private/qapplication_p.h> #include <private/qwininputcontext_p.h> #include <private/qpaintengine_raster_p.h> -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) #include "qguifunctions_wince.h" QT_USE_NAMESPACE extern void qt_wince_maximize(QWidget *widget); //defined in qguifunctions_wince.cpp @@ -146,14 +140,8 @@ static void init_wintab_functions() if (!qt_is_gui_used) return; QLibrary library(QLatin1String("wintab32")); - QT_WA({ - ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenW"); - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); - } , { - ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenA"); - ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoA"); - }); - + ptrWTOpen = (PtrWTOpen)library.resolve("WTOpenW"); + ptrWTInfo = (PtrWTInfo)library.resolve("WTInfoW"); ptrWTClose = (PtrWTClose)library.resolve("WTClose"); ptrWTQueueSizeGet = (PtrWTQueueSizeGet)library.resolve("WTQueueSizeGet"); ptrWTQueueSizeSet = (PtrWTQueueSizeSet)library.resolve("WTQueueSizeSet"); @@ -257,7 +245,7 @@ extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM); QWidget member functions *****************************************************************************/ -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) { Q_Q(QWidget); @@ -276,7 +264,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO HINSTANCE appinst = qWinAppInst(); HWND parentw, destroyw = 0; - WId id; + WId id = 0; QString windowClassName = qt_reg_winclass(q); @@ -293,25 +281,18 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (desktop && !q->testAttribute(Qt::WA_DontShowOnScreen)) { // desktop widget popup = false; // force this flags off - if (QSysInfo::WindowsVersion != QSysInfo::WV_NT && QSysInfo::WindowsVersion != QSysInfo::WV_95) - data.crect.setRect(GetSystemMetrics(76 /* SM_XVIRTUALSCREEN */), GetSystemMetrics(77 /* SM_YVIRTUALSCREEN */), + data.crect.setRect(GetSystemMetrics(76 /* SM_XVIRTUALSCREEN */), GetSystemMetrics(77 /* SM_YVIRTUALSCREEN */), GetSystemMetrics(78 /* SM_CXVIRTUALSCREEN */), GetSystemMetrics(79 /* SM_CYVIRTUALSCREEN */)); - else - data.crect.setRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); } parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0; -#ifdef UNICODE QString title; - const TCHAR *ttitle = 0; -#endif - QByteArray title95; int style = WS_CHILD; int exsty = 0; if (window) { - style = GetWindowLongA(window, GWL_STYLE); + style = GetWindowLong(window, GWL_STYLE); if (!style) qErrnoWarning("QWidget::create: GetWindowLong failed"); topLevel = false; // #### needed for some IE plugins?? @@ -367,12 +348,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } if (flags & Qt::WindowTitleHint) { - QT_WA({ - title = q->isWindow() ? qAppName() : q->objectName(); - ttitle = (TCHAR*)title.utf16(); - } , { - title95 = q->isWindow() ? qAppName().toLocal8Bit() : q->objectName().toLatin1(); - }); + title = q->isWindow() ? qAppName() : q->objectName(); } // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in @@ -385,13 +361,13 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO destroyw = data.winid; id = window; setWinId(window); - LONG res = SetWindowLongA(window, GWL_STYLE, style); + LONG res = SetWindowLong(window, GWL_STYLE, style); if (!res) qErrnoWarning("QWidget::create: Failed to set window style"); #ifdef _WIN64 - res = SetWindowLongPtrA( window, GWLP_WNDPROC, (LONG_PTR)QtWndProc ); + res = SetWindowLongPtr( window, GWLP_WNDPROC, (LONG_PTR)QtWndProc ); #else - res = SetWindowLongA( window, GWL_WNDPROC, (LONG)QtWndProc ); + res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc ); #endif if (!res) qErrnoWarning("QWidget::create: Failed to set window procedure"); @@ -442,16 +418,10 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } } - QT_WA({ - const TCHAR *cname = (TCHAR*)windowClassName.utf16(); - id = CreateWindowEx(exsty, cname, ttitle, style, - x, y, w, h, - parentw, 0, appinst, 0); - } , { - id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style, - x, y, w, h, - parentw, 0, appinst, 0); - }); + id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()), + reinterpret_cast<const wchar_t *>(title.utf16()), style, + x, y, w, h, + parentw, NULL, appinst, NULL); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); setWinId(id); @@ -463,16 +433,10 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO SetWindowPos(id, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); winUpdateIsOpaque(); } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget - QT_WA({ - const TCHAR *cname = (TCHAR*)windowClassName.utf16(); - id = CreateWindowEx(exsty, cname, ttitle, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), - parentw, NULL, appinst, NULL); - } , { - id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), + id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()), + reinterpret_cast<const wchar_t *>(title.utf16()), style, + data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), parentw, NULL, appinst, NULL); - }); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -506,6 +470,9 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO q->setAttribute(Qt::WA_WState_Created); // accept move/resize events hd = 0; // no display context + if (q->testAttribute(Qt::WA_AcceptTouchEvents)) + registerTouchWindow(); + if (window) { // got window from outside if (IsWindowVisible(window)) q->setAttribute(Qt::WA_WState_Visible); @@ -546,7 +513,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } } -#endif //Q_OS_WINCE +#endif //Q_WS_WINCE void QWidget::destroy(bool destroyWindow, bool destroySubWindows) @@ -574,7 +541,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) if (destroyWindow && !(windowType() == Qt::Desktop) && internalWinId()) { DestroyWindow(internalWinId()); } -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE if (destroyWindow && (windowType() == Qt::Desktop) && !GetDesktopWindow()) { DestroyWindow(internalWinId()); } @@ -681,11 +648,11 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED); } -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE // Show borderless toplevel windows in tasklist & NavBar if (!parent) { QString txt = q->windowTitle().isEmpty()?qAppName():q->windowTitle(); - SetWindowText(q->internalWinId(), (TCHAR*)txt.utf16()); + SetWindowText(q->internalWinId(), (wchar_t*)txt.utf16()); } #endif invalidateBuffer(q->rect()); @@ -770,11 +737,7 @@ void QWidgetPrivate::setWindowTitle_sys(const QString &caption) return; Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - QT_WA({ - SetWindowText(q->internalWinId(), (TCHAR*)caption.utf16()); - } , { - SetWindowTextA(q->internalWinId(), caption.toLocal8Bit()); - }); + SetWindowText(q->internalWinId(), (wchar_t*)caption.utf16()); } /* @@ -856,11 +819,11 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), &(x->iconPixmap)); if (x->winIconBig) { - SendMessageA(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); - SendMessageA(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconBig); + SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); + SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconBig); } else { - SendMessageA(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); - SendMessageA(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconSmall); + SendMessage(q->internalWinId(), WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)x->winIconSmall); + SendMessage(q->internalWinId(), WM_SETICON, 1 /* ICON_BIG */, (LPARAM)x->winIconSmall); } } @@ -877,17 +840,17 @@ QCursor *qt_grab_cursor() } // The procedure does nothing, but is required for mousegrabbing to work -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE LRESULT CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) { return CallNextHookEx(journalRec, nCode, wParam, lParam); } -#endif //Q_OS_WINCE +#endif //Q_WS_WINCE /* Works only as long as pointer is inside the application's window, which is good enough for QDockWidget. - Doesn't call SetWindowsHookExA() - this function causes a system-wide + Doesn't call SetWindowsHookEx() - this function causes a system-wide freeze if any other app on the system installs a hook and fails to process events. */ void QWidgetPrivate::grabMouseWhileInWindow() @@ -905,13 +868,13 @@ void QWidgetPrivate::grabMouseWhileInWindow() } } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE void QWidget::grabMouse() { if (!qt_nograb()) { if (mouseGrb) mouseGrb->releaseMouse(); - journalRec = SetWindowsHookExA(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandleA(0), 0); + journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0); Q_ASSERT(testAttribute(Qt::WA_WState_Created)); SetCapture(effectiveWinId()); mouseGrb = this; @@ -924,7 +887,7 @@ void QWidget::grabMouse(const QCursor &cursor) if (!qt_nograb()) { if (mouseGrb) mouseGrb->releaseMouse(); - journalRec = SetWindowsHookExA(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandleA(0), 0); + journalRec = SetWindowsHookEx(WH_JOURNALRECORD, (HOOKPROC)qJournalRecordProc, GetModuleHandle(0), 0); Q_ASSERT(testAttribute(Qt::WA_WState_Created)); SetCapture(effectiveWinId()); mouseGrbCur = new QCursor(cursor); @@ -982,7 +945,7 @@ void QWidget::activateWindow() SetForegroundWindow(window()->internalWinId()); } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE void QWidget::setWindowState(Qt::WindowStates newstate) { Q_D(QWidget); @@ -1031,18 +994,18 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowFullScreen) { if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = GetWindowLongA(internalWinId(), GWL_STYLE); + d->topData()->savedFlags = Qt::WindowFlags(GetWindowLong(internalWinId(), GWL_STYLE)); #ifndef Q_FLATTEN_EXPOSE UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; #else UINT style = WS_POPUP; #endif - if (d->topData()->savedFlags & WS_SYSMENU) + if (ulong(d->topData()->savedFlags) & WS_SYSMENU) style |= WS_SYSMENU; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); - QRect r = qApp->desktop()->screenGeometry(this); + SetWindowLong(internalWinId(), GWL_STYLE, style); + QRect r = QApplication::desktop()->screenGeometry(this); UINT swpf = SWP_FRAMECHANGED; if (newstate & Qt::WindowActive) swpf |= SWP_NOACTIVATE; @@ -1053,7 +1016,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) UINT style = d->topData()->savedFlags; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); + SetWindowLong(internalWinId(), GWL_STYLE, style); UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; if (newstate & Qt::WindowActive) @@ -1084,7 +1047,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) QWindowStateChangeEvent e(oldstate); QApplication::sendEvent(this, &e); } -#endif //Q_OS_WINCE +#endif //Q_WS_WINCE /* @@ -1097,7 +1060,7 @@ void QWidgetPrivate::hide_sys() Q_Q(QWidget); deactivateWidgetCleanup(); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE if (!qt_wince_is_mobile() && q->isFullScreen()) { HWND handle = FindWindow(L"HHTaskBar", L""); if (handle) { @@ -1126,7 +1089,7 @@ void QWidgetPrivate::hide_sys() \internal Platform-specific part of QWidget::show(). */ -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE void QWidgetPrivate::show_sys() { Q_Q(QWidget); @@ -1194,7 +1157,7 @@ void QWidgetPrivate::show_sys() invalidateBuffer(q->rect()); } -#endif //Q_OS_WINCE +#endif //Q_WS_WINCE void QWidgetPrivate::setFocus_sys() { @@ -1240,7 +1203,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget* w) (In all comments below: s/X/Windows/g) */ -void QWidgetPrivate::setWSGeometry(bool dontShow) +void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) { Q_Q(QWidget); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); @@ -1398,7 +1361,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) UINT style = top->savedFlags; if (q->isVisible()) style |= WS_VISIBLE; - SetWindowLongA(q->internalWinId(), GWL_STYLE, style); + SetWindowLong(q->internalWinId(), GWL_STYLE, style); UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; if (data.window_state & Qt::WindowActive) @@ -1413,7 +1376,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false; const bool isTranslucentWindow = !isOpaque && ptrUpdateLayeredWindowIndirect && (data.window_flags & Qt::FramelessWindowHint) - && GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED; + && GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED; if (q->testAttribute(Qt::WA_WState_ConfigPending)) { // processing config event if (q->internalWinId()) @@ -1452,7 +1415,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) show_sys(); } else if (!q->testAttribute(Qt::WA_DontShowOnScreen)) { q->setAttribute(Qt::WA_OutsideWSRange, false); -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE // If the window is hidden and in maximized state or minimized, instead of moving the // window, set the normal position of the window. WINDOWPLACEMENT wndpl; @@ -1571,7 +1534,7 @@ bool QWidgetPrivate::shouldShowMaximizeButton() void QWidgetPrivate::winUpdateIsOpaque() { -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE Q_Q(QWidget); if (!q->isWindow() || !q->testAttribute(Qt::WA_TranslucentBackground)) @@ -1581,26 +1544,26 @@ void QWidgetPrivate::winUpdateIsOpaque() return; if (!isOpaque && ptrUpdateLayeredWindowIndirect) { - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, - GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) | Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, + GetWindowLong(q->internalWinId(), GWL_EXSTYLE) | Q_WS_EX_LAYERED); } else { - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, - GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) & ~Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, + GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & ~Q_WS_EX_LAYERED); } #endif } void QWidgetPrivate::setConstraints_sys() { -#ifndef Q_OS_WINCE_WM +#ifndef Q_WS_WINCE_WM Q_Q(QWidget); if (q->isWindow() && q->testAttribute(Qt::WA_WState_Created)) { - int style = GetWindowLongA(q->internalWinId(), GWL_STYLE); + int style = GetWindowLong(q->internalWinId(), GWL_STYLE); if (shouldShowMaximizeButton()) style |= WS_MAXIMIZEBOX; else style &= ~WS_MAXIMIZEBOX; - SetWindowLongA(q->internalWinId(), GWL_STYLE, style); + SetWindowLong(q->internalWinId(), GWL_STYLE, style); } #endif } @@ -1710,28 +1673,24 @@ int QWidget::metric(PaintDeviceMetric m) const return val; } -#ifndef Q_OS_WINCE void QWidgetPrivate::createSysExtra() { #ifndef QT_NO_DRAGANDDROP extra->dropTarget = 0; #endif -#ifndef QT_NO_DIRECT3D - extra->had_auto_fill_bg = 0; - extra->had_paint_on_screen = 0; - extra->had_no_system_bg = 0; -#endif } +#ifndef Q_WS_WINCE void QWidgetPrivate::deleteSysExtra() { } -#endif //Q_OS_WINCE +#endif //Q_WS_WINCE void QWidgetPrivate::createTLSysExtra() { - extra->topextra->winIconSmall = 0; + extra->topextra->savedFlags = 0; extra->topextra->winIconBig = 0; + extra->topextra->winIconSmall = 0; } void QWidgetPrivate::deleteTLSysExtra() @@ -1855,7 +1814,8 @@ void QWidgetPrivate::setMask_sys(const QRegion ®ion) OffsetRgn(wr, offset.x(), offset.y()); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - SetWindowRgn(data.winid, wr, true); + if (!SetWindowRgn(data.winid, wr, true)) + DeleteObject(wr); } void QWidgetPrivate::updateFrameStrut() @@ -1873,11 +1833,9 @@ void QWidgetPrivate::updateFrameStrut() RECT rect = {0,0,0,0}; QTLWExtra *top = topData(); - uint exstyle = QT_WA_INLINE(GetWindowLongW(q->internalWinId(), GWL_EXSTYLE), - GetWindowLongA(q->internalWinId(), GWL_EXSTYLE)); - uint style = QT_WA_INLINE(GetWindowLongW(q->internalWinId(), GWL_STYLE), - GetWindowLongA(q->internalWinId(), GWL_STYLE)); -#ifndef Q_OS_WINCE + uint exstyle = GetWindowLong(q->internalWinId(), GWL_EXSTYLE); + uint style = GetWindowLong(q->internalWinId(), GWL_STYLE); +#ifndef Q_WS_WINCE if (AdjustWindowRectEx(&rect, style & ~(WS_OVERLAPPED), FALSE, exstyle)) { #else if (AdjustWindowRectEx(&rect, style, FALSE, exstyle)) { @@ -1887,16 +1845,15 @@ void QWidgetPrivate::updateFrameStrut() } } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE void QWidgetPrivate::setWindowOpacity_sys(qreal level) { Q_Q(QWidget); - if (!isOpaque && ptrUpdateLayeredWindowIndirect && (data.window_flags & Qt::FramelessWindowHint)) { - if (GetWindowLongA(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED) { - Q_BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), Q_AC_SRC_ALPHA}; - Q_UPDATELAYEREDWINDOWINFO info = {sizeof(info), NULL, NULL, NULL, NULL, NULL, 0, &blend, Q_ULW_ALPHA, NULL}; - (*ptrUpdateLayeredWindowIndirect)(q->internalWinId(), &info); + if (!isOpaque && ptrUpdateLayeredWindow && (data.window_flags & Qt::FramelessWindowHint)) { + if (GetWindowLong(q->internalWinId(), GWL_EXSTYLE) & Q_WS_EX_LAYERED) { + BLENDFUNCTION blend = {AC_SRC_OVER, 0, (int)(255.0 * level), AC_SRC_ALPHA}; + ptrUpdateLayeredWindow(q->internalWinId(), NULL, NULL, NULL, NULL, NULL, 0, &blend, Q_ULW_ALPHA); } return; } @@ -1912,17 +1869,17 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) if (!ptrSetLayeredWindowAttributes) return; - int wl = GetWindowLongA(q->internalWinId(), GWL_EXSTYLE); + int wl = GetWindowLong(q->internalWinId(), GWL_EXSTYLE); if (level != 1.0) { if ((wl&Q_WS_EX_LAYERED) == 0) - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, wl|Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl | Q_WS_EX_LAYERED); } else if (wl&Q_WS_EX_LAYERED) { - SetWindowLongA(q->internalWinId(), GWL_EXSTYLE, wl & ~Q_WS_EX_LAYERED); + SetWindowLong(q->internalWinId(), GWL_EXSTYLE, wl & ~Q_WS_EX_LAYERED); } - (*ptrSetLayeredWindowAttributes)(q->internalWinId(), 0, (int)(level * 255), Q_LWA_ALPHA); + ptrSetLayeredWindowAttributes(q->internalWinId(), 0, (int)(level * 255), Q_LWA_ALPHA); } -#endif //Q_OS_WINCE +#endif //Q_WS_WINCE // class QGlobalRasterPaintEngine: public QRasterPaintEngine // { @@ -1931,22 +1888,6 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) // }; // Q_GLOBAL_STATIC(QGlobalRasterPaintEngine, globalRasterPaintEngine) -#ifndef QT_NO_DIRECT3D -static void cleanup_d3d_engine(); -Q_GLOBAL_STATIC_WITH_INITIALIZER(QDirect3DPaintEngine, _qt_d3dEngine, - { - qAddPostRoutine(cleanup_d3d_engine); - }) -static void cleanup_d3d_engine() -{ - _qt_d3dEngine()->cleanup(); -} -QDirect3DPaintEngine* qt_d3dEngine() -{ - return _qt_d3dEngine(); -} -#endif - #ifndef QT_NO_DIRECTDRAW static uchar *qt_primary_surface_bits; @@ -2002,8 +1943,8 @@ public: // in QOnScreenRasterPaintEngine() : QRasterPaintEngine(new QImage(qt_primary_surface_bits, - qApp->desktop()->width(), - qApp->desktop()->height(), + QApplication::desktop()->width(), + QApplication::desktop()->height(), qt_primary_surface_stride, qt_primary_surface_format)) { @@ -2059,19 +2000,6 @@ void qt_win_initialize_directdraw() { } QPaintEngine *QWidget::paintEngine() const { -#ifndef QT_NO_DIRECT3D - if ((qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault) - || testAttribute(Qt::WA_MSWindowsUseDirect3D)) - && qt_d3dEngine()->hasDirect3DSupport()) - { - QDirect3DPaintEngine *engine = qt_d3dEngine(); - if (qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault)) - engine->setFlushOnEnd(false); - else - engine->setFlushOnEnd(true); - return engine; - } -#endif #ifndef QT_NO_DIRECTDRAW QOnScreenRasterPaintEngine *pe = onScreenPaintEngine(); pe->widget = this; @@ -2100,13 +2028,6 @@ QPaintEngine *QWidget::paintEngine() const QWindowSurface *QWidgetPrivate::createDefaultWindowSurface_sys() { Q_Q(QWidget); -#ifndef QT_NO_DIRECT3D - extern QDirect3DPaintEngine *qt_d3dEngine(); - if (qApp->testAttribute(Qt::AA_MSWindowsUseDirect3DByDefault) && (q->windowOpacity() == 1.0f) - && qt_d3dEngine()->hasDirect3DSupport()) { - return new QD3DWindowSurface(q); - } -#endif return new QRasterWindowSurface(q); } @@ -2114,11 +2035,19 @@ void QWidgetPrivate::setModal_sys() { } +void QWidgetPrivate::registerTouchWindow() +{ + Q_Q(QWidget); - + // enable WM_TOUCH* messages on our window + if (q->testAttribute(Qt::WA_WState_Created) + && QApplicationPrivate::RegisterTouchWindow + && q->windowType() != Qt::Desktop) + QApplicationPrivate::RegisterTouchWindow(q->effectiveWinId(), 0); +} QT_END_NAMESPACE -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE # include "qwidget_wince.cpp" #endif diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp index 1430a66..b0eaa12 100644 --- a/src/gui/kernel/qwidget_wince.cpp +++ b/src/gui/kernel/qwidget_wince.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE #include "qguifunctions_wince.h" @@ -188,11 +188,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0; -#ifdef UNICODE QString title; - const TCHAR *ttitle = 0; -#endif - QByteArray title95; int style = WS_CHILD; int exsty = WS_EX_NOPARENTNOTIFY; @@ -211,7 +207,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO style |= WS_SYSMENU; if (flags & Qt::WindowContextHelpButtonHint) exsty |= WS_EX_CONTEXTHELP; -#ifndef Q_OS_WINCE_WM +#ifndef Q_WS_WINCE_WM if (flags & Qt::WindowMinimizeButtonHint) style |= WS_MINIMIZEBOX; if (shouldShowMaximizeButton()) @@ -236,12 +232,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } if (flags & Qt::WindowTitleHint) { - QT_WA({ - title = q->isWindow() ? qAppName() : q->objectName(); - ttitle = (TCHAR*)title.utf16(); - } , { - title95 = q->isWindow() ? qAppName().toLocal8Bit() : q->objectName().toLatin1(); - }); + title = q->isWindow() ? qAppName() : q->objectName(); } // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in @@ -254,11 +245,11 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO destroyw = data.winid; id = window; setWinId(window); - LONG res = SetWindowLongA(window, GWL_STYLE, style); + LONG res = SetWindowLong(window, GWL_STYLE, style); if (!res) qErrnoWarning("QWidget::create: Failed to set window style"); - res = SetWindowLongA( window, GWL_WNDPROC, (LONG)QtWndProc ); + res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc ); if (!res) qErrnoWarning("QWidget::create: Failed to set window procedure"); @@ -267,10 +258,10 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (!id) { //Create a dummy desktop RECT r; SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); - const TCHAR *cname = reinterpret_cast<const TCHAR *> (windowClassName.utf16()); - id = CreateWindow(cname, ttitle, style, - r.left, r.top, r.right - r.left, r.bottom - r.top, - 0, 0, appinst, 0); + id = CreateWindow(reinterpret_cast<const wchar_t *>(windowClassName.utf16()), + reinterpret_cast<const wchar_t *>(title.utf16()), style, + r.left, r.top, r.right - r.left, r.bottom - r.top, + 0, 0, appinst, 0); } setWinId(id); } else if (topLevel) { // create top-level widget @@ -303,8 +294,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } } - const TCHAR *cname = reinterpret_cast<const TCHAR *> (windowClassName.utf16()); - id = CreateWindowEx(exsty, cname, ttitle, style, + id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()), + reinterpret_cast<const wchar_t *>(title.utf16()), style, x, y, w, h, 0, 0, appinst, 0); @@ -314,16 +305,9 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget - QT_WA({ - const TCHAR *cname = (TCHAR*)windowClassName.utf16(); - id = CreateWindowEx(exsty, cname, ttitle, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), - parentw, NULL, appinst, NULL); - } , { - id = CreateWindowExA(exsty, windowClassName.toLatin1(), title95, style, - data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), + id = CreateWindowEx(exsty, (wchar_t*)windowClassName.utf16(), (wchar_t*)title.utf16(), style, + data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), parentw, NULL, appinst, NULL); - }); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -414,7 +398,7 @@ void QWidgetPrivate::show_sys() { int sm = SW_SHOW; bool fakedMaximize = false; if (q->isWindow()) { -#ifndef Q_OS_WINCE_WM +#ifndef Q_WS_WINCE_WM if (q->isMinimized()) { sm = SW_SHOWMINIMIZED; } else if (q->isMaximized()) { @@ -450,7 +434,7 @@ void QWidgetPrivate::show_sys() { if (q->isMaximized() && q->isWindow()) qt_wince_maximize(q); -#ifndef Q_OS_WINCE_WM +#ifndef Q_WS_WINCE_WM if (!qt_wince_is_mobile() && q->isFullScreen()) { HWND handle = FindWindow(L"HHTaskBar", L""); if (handle) { @@ -510,7 +494,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) } if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) { if (!(newstate & Qt::WindowMaximized)) { - int style = GetWindowLongW(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION; + int style = GetWindowLong(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION; SetWindowLong(internalWinId(), GWL_STYLE, style); SetWindowLong(internalWinId(), GWL_EXSTYLE, GetWindowLong (internalWinId(), GWL_EXSTYLE) & ~ WS_EX_NODRAG); } @@ -535,11 +519,11 @@ void QWidget::setWindowState(Qt::WindowStates newstate) if (newstate & Qt::WindowFullScreen) { if (d->topData()->normalGeometry.width() < 0 && !(oldstate & Qt::WindowMaximized)) d->topData()->normalGeometry = geometry(); - d->topData()->savedFlags = GetWindowLongA(internalWinId(), GWL_STYLE); + d->topData()->savedFlags = (Qt::WindowFlags)GetWindowLong(internalWinId(), GWL_STYLE); UINT style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); + SetWindowLong(internalWinId(), GWL_STYLE, style); QRect r = qApp->desktop()->screenGeometry(this); UINT swpf = SWP_FRAMECHANGED; if (newstate & Qt::WindowActive) @@ -550,7 +534,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) UINT style = d->topData()->savedFlags; if (isVisible()) style |= WS_VISIBLE; - SetWindowLongA(internalWinId(), GWL_STYLE, style); + SetWindowLong(internalWinId(), GWL_STYLE, style); UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; if (newstate & Qt::WindowActive) swpf |= SWP_NOACTIVATE; @@ -583,7 +567,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) } if ((newstate & Qt::WindowMaximized) && !(newstate & Qt::WindowFullScreen)) { QRect r = d->topData()->normalGeometry; -#ifdef Q_OS_WINCE_WM +#ifdef Q_WS_WINCE_WM if (!inherits("QDialog") && !inherits("QMdiArea") && !isVisible()) { d->data.crect.setRect(0, 0, -1, -1); } @@ -598,13 +582,6 @@ void QWidget::setWindowState(Qt::WindowStates newstate) QApplication::sendEvent(this, &e); } - -void QWidgetPrivate::createSysExtra() { -#ifndef QT_NO_DRAGANDDROP - extra->dropTarget = 0; -#endif -} - void QWidgetPrivate::deleteSysExtra() { Q_Q(QWidget); @@ -704,4 +681,4 @@ void QWidget::show() QT_END_NAMESPACE -#endif Q_OS_WINCE +#endif // Q_WS_WINCE diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index c7b32f2..2a3d2f3 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -754,11 +754,14 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO qBound(1, data.crect.width(), XCOORD_MAX), qBound(1, data.crect.height(), XCOORD_MAX)); XStoreName(dpy, id, appName.data()); - Atom protocols[4]; + Atom protocols[5]; int n = 0; protocols[n++] = ATOM(WM_DELETE_WINDOW); // support del window protocol protocols[n++] = ATOM(WM_TAKE_FOCUS); // support take focus window protocol protocols[n++] = ATOM(_NET_WM_PING); // support _NET_WM_PING protocol +#ifndef QT_NO_XSYNC + protocols[n++] = ATOM(_NET_WM_SYNC_REQUEST); // support _NET_WM_SYNC_REQUEST protocol +#endif // QT_NO_XSYNC if (flags & Qt::WindowContextHelpButtonHint) protocols[n++] = ATOM(_NET_WM_CONTEXT_HELP); XSetWMProtocols(dpy, id, protocols, n); @@ -893,19 +896,70 @@ void QWidgetPrivate::x11UpdateIsOpaque() int screen = xinfo.screen(); if (topLevel && X11->use_xrender && X11->argbVisuals[screen] && xinfo.depth() != 32) { - // recreate widget - QPoint pos = q->pos(); - bool visible = q->isVisible(); - if (visible) - q->hide(); - q->setParent(q->parentWidget(), q->windowFlags()); - q->move(pos); - if (visible) - q->show(); + + if (q->inherits("QGLWidget")) { + // We send QGLWidgets a ParentChange event which causes them to + // recreate their GL context, which in turn causes them to choose + // their visual again. Now that WA_TranslucentBackground is set, + // QGLContext::chooseVisual will select an ARGB visual. + QEvent e(QEvent::ParentChange); + QApplication::sendEvent(q, &e); + } + else { + // For regular widgets, reparent them with their parent which + // also triggers a recreation of the native window + QPoint pos = q->pos(); + bool visible = q->isVisible(); + if (visible) + q->hide(); + + q->setParent(q->parentWidget(), q->windowFlags()); + q->move(pos); + if (visible) + q->show(); + } } #endif } +/* + Returns true if the background is inherited; otherwise returns + false. + + Mainly used in the paintOnScreen case. +*/ +bool QWidgetPrivate::isBackgroundInherited() const +{ + Q_Q(const QWidget); + + // windows do not inherit their background + if (q->isWindow() || q->windowType() == Qt::SubWindow) + return false; + + if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent)) + return false; + + const QPalette &pal = q->palette(); + QPalette::ColorRole bg = q->backgroundRole(); + QBrush brush = pal.brush(bg); + + // non opaque brushes leaves us no choice, we must inherit + if (!q->autoFillBackground() || !brush.isOpaque()) + return true; + + if (brush.style() == Qt::SolidPattern) { + // the background is just a solid color. If there is no + // propagated contents, then we claim as performance + // optimization that it was not inheritet. This is the normal + // case in standard Windows or Motif style. + const QWidget *w = q->parentWidget(); + if (!w->d_func()->isBackgroundInherited()) + return false; + } + + return true; +} + void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); @@ -1308,17 +1362,10 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) // already been set return; - XWMHints *h = 0; - if (q->internalWinId()) - h = XGetWMHints(X11->display, q->internalWinId()); - XWMHints wm_hints; - if (!h) { - memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy - h = &wm_hints; - } - // preparing images to set the _NET_WM_ICON property QIcon icon = q->windowIcon(); + QVector<long> icon_data; + Qt::HANDLE pixmap_handle = 0; if (!icon.isNull()) { QList<QSize> availableSizes = icon.availableSizes(); if(availableSizes.isEmpty()) { @@ -1328,7 +1375,6 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) availableSizes.push_back(QSize(64,64)); availableSizes.push_back(QSize(128,128)); } - QVector<long> icon_data; for(int i = 0; i < availableSizes.size(); ++i) { QSize size = availableSizes.at(i); QPixmap pixmap = icon.pixmap(size); @@ -1350,11 +1396,6 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) } } if (!icon_data.isEmpty()) { - if (q->internalWinId()) { - XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32, - PropModeReplace, (unsigned char *) icon_data.data(), - icon_data.size()); - } extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap); /* if the app is running on an unknown desktop, or it is not @@ -1368,22 +1409,44 @@ void QWidgetPrivate::setWindowIcon_sys(bool forceReset) // unknown DE or non-default visual/colormap, use 1bpp bitmap if (!forceReset || !topData->iconPixmap) topData->iconPixmap = new QBitmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64)))); - h->icon_pixmap = topData->iconPixmap->handle(); + pixmap_handle = topData->iconPixmap->handle(); } else { // default depth, use a normal pixmap (even though this // violates the ICCCM), since this works on all DEs known to Qt if (!forceReset || !topData->iconPixmap) topData->iconPixmap = new QPixmap(qt_toX11Pixmap(icon.pixmap(QSize(64,64)))); - h->icon_pixmap = static_cast<QX11PixmapData*>(topData->iconPixmap->data)->x11ConvertToDefaultDepth(); + pixmap_handle = static_cast<QX11PixmapData*>(topData->iconPixmap->data)->x11ConvertToDefaultDepth(); } - h->flags |= IconPixmapHint; - } else { - h->flags &= ~(IconPixmapHint | IconMaskHint); } } - if (q->internalWinId()) - XSetWMHints(X11->display, q->internalWinId(), h); + if (!q->internalWinId()) + return; + + if (!icon_data.isEmpty()) { + XChangeProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32, + PropModeReplace, (unsigned char *) icon_data.data(), + icon_data.size()); + } else { + XDeleteProperty(X11->display, q->internalWinId(), ATOM(_NET_WM_ICON)); + } + + XWMHints *h = XGetWMHints(X11->display, q->internalWinId()); + XWMHints wm_hints; + if (!h) { + memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy + h = &wm_hints; + } + + if (pixmap_handle) { + h->icon_pixmap = pixmap_handle; + h->flags |= IconPixmapHint; + } else { + h->icon_pixmap = 0; + h->flags &= ~(IconPixmapHint | IconMaskHint); + } + + XSetWMHints(X11->display, q->internalWinId(), h); if (h != &wm_hints) XFree((char *)h); } @@ -1817,6 +1880,23 @@ void QWidgetPrivate::show_sys() if (setUserTime) qt_net_update_user_time(q, userTime); +#ifndef QT_NO_XSYNC + if (!topData()->syncUpdateCounter) { + XSyncValue value; + XSyncIntToValue(&value, 0); + topData()->syncUpdateCounter = XSyncCreateCounter(X11->display, value); + + XChangeProperty(X11->display, q->internalWinId(), + ATOM(_NET_WM_SYNC_REQUEST_COUNTER), + XA_CARDINAL, + 32, PropModeReplace, + (uchar *) &topData()->syncUpdateCounter, 1); + + topData()->newCounterValueHi = 0; + topData()->newCounterValueLo = 0; + } +#endif + if (!topData()->embedded && (topData()->validWMState || topData()->waitingForMapNotify) && !q->isMinimized()) { @@ -2151,7 +2231,7 @@ static void do_size_hints(QWidget* widget, QWExtra *x) parentWRect is the geometry of the parent's X rect, measured in parent's coord sys */ -void QWidgetPrivate::setWSGeometry(bool dontShow) +void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &) { Q_Q(QWidget); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); @@ -2611,8 +2691,8 @@ int QWidget::metric(PaintDeviceMetric m) const void QWidgetPrivate::createSysExtra() { - extra->xDndProxy = 0; extra->compress_events = true; + extra->xDndProxy = 0; } void QWidgetPrivate::deleteSysExtra() @@ -2621,9 +2701,18 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::createTLSysExtra() { + extra->topextra->spont_unmapped = 0; + extra->topextra->dnd = 0; extra->topextra->validWMState = 0; extra->topextra->waitingForMapNotify = 0; + extra->topextra->parentWinId = 0; extra->topextra->userTimeWindow = 0; +#ifndef QT_NO_XSYNC + extra->topextra->syncUpdateCounter = 0; + extra->topextra->syncRequestTimestamp = 0; + extra->topextra->newCounterValueHi = 0; + extra->topextra->newCounterValueLo = 0; +#endif } void QWidgetPrivate::deleteTLSysExtra() diff --git a/src/gui/kernel/qwidgetaction.cpp b/src/gui/kernel/qwidgetaction.cpp index 4b1398e..df3e47e 100644 --- a/src/gui/kernel/qwidgetaction.cpp +++ b/src/gui/kernel/qwidgetaction.cpp @@ -228,8 +228,8 @@ bool QWidgetAction::event(QEvent *event) if (event->type() == QEvent::ActionChanged) { if (d->defaultWidget) d->defaultWidget->setEnabled(isEnabled()); - foreach (QWidget *w, d->createdWidgets) - w->setEnabled(isEnabled()); + for (int i = 0; i < d->createdWidgets.count(); ++i) + d->createdWidgets.at(i)->setEnabled(isEnabled()); } return QAction::event(event); } diff --git a/src/gui/kernel/qwindowdefs_win.h b/src/gui/kernel/qwindowdefs_win.h index 0d883da..d10d016 100644 --- a/src/gui/kernel/qwindowdefs_win.h +++ b/src/gui/kernel/qwindowdefs_win.h @@ -122,7 +122,7 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT HINSTANCE qWinAppInst(); Q_CORE_EXPORT HINSTANCE qWinAppPrevInst(); -Q_GUI_EXPORT int qWinAppCmdShow(); +Q_CORE_EXPORT int qWinAppCmdShow(); Q_GUI_EXPORT HDC qt_win_display_dc(); QT_END_NAMESPACE diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp index f70ed57..659331f 100644 --- a/src/gui/kernel/qx11embed_x11.cpp +++ b/src/gui/kernel/qx11embed_x11.cpp @@ -826,7 +826,7 @@ bool QX11EmbedWidget::x11Event(XEvent *event) &actual_format_return, &nitems_return, &bytes_after_return, &prop_return) == Success) { if (nitems_return > 1) { - if (((int * )prop_return)[1] & XEMBED_MAPPED) { + if (((long * )prop_return)[1] & XEMBED_MAPPED) { XMapWindow(x11Info().display(), internalWinId()); } else { XUnmapWindow(x11Info().display(), internalWinId()); @@ -1297,9 +1297,6 @@ bool QX11EmbedContainer::eventFilter(QObject *o, QEvent *event) // focus is set to our focus proxy. We want to intercept all // keypresses. if (o == window() && d->client) { - if (!d->isEmbedded() && d->activeContainer == this) - d->moveInputToProxy(); - if (d->clientIsXEmbed) { sendXEmbedMessage(d->client, x11Info().display(), XEMBED_WINDOW_ACTIVATE); } else { @@ -1307,6 +1304,8 @@ bool QX11EmbedContainer::eventFilter(QObject *o, QEvent *event) if (hasFocus()) XSetInputFocus(x11Info().display(), d->client, XRevertToParent, x11Time()); } + if (!d->isEmbedded()) + d->moveInputToProxy(); } break; case QEvent::WindowDeactivate: @@ -1671,9 +1670,9 @@ void QX11EmbedContainerPrivate::acceptClient(WId window) // Clients with the _XEMBED_INFO property are XEMBED clients. clientIsXEmbed = true; - unsigned int *p = (unsigned int *)prop_return; + long *p = (long *)prop_return; if (nitems_return >= 2) - clientversion = p[0]; + clientversion = (unsigned int)p[0]; } XFree(prop_return); @@ -1729,10 +1728,10 @@ void QX11EmbedContainerPrivate::acceptClient(WId window) checkGrab(); if (q->hasFocus()) { XSetInputFocus(q->x11Info().display(), client, XRevertToParent, x11Time()); - } else { - if (!isEmbedded()) - moveInputToProxy(); } + } else { + if (!isEmbedded()) + moveInputToProxy(); } emit q->clientIsEmbedded(); @@ -1749,11 +1748,9 @@ void QX11EmbedContainerPrivate::acceptClient(WId window) void QX11EmbedContainerPrivate::moveInputToProxy() { Q_Q(QX11EmbedContainer); - WId focus; - int revert_to; - XGetInputFocus(q->x11Info().display(), &focus, &revert_to); - if (focus != focusProxy->internalWinId()) - XSetInputFocus(q->x11Info().display(), focusProxy->internalWinId(), XRevertToParent, x11Time()); + // Following Owen Taylor's advice from the XEmbed specification to + // always use CurrentTime when no explicit user action is involved. + XSetInputFocus(q->x11Info().display(), focusProxy->internalWinId(), XRevertToParent, CurrentTime); } /*! \internal |