summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication.cpp47
-rw-r--r--src/gui/kernel/qapplication.h1
-rw-r--r--src/gui/kernel/qapplication_mac.mm32
-rw-r--r--src/gui/kernel/qapplication_p.h3
-rw-r--r--src/gui/kernel/qapplication_s60.cpp89
-rw-r--r--src/gui/kernel/qapplication_win.cpp48
-rw-r--r--src/gui/kernel/qapplication_x11.cpp90
-rw-r--r--src/gui/kernel/qclipboard.cpp6
-rw-r--r--src/gui/kernel/qclipboard_x11.cpp15
-rw-r--r--src/gui/kernel/qcocoaapplicationdelegate_mac.mm13
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac.mm23
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac_p.h4
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h20
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm102
-rw-r--r--src/gui/kernel/qcursor.cpp3
-rw-r--r--src/gui/kernel/qcursor_mac.mm33
-rw-r--r--src/gui/kernel/qcursor_s60.cpp2
-rw-r--r--src/gui/kernel/qcursor_x11.cpp68
-rw-r--r--src/gui/kernel/qdesktopwidget_s60.cpp1
-rw-r--r--src/gui/kernel/qdesktopwidget_win.cpp4
-rw-r--r--src/gui/kernel/qdnd_win.cpp16
-rw-r--r--src/gui/kernel/qdnd_x11.cpp12
-rw-r--r--src/gui/kernel/qeventdispatcher_mac.mm17
-rw-r--r--src/gui/kernel/qeventdispatcher_mac_p.h1
-rw-r--r--src/gui/kernel/qgesture_p.h4
-rw-r--r--src/gui/kernel/qgesturemanager.cpp4
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp2
-rw-r--r--src/gui/kernel/qgridlayout.cpp2
-rw-r--r--src/gui/kernel/qguifunctions_wince.cpp9
-rw-r--r--src/gui/kernel/qkeymapper_mac.cpp54
-rw-r--r--src/gui/kernel/qkeymapper_p.h2
-rw-r--r--src/gui/kernel/qkeymapper_win.cpp2
-rw-r--r--src/gui/kernel/qkeymapper_x11.cpp47
-rw-r--r--src/gui/kernel/qkeysequence.cpp36
-rw-r--r--src/gui/kernel/qmime_win.cpp12
-rw-r--r--src/gui/kernel/qsoftkeymanager.cpp61
-rw-r--r--src/gui/kernel/qsoftkeymanager_common_p.h3
-rw-r--r--src/gui/kernel/qsoftkeymanager_p.h5
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60.cpp77
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60_p.h3
-rw-r--r--src/gui/kernel/qsound.cpp3
-rw-r--r--src/gui/kernel/qsound_mac.mm1
-rw-r--r--src/gui/kernel/qstandardgestures.cpp7
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm60
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h2
-rw-r--r--src/gui/kernel/qt_s60_p.h6
-rw-r--r--src/gui/kernel/qt_x11_p.h11
-rw-r--r--src/gui/kernel/qtooltip.cpp11
-rw-r--r--src/gui/kernel/qwidget.cpp143
-rw-r--r--src/gui/kernel/qwidget.h1
-rw-r--r--src/gui/kernel/qwidget_mac.mm100
-rw-r--r--src/gui/kernel/qwidget_p.h24
-rw-r--r--src/gui/kernel/qwidget_s60.cpp69
-rw-r--r--src/gui/kernel/qwidget_win.cpp6
-rw-r--r--src/gui/kernel/qwidget_wince.cpp4
-rw-r--r--src/gui/kernel/qwidget_x11.cpp90
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win_p.h32
-rw-r--r--src/gui/kernel/qx11embed_x11.cpp4
58 files changed, 1125 insertions, 422 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 4ec2ae2..b0a23d4 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -498,9 +498,7 @@ inline bool QApplicationPrivate::isAlien(QWidget *widget)
{
if (!widget)
return false;
-#if defined(Q_WS_MAC) // Fake alien behavior on the Mac :)
- return !widget->isWindow() && widget->window()->testAttribute(Qt::WA_DontShowOnScreen);
-#elif defined(Q_WS_QWS)
+#if defined(Q_WS_QWS)
return !widget->isWindow()
# ifdef Q_BACKINGSTORE_SUBSURFACES
&& !(widget->d_func()->maybeTopData() && widget->d_func()->maybeTopData()->windowSurface)
@@ -905,6 +903,14 @@ void QApplicationPrivate::initialize()
{
QWidgetPrivate::mapper = new QWidgetMapper;
QWidgetPrivate::allWidgets = new QWidgetSet;
+
+#if !defined(Q_WS_X11) && !defined(Q_WS_QWS)
+ // initialize the graphics system - on X11 this is initialized inside
+ // qt_init() in qapplication_x11.cpp because of several reasons.
+ // On QWS, the graphics system is set by the QScreen plugin.
+ graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
+#endif
+
if (qt_appType != QApplication::Tty)
(void) QApplication::style(); // trigger creation of application style
// trigger registering of QVariant's GUI types
@@ -938,13 +944,7 @@ void QApplicationPrivate::initialize()
// Set up which span functions should be used in raster engine...
qInitDrawhelperAsm();
-
-#if !defined(Q_WS_X11) && !defined(Q_WS_QWS)
- // initialize the graphics system - on X11 this is initialized inside
- // qt_init() in qapplication_x11.cpp because of several reasons.
- // On QWS, the graphics system is set by the QScreen plugin.
- graphics_system = QGraphicsSystemFactory::create(graphics_system_name);
-#endif
+
#ifndef QT_NO_WHEELEVENT
QApplicationPrivate::wheel_scroll_lines = 3;
#endif
@@ -2311,6 +2311,22 @@ static bool qt_detectRTLLanguage()
" languages or to 'RTL' in right-to-left languages (such as Hebrew"
" and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
}
+#if defined(Q_WS_MAC)
+static const char *application_menu_strings[] = {
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Preferences..."),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Quit %1"),
+ QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","About %1")
+ };
+QString qt_mac_applicationmenu_string(int type)
+{
+ return qApp->translate("MAC_APPLICATION_MENU",
+ application_menu_strings[type]);
+}
+#endif
#endif
/*!\reimp
@@ -2339,6 +2355,9 @@ bool QApplication::event(QEvent *e)
#ifndef QT_NO_TRANSLATION
setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight);
#endif
+#if defined(QT_MAC_USE_COCOA)
+ qt_mac_post_retranslateAppMenu();
+#endif
QWidgetList list = topLevelWidgets();
for (int i = 0; i < list.size(); ++i) {
QWidget *w = list.at(i);
@@ -3013,7 +3032,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
return result;
}
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_MAC)
/*
This function should only be called when the widget changes visibility, i.e.
when the \a widget is shown, hidden or deleted. This function does nothing
@@ -3073,7 +3092,7 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
#endif // QT_NO_CURSOR
}
-#endif // Q_WS_WIN || Q_WS_X11
+#endif // Q_WS_WIN || Q_WS_X11 || Q_WS_MAC
/*!
Returns the desktop widget (also called the root window).
@@ -5273,9 +5292,9 @@ QInputContext *QApplication::inputContext() const
QApplication *that = const_cast<QApplication *>(this);
const QStringList keys = QInputContextFactory::keys();
// Try hbim and coefep first, then try others.
- if (keys.contains("hbim")) {
+ if (keys.contains(QLatin1String("hbim"))) {
that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("hbim"), that);
- } else if (keys.contains("coefep")) {
+ } else if (keys.contains(QLatin1String("coefep"))) {
that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("coefep"), that);
} else {
for (int c = 0; c < keys.size() && !d->inputContext; ++c) {
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index ee74350..c21b982 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -376,6 +376,7 @@ private:
Q_DECLARE_PRIVATE(QApplication)
friend class QGraphicsWidget;
+ friend class QGraphicsItem;
friend class QGraphicsScene;
friend class QGraphicsScenePrivate;
friend class QWidget;
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index e511c3a..28072fc 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -184,7 +184,8 @@ bool qt_mac_app_fullscreen = false;
bool qt_scrollbar_jump_to_pos = false;
static bool qt_mac_collapse_on_dblclick = true;
extern int qt_antialiasing_threshold; // from qapplication.cpp
-QPointer<QWidget> qt_button_down; // widget got last button-down
+QWidget * qt_button_down; // widget got last button-down
+QPointer<QWidget> qt_last_mouse_receiver;
#ifndef QT_MAC_USE_COCOA
static bool qt_button_down_in_content; // whether the button_down was in the content area.
static bool qt_mac_previous_press_in_popup_mode = false;
@@ -1222,9 +1223,16 @@ void qt_init(QApplicationPrivate *priv, int)
#endif
if (!app_proc_ae_handlerUPP) {
app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor);
- for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i)
- AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
- app_proc_ae_handlerUPP, SRefCon(qApp), false);
+ for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) {
+ // Install apple event handler, but avoid overwriting an already
+ // existing handler (it means a 3rd party application has installed one):
+ SRefCon refCon = 0;
+ AEEventHandlerUPP current_handler = NULL;
+ AEGetEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id, &current_handler, &refCon, false);
+ if (!current_handler)
+ AEInstallEventHandler(app_apple_events[i].mac_class, app_apple_events[i].mac_id,
+ app_proc_ae_handlerUPP, SRefCon(qApp), false);
+ }
}
if (QApplicationPrivate::app_style) {
@@ -1751,14 +1759,19 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event
// (actually two events; one for horizontal and one for vertical).
// As a results of this, and to make sure we dont't receive duplicate events,
// we try to detect when this happend by checking the 'compatibilityEvent'.
+ // Since delta is delivered as pixels rather than degrees, we need to
+ // convert from pixels to degrees in a sensible manner.
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2;
SInt32 mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaX = mdelt;
+ wheel_deltaX = mdelt * pixelsToDegrees;
mdelt = 0;
GetEventParameter(event, kEventParamMouseWheelSmoothVerticalDelta, typeSInt32, 0,
sizeof(mdelt), 0, &mdelt);
- wheel_deltaY = mdelt;
+ wheel_deltaY = mdelt * pixelsToDegrees;
GetEventParameter(event, kEventParamEventRef, typeEventRef, 0,
sizeof(compatibilityEvent), 0, &compatibilityEvent);
} else if (ekind == kEventMouseWheelMoved) {
@@ -2495,6 +2508,13 @@ void QApplicationPrivate::setupAppleEvents()
// finished initialization, which appears to be just after [NSApplication run] has
// started to execute. By setting up our apple events handlers this late, we override
// the ones set up by NSApplication.
+
+ // If Qt is used as a plugin, we let the 3rd party application handle events
+ // like quit and open file events. Otherwise, if we install our own handlers, we
+ // easily end up breaking functionallity the 3rd party application depend on:
+ if (QApplication::testAttribute(Qt::AA_MacPluginApplication))
+ return;
+
QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) *newDelegate = [QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate) sharedDelegate];
NSAppleEventManager *eventManager = [NSAppleEventManager sharedAppleEventManager];
[eventManager setEventHandler:newDelegate andSelector:@selector(appleEventQuit:withReplyEvent:)
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index e0a6103..6d71cfe 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -514,7 +514,7 @@ public:
int symbianResourceChange(const QSymbianEvent *symbianEvent);
#endif
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
void sendSyntheticEnterLeave(QWidget *widget);
#endif
@@ -543,6 +543,7 @@ public:
const QList<QTouchEvent::TouchPoint> &touchPoints);
#if defined(Q_WS_WIN)
+ static bool HasTouchSupport;
static PtrRegisterTouchWindow RegisterTouchWindow;
static PtrGetTouchInputInfo GetTouchInputInfo;
static PtrCloseTouchInputHandle CloseTouchInputHandle;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index baefdfd..c735d1f 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -52,6 +52,7 @@
#include "qstring.h"
#include "qdebug.h"
#include "qimage.h"
+#include "qcombobox.h"
#include "private/qkeymapper_p.h"
#include "private/qfont_p.h"
#ifndef QT_NO_STYLE_S60
@@ -371,8 +372,13 @@ QSymbianControl::~QSymbianControl()
{
if (S60->curWin == this)
S60->curWin = 0;
- if (!QApplicationPrivate::is_app_closing)
- setFocusSafely(false);
+ if (!QApplicationPrivate::is_app_closing) {
+ QT_TRY {
+ setFocusSafely(false);
+ } QT_CATCH(const std::exception&) {
+ // ignore exceptions, nothing can be done
+ }
+ }
S60->appUi()->RemoveFromStack(this);
delete m_longTapDetector;
}
@@ -597,9 +603,9 @@ TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCod
TUint s60Keysym = QApplicationPrivate::resolveS60ScanCode(keyEvent.iScanCode,
keyEvent.iCode);
int keyCode;
- if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
- keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
- } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
+ if (s60Keysym == EKeyNull){ //some key events have 0 in iCode, for them iScanCode should be used
+ keyCode = qt_keymapper_private()->mapS60ScanCodesToQt(keyEvent.iScanCode);
+ } else if (s60Keysym >= 0x20 && s60Keysym < ENonCharacterKeyBase) {
// Normal characters keys.
keyCode = s60Keysym;
} else {
@@ -966,16 +972,29 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
#ifdef Q_WS_S60
// If widget is fullscreen/minimized, hide status pane and button container otherwise show them.
- CEikStatusPane* statusPane = S60->statusPane();
- CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
+ CEikStatusPane *statusPane = S60->statusPane();
+ CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized));
if (statusPane)
statusPane->MakeVisible(visible);
- if (buttonGroup)
- buttonGroup->MakeVisible(visible);
+ if (buttonGroup) {
+ // Visibility
+ const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
+ const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint));
+
+ // Responsiviness
+ CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
+ TUint cbaFlags = cba->ButtonGroupFlags();
+ if(qwidget->windowFlags() & Qt::WindowSoftkeysRespondHint)
+ cbaFlags |= EAknCBAFlagRespondWhenInvisible;
+ else
+ cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
+ cba->SetButtonGroupFlags(cbaFlags);
+ }
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
- if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) {
+ if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) {
QWidget *fw = QApplication::focusWidget();
if (fw) {
QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason);
@@ -990,16 +1009,32 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
// else { We don't touch the active window unless we were explicitly activated or deactivated }
}
+void QSymbianControl::handleClientAreaChange()
+{
+ const bool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ if (qwidget->isFullScreen() && !cbaVisibilityHint) {
+ SetExtentToWholeScreen();
+ } else if (qwidget->isMaximized() || (qwidget->isFullScreen() && cbaVisibilityHint)) {
+ TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+ SetExtent(r.iTl, r.Size());
+ } else if (!qwidget->isMinimized()) { // Normal geometry
+ if (!qwidget->testAttribute(Qt::WA_Resized)) {
+ qwidget->adjustSize();
+ qwidget->setAttribute(Qt::WA_Resized, false); //not a user resize
+ }
+ if (!qwidget->testAttribute(Qt::WA_Moved) && qwidget->windowType() != Qt::Dialog) {
+ TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+ SetPosition(r.iTl);
+ qwidget->setAttribute(Qt::WA_Moved, false); // not really an explicit position
+ }
+ }
+}
+
void QSymbianControl::HandleResourceChange(int resourceType)
{
switch (resourceType) {
case KInternalStatusPaneChange:
- if (qwidget->isFullScreen()) {
- SetExtentToWholeScreen();
- } else if (qwidget->isMaximized()) {
- TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
- SetExtent(r.iTl, r.Size());
- }
+ handleClientAreaChange();
if (IsFocused() && IsVisible()) {
qwidget->d_func()->setWindowIcon_sys(true);
qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle());
@@ -1011,12 +1046,7 @@ void QSymbianControl::HandleResourceChange(int resourceType)
#ifdef Q_WS_S60
case KEikDynamicLayoutVariantSwitch:
{
- if (qwidget->isFullScreen()) {
- SetExtentToWholeScreen();
- } else if (qwidget->isMaximized()) {
- TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
- SetExtent(r.iTl, r.Size());
- }
+ handleClientAreaChange();
break;
}
#endif
@@ -1214,6 +1244,7 @@ void qt_init(QApplicationPrivate * /* priv */, int)
}
S60->avkonComponentsSupportTransparency = false;
+ S60->menuBeingConstructed = false;
#ifdef Q_WS_S60
TUid KCRUidAvkon = { 0x101F876E };
@@ -1229,13 +1260,15 @@ void qt_init(QApplicationPrivate * /* priv */, int)
S60->avkonComponentsSupportTransparency = (value==1) ? true : false;
}
}
-#endif
+#endif
+#ifdef QT_KEYPAD_NAVIGATION
if (touch) {
QApplicationPrivate::navigationMode = Qt::NavigationModeNone;
} else {
QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
}
+#endif
#ifndef QT_NO_CURSOR
//Check if window server pointer cursors are supported or not
@@ -1384,11 +1417,13 @@ void QApplicationPrivate::leaveModal_sys(QWidget *widget)
void QApplicationPrivate::openPopup(QWidget *popup)
{
+ if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
+ static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(ETrue);
+
if (!QApplicationPrivate::popupWidgets)
QApplicationPrivate::popupWidgets = new QWidgetList;
QApplicationPrivate::popupWidgets->append(popup);
-
// Cancel focus widget pointer capture and long tap timer
if (QApplication::focusWidget()) {
static_cast<QSymbianControl*>(QApplication::focusWidget()->effectiveWinId())->CancelLongTapTimer();
@@ -1427,6 +1462,9 @@ void QApplicationPrivate::openPopup(QWidget *popup)
void QApplicationPrivate::closePopup(QWidget *popup)
{
+ if (popup && qobject_cast<QComboBox *>(popup->parentWidget()))
+ static_cast<QSymbianControl *>(popup->effectiveWinId())->FadeBehindPopup(EFalse);
+
if (!QApplicationPrivate::popupWidgets)
return;
QApplicationPrivate::popupWidgets->removeAll(popup);
@@ -1450,6 +1488,9 @@ void QApplicationPrivate::closePopup(QWidget *popup)
QWidget *fw = QApplicationPrivate::active_window ? QApplicationPrivate::active_window->focusWidget()
: q_func()->focusWidget();
if (fw) {
+ if(fw->window()->isModal()) // restore pointer capture for modal window
+ fw->effectiveWinId()->SetPointerCapture(true);
+
if (fw != q_func()->focusWidget()) {
fw->setFocus(Qt::PopupFocusReason);
} else {
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 131b9bb..1d8eb4c 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -115,6 +115,8 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c
# include <winable.h>
#endif
+#include "private/qwinnativepangesturerecognizer_win_p.h"
+
#ifndef WM_TOUCH
# define WM_TOUCH 0x0240
@@ -439,7 +441,7 @@ extern QCursor *qt_grab_cursor();
#define __export
#endif
-extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
class QETWidget : public QWidget // event translator widget
{
@@ -1398,8 +1400,7 @@ static bool qt_is_translatable_mouse_event(UINT message)
;
}
-extern "C"
-LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
bool result = true;
QEvent::Type evt_type = QEvent::None;
@@ -1577,6 +1578,10 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_XBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDBLCLK:
+ case WM_MBUTTONDBLCLK:
+ case WM_XBUTTONDBLCLK:
if (qt_win_ignoreNextMouseReleaseEvent)
qt_win_ignoreNextMouseReleaseEvent = false;
break;
@@ -2277,7 +2282,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
case WM_GETOBJECT:
{
// Ignoring all requests while starting up
- if (QApplication::startingUp() || QApplication::closingDown() || (DWORD)lParam != OBJID_CLIENT) {
+ if (QApplication::startingUp() || QApplication::closingDown() || (LONG)lParam != OBJID_CLIENT) {
result = false;
break;
}
@@ -2524,6 +2529,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
}
result = false;
break;
+#if !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
case WM_GESTURE: {
GESTUREINFO gi;
memset(&gi, 0, sizeof(GESTUREINFO));
@@ -2556,6 +2562,7 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
result = true;
break;
}
+#endif // !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES)
#ifndef QT_NO_CURSOR
case WM_SETCURSOR: {
QCursor *ovr = QApplication::overrideCursor();
@@ -4012,12 +4019,45 @@ void QSessionManager::cancel()
#endif //QT_NO_SESSIONMANAGER
+bool QApplicationPrivate::HasTouchSupport = false;
PtrRegisterTouchWindow QApplicationPrivate::RegisterTouchWindow = 0;
PtrGetTouchInputInfo QApplicationPrivate::GetTouchInputInfo = 0;
PtrCloseTouchInputHandle QApplicationPrivate::CloseTouchInputHandle = 0;
void QApplicationPrivate::initializeMultitouch_sys()
{
+ static const IID QT_IID_IInkTablets = {0x112086D9, 0x7779, 0x4535, {0xA6, 0x99, 0x86, 0x2B, 0x43, 0xAC, 0x18, 0x63} };
+ static const IID QT_IID_IInkTablet2 = {0x90c91ad2, 0xfa36, 0x49d6, {0x95, 0x16, 0xce, 0x8d, 0x57, 0x0f, 0x6f, 0x85} };
+ static const CLSID QT_CLSID_InkTablets = {0x6E4FCB12, 0x510A, 0x4d40, {0x93, 0x04, 0x1D, 0xA1, 0x0A, 0xE9, 0x14, 0x7C} };
+
+ IInkTablets *iInkTablets = 0;
+ HRESULT hr = CoCreateInstance(QT_CLSID_InkTablets, NULL, CLSCTX_ALL, QT_IID_IInkTablets, (void**)&iInkTablets);
+ if (SUCCEEDED(hr)) {
+ long count = 0;
+ iInkTablets->get_Count(&count);
+ for (long i = 0; i < count; ++i) {
+ IInkTablet *iInkTablet = 0;
+ hr = iInkTablets->Item(i, &iInkTablet);
+ if (FAILED(hr))
+ continue;
+ IInkTablet2 *iInkTablet2 = 0;
+ hr = iInkTablet->QueryInterface(QT_IID_IInkTablet2, (void**)&iInkTablet2);
+ iInkTablet->Release();
+ if (FAILED(hr))
+ continue;
+ TabletDeviceKind kind;
+ hr = iInkTablet2->get_DeviceKind(&kind);
+ iInkTablet2->Release();
+ if (FAILED(hr))
+ continue;
+ if (kind == TDK_Touch) {
+ QApplicationPrivate::HasTouchSupport = true;
+ break;
+ }
+ }
+ iInkTablets->Release();
+ }
+
QLibrary library(QLatin1String("user32"));
// MinGW (g++ 3.4.5) accepts only C casts.
RegisterTouchWindow = (PtrRegisterTouchWindow)(library.resolve("RegisterTouchWindow"));
diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp
index 3c2c743..78fc704 100644
--- a/src/gui/kernel/qapplication_x11.cpp
+++ b/src/gui/kernel/qapplication_x11.cpp
@@ -96,6 +96,11 @@ extern "C" {
}
#endif
+#ifndef QT_GUI_DOUBLE_CLICK_RADIUS
+#define QT_GUI_DOUBLE_CLICK_RADIUS 5
+#endif
+
+
//#define ALIEN_DEBUG
#if !defined(QT_NO_GLIB)
@@ -270,6 +275,8 @@ static const char * x11_atomnames = {
"_NET_SYSTEM_TRAY_VISUAL\0"
+ "_NET_ACTIVE_WINDOW\0"
+
// Property formats
"COMPOUND_TEXT\0"
"TEXT\0"
@@ -312,9 +319,14 @@ static const char * x11_atomnames = {
"_XEMBED\0"
"_XEMBED_INFO\0"
+ // Wacom old. (before version 0.10)
"Wacom Stylus\0"
"Wacom Cursor\0"
"Wacom Eraser\0"
+
+ // Tablet
+ "STYLUS\0"
+ "ERASER\0"
};
Q_GUI_EXPORT QX11Data *qt_x11Data = 0;
@@ -657,11 +669,6 @@ static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
return 0;
break;
- case BadMatch:
- if (err->request_code == 42 /* X_SetInputFocus */)
- return 0;
- break;
-
default:
#if !defined(QT_NO_XINPUT)
if (err->request_code == X11->xinput_major
@@ -699,6 +706,10 @@ static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
extensionName = "XInputExtension";
else if (err->request_code == X11->mitshm_major)
extensionName = "MIT-SHM";
+#ifndef QT_NO_XKB
+ else if(err->request_code == X11->xkb_major)
+ extensionName = "XKEYBOARD";
+#endif
char minor_str[256];
if (extensionName) {
@@ -1625,6 +1636,11 @@ void qt_init(QApplicationPrivate *priv, int,
X11->xinput_eventbase = 0;
X11->xinput_errorbase = 0;
+ X11->use_xkb = false;
+ X11->xkb_major = 0;
+ X11->xkb_eventbase = 0;
+ X11->xkb_errorbase = 0;
+
// MIT-SHM
X11->use_mitshm = false;
X11->use_mitshm_pixmaps = false;
@@ -2098,6 +2114,33 @@ void qt_init(QApplicationPrivate *priv, int,
}
#endif // QT_NO_XINPUT
+#ifndef QT_NO_XKB
+ int xkblibMajor = XkbMajorVersion;
+ int xkblibMinor = XkbMinorVersion;
+ X11->use_xkb = XkbQueryExtension(X11->display,
+ &X11->xkb_major,
+ &X11->xkb_eventbase,
+ &X11->xkb_errorbase,
+ &xkblibMajor,
+ &xkblibMinor);
+ if (X11->use_xkb) {
+ // If XKB is detected, set the GrabsUseXKBState option so input method
+ // compositions continue to work (ie. deadkeys)
+ unsigned int state = XkbPCF_GrabsUseXKBStateMask;
+ (void) XkbSetPerClientControls(X11->display, state, &state);
+
+ // select for group change events
+ XkbSelectEventDetails(X11->display,
+ XkbUseCoreKbd,
+ XkbStateNotify,
+ XkbAllStateComponentsMask,
+ XkbGroupStateMask);
+
+ // current group state is queried when creating the keymapper, no need to do it here
+ }
+#endif
+
+
#if !defined(QT_NO_FONTCONFIG)
int dpi = 0;
getXDefault("Xft", FC_DPI, &dpi);
@@ -2176,15 +2219,6 @@ void qt_init(QApplicationPrivate *priv, int,
// initialize key mapper
QKeyMapper::changeKeyboard();
-#ifndef QT_NO_XKB
- if (qt_keymapper_private()->useXKB) {
- // If XKB is detected, set the GrabsUseXKBState option so input method
- // compositions continue to work (ie. deadkeys)
- unsigned int state = XkbPCF_GrabsUseXKBStateMask;
- (void) XkbSetPerClientControls(X11->display, state, &state);
- }
-#endif // QT_NO_XKB
-
// Misc. initialization
#if 0 //disabled for now..
QSegfaultHandler::initialize(priv->argv, priv->argc);
@@ -2340,12 +2374,12 @@ void qt_init(QApplicationPrivate *priv, int,
gotStylus = true;
}
#else
- if (devs->type == ATOM(XWacomStylus)) {
+ if (devs->type == ATOM(XWacomStylus) || devs->type == ATOM(XTabletStylus)) {
deviceType = QTabletEvent::Stylus;
if (wacomDeviceName()->isEmpty())
wacomDeviceName()->append(devs->name);
gotStylus = true;
- } else if (devs->type == ATOM(XWacomEraser)) {
+ } else if (devs->type == ATOM(XWacomEraser) || devs->type == ATOM(XTabletEraser)) {
deviceType = QTabletEvent::XFreeEraser;
gotEraser = true;
}
@@ -3021,6 +3055,8 @@ int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
if ((ulong) event->xclient.data.l[1] > X11->time)
X11->time = event->xclient.data.l[1];
QWidget *amw = activeModalWidget();
+ if (amw && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus))
+ amw = 0;
if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) {
QWidget *p = amw->parentWidget();
while (p && p != widget)
@@ -3219,6 +3255,24 @@ int QApplication::x11ProcessEvent(XEvent* event)
QKeyMapper::changeKeyboard();
return 0;
}
+#ifndef QT_NO_XKB
+ else if (X11->use_xkb && event->type == X11->xkb_eventbase) {
+ XkbAnyEvent *xkbevent = (XkbAnyEvent *) event;
+ switch (xkbevent->xkb_type) {
+ case XkbStateNotify:
+ {
+ XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent;
+ if ((xkbstateevent->changed & XkbGroupStateMask) != 0) {
+ qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group;
+ QKeyMapper::changeKeyboard();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#endif
if (!widget) { // don't know this windows
QWidget* popup = QApplication::activePopupWidget();
@@ -4194,8 +4248,8 @@ bool QETWidget::translateMouseEvent(const XEvent *event)
mouseButtonPressed == button &&
(long)event->xbutton.time -(long)mouseButtonPressTime
< QApplication::doubleClickInterval() &&
- qAbs(event->xbutton.x - mouseXPos) < 5 &&
- qAbs(event->xbutton.y - mouseYPos) < 5) {
+ qAbs(event->xbutton.x - mouseXPos) < QT_GUI_DOUBLE_CLICK_RADIUS &&
+ qAbs(event->xbutton.y - mouseYPos) < QT_GUI_DOUBLE_CLICK_RADIUS) {
type = QEvent::MouseButtonDblClick;
mouseButtonPressTime -= 2000; // no double-click next time
} else {
diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp
index a59bb98..f7c0b6e 100644
--- a/src/gui/kernel/qclipboard.cpp
+++ b/src/gui/kernel/qclipboard.cpp
@@ -107,6 +107,12 @@ QT_BEGIN_NAMESPACE
store or retrieve the clipboard contents in response to timer or
non-user-input events.
+ \i Since there is no standard way to copy and paste files between
+ applications on X11, various MIME types and conventions are currently
+ in use. For instance, Nautilus expects files to be supplied with a
+ \c{x-special/gnome-copied-files} MIME type with data beginning with
+ the cut/copy action, a newline character, and the URL of the file.
+
\endlist
\section1 Notes for Mac OS X Users
diff --git a/src/gui/kernel/qclipboard_x11.cpp b/src/gui/kernel/qclipboard_x11.cpp
index 047bd09..3bdc971 100644
--- a/src/gui/kernel/qclipboard_x11.cpp
+++ b/src/gui/kernel/qclipboard_x11.cpp
@@ -65,7 +65,6 @@
#include "qapplication.h"
#include "qdesktopwidget.h"
#include "qbitmap.h"
-#include "qdatetime.h"
#include "qiodevice.h"
#include "qbuffer.h"
#include "qtextcodec.h"
@@ -76,6 +75,7 @@
#include "qt_x11_p.h"
#include "qx11info_x11.h"
#include "qimagewriter.h"
+#include "qelapsedtimer.h"
#include "qvariant.h"
#include "qdnd_p.h"
#include <private/qwidget_p.h>
@@ -516,8 +516,9 @@ static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer)
bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int timeout)
{
- QTime started = QTime::currentTime();
- QTime now = started;
+ QElapsedTimer started;
+ started.start();
+ QElapsedTimer now = started;
if (QAbstractEventDispatcher::instance()->inherits("QtMotif")
|| QApplication::clipboard()->property("useEventLoopWhenWaiting").toBool()) {
@@ -545,9 +546,7 @@ bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int ti
XSync(X11->display, false);
usleep(50000);
- now = QTime::currentTime();
- if (started > now) // crossed midnight
- started = now;
+ now.start();
QEventLoop::ProcessEventsFlags flags(QEventLoop::ExcludeUserInputEvents
| QEventLoop::ExcludeSocketNotifiers
@@ -576,9 +575,7 @@ bool QX11Data::clipboardWaitForEvent(Window win, int type, XEvent *event, int ti
if (XCheckIfEvent(X11->display, &e, checkForClipboardEvents, 0))
qApp->x11ProcessEvent(&e);
- now = QTime::currentTime();
- if ( started > now ) // crossed midnight
- started = now;
+ now.start();
XFlush(X11->display);
diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
index ab71a05..5dcf613 100644
--- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
+++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm
@@ -179,7 +179,7 @@ static void cleanupCocoaApplicationDelegate()
}
// This function will only be called when NSApp is actually running. Before
-// that, the kAEQuitApplication apple event will be sendt to
+// that, the kAEQuitApplication Apple event will be sent to
// QApplicationPrivate::globalAppleEventProcessor in qapplication_mac.mm
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
@@ -196,21 +196,18 @@ static void cleanupCocoaApplicationDelegate()
qAppInstance()->quit();
startedQuit = false;
}
+ return NSTerminateNow;
}
if (qtPrivate->threadData->eventLoops.size() == 0) {
// INVARIANT: No event loop is executing. This probably
// means that Qt is used as a plugin, or as a part of a native
- // Cocoa application. In any case it should be fine to
+ // Cocoa application. In any case it should be fine to
// terminate now:
return NSTerminateNow;
- } else {
- // Prevent Cocoa from terminating the application, since this simply
- // exits the program whithout allowing QApplication::exec() to return.
- // The call to QApplication::quit() above will instead quit the
- // application from the Qt side.
- return NSTerminateCancel;
}
+
+ return NSTerminateCancel;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm
index 573b763..b58fd7c 100644
--- a/src/gui/kernel/qcocoamenuloader_mac.mm
+++ b/src/gui/kernel/qcocoamenuloader_mac.mm
@@ -48,6 +48,7 @@
#include <private/qt_mac_p.h>
#include <private/qmenubar_p.h>
#include <qmenubar.h>
+#include <private/qt_cocoa_helpers_mac_p.h>
QT_FORWARD_DECLARE_CLASS(QCFString)
QT_FORWARD_DECLARE_CLASS(QString)
@@ -58,6 +59,10 @@ QT_USE_NAMESPACE
- (void)awakeFromNib
{
+ servicesItem = [[appMenu itemWithTitle:@"Services"] retain];
+ hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain];
+ showAllItem = [[appMenu itemWithTitle:@"Show All"] retain];
+
// Get the names in the nib to match the app name set by Qt.
NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qAppName()));
[quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
@@ -119,6 +124,10 @@ QT_USE_NAMESPACE
- (void)dealloc
{
+ [servicesItem release];
+ [hideAllOthersItem release];
+ [showAllItem release];
+
[lastAppSpecificItem release];
[theMenu release];
[appMenu release];
@@ -214,6 +223,20 @@ QT_USE_NAMESPACE
QMenuBarPrivate::macUpdateMenuBarImmediatly();
}
+- (void)qtTranslateApplicationMenu
+{
+#ifndef QT_NO_TRANSLATION
+ extern QString qt_mac_applicationmenu_string(int type);
+ [servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))];
+ [hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qAppName()))];
+ [hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))];
+ [showAllItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(3))];
+ [preferencesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(4))];
+ [quitItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(5).arg(qAppName()))];
+ [aboutItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(6).arg(qAppName()))];
+#endif
+}
+
- (IBAction)qtDispatcherToQAction:(id)sender
{
QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h
index 2504b8c..a75ad0a 100644
--- a/src/gui/kernel/qcocoamenuloader_mac_p.h
+++ b/src/gui/kernel/qcocoamenuloader_mac_p.h
@@ -67,7 +67,9 @@
IBOutlet NSMenuItem *aboutQtItem;
IBOutlet NSMenuItem *hideItem;
NSMenuItem *lastAppSpecificItem;
-
+ NSMenuItem *servicesItem;
+ NSMenuItem *hideAllOthersItem;
+ NSMenuItem *showAllItem;
}
- (void)ensureAppMenuInMenu:(NSMenu *)menu;
- (void)removeActionsFromAppMenu;
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index 9fe5ae0..129e0a5 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -132,26 +132,6 @@ QT_END_NAMESPACE
[super toggleToolbarShown:sender];
}
-/*
- The methods keyDown, keyUp, and flagsChanged... These really shouldn't ever
- get hit. We automatically say we can be first responder if we are a window.
- So, the handling should get handled by the view. This is here more as a
- last resort (i.e., this is code that can potentially be removed).
- */
-- (void)keyDown:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyDown:theEvent];
-}
-
-- (void)keyUp:(NSEvent *)theEvent
-{
- bool keyOK = qt_dispatchKeyEvent(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
- if (!keyOK)
- [super keyUp:theEvent];
-}
-
- (void)flagsChanged:(NSEvent *)theEvent
{
qt_dispatchModifiersChanged(theEvent, [self QT_MANGLE_NAMESPACE(qt_qwidget)]);
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 6a16403..06eb7ff 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -185,6 +185,9 @@ extern "C" {
extern NSString *NSTextInputReplacementRangeAttributeName;
}
+#ifdef ALIEN_DEBUG
+static int qCocoaViewCount = 0;
+#endif
@implementation QT_MANGLE_NAMESPACE(QCocoaView)
@@ -194,7 +197,14 @@ extern "C" {
if (self) {
[self finishInitWithQWidget:widget widgetPrivate:widgetprivate];
}
+ [self setFocusRingType:NSFocusRingTypeNone];
composingText = new QString();
+
+#ifdef ALIEN_DEBUG
+ ++qCocoaViewCount;
+ qDebug() << "init: qCocoaViewCount is" << qCocoaViewCount;
+#endif
+
composing = false;
sendKeyEvents = true;
[self setHidden:YES];
@@ -232,7 +242,8 @@ extern "C" {
QRegion mask = qt_widget_private(cursorWidget)->extra->mask;
NSCursor *nscursor = static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursorWidget->cursor()));
- if (mask.isEmpty()) {
+ // The mask could have the WA_MouseNoMask attribute set and that means that we have to ignore the mask.
+ if (mask.isEmpty() || cursorWidget->testAttribute(Qt::WA_MouseNoMask)) {
[self addCursorRect:[qt_mac_nativeview_for(cursorWidget) visibleRect] cursor:nscursor];
} else {
const QVector<QRect> &rects = mask.rects();
@@ -414,6 +425,12 @@ extern "C" {
{
delete composingText;
[[NSNotificationCenter defaultCenter] removeObserver:self];
+
+#ifdef ALIEN_DEBUG
+ --qCocoaViewCount;
+ qDebug() << "qCocoaViewCount is" << qCocoaViewCount;
+#endif
+
[super dealloc];
}
@@ -429,7 +446,11 @@ extern "C" {
return YES;
}
-- (BOOL) preservesContentDuringLiveResize;
+// We preserve the content of the view if WA_StaticContents is defined.
+//
+// More info in the Cocoa documentation:
+// http://developer.apple.com/mac/library/documentation/cocoa/conceptual/CocoaViewsGuide/Optimizing/Optimizing.html
+- (BOOL) preservesContentDuringLiveResize
{
return qwidget->testAttribute(Qt::WA_StaticContents);
}
@@ -459,13 +480,25 @@ extern "C" {
}
}
+// We catch the 'setNeedsDisplay:' message in order to avoid a useless full repaint.
+// During the resize, the top of the widget is repainted, probably because of the
+// change of coordinate space (Quartz vs Qt). This is then followed by this message:
+// -[NSView _setNeedsDisplayIfTopLeftChanged]
+// which force a full repaint by sending the message 'setNeedsDisplay:'.
+// That is what we are preventing here.
+- (void)setNeedsDisplay:(BOOL)flag {
+ if (![self inLiveResize] || !(qwidget->testAttribute(Qt::WA_StaticContents))) {
+ [super setNeedsDisplay:flag];
+ }
+}
+
- (void)drawRect:(NSRect)aRect
{
if (!qwidget)
return;
if (QApplicationPrivate::graphicsSystem() != 0) {
- if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) {
+ if (qwidgetprivate->maybeBackingStore()) {
// Drawing is handled on the window level
// See qcocoasharedwindowmethods_mac_p.h
if (!qwidget->testAttribute(Qt::WA_PaintOnScreen))
@@ -523,6 +556,10 @@ extern "C" {
CGContextClearRect(cg, NSRectToCGRect(aRect));
}
+ // Check for alien widgets, use qwidgetPrivate->drawWidget() to draw the widget if this
+ // is the case. This makes sure child widgets are drawn as well, Cocoa does not know about
+ // those and wont send them drawRect calls.
+ if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false) {
if (engine && !qwidget->testAttribute(Qt::WA_NoSystemBackground)
&& (qwidget->isWindow() || qwidget->autoFillBackground())
|| qwidget->testAttribute(Qt::WA_TintedBackground)
@@ -542,6 +579,12 @@ extern "C" {
e.setErased(true);
#endif
qt_sendSpontaneousEvent(qwidget, &e);
+ } else {
+ qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false); // QWidgetPrivate::drawWidget sets this
+ QWidgetPrivate *qwidgetPrivate = qt_widget_private(qwidget);
+ qwidgetPrivate->drawWidget(qwidget, qrgn, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen | QWidgetPrivate::DrawRecursive, 0);
+ }
+
if (!redirectionOffset.isNull())
QPainter::restoreRedirected(qwidget);
if (engine)
@@ -794,11 +837,12 @@ extern "C" {
// The mouse device containts pixel scroll wheel support (Mighty Mouse, Trackpad).
// Since deviceDelta is delivered as pixels rather than degrees, we need to
// convert from pixels to degrees in a sensible manner.
- // It looks like four degrees per pixel behaves most native.
- // Qt expects the unit for delta to be 1/8 of a degree:
- deltaX = [theEvent deviceDeltaX];
- deltaY = [theEvent deviceDeltaY];
- deltaZ = [theEvent deviceDeltaZ];
+ // It looks like 1/4 degrees per pixel behaves most native.
+ // (NB: Qt expects the unit for delta to be 8 per degree):
+ const int pixelsToDegrees = 2; // 8 * 1/4
+ deltaX = [theEvent deviceDeltaX] * pixelsToDegrees;
+ deltaY = [theEvent deviceDeltaY] * pixelsToDegrees;
+ deltaZ = [theEvent deviceDeltaZ] * pixelsToDegrees;
} else {
// carbonEventKind == kEventMouseWheelMoved
// Remove acceleration, and use either -120 or 120 as delta:
@@ -1003,8 +1047,16 @@ extern "C" {
{
if (!qwidget)
return NO;
- if (qwidget->isWindow())
+ // disabled widget shouldn't get focus even if it's a window.
+ // hence disabled windows will not get any key or mouse events.
+ if (!qwidget->isEnabled())
+ return NO;
+ // Before accepting the focus for a window, we check that
+ // the focusWidget (if any) is not contained in the same window.
+ if (qwidget->isWindow() && !qt_widget_private(qwidget)->topData()->embedded
+ && (!qApp->focusWidget() || qApp->focusWidget()->window() != qwidget)) {
return YES; // Always do it, so that windows can accept key press events.
+ }
return qwidget->focusPolicy() != Qt::NoFocus;
}
@@ -1015,7 +1067,17 @@ extern "C" {
// Seems like the following test only triggers if this
// view is inside a QMacNativeWidget:
if (qwidget == QApplication::focusWidget())
- QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason);
+ qwidget->clearFocus();
+ return YES;
+}
+
+- (BOOL)becomeFirstResponder
+{
+ // see the comment in the acceptsFirstResponder - if the window "stole" focus
+ // let it become the responder, but don't tell Qt
+ if (qwidget && qt_widget_private(qwidget->window())->topData()->embedded
+ && !QApplication::focusWidget() && qwidget->focusPolicy() != Qt::NoFocus)
+ qwidget->setFocus(Qt::OtherFocusReason);
return YES;
}
@@ -1089,8 +1151,15 @@ extern "C" {
}
if (sendKeyEvents && !composing) {
bool keyOK = qt_dispatchKeyEvent(theEvent, widgetToGetKey);
- if (!keyOK && !sendToPopup)
- [super keyDown:theEvent];
+ if (!keyOK && !sendToPopup) {
+ // find the first responder that is not created by Qt and forward
+ // the event to it (for example if Qt widget is embedded into native).
+ QWidget *toplevel = qwidget->window();
+ if (toplevel && qt_widget_private(toplevel)->topData()->embedded) {
+ if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview])
+ [w keyDown:theEvent];
+ }
+ }
}
}
@@ -1099,8 +1168,13 @@ extern "C" {
{
if (sendKeyEvents) {
bool keyOK = qt_dispatchKeyEvent(theEvent, qwidget);
- if (!keyOK)
- [super keyUp:theEvent];
+ if (!keyOK) {
+ QWidget *toplevel = qwidget->window();
+ if (toplevel && qt_widget_private(toplevel)->topData()->embedded) {
+ if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview])
+ [w keyUp:theEvent];
+ }
+ }
}
}
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index f38e4f5..ae1f60d 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -348,7 +348,8 @@ QCursor::QCursor(const QPixmap &pixmap, int hotX, int hotY)
\o B=1 and M=1 gives black.
\o B=0 and M=1 gives white.
\o B=0 and M=0 gives transparent.
- \o B=1 and M=0 gives an XOR'd result.
+ \o B=1 and M=0 gives an XOR'd result under Windows, undefined
+ results on all other platforms.
\endlist
Use the global Qt color Qt::color0 to draw 0-pixels and Qt::color1 to
diff --git a/src/gui/kernel/qcursor_mac.mm b/src/gui/kernel/qcursor_mac.mm
index cfebf60..03e38b0 100644
--- a/src/gui/kernel/qcursor_mac.mm
+++ b/src/gui/kernel/qcursor_mac.mm
@@ -114,27 +114,18 @@ void qt_mac_set_cursor(const QCursor *c, const QPoint &)
}
c->handle(); //force the cursor to get loaded, if it's not
- if(1 || currentCursor != c->d) {
- if(currentCursor && currentCursor->type == QCursorData::TYPE_ThemeCursor
- && currentCursor->curs.tc.anim)
- currentCursor->curs.tc.anim->stop();
- QMacCocoaAutoReleasePool pool;
- if(c->d->type == QCursorData::TYPE_ImageCursor) {
- [static_cast<NSCursor *>(c->d->curs.cp.nscursor) set];
- } else if(c->d->type == QCursorData::TYPE_ThemeCursor) {
-#ifdef QT_MAC_USE_COCOA
- if (c->d->curs.cp.nscursor == 0)
- [[NSCursor arrowCursor] set];
- [static_cast<NSCursor *>(c->d->curs.cp.nscursor) set];
-#else
- if(SetAnimatedThemeCursor(c->d->curs.tc.curs, 0) == themeBadCursorIndexErr) {
- SetThemeCursor(c->d->curs.tc.curs);
- } else {
- if(!c->d->curs.tc.anim)
- c->d->curs.tc.anim = new QMacAnimateCursor;
- c->d->curs.tc.anim->start(c->d->curs.tc.curs);
- }
-#endif
+ if(currentCursor && currentCursor->type == QCursorData::TYPE_ThemeCursor
+ && currentCursor->curs.tc.anim)
+ currentCursor->curs.tc.anim->stop();
+ if(c->d->type == QCursorData::TYPE_ImageCursor) {
+ [static_cast<NSCursor *>(c->d->curs.cp.nscursor) set];
+ } else if(c->d->type == QCursorData::TYPE_ThemeCursor) {
+ if(SetAnimatedThemeCursor(c->d->curs.tc.curs, 0) == themeBadCursorIndexErr) {
+ SetThemeCursor(c->d->curs.tc.curs);
+ } else {
+ if(!c->d->curs.tc.anim)
+ c->d->curs.tc.anim = new QMacAnimateCursor;
+ c->d->curs.tc.anim->start(c->d->curs.tc.curs);
}
}
currentCursor = c->d;
diff --git a/src/gui/kernel/qcursor_s60.cpp b/src/gui/kernel/qcursor_s60.cpp
index 54a9176..68e079e 100644
--- a/src/gui/kernel/qcursor_s60.cpp
+++ b/src/gui/kernel/qcursor_s60.cpp
@@ -44,7 +44,7 @@
#include <private/qapplication_p.h>
#include <coecntrl.h>
#include <qcursor.h>
-#include <qt_s60_p.h>
+#include <private/qt_s60_p.h>
#include <qbitmap.h>
#include <w32std.h>
#include <qapplication.h>
diff --git a/src/gui/kernel/qcursor_x11.cpp b/src/gui/kernel/qcursor_x11.cpp
index 4e871a6..8e48628 100644
--- a/src/gui/kernel/qcursor_x11.cpp
+++ b/src/gui/kernel/qcursor_x11.cpp
@@ -294,7 +294,7 @@ void QCursorData::update()
return;
#endif // QT_NO_XCURSOR
- static const char cur_blank_bits[] = {
+ static const uchar cur_blank_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -302,44 +302,44 @@ void QCursorData::update()
// Non-standard X11 cursors are created from bitmaps
#ifndef QT_USE_APPROXIMATE_CURSORS
- static const char cur_ver_bits[] = {
+ static const uchar cur_ver_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
- static const char mcur_ver_bits[] = {
+ static const uchar mcur_ver_bits[] = {
0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
- static const char cur_hor_bits[] = {
+ static const uchar cur_hor_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const char mcur_hor_bits[] = {
+ static const uchar mcur_hor_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
- static const char cur_bdiag_bits[] = {
+ static const uchar cur_bdiag_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const char mcur_bdiag_bits[] = {
+ static const uchar mcur_bdiag_bits[] = {
0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
- static const char cur_fdiag_bits[] = {
+ static const uchar cur_fdiag_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
- static const char mcur_fdiag_bits[] = {
+ static const uchar mcur_fdiag_bits[] = {
0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
- static const char *cursor_bits16[] = {
+ static const uchar *cursor_bits16[] = {
cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
0, 0, cur_blank_bits, cur_blank_bits };
- static const char vsplit_bits[] = {
+ static const uchar vsplit_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
@@ -351,7 +351,7 @@ void QCursorData::update()
0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const char vsplitm_bits[] = {
+ static const uchar vsplitm_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
@@ -363,7 +363,7 @@ void QCursorData::update()
0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const char hsplit_bits[] = {
+ static const uchar hsplit_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
@@ -375,7 +375,7 @@ void QCursorData::update()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const char hsplitm_bits[] = {
+ static const uchar hsplitm_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
@@ -387,7 +387,7 @@ void QCursorData::update()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const char whatsthis_bits[] = {
+ static const uchar whatsthis_bits[] = {
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
@@ -399,7 +399,7 @@ void QCursorData::update()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
- static const char whatsthism_bits[] = {
+ static const uchar whatsthism_bits[] = {
0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
@@ -411,7 +411,7 @@ void QCursorData::update()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
- static const char busy_bits[] = {
+ static const uchar busy_bits[] = {
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
@@ -423,7 +423,7 @@ void QCursorData::update()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- static const char busym_bits[] = {
+ static const uchar busym_bits[] = {
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
@@ -436,41 +436,41 @@ void QCursorData::update()
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- static const char * const cursor_bits32[] = {
+ static const uchar * const cursor_bits32[] = {
vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
};
- static const char forbidden_bits[] = {
+ static const uchar forbidden_bits[] = {
0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
- static const char forbiddenm_bits[] = {
+ static const uchar forbiddenm_bits[] = {
0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
- static const char openhand_bits[] = {
+ static const uchar openhand_bits[] = {
0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
0x08,0x20,0x10,0x10,0x20,0x10,0x00,0x00};
- static const char openhandm_bits[] = {
+ static const uchar openhandm_bits[] = {
0x80,0x01,0xd8,0x0f,0xfc,0x1f,0xfc,0x5f,0xf8,0xff,0xf8,0xff,
0xf6,0xff,0xff,0xff,0xff,0x7f,0xfe,0x7f,0xfc,0x7f,0xfc,0x3f,
0xf8,0x3f,0xf0,0x1f,0xe0,0x1f,0x00,0x00};
- static const char closedhand_bits[] = {
+ static const uchar closedhand_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0x48,0x32,0x08,0x50,
0x10,0x40,0x18,0x40,0x04,0x40,0x04,0x20,0x08,0x20,0x10,0x10,
0x20,0x10,0x20,0x10,0x00,0x00,0x00,0x00};
- static const char closedhandm_bits[] = {
+ static const uchar closedhandm_bits[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0xb0,0x0d,0xf8,0x3f,0xf8,0x7f,
0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
- static const char * const cursor_bits20[] = {
+ static const uchar * const cursor_bits20[] = {
forbidden_bits, forbiddenm_bits
};
@@ -484,8 +484,8 @@ void QCursorData::update()
fg.green = 0;
fg.blue = 0;
int i = (cshape - Qt::SizeVerCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, cursor_bits16[i], 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits16[i + 1], 16, 16);
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i]), 16, 16);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char*>(cursor_bits16[i + 1]), 16, 16);
hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
} else if ((cshape >= Qt::SplitVCursor && cshape <= Qt::SplitHCursor)
|| cshape == Qt::WhatsThisCursor || cshape == Qt::BusyCursor) {
@@ -497,8 +497,8 @@ void QCursorData::update()
fg.green = 0;
fg.blue = 0;
int i = (cshape - Qt::SplitVCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, cursor_bits32[i], 32, 32);
- pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits32[i + 1], 32, 32);
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i]), 32, 32);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits32[i + 1]), 32, 32);
int hs = (cshape == Qt::PointingHandCursor || cshape == Qt::WhatsThisCursor
|| cshape == Qt::BusyCursor) ? 0 : 16;
hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, hs, hs);
@@ -511,8 +511,8 @@ void QCursorData::update()
fg.green = 0;
fg.blue = 0;
int i = (cshape - Qt::ForbiddenCursor) * 2;
- pm = XCreateBitmapFromData(dpy, rootwin, cursor_bits20[i], 20, 20);
- pmm = XCreateBitmapFromData(dpy, rootwin, cursor_bits20[i + 1], 20, 20);
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i]), 20, 20);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(cursor_bits20[i + 1]), 20, 20);
hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 10, 10);
} else if (cshape == Qt::OpenHandCursor || cshape == Qt::ClosedHandCursor) {
XColor bg, fg;
@@ -523,8 +523,8 @@ void QCursorData::update()
fg.green = 0;
fg.blue = 0;
bool open = cshape == Qt::OpenHandCursor;
- pm = XCreateBitmapFromData(dpy, rootwin, open ? openhand_bits : closedhand_bits, 16, 16);
- pmm = XCreateBitmapFromData(dpy, rootwin, open ? openhandm_bits : closedhandm_bits, 16, 16);
+ pm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhand_bits : closedhand_bits), 16, 16);
+ pmm = XCreateBitmapFromData(dpy, rootwin, reinterpret_cast<const char *>(open ? openhandm_bits : closedhandm_bits), 16, 16);
hcurs = XCreatePixmapCursor(dpy, pm, pmm, &fg, &bg, 8, 8);
} else if (cshape == Qt::DragCopyCursor || cshape == Qt::DragMoveCursor
|| cshape == Qt::DragLinkCursor) {
diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp
index 84e3c5d..e4d0bf3 100644
--- a/src/gui/kernel/qdesktopwidget_s60.cpp
+++ b/src/gui/kernel/qdesktopwidget_s60.cpp
@@ -88,6 +88,7 @@ QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
void QDesktopWidgetPrivate::init(QDesktopWidget *that)
{
+ Q_UNUSED(that);
// int screenCount=0;
// ### TODO: Implement proper multi-display support
diff --git a/src/gui/kernel/qdesktopwidget_win.cpp b/src/gui/kernel/qdesktopwidget_win.cpp
index 1fea8d6..07dbc24 100644
--- a/src/gui/kernel/qdesktopwidget_win.cpp
+++ b/src/gui/kernel/qdesktopwidget_win.cpp
@@ -76,7 +76,7 @@ public:
};
typedef BOOL (WINAPI *InfoFunc)(HMONITOR, MONITORINFO*);
- typedef BOOL (CALLBACK *EnumProc)(HMONITOR, HDC, LPRECT, LPARAM);
+ typedef BOOL (QT_WIN_CALLBACK *EnumProc)(HMONITOR, HDC, LPRECT, LPARAM);
typedef BOOL (WINAPI *EnumFunc)(HDC, LPCRECT, EnumProc, LPARAM);
static EnumFunc enumDisplayMonitors;
@@ -107,7 +107,7 @@ static inline void qt_get_sip_info(QRect &rect)
#endif
-BOOL CALLBACK enumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM)
+BOOL QT_WIN_CALLBACK enumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM)
{
QDesktopWidgetPrivate::screenCount++;
QDesktopWidgetPrivate::rects->resize(QDesktopWidgetPrivate::screenCount);
diff --git a/src/gui/kernel/qdnd_win.cpp b/src/gui/kernel/qdnd_win.cpp
index 0742a93..a164c2a 100644
--- a/src/gui/kernel/qdnd_win.cpp
+++ b/src/gui/kernel/qdnd_win.cpp
@@ -524,18 +524,14 @@ QOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
if (fEscapePressed) {
return ResultFromScode(DRAGDROP_S_CANCEL);
- } else if (!(grfKeyState & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))) {
+ } else if ((GetAsyncKeyState(VK_LBUTTON) == 0)
+ && (GetAsyncKeyState(VK_MBUTTON) == 0)
+ && (GetAsyncKeyState(VK_RBUTTON) == 0)) {
+ // grfKeyState is broken on CE & some Windows XP versions,
+ // therefore we need to check the state manually
return ResultFromScode(DRAGDROP_S_DROP);
} else {
-#if defined(Q_OS_WINCE)
- // grfKeyState is broken on CE, therefore need to check
- // the state manually
- if ((GetAsyncKeyState(VK_LBUTTON) == 0) &&
- (GetAsyncKeyState(VK_MBUTTON) == 0) &&
- (GetAsyncKeyState(VK_RBUTTON) == 0)) {
- return ResultFromScode(DRAGDROP_S_DROP);
- }
-#else
+#if !defined(Q_OS_WINCE)
if (currentButtons == Qt::NoButton) {
currentButtons = keystate_to_mousebutton(grfKeyState);
} else {
diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp
index 9591b9a..0a05d8e 100644
--- a/src/gui/kernel/qdnd_x11.cpp
+++ b/src/gui/kernel/qdnd_x11.cpp
@@ -51,10 +51,10 @@
#include "qbitmap.h"
#include "qdesktopwidget.h"
#include "qevent.h"
-#include "qdatetime.h"
#include "qiodevice.h"
#include "qpointer.h"
#include "qcursor.h"
+#include "qelapsedtimer.h"
#include "qvariant.h"
#include "qvector.h"
#include "qurl.h"
@@ -1911,23 +1911,19 @@ Qt::DropAction QDragManager::drag(QDrag * o)
// then we could still have problems, but this is highly unlikely
QApplication::flush();
- QTime started = QTime::currentTime();
- QTime now = started;
+ QElapsedTimer timer;
+ timer.start();
do {
XEvent event;
if (XCheckTypedEvent(X11->display, ClientMessage, &event))
qApp->x11ProcessEvent(&event);
- now = QTime::currentTime();
- if (started > now) // crossed midnight
- started = now;
-
// sleep 50 ms, so we don't use up CPU cycles all the time.
struct timeval usleep_tv;
usleep_tv.tv_sec = 0;
usleep_tv.tv_usec = 50000;
select(0, 0, 0, 0, &usleep_tv);
- } while (object && started.msecsTo(now) < 1000);
+ } while (object && timer.hasExpired(1000));
}
object = o;
diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm
index afea3ec..a7f1224 100644
--- a/src/gui/kernel/qeventdispatcher_mac.mm
+++ b/src/gui/kernel/qeventdispatcher_mac.mm
@@ -829,7 +829,16 @@ NSModalSession QEventDispatcherMacPrivate::currentModalSession()
ensureNSAppInitialized();
QBoolBlocker block1(blockSendPostedEvents, true);
- info.session = [NSApp beginModalSessionForWindow:window];
+ info.nswindow = window;
+ [(NSWindow*) info.nswindow retain];
+ // When creating a modal session cocoa will rearrange the windows.
+ // In order to avoid windows to be put behind another we need to
+ // keep the window level.
+ {
+ int level = [window level];
+ info.session = [NSApp beginModalSessionForWindow:window];
+ [window setLevel:level];
+ }
}
currentModalSessionCached = info.session;
}
@@ -903,8 +912,10 @@ void QEventDispatcherMacPrivate::cleanupModalSessions()
}
cocoaModalSessionStack.remove(i);
currentModalSessionCached = 0;
- if (info.session)
+ if (info.session) {
[NSApp endModalSession:info.session];
+ [(NSWindow *)info.nswindow release];
+ }
}
updateChildrenWorksWhenModal();
@@ -920,7 +931,7 @@ void QEventDispatcherMacPrivate::beginModalSession(QWidget *widget)
// currentModalSession). A QCocoaModalSessionInfo is considered pending to be stopped if
// the widget pointer is zero, and the session pointer is non-zero (it will be fully
// stopped in cleanupModalSessions()).
- QCocoaModalSessionInfo info = {widget, 0};
+ QCocoaModalSessionInfo info = {widget, 0, 0};
cocoaModalSessionStack.push(info);
updateChildrenWorksWhenModal();
currentModalSessionCached = 0;
diff --git a/src/gui/kernel/qeventdispatcher_mac_p.h b/src/gui/kernel/qeventdispatcher_mac_p.h
index e932532..8ac7c65 100644
--- a/src/gui/kernel/qeventdispatcher_mac_p.h
+++ b/src/gui/kernel/qeventdispatcher_mac_p.h
@@ -100,6 +100,7 @@ typedef struct _NSModalSession *NSModalSession;
typedef struct _QCocoaModalSessionInfo {
QPointer<QWidget> widget;
NSModalSession session;
+ void *nswindow;
} QCocoaModalSessionInfo;
#endif
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 649a310..bf60f97 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -55,8 +55,8 @@
#include "qrect.h"
#include "qpoint.h"
-#include "qdatetime.h"
#include "qgesture.h"
+#include "qelapsedtimer.h"
#include "private/qobject_p.h"
QT_BEGIN_NAMESPACE
@@ -148,7 +148,7 @@ public:
QPoint lastPositions[3];
bool started;
qreal speed;
- QTime time;
+ QElapsedTimer time;
};
class QTapGesturePrivate : public QGesturePrivate
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 89ad94d..aa6720e 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -45,6 +45,7 @@
#include "private/qgesture_p.h"
#include "private/qgraphicsitem_p.h"
#include "private/qevent_p.h"
+#include "private/qapplication_p.h"
#include "qgesture.h"
#include "qevent.h"
#include "qgraphicsitem.h"
@@ -86,7 +87,8 @@ QGestureManager::QGestureManager(QObject *parent)
#endif
#if defined(Q_OS_WIN)
#if !defined(QT_NO_NATIVE_GESTURES)
- registerGestureRecognizer(new QWinNativePanGestureRecognizer);
+ if (QApplicationPrivate::HasTouchSupport)
+ registerGestureRecognizer(new QWinNativePanGestureRecognizer);
#endif
#else
registerGestureRecognizer(new QTapAndHoldGestureRecognizer);
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
index c88a9a7..9dcca17 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -161,6 +161,8 @@ QGestureRecognizer::~QGestureRecognizer()
Reimplement this function to create a custom QGesture-derived gesture
object if necessary.
+
+ The application takes ownership of the created gesture object.
*/
QGesture *QGestureRecognizer::create(QObject *target)
{
diff --git a/src/gui/kernel/qgridlayout.cpp b/src/gui/kernel/qgridlayout.cpp
index dbd3c01..81a4d04 100644
--- a/src/gui/kernel/qgridlayout.cpp
+++ b/src/gui/kernel/qgridlayout.cpp
@@ -1852,7 +1852,7 @@ void QGridLayout::invalidate()
/*!
\fn int QGridLayout::colSpacing(int col) const
- Use columnSpacing() instead.
+ Use columnMinimumWidth() instead.
*/
/*!
diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp
index ac4cdc8..f5004b0 100644
--- a/src/gui/kernel/qguifunctions_wince.cpp
+++ b/src/gui/kernel/qguifunctions_wince.cpp
@@ -278,7 +278,14 @@ int qt_wince_get_version()
bool qt_wince_is_windows_mobile_65()
{
- return ((qt_wince_get_version() == 52) && (qt_wince_get_build() > 2000));
+ const DWORD dwFirstWM65BuildNumber = 21139;
+ OSVERSIONINFO osvi;
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ if (!GetVersionEx(&osvi))
+ return false;
+ return osvi.dwMajorVersion > 5
+ || (osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion > 2 ||
+ (osvi.dwMinorVersion == 2 && osvi.dwBuildNumber >= dwFirstWM65BuildNumber)));
}
bool qt_wince_is_pocket_pc() {
diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp
index a31480d..f259654 100644
--- a/src/gui/kernel/qkeymapper_mac.cpp
+++ b/src/gui/kernel/qkeymapper_mac.cpp
@@ -323,6 +323,32 @@ static qt_mac_enum_mapper qt_mac_keyvkey_symbols[] = { //real scan codes
{ 0, QT_MAC_MAP_ENUM(0) }
};
+static qt_mac_enum_mapper qt_mac_private_unicode[] = {
+ { 0xF700, QT_MAC_MAP_ENUM(Qt::Key_Up) }, //NSUpArrowFunctionKey
+ { 0xF701, QT_MAC_MAP_ENUM(Qt::Key_Down) }, //NSDownArrowFunctionKey
+ { 0xF702, QT_MAC_MAP_ENUM(Qt::Key_Left) }, //NSLeftArrowFunctionKey
+ { 0xF703, QT_MAC_MAP_ENUM(Qt::Key_Right) }, //NSRightArrowFunctionKey
+ { 0xF727, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertFunctionKey
+ { 0xF728, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteFunctionKey
+ { 0xF729, QT_MAC_MAP_ENUM(Qt::Key_Home) }, //NSHomeFunctionKey
+ { 0xF72B, QT_MAC_MAP_ENUM(Qt::Key_End) }, //NSEndFunctionKey
+ { 0xF72C, QT_MAC_MAP_ENUM(Qt::Key_PageUp) }, //NSPageUpFunctionKey
+ { 0xF72D, QT_MAC_MAP_ENUM(Qt::Key_PageDown) }, //NSPageDownFunctionKey
+ { 0xF72F, QT_MAC_MAP_ENUM(Qt::Key_ScrollLock) }, //NSScrollLockFunctionKey
+ { 0xF730, QT_MAC_MAP_ENUM(Qt::Key_Pause) }, //NSPauseFunctionKey
+ { 0xF731, QT_MAC_MAP_ENUM(Qt::Key_SysReq) }, //NSSysReqFunctionKey
+ { 0xF735, QT_MAC_MAP_ENUM(Qt::Key_Menu) }, //NSMenuFunctionKey
+ { 0xF738, QT_MAC_MAP_ENUM(Qt::Key_Print) }, //NSPrintFunctionKey
+ { 0xF73A, QT_MAC_MAP_ENUM(Qt::Key_Clear) }, //NSClearDisplayFunctionKey
+ { 0xF73D, QT_MAC_MAP_ENUM(Qt::Key_Insert) }, //NSInsertCharFunctionKey
+ { 0xF73E, QT_MAC_MAP_ENUM(Qt::Key_Delete) }, //NSDeleteCharFunctionKey
+ { 0xF741, QT_MAC_MAP_ENUM(Qt::Key_Select) }, //NSSelectFunctionKey
+ { 0xF742, QT_MAC_MAP_ENUM(Qt::Key_Execute) }, //NSExecuteFunctionKey
+ { 0xF746, QT_MAC_MAP_ENUM(Qt::Key_Help) }, //NSHelpFunctionKey
+ { 0xF747, QT_MAC_MAP_ENUM(Qt::Key_Mode_switch) }, //NSModeSwitchFunctionKey
+ { 0, QT_MAC_MAP_ENUM(0) }
+};
+
static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
{
#ifdef DEBUG_KEY_BINDINGS
@@ -379,6 +405,19 @@ static int qt_mac_get_key(int modif, const QChar &key, int virtualKey)
}
}
+ // check if they belong to key codes in private unicode range
+ if (key >= 0xf700 && key <= 0xf747) {
+ if (key >= 0xf704 && key <= 0xf726) {
+ return Qt::Key_F1 + (key.unicode() - 0xf704) ;
+ }
+ for (int i = 0; qt_mac_private_unicode[i].qt_code; i++) {
+ if (qt_mac_private_unicode[i].mac_code == key) {
+ return qt_mac_private_unicode[i].qt_code;
+ }
+ }
+
+ }
+
//oh well
#ifdef DEBUG_KEY_BINDINGS
qDebug("Unknown case.. %s:%d %d[%d] %d", __FILE__, __LINE__, key.unicode(), key.toLatin1(), virtualKey);
@@ -847,7 +886,11 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e
}
void
-QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *)
+QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *
+#if defined(QT_MAC_USE_COCOA)
+ unicodeKey // unicode character from NSEvent (modifiers applied)
+#endif
+ )
{
UInt32 macVirtualKey = 0;
GetEventParameter(event, kEventParamKeyCode, typeUInt32, 0, sizeof(macVirtualKey), 0, &macVirtualKey);
@@ -875,6 +918,15 @@ QKeyMapperPrivate::updateKeyMap(EventHandlerCallRef, EventRef event, void *)
qtkey = unicode.unicode();
keyLayout[macVirtualKey]->qtKey[i] = qtkey;
}
+#ifndef Q_WS_MAC32
+ else {
+ const QChar unicode(*((UniChar *)unicodeKey));
+ int qtkey = qt_mac_get_key(keyModifier, unicode, macVirtualKey);
+ if (qtkey == Qt::Key_unknown)
+ qtkey = unicode.unicode();
+ keyLayout[macVirtualKey]->qtKey[i] = qtkey;
+ }
+#endif
#ifdef Q_WS_MAC32
} else {
const UInt32 keyModifier = (qt_mac_get_mac_modifiers(ModsTbl[i]));
diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h
index 3e42d6e..38f141e 100644
--- a/src/gui/kernel/qkeymapper_p.h
+++ b/src/gui/kernel/qkeymapper_p.h
@@ -183,7 +183,7 @@ public:
const XEvent *,
bool grab);
- bool useXKB;
+ int xkb_currentGroup;
QXCoreDesc coreDesc;
#elif defined(Q_WS_MAC)
diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp
index e555c5c..f84b902 100644
--- a/src/gui/kernel/qkeymapper_win.cpp
+++ b/src/gui/kernel/qkeymapper_win.cpp
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
//#define DEBUG_KEYMAPPER
// Implemented elsewhere
-extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
extern Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id);
#ifndef LANG_PASHTO
diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp
index 4e6c847..807959c 100644
--- a/src/gui/kernel/qkeymapper_x11.cpp
+++ b/src/gui/kernel/qkeymapper_x11.cpp
@@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE
(((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF))
#endif
-static void getLocaleAndDirection(QLocale *locale,
+void q_getLocaleAndDirection(QLocale *locale,
Qt::LayoutDirection *direction,
const QByteArray &layoutName,
const QByteArray &variantName)
@@ -248,22 +248,17 @@ qt_XTranslateKey(register QXCoreDesc *dpy,
QKeyMapperPrivate::QKeyMapperPrivate()
- : keyboardInputDirection(Qt::LeftToRight), useXKB(false)
+ : keyboardInputDirection(Qt::LeftToRight), xkb_currentGroup(0)
{
memset(&coreDesc, 0, sizeof(coreDesc));
#ifndef QT_NO_XKB
- int opcode = -1;
- int xkbEventBase = -1;
- int xkbErrorBase = -1;
- int xkblibMajor = XkbMajorVersion;
- int xkblibMinor = XkbMinorVersion;
- if (XkbQueryExtension(X11->display, &opcode, &xkbEventBase, &xkbErrorBase, &xkblibMajor, &xkblibMinor))
- useXKB = true;
-#endif
-
-#if 0
- qDebug() << "useXKB =" << useXKB;
+ if (X11->use_xkb) {
+ // get the current group
+ XkbStateRec xkbState;
+ if (XkbGetState(X11->display, XkbUseCoreKbd, &xkbState) == Success)
+ xkb_currentGroup = xkbState.group;
+ }
#endif
}
@@ -276,7 +271,7 @@ QKeyMapperPrivate::~QKeyMapperPrivate()
QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *event)
{
#ifndef QT_NO_XKB
- if (useXKB)
+ if (X11->use_xkb)
return possibleKeysXKB(event);
#endif
return possibleKeysCore(event);
@@ -486,7 +481,7 @@ enum {
void QKeyMapperPrivate::clearMappings()
{
#ifndef QT_NO_XKB
- if (useXKB) {
+ if (X11->use_xkb) {
// try to determine the layout name and input direction by reading the _XKB_RULES_NAMES property off
// the root window
QByteArray layoutName;
@@ -515,15 +510,20 @@ void QKeyMapperPrivate::clearMappings()
p += qstrlen(p) + 1;
} while (p < end);
- layoutName = QByteArray::fromRawData(names[2], qstrlen(names[2]));
- variantName = QByteArray::fromRawData(names[3], qstrlen(names[3]));
+ // the layout names and variants are saved in the _XKB_RULES_NAMES property as a comma separated list
+ QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(',');
+ if (uint(xkb_currentGroup) < uint(layoutNames.count()))
+ layoutName = layoutNames.at(xkb_currentGroup);
+ QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(',');
+ if (uint(xkb_currentGroup) < uint(variantNames.count()))
+ variantName = variantNames.at(xkb_currentGroup);
}
// ### ???
// if (keyboardLayoutName.isEmpty())
// qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ?
- getLocaleAndDirection(&keyboardInputLocale,
+ q_getLocaleAndDirection(&keyboardInputLocale,
&keyboardInputDirection,
layoutName,
variantName);
@@ -534,7 +534,6 @@ void QKeyMapperPrivate::clearMappings()
<< "direction ="
<< keyboardInputDirection;
#endif
-
if (data)
XFree(data);
} else
@@ -574,7 +573,7 @@ void QKeyMapperPrivate::clearMappings()
// look at the modifier mapping, and get the correct masks for alt, meta, super, hyper, and mode_switch
#ifndef QT_NO_XKB
- if (useXKB) {
+ if (X11->use_xkb) {
XkbDescPtr xkbDesc = XkbGetMap(X11->display, XkbAllClientInfoMask, XkbUseCoreKbd);
for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) {
const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0;
@@ -1073,8 +1072,8 @@ static const unsigned int KeyTbl[] = {
XF86XK_AudioNext, Qt::Key_MediaNext,
XF86XK_AudioRecord, Qt::Key_MediaRecord,
XF86XK_Mail, Qt::Key_LaunchMail,
- XF86XK_MyComputer, Qt::Key_Launch0,
- XF86XK_Calculator, Qt::Key_Calculator,
+ XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 5: remap properly
+ XF86XK_Calculator, Qt::Key_Launch1,
XF86XK_Memo, Qt::Key_Memo,
XF86XK_ToDoList, Qt::Key_ToDoList,
XF86XK_Calendar, Qt::Key_Calendar,
@@ -1172,7 +1171,7 @@ static const unsigned int KeyTbl[] = {
XF86XK_Bluetooth, Qt::Key_Bluetooth,
XF86XK_Suspend, Qt::Key_Suspend,
XF86XK_Hibernate, Qt::Key_Hibernate,
- XF86XK_Launch0, Qt::Key_Launch2,
+ XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly
XF86XK_Launch1, Qt::Key_Launch3,
XF86XK_Launch2, Qt::Key_Launch4,
XF86XK_Launch3, Qt::Key_Launch5,
@@ -1186,6 +1185,8 @@ static const unsigned int KeyTbl[] = {
XF86XK_LaunchB, Qt::Key_LaunchD,
XF86XK_LaunchC, Qt::Key_LaunchE,
XF86XK_LaunchD, Qt::Key_LaunchF,
+ XF86XK_LaunchE, Qt::Key_LaunchG,
+ XF86XK_LaunchF, Qt::Key_LaunchH,
// Qtopia keys
QTOPIAXK_Select, Qt::Key_Select,
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 99bf971..9efcc4e 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -580,6 +580,41 @@ static const struct {
{ Qt::Key_Hangup, QT_TRANSLATE_NOOP("QShortcut", "Hangup") },
{ Qt::Key_Flip, QT_TRANSLATE_NOOP("QShortcut", "Flip") },
+ // --------------------------------------------------------------
+ // Japanese keyboard support
+ { Qt::Key_Kanji, QT_TRANSLATE_NOOP("QShortcut", "Kanji") },
+ { Qt::Key_Muhenkan, QT_TRANSLATE_NOOP("QShortcut", "Muhenkan") },
+ { Qt::Key_Henkan, QT_TRANSLATE_NOOP("QShortcut", "Henkan") },
+ { Qt::Key_Romaji, QT_TRANSLATE_NOOP("QShortcut", "Romaji") },
+ { Qt::Key_Hiragana, QT_TRANSLATE_NOOP("QShortcut", "Hiragana") },
+ { Qt::Key_Katakana, QT_TRANSLATE_NOOP("QShortcut", "Katakana") },
+ { Qt::Key_Hiragana_Katakana,QT_TRANSLATE_NOOP("QShortcut", "Hiragana Katakana") },
+ { Qt::Key_Zenkaku, QT_TRANSLATE_NOOP("QShortcut", "Zenkaku") },
+ { Qt::Key_Hankaku, QT_TRANSLATE_NOOP("QShortcut", "Hankaku") },
+ { Qt::Key_Zenkaku_Hankaku, QT_TRANSLATE_NOOP("QShortcut", "Zenkaku Hankaku") },
+ { Qt::Key_Touroku, QT_TRANSLATE_NOOP("QShortcut", "Touroku") },
+ { Qt::Key_Massyo, QT_TRANSLATE_NOOP("QShortcut", "Massyo") },
+ { Qt::Key_Kana_Lock, QT_TRANSLATE_NOOP("QShortcut", "Kana Lock") },
+ { Qt::Key_Kana_Shift, QT_TRANSLATE_NOOP("QShortcut", "Kana Shift") },
+ { Qt::Key_Eisu_Shift, QT_TRANSLATE_NOOP("QShortcut", "Eisu Shift") },
+ { Qt::Key_Eisu_toggle, QT_TRANSLATE_NOOP("QShortcut", "Eisu toggle") },
+ { Qt::Key_Codeinput, QT_TRANSLATE_NOOP("QShortcut", "Code input") },
+ { Qt::Key_MultipleCandidate,QT_TRANSLATE_NOOP("QShortcut", "Multiple Candidate") },
+ { Qt::Key_PreviousCandidate,QT_TRANSLATE_NOOP("QShortcut", "Previous Candidate") },
+
+ // --------------------------------------------------------------
+ // Korean keyboard support
+ { Qt::Key_Hangul, QT_TRANSLATE_NOOP("QShortcut", "Hangul") },
+ { Qt::Key_Hangul_Start, QT_TRANSLATE_NOOP("QShortcut", "Hangul Start") },
+ { Qt::Key_Hangul_End, QT_TRANSLATE_NOOP("QShortcut", "Hangul End") },
+ { Qt::Key_Hangul_Hanja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Hanja") },
+ { Qt::Key_Hangul_Jamo, QT_TRANSLATE_NOOP("QShortcut", "Hangul Jamo") },
+ { Qt::Key_Hangul_Romaja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Romaja") },
+ { Qt::Key_Hangul_Jeonja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Jeonja") },
+ { Qt::Key_Hangul_Banja, QT_TRANSLATE_NOOP("QShortcut", "Hangul Banja") },
+ { Qt::Key_Hangul_PreHanja, QT_TRANSLATE_NOOP("QShortcut", "Hangul PreHanja") },
+ { Qt::Key_Hangul_PostHanja,QT_TRANSLATE_NOOP("QShortcut", "Hangul PostHanja") },
+ { Qt::Key_Hangul_Special, QT_TRANSLATE_NOOP("QShortcut", "Hangul Special") },
{ 0, 0 }
};
@@ -696,6 +731,7 @@ const QKeyBinding QKeySequencePrivate::keyBindings[] = {
{QKeySequence::Redo, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Z, QApplicationPrivate::KB_Mac}, //different priority from above
{QKeySequence::PreviousChild, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11},
{QKeySequence::PreviousChild, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Backtab, QApplicationPrivate::KB_Mac },//different priority from above
+ {QKeySequence::Paste, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert, QApplicationPrivate::KB_X11},
{QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
{QKeySequence::SelectEndOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_End, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
{QKeySequence::SelectPreviousWord, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Left, QApplicationPrivate::KB_Win | QApplicationPrivate::KB_X11 | QApplicationPrivate::KB_S60},
diff --git a/src/gui/kernel/qmime_win.cpp b/src/gui/kernel/qmime_win.cpp
index e191d7b..2840843 100644
--- a/src/gui/kernel/qmime_win.cpp
+++ b/src/gui/kernel/qmime_win.cpp
@@ -640,14 +640,18 @@ bool QWindowsMimeURI::convertFromMime(const FORMATETC &formatetc, const QMimeDat
} 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() * sizeof(ushort));
+ if (!urls.isEmpty()) {
+ QString url = urls.at(0).toString();
+ result = QByteArray((const char *)url.utf16(), url.length() * sizeof(ushort));
+ }
result.append('\0');
result.append('\0');
return setData(result, pmedium);
} else if (getCf(formatetc) == CF_INETURL) {
QList<QUrl> urls = mimeData->urls();
- QByteArray result = urls.at(0).toString().toLocal8Bit();
+ QByteArray result;
+ if (!urls.isEmpty())
+ result = urls.at(0).toString().toLocal8Bit();
return setData(result, pmedium);
}
}
@@ -948,6 +952,8 @@ bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeD
QDataStream s(&ba, QIODevice::WriteOnly);
s.setByteOrder(QDataStream::LittleEndian);// Intel byte order ####
if (cf == CF_DIB) {
+ if (img.format() > QImage::Format_ARGB32)
+ img = img.convertToFormat(QImage::Format_RGB32);
if (qt_write_dib(s, img))
return setData(ba, pmedium);
} else {
diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp
index c9a94ee..23f1481 100644
--- a/src/gui/kernel/qsoftkeymanager.cpp
+++ b/src/gui/kernel/qsoftkeymanager.cpp
@@ -115,6 +115,8 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act
break;
}
action->setSoftKeyRole(softKeyRole);
+ action->setVisible(false);
+ setForceEnabledInSoftkeys(action);
return action;
}
@@ -168,25 +170,55 @@ bool QSoftKeyManager::appendSoftkeys(const QWidget &source, int level)
{
Q_D(QSoftKeyManager);
bool ret = false;
- QList<QAction*> actions = source.actions();
- for (int i = 0; i < actions.count(); ++i) {
- if (actions.at(i)->softKeyRole() != QAction::NoSoftKey) {
- d->requestedSoftKeyActions.insert(level, actions.at(i));
+ foreach(QAction *action, source.actions()) {
+ if (action->softKeyRole() != QAction::NoSoftKey
+ && (action->isVisible() || isForceEnabledInSofkeys(action))) {
+ d->requestedSoftKeyActions.insert(level, action);
ret = true;
}
}
return ret;
}
+
+static bool isChildOf(const QWidget *c, const QWidget *p)
+{
+ while (c) {
+ if (c == p)
+ return true;
+ c = c->parentWidget();
+ }
+ return false;
+}
+
QWidget *QSoftKeyManager::softkeySource(QWidget *previousSource, bool& recursiveMerging)
{
Q_D(QSoftKeyManager);
QWidget *source = NULL;
if (!previousSource) {
// Initial source is primarily focuswidget and secondarily activeWindow
- source = QApplication::focusWidget();
- if (!source)
- source = QApplication::activeWindow();
+ QWidget *focus = QApplication::focusWidget();
+ QWidget *popup = QApplication::activePopupWidget();
+ if (popup) {
+ if (isChildOf(focus, popup))
+ source = focus;
+ else
+ source = popup;
+ }
+ if (!source) {
+ QWidget *modal = QApplication::activeModalWidget();
+ if (modal) {
+ if (isChildOf(focus, modal))
+ source = focus;
+ else
+ source = modal;
+ }
+ }
+ if (!source) {
+ source = focus;
+ if (!source)
+ source = QApplication::activeWindow();
+ }
} else {
// Softkey merging is based on four criterias
// 1. Implicit merging is used whenever focus widget does not specify any softkeys
@@ -210,6 +242,7 @@ bool QSoftKeyManager::handleUpdateSoftKeys()
d->requestedSoftKeyActions.clear();
bool recursiveMerging = false;
QWidget *source = softkeySource(NULL, recursiveMerging);
+ d->initialSoftKeySource = source;
while (source) {
if (appendSoftkeys(*source, level))
++level;
@@ -220,6 +253,20 @@ bool QSoftKeyManager::handleUpdateSoftKeys()
return true;
}
+void QSoftKeyManager::setForceEnabledInSoftkeys(QAction *action)
+{
+ action->setProperty(FORCE_ENABLED_PROPERTY, QVariant(true));
+}
+
+bool QSoftKeyManager::isForceEnabledInSofkeys(QAction *action)
+{
+ bool ret = false;
+ QVariant property = action->property(FORCE_ENABLED_PROPERTY);
+ if (property.isValid() && property.toBool())
+ ret = true;
+ return ret;
+}
+
bool QSoftKeyManager::event(QEvent *e)
{
#ifndef QT_NO_ACTION
diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h
index 460d0dc..04ddf7d 100644
--- a/src/gui/kernel/qsoftkeymanager_common_p.h
+++ b/src/gui/kernel/qsoftkeymanager_common_p.h
@@ -70,6 +70,7 @@ protected:
static QSoftKeyManager *self;
QHash<QAction*, Qt::Key> keyedActions;
QMultiHash<int, QAction*> requestedSoftKeyActions;
+ QWidget *initialSoftKeySource;
};
@@ -79,4 +80,4 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QSOFTKEYMANAGER_COMMON_P_H \ No newline at end of file
+#endif // QSOFTKEYMANAGER_COMMON_P_H
diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h
index a6fe17e..a5b258b 100644
--- a/src/gui/kernel/qsoftkeymanager_p.h
+++ b/src/gui/kernel/qsoftkeymanager_p.h
@@ -63,7 +63,8 @@ QT_BEGIN_NAMESPACE
class QSoftKeyManagerPrivate;
-const char MENU_ACTION_PROPERTY[] = "_q_menuaction";
+const char MENU_ACTION_PROPERTY[] = "_q_menuAction";
+const char FORCE_ENABLED_PROPERTY[] = "_q_forceEnabledInSoftkeys";
class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject
{
@@ -88,6 +89,8 @@ public:
static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget);
static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget);
static QString standardSoftKeyText(StandardSoftKey standardKey);
+ static void setForceEnabledInSoftkeys(QAction *action);
+ static bool isForceEnabledInSofkeys(QAction *action);
protected:
bool event(QEvent *e);
diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp
index 8ac1e31..c0761f0 100644
--- a/src/gui/kernel/qsoftkeymanager_s60.cpp
+++ b/src/gui/kernel/qsoftkeymanager_s60.cpp
@@ -60,7 +60,7 @@ const int LSK_POSITION = 0;
const int MSK_POSITION = 3;
const int RSK_POSITION = 2;
-QSoftKeyManagerPrivateS60::QSoftKeyManagerPrivateS60()
+QSoftKeyManagerPrivateS60::QSoftKeyManagerPrivateS60() : cbaHasImage(4) // 4 since MSK position index is 3
{
cachedCbaIconSize[0] = QSize(0,0);
cachedCbaIconSize[1] = QSize(0,0);
@@ -73,11 +73,21 @@ bool QSoftKeyManagerPrivateS60::skipCbaUpdate()
// Lets not update softkeys if
// 1. We don't have application panes, i.e. cba
// 2. Our CBA is not active, i.e. S60 native dialog or menu with custom CBA is shown
+ // 2.1. Except if thre is no current CBA at all and WindowSoftkeysRespondHint is set
+
// Note: Cannot use IsDisplayingMenuOrDialog since CBA update can be triggered before
// menu/dialog CBA is actually displayed i.e. it is being costructed.
CEikButtonGroupContainer *appUiCba = S60->buttonGroupContainer();
+ // CEikButtonGroupContainer::Current returns 0 if CBA is not visible at all
CEikButtonGroupContainer *currentCba = CEikButtonGroupContainer::Current();
- if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes) || appUiCba != currentCba) {
+ // Check if softkey need to be update even they are not visible
+ bool cbaRespondsWhenInvisible = false;
+ QWidget *window = QApplication::activeWindow();
+ if (window && (window->windowFlags() & Qt::WindowSoftkeysRespondHint))
+ cbaRespondsWhenInvisible = true;
+
+ if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
+ || (appUiCba != currentCba && !cbaRespondsWhenInvisible)) {
return true;
}
return false;
@@ -255,10 +265,14 @@ bool QSoftKeyManagerPrivateS60::setSoftkeyImage(CEikButtonGroupContainer *cba,
myimage->SetPicture( nBitmap, nMask ); // nBitmap and nMask ownership transfered
EikSoftkeyImage::SetImage(cba, *myimage, left); // Takes myimage ownership
+ cbaHasImage[position] = true;
ret = true;
} else {
// Restore softkey to text based
- EikSoftkeyImage::SetLabel(cba, left);
+ if (cbaHasImage[position]) {
+ EikSoftkeyImage::SetLabel(cba, left);
+ cbaHasImage[position] = false;
+ }
}
}
return ret;
@@ -274,7 +288,8 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba,
TPtrC nativeText = qt_QString2TPtrC(text);
int command = S60_COMMAND_START + position;
setNativeSoftkey(cba, position, command, nativeText);
- cba.DimCommand(command, !action->isEnabled());
+ const bool dimmed = !action->isEnabled() && !QSoftKeyManager::isForceEnabledInSofkeys(action);
+ cba.DimCommand(command, dimmed);
realSoftKeyActions.insert(command, action);
return true;
}
@@ -297,22 +312,17 @@ bool QSoftKeyManagerPrivateS60::setMiddleSoftkey(CEikButtonGroupContainer &cba)
bool QSoftKeyManagerPrivateS60::setRightSoftkey(CEikButtonGroupContainer &cba)
{
if (!setSoftkey(cba, QAction::NegativeSoftKey, RSK_POSITION)) {
- Qt::WindowType windowType = Qt::Window;
- QAction *action = requestedSoftKeyActions.value(0);
- if (action) {
- QWidget *actionParent = action->parentWidget();
- Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
-
- QWidget *actionWindow = actionParent->window();
- Q_ASSERT_X(actionWindow, Q_FUNC_INFO, "Softkey action does not have window!");
- windowType = actionWindow->windowType();
- }
-
+ const Qt::WindowType windowType = initialSoftKeySource
+ ? initialSoftKeySource->window()->windowType() : Qt::Window;
if (windowType != Qt::Dialog && windowType != Qt::Popup) {
QString text(QSoftKeyManager::tr("Exit"));
TPtrC nativeText = qt_QString2TPtrC(text);
- EikSoftkeyImage::SetLabel(&cba, false);
+ if (cbaHasImage[RSK_POSITION]) {
+ EikSoftkeyImage::SetLabel(&cba, false);
+ cbaHasImage[RSK_POSITION] = false;
+ }
setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText);
+ cba.DimCommand(EAknSoftkeyExit, false);
return true;
}
}
@@ -355,17 +365,30 @@ void QSoftKeyManagerPrivateS60::updateSoftKeys_sys()
nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation
}
+static void resetMenuBeingConstructed(TAny* /*aAny*/)
+{
+ S60->menuBeingConstructed = false;
+}
+
+void QSoftKeyManagerPrivateS60::tryDisplayMenuBarL()
+{
+ CleanupStack::PushL(TCleanupItem(resetMenuBeingConstructed, NULL));
+ S60->menuBeingConstructed = true;
+ S60->menuBar()->TryDisplayMenuBarL();
+ CleanupStack::PopAndDestroy(); // Reset menuBeingConstructed to false in all cases
+}
+
bool QSoftKeyManagerPrivateS60::handleCommand(int command)
{
QAction *action = realSoftKeyActions.value(command);
if (action) {
QVariant property = action->property(MENU_ACTION_PROPERTY);
if (property.isValid() && property.toBool()) {
- QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL());
+ QT_TRAP_THROWING(tryDisplayMenuBarL());
} else if (action->menu()) {
// TODO: This is hack, in order to use exising QMenuBar implementation for Symbian
// menubar needs to have widget to which it is associated. Since we want to associate
- // menubar to action (which is inherited from QObejct), we create and associate QWidget
+ // menubar to action (which is inherited from QObject), we create and associate QWidget
// to action and pass that for QMenuBar. This associates the menubar to action, and we
// can have own menubar for each action.
QWidget *actionContainer = action->property("_q_action_widget").value<QWidget*>();
@@ -384,15 +407,15 @@ bool QSoftKeyManagerPrivateS60::handleCommand(int command)
action->setProperty("_q_action_widget", v);
}
qt_symbian_next_menu_from_action(actionContainer);
- QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL());
- } else {
- Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey);
- QWidget *actionParent = action->parentWidget();
- Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
- if (actionParent->isEnabled()) {
- action->activate(QAction::Trigger);
- return true;
- }
+ QT_TRAP_THROWING(tryDisplayMenuBarL());
+ }
+
+ Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey);
+ QWidget *actionParent = action->parentWidget();
+ Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!");
+ if (actionParent->isEnabled()) {
+ action->activate(QAction::Trigger);
+ return true;
}
}
return false;
diff --git a/src/gui/kernel/qsoftkeymanager_s60_p.h b/src/gui/kernel/qsoftkeymanager_s60_p.h
index 823a2db..d14993c 100644
--- a/src/gui/kernel/qsoftkeymanager_s60_p.h
+++ b/src/gui/kernel/qsoftkeymanager_s60_p.h
@@ -53,6 +53,7 @@
// We mean it.
//
+#include "qbitarray.h"
#include "private/qobject_p.h"
#include "private/qsoftkeymanager_common_p.h"
@@ -77,6 +78,7 @@ public:
bool handleCommand(int command);
private:
+ void tryDisplayMenuBarL();
bool skipCbaUpdate();
void ensureCbaVisibilityAndResponsiviness(CEikButtonGroupContainer &cba);
void clearSoftkeys(CEikButtonGroupContainer &cba);
@@ -98,6 +100,7 @@ private:
private:
QHash<int, QAction*> realSoftKeyActions;
QSize cachedCbaIconSize[4];
+ QBitArray cbaHasImage;
};
diff --git a/src/gui/kernel/qsound.cpp b/src/gui/kernel/qsound.cpp
index 165e6ce..9d8ffa5 100644
--- a/src/gui/kernel/qsound.cpp
+++ b/src/gui/kernel/qsound.cpp
@@ -147,12 +147,13 @@ public:
supports WAVE and AU files.
\row
\o Mac OS X
- \o NSSound is used. All formats that NSSound supports, including QuickTime formats,
+ \o NSSound is used. All formats that NSSound supports, including QuickTime formats,
are supported by Qt for Mac OS X.
\row
\o Qt for Embedded Linux
\o A built-in mixing sound server is used, accessing \c /dev/dsp
directly. Only the WAVE format is supported.
+ \row
\o Symbian
\o CMdaAudioPlayerUtility is used. All formats that Symbian OS or devices support
are supported also by Qt.
diff --git a/src/gui/kernel/qsound_mac.mm b/src/gui/kernel/qsound_mac.mm
index 61e42ba..71fd663 100644
--- a/src/gui/kernel/qsound_mac.mm
+++ b/src/gui/kernel/qsound_mac.mm
@@ -174,6 +174,7 @@ NSSound *QAuServerMac::createNSSound(const QString &fileName, QSound *qSound)
NSSound * const nsSound = [[NSSound alloc] initWithContentsOfFile: nsFileName byReference:YES];
QMacSoundDelegate * const delegate = [[QMacSoundDelegate alloc] initWithQSound:qSound:this];
[nsSound setDelegate:delegate];
+ [nsFileName release];
return nsSound;
}
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index 86bf1b2e..a575717 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -301,7 +301,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
switch (event->type()) {
case QEvent::TouchBegin: {
d->speed = 1;
- d->time = QTime::currentTime();
+ d->time.start();
d->started = true;
result = QGestureRecognizer::MayBeGesture;
break;
@@ -338,11 +338,10 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
p3.screenPos().y() - d->lastPositions[2].y()) / 3;
const int distance = xDistance >= yDistance ? xDistance : yDistance;
- int elapsedTime = d->time.msecsTo(QTime::currentTime());
+ int elapsedTime = d->time.restart();
if (!elapsedTime)
elapsedTime = 1;
d->speed = 0.9 * d->speed + distance / elapsedTime;
- d->time = QTime::currentTime();
d->swipeAngle = QLineF(p1.startScreenPos(), p1.screenPos()).angle();
static const int MoveThreshold = 50;
@@ -405,7 +404,7 @@ void QSwipeGestureRecognizer::reset(QGesture *state)
d->lastPositions[0] = d->lastPositions[1] = d->lastPositions[2] = QPoint();
d->started = false;
d->speed = 0;
- d->time = QTime();
+ d->time.invalidate();
QGestureRecognizer::reset(state);
}
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index 9560952..b1e4c94 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -139,7 +139,7 @@ void QMacWindowFader::performFade()
extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp;
extern QWidget * mac_mouse_grabber;
-extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
+extern QWidget *qt_button_down; //qapplication_mac.cpp
void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds)
{
@@ -373,7 +373,7 @@ QMacTabletHash *qt_mac_tablet_hash()
// Clears the QWidget pointer that each QCocoaView holds.
void qt_mac_clearCocoaViewQWidgetPointers(QWidget *widget)
{
- QCocoaView *cocoaView = reinterpret_cast<QCocoaView *>(qt_mac_nativeview_for(widget));
+ QT_MANGLE_NAMESPACE(QCocoaView) *cocoaView = reinterpret_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget));
if (cocoaView && [cocoaView respondsToSelector:@selector(qt_qwidget)]) {
[cocoaView qt_clearQWidget];
}
@@ -652,8 +652,7 @@ bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widge
UInt32 macScanCode = 1;
QKeyEventEx ke(cocoaEvent2QtEvent([event type]), qtKey, keyMods, text, [event isARepeat], qMax(1, keyLength),
macScanCode, [event keyCode], [event modifierFlags]);
- qt_sendSpontaneousEvent(widgetToGetEvent, &ke);
- return ke.isAccepted();
+ return qt_sendSpontaneousEvent(widgetToGetEvent, &ke) && ke.isAccepted();
}
#endif
@@ -684,8 +683,16 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve
EventRef key_event = static_cast<EventRef>(const_cast<void *>([event eventRef]));
Q_ASSERT(key_event);
if ([event type] == NSKeyDown) {
- qt_keymapper_private()->updateKeyMap(0, key_event, 0);
+ NSString *characters = [event characters];
+ unichar value = [characters characterAtIndex:0];
+ qt_keymapper_private()->updateKeyMap(0, key_event, (void *)&value);
}
+
+ // Redirect keys to alien widgets.
+ if (widgetToGetEvent->testAttribute(Qt::WA_NativeWindow) == false) {
+ widgetToGetEvent = qApp->focusWidget();
+ }
+
if (widgetToGetEvent == 0)
return false;
@@ -695,8 +702,8 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve
if (mustUseCocoaKeyEvent())
return qt_dispatchKeyEventWithCocoa(keyEvent, widgetToGetEvent);
bool isAccepted;
- qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &isAccepted, true);
- return isAccepted;
+ bool consumed = qt_keymapper_private()->translateKeyEvent(widgetToGetEvent, 0, key_event, &isAccepted, true);
+ return consumed && isAccepted;
#endif
}
@@ -940,7 +947,7 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
[static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget];
}
} else {
- extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
+ extern QWidget * qt_button_down; //qapplication_mac.cpp
QPoint pos;
widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint,
pos, eventType,
@@ -952,7 +959,20 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
return false;
NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil];
- QPoint qlocalPoint(localPoint.x, localPoint.y);
+ QPoint qlocalPoint = QPoint(localPoint.x, localPoint.y);
+
+ // Search for alien child widgets (either on this qwidget or on the popup)
+ if (widgetToGetMouse->testAttribute(Qt::WA_NativeWindow) == false || qt_widget_private(widgetToGetMouse)->hasAlienChildren) {
+ QPoint qScreenPoint = flipPoint(globalPoint).toPoint();
+#ifdef ALIEN_DEBUG
+ qDebug() << "alien mouse event" << qScreenPoint << possibleAlien;
+#endif
+ QWidget *possibleAlien = widgetToGetMouse->childAt(qlocalPoint);
+ if (possibleAlien) {
+ qlocalPoint = possibleAlien->mapFromGlobal(widgetToGetMouse->mapToGlobal(qlocalPoint));
+ widgetToGetMouse = possibleAlien;
+ }
+ }
EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([theEvent eventRef]));
if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent))
@@ -997,7 +1017,19 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev
}
[QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint;
QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods);
- qt_sendSpontaneousEvent(widgetToGetMouse, &qme);
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "sending mouse event to" << widgetToGetMouse;
+#endif
+ extern QWidget *qt_button_down;
+ extern QPointer<QWidget> qt_last_mouse_receiver;
+
+ if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false)
+ qt_sendSpontaneousEvent(widgetToGetMouse, &qme);
+ else
+ QApplicationPrivate::sendMouseEvent(widgetToGetMouse, &qme, widgetToGetMouse, qwidget, &qt_button_down,
+ qt_last_mouse_receiver);
+
if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) {
QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods);
qt_sendSpontaneousEvent(widgetToGetMouse, &qcme);
@@ -1355,4 +1387,12 @@ QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool()
[(NSAutoreleasePool*)pool release];
}
+void qt_mac_post_retranslateAppMenu()
+{
+#ifdef QT_MAC_USE_COCOA
+ QMacCocoaAutoReleasePool pool;
+ qt_cocoaPostMessage([NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)], @selector(qtTranslateApplicationMenu));
+#endif
+}
+
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 c43ea55..3fd62a4 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -208,4 +208,6 @@ bool qt_cocoaPostMessage(id target, SEL selector);
#endif
+void qt_mac_post_retranslateAppMenu();
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index 735ca7a..a714221 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -68,12 +68,12 @@
#include <eikappui.h>
#ifdef Q_WS_S60
-#include <aknutils.h> // AknLayoutUtils
+#include <AknUtils.h> // AknLayoutUtils
#include <avkon.hrh> // EEikStatusPaneUidTitle
#include <akntitle.h> // CAknTitlePane
#include <akncontext.h> // CAknContextPane
#include <eikspane.h> // CEikStatusPane
-#include <aknpopupfader.h> // MAknFadedComponent and TAknPopupFader
+#include <AknPopupFader.h> // MAknFadedComponent and TAknPopupFader
#endif
QT_BEGIN_NAMESPACE
@@ -122,6 +122,7 @@ public:
int qtOwnsS60Environment : 1;
int supportsPremultipliedAlpha : 1;
int avkonComponentsSupportTransparency : 1;
+ int menuBeingConstructed : 1;
QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type
static inline void updateScreenSize();
static inline RWsSession& wsSession();
@@ -212,6 +213,7 @@ private:
#ifdef QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event);
#endif
+ void handleClientAreaChange();
private:
static QSymbianControl *lastFocusedControl;
diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h
index 167557b..7383382 100644
--- a/src/gui/kernel/qt_x11_p.h
+++ b/src/gui/kernel/qt_x11_p.h
@@ -439,6 +439,12 @@ struct QX11Data
int xinput_eventbase;
int xinput_errorbase;
+ // for XKEYBOARD support
+ bool use_xkb;
+ int xkb_major;
+ int xkb_eventbase;
+ int xkb_errorbase;
+
QList<QWidget *> deferred_map;
struct ScrollInProgress {
long id;
@@ -626,6 +632,8 @@ struct QX11Data
_NET_SYSTEM_TRAY_VISUAL,
+ _NET_ACTIVE_WINDOW,
+
// Property formats
COMPOUND_TEXT,
TEXT,
@@ -672,6 +680,9 @@ struct QX11Data
XWacomCursor,
XWacomEraser,
+ XTabletStylus,
+ XTabletEraser,
+
NPredefinedAtoms,
_QT_SETTINGS_TIMESTAMP = NPredefinedAtoms,
diff --git a/src/gui/kernel/qtooltip.cpp b/src/gui/kernel/qtooltip.cpp
index c912129..1343959 100644
--- a/src/gui/kernel/qtooltip.cpp
+++ b/src/gui/kernel/qtooltip.cpp
@@ -368,7 +368,16 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
#ifdef Q_WS_MAC
- QRect screen = QApplication::desktop()->availableGeometry(getTipScreen(pos, w));
+ // When in full screen mode, there is no Dock nor Menu so we can use
+ // the whole screen for displaying the tooltip. However when not in
+ // full screen mode we need to save space for the dock, so we use
+ // availableGeometry instead.
+ extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
+ QRect screen;
+ if(qt_mac_app_fullscreen)
+ screen = QApplication::desktop()->screenGeometry(getTipScreen(pos, w));
+ else
+ screen = QApplication::desktop()->availableGeometry(getTipScreen(pos, w));
#else
QRect screen = QApplication::desktop()->screenGeometry(getTipScreen(pos, w));
#endif
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 2f6ec6b..72ffe87 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -205,6 +205,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, nativeGesturePanEnabled(0)
#elif defined(Q_WS_MAC)
, needWindowChange(0)
+ , hasAlienChildren(0)
, window_event(0)
, qd_hd(0)
#endif
@@ -1121,7 +1122,8 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
qFatal("QWidget: Cannot create a QWidget when no GUI is being used");
Q_ASSERT(allWidgets);
- allWidgets->insert(q);
+ if (allWidgets)
+ allWidgets->insert(q);
QWidget *desktopWidget = 0;
if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
@@ -1168,6 +1170,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
if (f & Qt::MSWindowsOwnDC)
q->setAttribute(Qt::WA_NativeWindow);
+#ifdef Q_WS_MAC
+ q->setAttribute(Qt::WA_NativeWindow);
+#endif
+
q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute()
adjustQuitOnCloseAttribute();
@@ -1263,6 +1269,10 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
}
if (QWidget *parent = parentWidget()) {
+#ifdef Q_WS_MAC
+ if (testAttribute(Qt::WA_NativeWindow) == false)
+ parent->d_func()->hasAlienChildren = true;
+#endif
if (type & Qt::Window) {
if (!parent->testAttribute(Qt::WA_WState_Created))
parent->createWinId();
@@ -1433,7 +1443,7 @@ QWidget::~QWidget()
}
}
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
else if (!internalWinId() && isVisible()) {
qApp->d_func()->sendSyntheticEnterLeave(this);
#ifdef Q_WS_QWS
@@ -1496,8 +1506,12 @@ QWidget::~QWidget()
if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication
QWidgetPrivate::allWidgets->remove(this);
- QEvent e(QEvent::Destroy);
- QCoreApplication::sendEvent(this, &e);
+ QT_TRY {
+ QEvent e(QEvent::Destroy);
+ QCoreApplication::sendEvent(this, &e);
+ } QT_CATCH(const std::exception&) {
+ // if this fails we can't do anything about it but at least we are not allowed to throw.
+ }
}
int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances
@@ -2306,6 +2320,9 @@ QWidget *QWidget::find(WId id)
WId QWidget::winId() const
{
if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidget::winId: creating native window for" << this;
+#endif
QWidget *that = const_cast<QWidget*>(this);
that->setAttribute(Qt::WA_NativeWindow);
that->d_func()->createWinId();
@@ -2318,6 +2335,10 @@ WId QWidget::winId() const
void QWidgetPrivate::createWinId(WId winid)
{
Q_Q(QWidget);
+
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidgetPrivate::createWinId for" << q << winid;
+#endif
const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow);
if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) {
if (!q->isWindow()) {
@@ -2360,6 +2381,9 @@ Ensures that the widget has a window system identifier, i.e. that it is known to
void QWidget::createWinId()
{
Q_D(QWidget);
+#ifdef ALIEN_DEBUG
+ qDebug() << "QWidget::createWinId" << this;
+#endif
// qWarning("QWidget::createWinId is obsolete, please fix your code.");
d->createWinId();
}
@@ -5249,7 +5273,15 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
QPaintEngine *paintEngine = pdev->paintEngine();
if (paintEngine) {
setRedirected(pdev, -offset);
+#ifdef Q_WS_MAC
+ // (Alien support) Special case for Mac when redirecting: If the paint device
+ // is of the Widget type we need to set WA_WState_InPaintEvent since painting
+ // outside the paint event is not supported on QWidgets. The attributeis
+ // restored further down.
+ if (pdev->devType() == QInternal::Widget)
+ static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent);
+#endif
if (sharedPainter)
paintEngine->d_func()->systemClip = toBePainted;
else
@@ -5290,6 +5322,10 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
//restore
if (paintEngine) {
+#ifdef Q_WS_MAC
+ if (pdev->devType() == QInternal::Widget)
+ static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent, false);
+#endif
restoreRedirected();
if (!sharedPainter)
paintEngine->d_func()->systemRect = QRect();
@@ -5339,7 +5375,6 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
const QRegion &sourceRegion, QWidget::RenderFlags renderFlags,
bool readyToRender)
{
- Q_Q(QWidget);
if (!target) {
qWarning("QWidget::render: null pointer to paint device");
return;
@@ -6140,6 +6175,8 @@ void QWidget::setFocus(Qt::FocusReason reason)
previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
if (previousProxyFocus && previousProxyFocus->focusProxy())
previousProxyFocus = previousProxyFocus->focusProxy();
+ if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus)
+ return;
}
}
#endif
@@ -6469,7 +6506,7 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
// QWidget *fp = first->d_func()->focus_prev;
QWidget *fn = first->d_func()->focus_next;
- if (fn == second)
+ if (fn == second || first == second)
return;
QWidget *sp = second->d_func()->focus_prev;
@@ -7322,7 +7359,7 @@ void QWidgetPrivate::hide_helper()
// next bit tries to move the focus if the focus widget is now
// hidden.
if (wasVisible) {
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
qApp->d_func()->sendSyntheticEnterLeave(q);
#endif
@@ -7454,7 +7491,7 @@ void QWidget::setVisible(bool visible)
d->show_helper();
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
qApp->d_func()->sendSyntheticEnterLeave(this);
#endif
}
@@ -7552,6 +7589,23 @@ void QWidgetPrivate::hideChildren(bool spontaneous)
QWidget *widget = qobject_cast<QWidget*>(childList.at(i));
if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden))
continue;
+#ifdef QT_MAC_USE_COCOA
+ // Before doing anything we need to make sure that we don't leave anything in a non-consistent state.
+ // When hiding a widget we need to make sure that no mouse_down events are active, because
+ // the mouse_up event will never be received by a hidden widget or one of its descendants.
+ // The solution is simple, before going through with this we check if there are any mouse_down events in
+ // progress, if so we check if it is related to this widget or not. If so, we just reset the mouse_down and
+ // then we continue.
+ // In X11 and Windows we send a mouse_release event, however we don't do that here because we were already
+ // ignoring that from before. I.e. Carbon did not send the mouse release event, so we will not send the
+ // mouse release event. There are two ways to interpret this:
+ // 1. If we don't send the mouse release event, the widget might get into an inconsistent state, i.e. it
+ // might be waiting for a release event that will never arrive.
+ // 2. If we send the mouse release event, then the widget might decide to trigger an action that is not
+ // supposed to trigger because it is not visible.
+ if(widget == qt_button_down)
+ qt_button_down = 0;
+#endif // QT_MAC_USE_COCOA
if (spontaneous)
widget->setAttribute(Qt::WA_Mapped, false);
else
@@ -7569,7 +7623,7 @@ void QWidgetPrivate::hideChildren(bool spontaneous)
widget->d_func()->hide_sys();
}
}
-#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC)
qApp->d_func()->sendSyntheticEnterLeave(widget);
#endif
#ifndef QT_NO_ACCESSIBILITY
@@ -7944,13 +7998,16 @@ inline void setDisabledStyle(QWidget *w, bool setStyle)
// set/reset WS_DISABLED style.
if(w && w->isWindow() && w->isVisible() && w->isEnabled()) {
LONG dwStyle = GetWindowLong(w->winId(), GWL_STYLE);
+ LONG newStyle = dwStyle;
if (setStyle)
- dwStyle |= WS_DISABLED;
+ newStyle |= WS_DISABLED;
else
- dwStyle &= ~WS_DISABLED;
- SetWindowLong(w->winId(), GWL_STYLE, dwStyle);
- // we might need to repaint in some situations (eg. menu)
- w->repaint();
+ newStyle &= ~WS_DISABLED;
+ if (newStyle != dwStyle) {
+ SetWindowLong(w->winId(), GWL_STYLE, newStyle);
+ // we might need to repaint in some situations (eg. menu)
+ w->repaint();
+ }
}
}
#endif
@@ -9787,7 +9844,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
desktopWidget = parent;
bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget;
-#if defined(Q_WS_X11) || defined(Q_WS_WIN)
+#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MAC)
if (newParent && parent && !desktopWidget) {
if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings))
parent->d_func()->enforceNativeChildren();
@@ -10262,6 +10319,29 @@ const QPixmap *QWidget::icon() const
#endif // QT3_SUPPORT
+ /*!
+ \internal
+
+ This just sets the corresponding attribute bit to 1 or 0
+ */
+static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data,
+ QWidgetPrivate *d)
+{
+ if (attribute < int(8*sizeof(uint))) {
+ if (on)
+ data->widget_attributes |= (1<<attribute);
+ else
+ data->widget_attributes &= ~(1<<attribute);
+ } else {
+ const int x = attribute - 8*sizeof(uint);
+ const int int_off = x / (8*sizeof(uint));
+ if (on)
+ d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint))));
+ else
+ d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint))));
+ }
+}
+
/*!
Sets the attribute \a attribute on this widget if \a on is true;
otherwise clears the attribute.
@@ -10288,19 +10368,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
#endif
- if (attribute < int(8*sizeof(uint))) {
- if (on)
- data->widget_attributes |= (1<<attribute);
- else
- data->widget_attributes &= ~(1<<attribute);
- } else {
- const int x = attribute - 8*sizeof(uint);
- const int int_off = x / (8*sizeof(uint));
- if (on)
- d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint))));
- else
- d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint))));
- }
+ setAttribute_internal(attribute, on, data, d);
switch (attribute) {
@@ -10359,14 +10427,11 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
#ifdef Q_WS_MAC
{
// We can only have one of these set at a time
- static const int MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize,
- Qt::WA_MacMiniSize, 0 };
- for (int i = 0; MacSizes[i] != 0; ++i) {
- if (MacSizes[i] == attribute)
- continue;
- int macsize_x = MacSizes[i] - 8*sizeof(uint);
- int macsize_int_off = macsize_x / (8*sizeof(uint));
- d->high_attributes[macsize_int_off] &= ~(1<<(macsize_x-(macsize_int_off*8*sizeof(uint))));
+ const Qt::WidgetAttribute MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize,
+ Qt::WA_MacMiniSize };
+ for (int i = 0; i < 3; ++i) {
+ if (MacSizes[i] != attribute)
+ setAttribute_internal(MacSizes[i], false, data, d);
}
d->macUpdateSizeAttribute();
}
@@ -10433,7 +10498,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
case Qt::WA_PaintOnScreen:
d->updateIsOpaque();
-#if defined(Q_WS_WIN) || defined(Q_WS_X11)
+#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC)
// Recreate the widget if it's already created as an alien widget and
// WA_PaintOnScreen is enabled. Paint on screen widgets must have win id.
// So must their children.
@@ -10489,6 +10554,10 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
case Qt::WA_X11OpenGLOverlay:
d->updateIsOpaque();
break;
+ case Qt::WA_X11DoNotAcceptFocus:
+ if (testAttribute(Qt::WA_WState_Created))
+ d->updateX11AcceptFocus();
+ break;
#endif
case Qt::WA_DontShowOnScreen: {
if (on && isVisible()) {
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index 0d7475e9..e12148b 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -773,6 +773,7 @@ private:
#ifdef Q_WS_X11
friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp);
friend void qt_net_remove_user_time(QWidget *tlw);
+ friend void qt_set_winid_on_widget(QWidget*, Qt::HANDLE);
#endif
friend Q_GUI_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget);
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index dcb87fc..3d86936 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -152,6 +152,7 @@ static bool qt_mac_raise_process = true;
static OSWindowRef qt_root_win = 0;
QWidget *mac_mouse_grabber = 0;
QWidget *mac_keyboard_grabber = 0;
+extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
#ifndef QT_MAC_USE_COCOA
#ifdef QT_NAMESPACE
@@ -459,7 +460,13 @@ static bool qt_isGenuineQWidget(OSViewRef ref)
bool qt_isGenuineQWidget(const QWidget *window)
{
- return window && qt_isGenuineQWidget(OSViewRef(window->winId()));
+ if (!window)
+ return false;
+
+ if (!window->internalWinId())
+ return true; //alien
+
+ return qt_isGenuineQWidget(OSViewRef(window->internalWinId()));
}
Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget *w)
@@ -866,7 +873,6 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event,
& ~Qt::WindowMaximized));
QApplication::sendSpontaneousEvent(widget, &e);
}
- extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
qt_button_down = 0;
} else if(ekind == kEventWindowCollapsed) {
if (!widget->isMinimized()) {
@@ -894,7 +900,6 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event,
//we send a hide to be like X11/Windows
QEvent e(QEvent::Hide);
QApplication::sendSpontaneousEvent(widget, &e);
- extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
qt_button_down = 0;
} else if(ekind == kEventWindowToolbarSwitchMode) {
macSendToolbarChangeEvent(widget);
@@ -1268,6 +1273,11 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event,
if (widget->isVisible() && widget->updatesEnabled()) { //process the actual paint event.
if(widget->testAttribute(Qt::WA_WState_InPaintEvent))
qWarning("QWidget::repaint: Recursive repaint detected");
+ if (widget->isWindow() && !widget->d_func()->isOpaque
+ && !widget->testAttribute(Qt::WA_MacBrushedMetal)) {
+ QRect qrgnRect = qrgn.boundingRect();
+ CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height()));
+ }
QPoint redirectionOffset(0, 0);
QWidget *tl = widget->window();
@@ -1318,13 +1328,6 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event,
widget->d_func()->restoreRedirected();
}
- if (widget->isWindow() && !widget->d_func()->isOpaque
- && !widget->testAttribute(Qt::WA_MacBrushedMetal)) {
- QRect qrgnRect = qrgn.boundingRect();
- CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height()));
- }
-
-
if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget))
CallNextEventHandler(er, event);
@@ -1521,7 +1524,6 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event,
if (widget) {
qt_event_request_window_change(widget);
if (!HIViewIsVisible(HIViewRef(widget->winId()))) {
- extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
if (widget == qt_button_down)
qt_button_down = 0;
}
@@ -1530,7 +1532,6 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event,
break; }
case kEventClassMouse: {
bool send_to_app = false;
- extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
if(qt_button_down)
send_to_app = true;
if(send_to_app) {
@@ -2608,7 +2609,16 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
}
} else {
data.fstrut_dirty = false; // non-toplevel widgets don't have a frame, so no need to update the strut
- if(OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) {
+
+#ifdef QT_MAC_USE_COCOA
+ if (q->testAttribute(Qt::WA_NativeWindow) == false ||
+ q->internalWinId() != 0) {
+#ifdef ALIEN_DEBUG
+ qDebug() << "Skipping native widget creation for" << this;
+#endif
+ } else
+#endif
+ if (OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) {
#ifndef QT_MAC_USE_COCOA
HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height());
HIViewSetFrame(osview, &bounds);
@@ -2869,9 +2879,12 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
q->setAttribute(Qt::WA_WState_Visible, false);
q->setAttribute(Qt::WA_WState_Hidden, false);
adjustFlags(data.window_flags, q);
- // keep compatibility with previous versions, we need to preserve the created state
- // (but we recreate the winId for the widget being reparented, again for compatibility)
- if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created))) {
+ // keep compatibility with previous versions, we need to preserve the created state.
+ // (but we recreate the winId for the widget being reparented, again for compatibility,
+ // unless this is an alien widget. )
+ const bool nonWindowWithCreatedParent = !q->isWindow() && parent->testAttribute(Qt::WA_WState_Created);
+ const bool nativeWidget = q->internalWinId() != 0;
+ if (wasCreated || nativeWidget && nonWindowWithCreatedParent) {
createWinId();
if (q->isWindow()) {
#ifndef QT_MAC_USE_COCOA
@@ -2955,7 +2968,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
QPoint QWidget::mapToGlobal(const QPoint &pos) const
{
Q_D(const QWidget);
- if (!testAttribute(Qt::WA_WState_Created)) {
+ if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
QPoint p = pos + data->crect.topLeft();
return isWindow() ? p : parentWidget()->mapToGlobal(p);
}
@@ -2982,7 +2995,7 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const
QPoint QWidget::mapFromGlobal(const QPoint &pos) const
{
Q_D(const QWidget);
- if (!testAttribute(Qt::WA_WState_Created)) {
+ if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) {
QPoint p = isWindow() ? pos : parentWidget()->mapFromGlobal(pos);
return p - data->crect.topLeft();
}
@@ -3281,7 +3294,7 @@ void QWidgetPrivate::update_sys(const QRect &r)
#ifndef QT_MAC_USE_COCOA
HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true);
#else
- [qt_mac_nativeview_for(q) setNeedsDisplay:YES];
+ qt_mac_set_needs_display(q, QRegion());
#endif
return;
}
@@ -3319,11 +3332,24 @@ void QWidgetPrivate::update_sys(const QRegion &rgn)
HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true); // do a complete repaint on overflow.
}
#else
- // Cocoa doesn't do regions, it seems more efficient to just update the bounding rect instead of a potential number of message passes for each rect.
- const QRect &boundingRect = rgn.boundingRect();
- [qt_mac_nativeview_for(q) setNeedsDisplayInRect:NSMakeRect(boundingRect.x(),
- boundingRect.y(), boundingRect.width(),
- boundingRect.height())];
+ // Alien support: get the first native ancestor widget (will be q itself in the non-alien case),
+ // map the coordinates from q space to NSView space and invalidate the rect.
+ QWidget *nativeParent = q->internalWinId() ? q : q->nativeParentWidget();
+ if (nativeParent == 0)
+ return;
+
+ QVector<QRect> rects = rgn.rects();
+ for (int i = 0; i < rects.count(); ++i) {
+ const QRect &rect = rects.at(i);
+
+ const QRect nativeBoundingRect = QRect(
+ QPoint(q->mapTo(nativeParent, rect.topLeft())),
+ QSize(rect.size()));
+
+ [qt_mac_nativeview_for(nativeParent) setNeedsDisplayInRect:NSMakeRect(nativeBoundingRect.x(),
+ nativeBoundingRect.y(), nativeBoundingRect.width(),
+ nativeBoundingRect.height())];
+ }
#endif
}
@@ -3405,8 +3431,10 @@ void QWidgetPrivate::show_sys()
// The window is modally shaddowed, so we need to make
// sure that we don't pop in front of the modal window:
[window orderFront:window];
- if (NSWindow *modalWin = qt_mac_window_for(top))
- [modalWin orderFront:window];
+ if (!top->testAttribute(Qt::WA_DontShowOnScreen)) {
+ if (NSWindow *modalWin = qt_mac_window_for(top))
+ [modalWin orderFront:window];
+ }
}
#endif
if (q->windowType() == Qt::Popup) {
@@ -3465,7 +3493,6 @@ void QWidgetPrivate::hide_sys()
Q_Q(QWidget);
if((q->windowType() == Qt::Desktop)) //you can't hide the desktop!
return;
-
QMacCocoaAutoReleasePool pool;
if(q->isWindow()) {
#ifdef QT_MAC_USE_COCOA
@@ -3906,7 +3933,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget *w)
widget, either by scrolling its contents or repainting, depending on the WA_StaticContents
flag
*/
-static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newRect)
+static void qt_mac_update_widget_position(QWidget *q, QRect oldRect, QRect newRect)
{
#ifndef QT_MAC_USE_COCOA
HIRect bounds = CGRectMake(newRect.x(), newRect.y(),
@@ -4003,7 +4030,7 @@ static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newR
#else
Q_UNUSED(oldRect);
NSRect bounds = NSMakeRect(newRect.x(), newRect.y(),
- newRect.width(), newRect.height());
+ newRect.width(), newRect.height());
[qt_mac_nativeview_for(q) setFrame:bounds];
#endif
}
@@ -4040,7 +4067,8 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
QRect xrect = data.crect;
QRect parentWRect;
- if (q->isWindow() && topData()->embedded) {
+ bool isEmbeddedWindow = (q->isWindow() && topData()->embedded);
+ if (isEmbeddedWindow) {
#ifndef QT_MAC_USE_COCOA
HIViewRef parentView = HIViewGetSuperview(qt_mac_nativeview_for(q));
#else
@@ -4065,7 +4093,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
if (parentWRect.isValid()) {
// parent is clipped, and we have to clip to the same limit as parent
- if (!parentWRect.contains(xrect)) {
+ if (!parentWRect.contains(xrect) && !isEmbeddedWindow) {
xrect &= parentWRect;
wrect = xrect;
//translate from parent's to my Qt coord sys
@@ -4167,7 +4195,7 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
}
}
- qt_mac_update_widget_posisiton(q, oldRect, xrect);
+ qt_mac_update_widget_position(q, oldRect, xrect);
if (jump)
q->update();
@@ -4759,8 +4787,10 @@ void QWidgetPrivate::syncCocoaMask()
if (!q->testAttribute(Qt::WA_WState_Created) || !extra)
return;
- if (extra->hasMask && extra->maskBits.size() != q->size()) {
- extra->maskBits = QImage(q->size(), QImage::Format_Mono);
+ if (extra->hasMask) {
+ if(extra->maskBits.size() != q->size()) {
+ extra->maskBits = QImage(q->size(), QImage::Format_Mono);
+ }
extra->maskBits.fill(QColor(Qt::color1).rgba());
extra->maskBits.setNumColors(2);
extra->maskBits.setColor(0, QColor(Qt::color0).rgba());
@@ -4804,7 +4834,7 @@ void QWidgetPrivate::finishCocoaMaskSetup()
[window setOpaque:(extra->imageMask == 0)];
[window invalidateShadow];
}
- [qt_mac_nativeview_for(q) setNeedsDisplay:YES];
+ qt_mac_set_needs_display(q, QRegion());
}
#endif
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index efd9a0a..89ea256 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -234,6 +234,15 @@ struct QWExtra {
uint activated : 1; // RWindowBase::Activated has been called
/**
+ * If this bit is set, each native widget receives the signals from the
+ * Symbian control immediately before and immediately after draw ops are
+ * sent to the window server for this control:
+ * void beginNativePaintEvent(const QRect &paintRect);
+ * void endNativePaintEvent(const QRect &paintRect);
+ */
+ uint receiveNativePaintEvents : 1;
+
+ /**
* Defines the behaviour of QSymbianControl::Draw.
*/
enum NativePaintMode {
@@ -258,16 +267,7 @@ struct QWExtra {
Default = Blit
};
- NativePaintMode nativePaintMode : 2;
-
- /**
- * If this bit is set, each native widget receives the signals from the
- * Symbian control immediately before and immediately after draw ops are
- * sent to the window server for this control:
- * void beginNativePaintEvent(const QRect &paintRect);
- * void endNativePaintEvent(const QRect &paintRect);
- */
- uint receiveNativePaintEvents : 1;
+ NativePaintMode nativePaintMode;
#endif
};
@@ -680,7 +680,7 @@ public:
QMap<Qt::GestureType, Qt::GestureFlags> gestureContext;
// Bit fields.
- uint high_attributes[3]; // the low ones are in QWidget::widget_attributes
+ uint high_attributes[4]; // the low ones are in QWidget::widget_attributes
QPalette::ColorRole fg_role : 8;
QPalette::ColorRole bg_role : 8;
uint dirtyOpaqueChildren : 1;
@@ -703,6 +703,7 @@ public:
void setNetWmWindowTypes();
void x11UpdateIsOpaque();
bool isBackgroundInherited() const;
+ void updateX11AcceptFocus();
#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
uint nativeGesturePanEnabled : 1;
@@ -720,6 +721,7 @@ public:
#elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC
// This is new stuff
uint needWindowChange : 1;
+ uint hasAlienChildren : 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
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index ebd289c..bfa7050 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -1037,15 +1037,34 @@ QPoint QWidget::mapFromGlobal(const QPoint &pos) const
return widgetPos;
}
+static Qt::WindowStates effectiveState(Qt::WindowStates state)
+{
+ if (state & Qt::WindowMinimized)
+ return Qt::WindowMinimized;
+ else if (state & Qt::WindowFullScreen)
+ return Qt::WindowFullScreen;
+ else if (state & Qt::WindowMaximized)
+ return Qt::WindowMaximized;
+ return Qt::WindowNoState;
+}
+
void QWidget::setWindowState(Qt::WindowStates newstate)
{
Q_D(QWidget);
Qt::WindowStates oldstate = windowState();
- if (oldstate == newstate)
+
+ const TBool isFullscreen = newstate & Qt::WindowFullScreen;
+ const TBool cbaRequested = windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ const TBool cbaVisible = CEikButtonGroupContainer::Current() ? true : false;
+ const TBool softkeyVisibilityChange = isFullscreen && (cbaRequested != cbaVisible);
+
+ if (oldstate == newstate && !softkeyVisibilityChange)
return;
if (isWindow()) {
+ const bool wasResized = testAttribute(Qt::WA_Resized);
+ const bool wasMoved = testAttribute(Qt::WA_Moved);
QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId());
if (window && newstate & Qt::WindowMinimized) {
@@ -1058,36 +1077,58 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
#ifdef Q_WS_S60
// Hide window decoration when switching to fullsccreen / minimized otherwise show decoration.
- // The window decoration visibility has to be changed before doing actual window state
- // change since in that order the availableGeometry will return directly the right size and
+ // The window decoration visibility has to be changed before doing actual window state
+ // change since in that order the availableGeometry will return directly the right size and
// we will avoid unnecessarty redraws
- CEikStatusPane* statusPane = S60->statusPane();
- CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer();
- TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
+ CEikStatusPane *statusPane = S60->statusPane();
+ CEikButtonGroupContainer *buttonGroup = S60->buttonGroupContainer();
+ TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized));
if (statusPane)
statusPane->MakeVisible(visible);
- if (buttonGroup)
- buttonGroup->MakeVisible(visible);
+ if (buttonGroup) {
+ // Visibility
+ buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested));
+
+ // Responsiviness
+ CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
+ TUint cbaFlags = cba->ButtonGroupFlags();
+ if(windowFlags() & Qt::WindowSoftkeysRespondHint)
+ cbaFlags |= EAknCBAFlagRespondWhenInvisible;
+ else
+ cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
+ cba->SetButtonGroupFlags(cbaFlags);
+ }
#endif // Q_WS_S60
createWinId();
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
// Ensure the initial size is valid, since we store it as normalGeometry below.
- if (!testAttribute(Qt::WA_Resized) && !isVisible())
+ if (!wasResized && !isVisible())
adjustSize();
QTLWExtra *top = d->topData();
const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
- if (newstate & Qt::WindowFullScreen)
+
+ const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
+ if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint)
setGeometry(qApp->desktop()->screenGeometry(this));
- else if (newstate & Qt::WindowMaximized)
+ else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint))
setGeometry(qApp->desktop()->availableGeometry(this));
else
setGeometry(normalGeometry);
//restore normal geometry
top->normalGeometry = normalGeometry;
+
+ // FixMe QTBUG-8977
+ // In some platforms, WA_Resized and WA_Moved are also not set when application window state is
+ // anything else than normal. In Symbian we can restore them only for normal window state since
+ // restoring for other modes, will make fluidlauncher to be launched in wrong size (200x100)
+ if (effectiveState(newstate) == Qt::WindowNoState) {
+ setAttribute(Qt::WA_Resized, wasResized);
+ setAttribute(Qt::WA_Moved, wasMoved);
+ }
}
data->window_state = newstate;
@@ -1220,8 +1261,10 @@ void QWidget::releaseMouse()
{
if (!qt_nograb() && QWidgetPrivate::mouseGrabber == this) {
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
- WId id = effectiveWinId();
- id->SetPointerCapture(false);
+ if(!window()->isModal()) {
+ WId id = effectiveWinId();
+ id->SetPointerCapture(false);
+ }
QWidgetPrivate::mouseGrabber = 0;
#ifndef QT_NO_CURSOR
QApplication::restoreOverrideCursor();
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 8cab387..7d647b7 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -243,7 +243,7 @@ static QCursor *mouseGrbCur = 0;
static QWidget *keyboardGrb = 0;
static HHOOK journalRec = 0;
-extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
#define XCOORD_MAX 16383
#define WRECT_MAX 16383
@@ -825,7 +825,7 @@ QCursor *qt_grab_cursor()
// The procedure does nothing, but is required for mousegrabbing to work
#ifndef Q_WS_WINCE
-LRESULT CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam)
+LRESULT QT_WIN_CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(journalRec, nCode, wParam, lParam);
}
@@ -2073,6 +2073,8 @@ void QWidgetPrivate::winSetupGestures()
if (!q || !q->isVisible() || !nativeGesturePanEnabled)
return;
+ if (!QApplicationPrivate::HasTouchSupport)
+ return;
QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
if (!qAppPriv->SetGestureConfig)
return;
diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp
index fa94703..509847b 100644
--- a/src/gui/kernel/qwidget_wince.cpp
+++ b/src/gui/kernel/qwidget_wince.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
const QString qt_reg_winclass(QWidget *w); // defined in qapplication_win.cpp
-extern "C" LRESULT CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
+extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND, UINT, WPARAM, LPARAM);
//#define TABLET_DEBUG
#define PACKETDATA (PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE \
@@ -586,7 +586,7 @@ void QWidgetPrivate::setWindowOpacity_sys(qreal level) {
}
// The procedure does nothing, but is required for mousegrabbing to work
-LRESULT CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) {
+LRESULT QT_WIN_CALLBACK qJournalRecordProc(int nCode, WPARAM wParam, LPARAM lParam) {
Q_UNUSED(nCode);
Q_UNUSED(wParam);
Q_UNUSED(lParam);
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 10fb009..37ac6bf 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -49,7 +49,7 @@
#include "qbitmap.h"
#include "qlayout.h"
#include "qtextcodec.h"
-#include "qdatetime.h"
+#include "qelapsedtimer.h"
#include "qcursor.h"
#include "qstack.h"
#include "qcolormap.h"
@@ -352,7 +352,7 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
return;
QApplication::flush();
XEvent ev;
- QTime t;
+ QElapsedTimer t;
t.start();
static const int maximumWaitTime = 2000;
if (!w->testAttribute(Qt::WA_WState_Created))
@@ -369,7 +369,7 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
// ConfigureNotify ... MapNotify ... Expose
enum State {
- Initial, Reparented, Mapped
+ Initial, Mapped
} state = Initial;
do {
@@ -377,33 +377,15 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w)
XNextEvent(X11->display, &ev);
qApp->x11ProcessEvent(&ev);
- if (w->windowFlags() & Qt::X11BypassWindowManagerHint) {
- switch (state) {
- case Initial:
- case Reparented:
- if (ev.type == MapNotify && ev.xany.window == winid)
- state = Mapped;
- break;
- case Mapped:
- if (ev.type == Expose && ev.xany.window == winid)
- return;
- break;
- }
- } else {
- switch (state) {
- case Initial:
- if (ev.type == ReparentNotify && ev.xany.window == winid)
- state = Reparented;
- break;
- case Reparented:
- if (ev.type == MapNotify && ev.xany.window == winid)
- state = Mapped;
- break;
- case Mapped:
- if (ev.type == Expose && ev.xany.window == winid)
- return;
- break;
- }
+ switch (state) {
+ case Initial:
+ if (ev.type == MapNotify && ev.xany.window == winid)
+ state = Mapped;
+ break;
+ case Mapped:
+ if (ev.type == Expose && ev.xany.window == winid)
+ return;
+ break;
}
} else {
if (!XEventsQueued(X11->display, QueuedAfterFlush))
@@ -798,7 +780,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
XWMHints wm_hints; // window manager hints
memset(&wm_hints, 0, sizeof(wm_hints)); // make valgrind happy
wm_hints.flags = InputHint | StateHint | WindowGroupHint;
- wm_hints.input = True;
+ wm_hints.input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
wm_hints.initial_state = NormalState;
wm_hints.window_group = X11->wm_client_leader;
@@ -1184,7 +1166,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
adjustFlags(data.window_flags, q);
// keep compatibility with previous versions, we need to preserve the created state
// (but we recreate the winId for the widget being reparented, again for compatibility)
- if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created)))
+ if (wasCreated)
createWinId();
if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden)
q->setAttribute(Qt::WA_WState_Hidden);
@@ -1659,7 +1641,29 @@ void QWidget::activateWindow()
if (X11->userTime == 0)
X11->userTime = X11->time;
qt_net_update_user_time(tlw, X11->userTime);
- XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
+
+ if (X11->isSupportedByWM(ATOM(_NET_ACTIVE_WINDOW))
+ && !(tlw->windowFlags() & Qt::X11BypassWindowManagerHint)) {
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = ATOM(_NET_ACTIVE_WINDOW);
+ e.xclient.display = X11->display;
+ e.xclient.window = tlw->internalWinId();
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = 1; // 1 == application
+ e.xclient.data.l[1] = X11->userTime;
+ if (QWidget *aw = QApplication::activeWindow())
+ e.xclient.data.l[2] = aw->internalWinId();
+ else
+ e.xclient.data.l[2] = XNone;
+ e.xclient.data.l[3] = 0;
+ e.xclient.data.l[4] = 0;
+ XSendEvent(X11->display, RootWindow(X11->display, tlw->x11Info().screen()),
+ false, SubstructureNotifyMask | SubstructureRedirectMask, &e);
+ } else {
+ if (!qt_widget_private(tlw)->topData()->waitingForMapNotify)
+ XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time);
+ }
}
}
@@ -3048,4 +3052,24 @@ void qt_x11_getX11InfoForWindow(QX11Info * xinfo, const QX11WindowAttributes &at
xinfo->setX11Data(xd);
}
+void QWidgetPrivate::updateX11AcceptFocus()
+{
+ Q_Q(QWidget);
+ if (!q->isWindow() || !q->internalWinId())
+ return;
+
+ 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;
+ }
+ h->flags |= InputHint;
+ h->input = q->testAttribute(Qt::WA_X11DoNotAcceptFocus) ? False : True;
+
+ XSetWMHints(X11->display, q->internalWinId(), h);
+ if (h != &wm_hints)
+ XFree((char *)h);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
index c65fa50..146b067 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h
@@ -54,6 +54,38 @@
//
#include <QGestureRecognizer>
+#include <objbase.h>
+
+class IInkRectangle;
+class TabletHardwareCapabilities;
+class TabletPropertyMetricUnit;
+DECLARE_INTERFACE_(IInkTablet, IDispatch)
+{
+ STDMETHOD(get_Name)(THIS_ BSTR *Name) PURE;
+ STDMETHOD(get_PlugAndPlayId)(THIS_ BSTR *Id) PURE;
+ STDMETHOD(get_MaximumInputRectangle)(THIS_ IInkRectangle **Rectangle) PURE;
+ STDMETHOD(get_HardwareCapabilities)(THIS_ TabletHardwareCapabilities *Capabilities) PURE;
+ STDMETHOD(IsPacketPropertySupported)(THIS_ BSTR packetPropertyName) PURE;
+ STDMETHOD(GetPropertyMetrics)(THIS_ BSTR propertyName, long *Minimum, long *Maximum, TabletPropertyMetricUnit *Units, float *Resolution) PURE;
+};
+enum TabletDeviceKind
+{
+ TDK_Mouse = 0,
+ TDK_Pen = 1,
+ TDK_Touch = 2
+};
+DECLARE_INTERFACE_(IInkTablet2, IDispatch)
+{
+ STDMETHOD(get_DeviceKind)(THIS_ TabletDeviceKind *Kind) PURE;
+};
+DECLARE_INTERFACE_(IInkTablets, IDispatch)
+{
+ STDMETHOD(get_Count)(THIS_ long *Count) PURE;
+ STDMETHOD(get__NewEnum)(THIS_ IUnknown **_NewEnum) PURE;
+ STDMETHOD(get_DefaultTablet)(THIS_ IInkTablet **DefaultTablet) PURE;
+ STDMETHOD(Item)(THIS_ long Index, IInkTablet **Tablet) PURE;
+ STDMETHOD(IsPacketPropertySupported)(THIS_ BSTR packetPropertyName, VARIANT_BOOL *Supported) PURE;
+};
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qx11embed_x11.cpp b/src/gui/kernel/qx11embed_x11.cpp
index 35850db..b527e72 100644
--- a/src/gui/kernel/qx11embed_x11.cpp
+++ b/src/gui/kernel/qx11embed_x11.cpp
@@ -47,7 +47,7 @@
#include <qlayout.h>
#include <qstyle.h>
#include <qstyleoption.h>
-#include <qdatetime.h>
+#include <qelapsedtimer.h>
#include <qpointer.h>
#include <qdebug.h>
#include <qx11info_x11.h>
@@ -1231,7 +1231,7 @@ void QX11EmbedContainer::embedClient(WId id)
For safety, we will not wait more than 500 ms, so that we can
preemptively workaround buggy window managers.
*/
- QTime t;
+ QElapsedTimer t;
t.start();
functorData data;