summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-04-11 14:36:55 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-04-11 14:36:55 +0200
commit98d3e40fb7c88b670a93e73dace2d0f05a5f903c (patch)
treeb1292124a86c219fb434db4ec28e8f805ff52287 /src/plugins
parenta74e4b85be83e2da47f4a1d8fcf0e78079335b80 (diff)
parentbab494e4d046f5617d19f5fec35eeff94377c51f (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: mkspecs/qnx-armv7le-qcc/qplatformdefs.h src/printsupport/kernel/qcups.cpp src/widgets/styles/qstyle.h tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp Change-Id: Ia41e13051169a6d4a8a1267548e7d47b859bb267
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/generic/evdevkeyboard/evdevkeyboard.pro1
-rw-r--r--src/plugins/generic/evdevmouse/evdevmouse.pro1
-rw-r--r--src/plugins/generic/evdevtablet/evdevtablet.pro1
-rw-r--r--src/plugins/generic/evdevtouch/evdevtouch.pro1
-rw-r--r--src/plugins/generic/meego/meego.pro1
-rw-r--r--src/plugins/generic/tslib/tslib.pro1
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro1
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp2
-rw-r--r--src/plugins/platforminputcontexts/ibus/ibus.pro1
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp467
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp3
-rw-r--r--src/plugins/platforms/cocoa/messages.cpp8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm43
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm101
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm37
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm63
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamimetypes.mm67
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h17
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm33
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm93
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm5
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm40
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm3
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp19
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp46
-rw-r--r--src/plugins/platforms/windows/qplatformfunctions_wince.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp33
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp50
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h11
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
-rw-r--r--src/plugins/platformthemes/gtk2/gtk2.pro1
47 files changed, 916 insertions, 351 deletions
diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro
index 281515145f..101ea30bcc 100644
--- a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro
+++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro
@@ -1,6 +1,7 @@
TARGET = qevdevkeyboardplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevKeyboardPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro
index 9a3cc839cc..57a67ead8d 100644
--- a/src/plugins/generic/evdevmouse/evdevmouse.pro
+++ b/src/plugins/generic/evdevmouse/evdevmouse.pro
@@ -1,6 +1,7 @@
TARGET = qevdevmouseplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevMousePlugin
load(qt_plugin)
diff --git a/src/plugins/generic/evdevtablet/evdevtablet.pro b/src/plugins/generic/evdevtablet/evdevtablet.pro
index ee3fbb3ec1..8ffc0db84d 100644
--- a/src/plugins/generic/evdevtablet/evdevtablet.pro
+++ b/src/plugins/generic/evdevtablet/evdevtablet.pro
@@ -1,6 +1,7 @@
TARGET = qevdevtabletplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevTabletPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro
index 3d1c481c36..1f4d1b7e93 100644
--- a/src/plugins/generic/evdevtouch/evdevtouch.pro
+++ b/src/plugins/generic/evdevtouch/evdevtouch.pro
@@ -1,6 +1,7 @@
TARGET = qevdevtouchplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevTouchScreenPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/meego/meego.pro b/src/plugins/generic/meego/meego.pro
index c428517cd5..4baaa43a4c 100644
--- a/src/plugins/generic/meego/meego.pro
+++ b/src/plugins/generic/meego/meego.pro
@@ -1,6 +1,7 @@
TARGET = qmeegointegration
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QMeeGoIntegrationPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/tslib/tslib.pro b/src/plugins/generic/tslib/tslib.pro
index 035857bb73..bc05efcc32 100644
--- a/src/plugins/generic/tslib/tslib.pro
+++ b/src/plugins/generic/tslib/tslib.pro
@@ -1,6 +1,7 @@
TARGET = qtslibplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QTsLibPlugin
load(qt_plugin)
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index 7182c458fc..10e50a7a7e 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -1,6 +1,7 @@
TARGET = composeplatforminputcontextplugin
PLUGIN_TYPE = platforminputcontexts
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin
load(qt_plugin)
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 8bbb490022..ea0b5261c4 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -430,8 +430,10 @@ void TableGenerator::parseKeySequence(char *line)
elem.keys[i] = XKB_KEY_dead_invertedbreve;
else if (!strcmp(sym, "dead_double_grave"))
elem.keys[i] = XKB_KEY_dead_doublegrave;
+#ifdef DEBUG_GENERATOR
else
qWarning() << QString("Qt Warning - invalid keysym: %1").arg(sym);
+#endif
}
} else {
elem.keys[i] = 0;
diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro
index 75a5b5838f..401be6d42f 100644
--- a/src/plugins/platforminputcontexts/ibus/ibus.pro
+++ b/src/plugins/platforminputcontexts/ibus/ibus.pro
@@ -1,6 +1,7 @@
TARGET = ibusplatforminputcontextplugin
PLUGIN_TYPE = platforminputcontexts
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QIbusPlatformInputContextPlugin
load(qt_plugin)
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 9efdcad158..760da7a767 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -47,9 +47,7 @@
#include <QTouchEvent>
#include <QPointer>
-#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
-# include <QDebug>
-#endif
+#include <QDebug>
using namespace QtAndroid;
@@ -277,226 +275,393 @@ namespace QtAndroidInput
if (key >= 0x0000001d && key <= 0x00000036)
return Qt::Key_A + key - 0x0000001d;
+ // F1--F12 0x00000083 -- 0x0000008e
+ if (key >= 0x00000083 && key <= 0x0000008e)
+ return Qt::Key_F1 + key - 0x00000083;
+
+ // NUMPAD_0--NUMPAD_9 0x00000090 -- 0x00000099
+ if (key >= 0x00000090 && key <= 0x00000099)
+ return Qt::KeypadModifier + Qt::Key_0 + key - 0x00000090;
+
+ // BUTTON_1--KEYCODE_BUTTON_16 0x000000bc -- 0x000000cb
+
switch (key) {
- case 0x00000039:
- case 0x0000003a:
- return Qt::Key_Alt;
+ case 0x00000000: // KEYCODE_UNKNOWN
+ return Qt::Key_unknown;
+
+ case 0x00000001: // KEYCODE_SOFT_LEFT
+ return Qt::Key_Left;
+
+ case 0x00000002: // KEYCODE_SOFT_RIGHT
+ return Qt::Key_Right;
+
+ // 0x00000003: // KEYCODE_HOME is never delivered to applications.
+
+ case 0x00000004: // KEYCODE_BACK
+ return Qt::Key_Back;
+
+ case 0x00000005: // KEYCODE_CALL
+ return Qt::Key_Call;
+
+ case 0x00000006: // KEYCODE_ENDCALL
+ return Qt::Key_Hangup;
+
+ // 0--9 0x00000007 -- 0x00000010
+
+ case 0x00000011: // KEYCODE_STAR
+ return Qt::Key_Asterisk;
+
+ case 0x00000012: // KEYCODE_POUND
+ return Qt::Key_NumberSign;
+
+ case 0x00000013: //KEYCODE_DPAD_UP
+ return Qt::Key_Up;
+
+ case 0x00000014: // KEYCODE_DPAD_DOWN
+ return Qt::Key_Down;
+
+ case 0x00000015: //KEYCODE_DPAD_LEFT
+ return Qt::Key_Left;
+
+ case 0x00000016: //KEYCODE_DPAD_RIGHT
+ return Qt::Key_Right;
+
+ case 0x00000017: // KEYCODE_DPAD_CENTER
+ return Qt::Key_Enter;
+
+ case 0x00000018: // KEYCODE_VOLUME_UP
+ return Qt::Key_VolumeUp;
+
+ case 0x00000019: // KEYCODE_VOLUME_DOWN
+ return Qt::Key_VolumeDown;
+
+ case 0x0000001a:
+ return Qt::Key_PowerOff;
+
+ case 0x0000001b: // KEYCODE_CAMERA
+ return Qt::Key_Camera;
+
+ case 0x0000001c: // KEYCODE_CLEAR
+ return Qt::Key_Clear;
+
+ // A--Z 0x0000001d -- 0x00000036
+
+ case 0x00000037: // KEYCODE_COMMA
+ return Qt::Key_Comma;
+
+ case 0x00000038: // KEYCODE_PERIOD
+ return Qt::Key_Period;
+
+ case 0x00000039: // KEYCODE_ALT_LEFT
+ case 0x0000003a: // KEYCODE_ALT_RIGHT
+ return Qt::Key_Alt;
+
+ case 0x0000003b: // KEYCODE_SHIFT_LEFT
+ case 0x0000003c: // KEYCODE_SHIFT_RIGHT
+ return Qt::Key_Shift;
+
+ case 0x0000003d: // KEYCODE_TAB
+ return Qt::Key_Tab;
+
+ case 0x0000003e: // KEYCODE_SPACE
+ return Qt::Key_Space;
+
+ case 0x0000003f: // KEYCODE_SYM
+ return Qt::Key_Meta;
+
+ case 0x00000040: // KEYCODE_EXPLORER
+ return Qt::Key_Explorer;
+
+ case 0x00000041: //KEYCODE_ENVELOPE
+ return Qt::Key_LaunchMail;
+
+ case 0x00000042: // KEYCODE_ENTER
+ return Qt::Key_Return;
+
+ case 0x00000043: // KEYCODE_DEL
+ return Qt::Key_Backspace;
+
+ case 0x00000044: // KEYCODE_GRAVE
+ return Qt::Key_QuoteLeft;
+
+ case 0x00000045: // KEYCODE_MINUS
+ return Qt::Key_Minus;
+
+ case 0x00000046: // KEYCODE_EQUALS
+ return Qt::Key_Equal;
+
+ case 0x00000047: // KEYCODE_LEFT_BRACKET
+ return Qt::Key_BracketLeft;
+
+ case 0x00000048: // KEYCODE_RIGHT_BRACKET
+ return Qt::Key_BracketRight;
+
+ case 0x00000049: // KEYCODE_BACKSLASH
+ return Qt::Key_Backslash;
+
+ case 0x0000004a: // KEYCODE_SEMICOLON
+ return Qt::Key_Semicolon;
+
+ case 0x0000004b: // KEYCODE_APOSTROPHE
+ return Qt::Key_Apostrophe;
+
+ case 0x0000004c: // KEYCODE_SLASH
+ return Qt::Key_Slash;
+
+ case 0x0000004d: // KEYCODE_AT
+ return Qt::Key_At;
+
+ case 0x0000004e: // KEYCODE_NUM
+ return Qt::Key_Alt;
+
+ case 0x0000004f: // KEYCODE_HEADSETHOOK
+ return 0;
+
+ case 0x00000050: // KEYCODE_FOCUS
+ return Qt::Key_CameraFocus;
+
+ case 0x00000051: // KEYCODE_PLUS
+ return Qt::Key_Plus;
+
+ case 0x00000052: // KEYCODE_MENU
+ return Qt::Key_Menu;
+
+ case 0x00000053: // KEYCODE_NOTIFICATION
+ return 0;
- case 0x0000004b:
- return Qt::Key_Apostrophe;
+ case 0x00000054: // KEYCODE_SEARCH
+ return Qt::Key_Search;
- case 0x00000004: // KEYCODE_BACK
- return Qt::Key_Back;
+ case 0x00000055: // KEYCODE_MEDIA_PLAY_PAUSE
+ return Qt::Key_MediaPlay;
- case 0x00000049:
- return Qt::Key_Backslash;
+ case 0x00000056: // KEYCODE_MEDIA_STOP
+ return Qt::Key_MediaStop;
- case 0x00000005:
- return Qt::Key_Call;
+ case 0x00000057: // KEYCODE_MEDIA_NEXT
+ return Qt::Key_MediaNext;
- case 0x0000001b: // KEYCODE_CAMERA
- return Qt::Key_Camera;
+ case 0x00000058: // KEYCODE_MEDIA_PREVIOUS
+ return Qt::Key_MediaPrevious;
- case 0x0000001c:
- return Qt::Key_Clear;
+ case 0x00000059: // KEYCODE_MEDIA_REWIND
+ return Qt::Key_AudioRewind;
- case 0x00000037:
- return Qt::Key_Comma;
+ case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD
+ return Qt::Key_AudioForward;
- case 0x00000043: // KEYCODE_DEL
- return Qt::Key_Backspace;
+ case 0x0000005b: // KEYCODE_MUTE
+ return Qt::Key_MicMute;
- case 0x00000017: // KEYCODE_DPAD_CENTER
- return Qt::Key_Enter;
+ case 0x0000005c: // KEYCODE_PAGE_UP
+ return Qt::Key_PageUp;
- case 0x00000014: // KEYCODE_DPAD_DOWN
- return Qt::Key_Down;
+ case 0x0000005d: // KEYCODE_PAGE_DOWN
+ return Qt::Key_PageDown;
- case 0x00000015: //KEYCODE_DPAD_LEFT
- return Qt::Key_Left;
+ case 0x0000005e: // KEYCODE_PICTSYMBOLS
+ return 0;
- case 0x00000016: //KEYCODE_DPAD_RIGHT
- return Qt::Key_Right;
+ case 0x00000060: // KEYCODE_BUTTON_A
+ case 0x00000061: // KEYCODE_BUTTON_B
+ case 0x00000062: // KEYCODE_BUTTON_B
+ case 0x00000063: // KEYCODE_BUTTON_X
+ case 0x00000064: // KEYCODE_BUTTON_Y
+ case 0x00000065: // KEYCODE_BUTTON_Z
+ case 0x00000066: // KEYCODE_BUTTON_L1
+ case 0x00000067: // KEYCODE_BUTTON_R1
+ case 0x00000068: // KEYCODE_BUTTON_L2
+ case 0x00000069: // KEYCODE_BUTTON_R2
+ case 0x0000006a: // KEYCODE_BUTTON_THUMBL
+ case 0x0000006b: // KEYCODE_BUTTON_THUMBR
+ case 0x0000006c: // KEYCODE_BUTTON_START
+ case 0x0000006d: // KEYCODE_BUTTON_SELECT
+ case 0x0000006e: // KEYCODE_BUTTON_MODE
+ return 0;
- case 0x00000013: //KEYCODE_DPAD_UP
- return Qt::Key_Up;
+ case 0x0000006f: // KEYCODE_ESCAPE
+ return Qt::Key_Escape;
- case 0x00000006: //KEYCODE_ENDCALL
- return Qt::Key_Hangup;
+ case 0x00000070: // KEYCODE_FORWARD_DEL
+ return Qt::Key_Delete;
- case 0x00000042:
- return Qt::Key_Return;
+ case 0x00000071: // KEYCODE_CTRL_LEFT
+ case 0x00000072: // KEYCODE_CTRL_RIGHT
+ return Qt::Key_Control;
- case 0x00000041: //KEYCODE_ENVELOPE
- return Qt::Key_LaunchMail;
+ case 0x00000073: // KEYCODE_CAPS_LOCK
+ return Qt::Key_CapsLock;
- case 0x00000046:
- return Qt::Key_Equal;
+ case 0x00000074: // KEYCODE_SCROLL_LOCK
+ return Qt::Key_ScrollLock;
- case 0x00000040:
- return Qt::Key_Explorer;
+ case 0x00000075: // KEYCODE_META_LEFT
+ case 0x00000076: // KEYCODE_META_RIGHT
+ return Qt::Key_Meta;
- case 0x00000003:
- return Qt::Key_Home;
+ case 0x00000077: // KEYCODE_FUNCTION
+ return 0;
- case 0x00000047:
- return Qt::Key_BracketLeft;
+ case 0x00000078: // KEYCODE_SYSRQ
+ return Qt::Key_Print;
- case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD
- return Qt::Key_AudioForward;
+ case 0x00000079: // KEYCODE_BREAK
+ return Qt::Key_Pause;
- case 0x00000057:
- return Qt::Key_MediaNext;
+ case 0x0000007a: // KEYCODE_MOVE_HOME
+ return Qt::Key_Home;
- case 0x00000055:
- return Qt::Key_MediaPlay;
+ case 0x0000007b: // KEYCODE_MOVE_END
+ return Qt::Key_End;
- case 0x00000058:
- return Qt::Key_MediaPrevious;
+ case 0x0000007c: // KEYCODE_MOVE_INSERT
+ return Qt::Key_Insert;
- case 0x00000059: // KEYCODE_MEDIA_REWIND
- return Qt::Key_AudioRewind;
+ case 0x0000007d: // KEYCODE_FORWARD
+ return Qt::Key_Forward;
- case 0x00000056:
- return Qt::Key_MediaStop;
+ case 0x0000007e: // KEYCODE_MEDIA_PLAY
+ return Qt::Key_MediaPlay;
- case 0x00000052: //KEYCODE_MENU
- return Qt::Key_Menu;
+ case 0x0000007f: // KEYCODE_MEDIA_PAUSE
+ return Qt::Key_MediaPause;
- case 0x00000045:
- return Qt::Key_Minus;
+ case 0x00000080: // KEYCODE_MEDIA_CLOSE
+ case 0x00000081: // KEYCODE_MEDIA_EJECT
+ return Qt::Key_Eject;
- case 0x0000005b: // KEYCODE_MUTE
- return Qt::Key_MicMute;
+ case 0x00000082: // KEYCODE_MEDIA_RECORD
+ return Qt::Key_MediaRecord;
- case 0x0000004e:
- return Qt::Key_NumLock;
+ // F1--F12 0x00000083 -- 0x0000008e
- case 0x00000038:
- return Qt::Key_Period;
+ case 0x0000008f: // KEYCODE_NUM_LOCK
+ return Qt::Key_NumLock;
- case 0x00000051:
- return Qt::Key_Plus;
+ // NUMPAD_0--NUMPAD_9 0x00000090 -- 0x00000099
- case 0x0000001a:
- return Qt::Key_PowerOff;
+ case 0x0000009a: // KEYCODE_NUMPAD_DIVIDE
+ return Qt::KeypadModifier + Qt::Key_Slash;
- case 0x00000048:
- return Qt::Key_BracketRight;
+ case 0x0000009b: // KEYCODE_NUMPAD_MULTIPLY
+ return Qt::KeypadModifier + Qt::Key_Asterisk;
- case 0x00000054:
- return Qt::Key_Search;
+ case 0x0000009c: // KEYCODE_NUMPAD_SUBTRACT
+ return Qt::KeypadModifier + Qt::Key_Minus;
- case 0x0000004a:
- return Qt::Key_Semicolon;
+ case 0x0000009d: // KEYCODE_NUMPAD_ADD
+ return Qt::KeypadModifier + Qt::Key_Plus;
- case 0x0000003b:
- case 0x0000003c:
- return Qt::Key_Shift;
+ case 0x0000009e: // KEYCODE_NUMPAD_DOT
+ return Qt::KeypadModifier + Qt::Key_Period;
- case 0x0000004c:
- return Qt::Key_Slash;
+ case 0x0000009f: // KEYCODE_NUMPAD_COMMA
+ return Qt::KeypadModifier + Qt::Key_Comma;
- case 0x00000001:
- return Qt::Key_Left;
+ case 0x000000a0: // KEYCODE_NUMPAD_ENTER
+ return Qt::Key_Enter;
- case 0x00000002:
- return Qt::Key_Right;
+ case 0x000000a1: // KEYCODE_NUMPAD_EQUALS
+ return Qt::KeypadModifier + Qt::Key_Equal;
- case 0x0000003e:
- return Qt::Key_Space;
+ case 0x000000a2: // KEYCODE_NUMPAD_LEFT_PAREN
+ return Qt::Key_ParenLeft;
- case 0x0000003f: // KEYCODE_SYM
- return Qt::Key_Meta;
+ case 0x000000a3: // KEYCODE_NUMPAD_RIGHT_PAREN
+ return Qt::Key_ParenRight;
- case 0x0000003d:
- return Qt::Key_Tab;
+ case 0x000000a4: // KEYCODE_VOLUME_MUTE
+ return Qt::Key_VolumeMute;
- case 0x00000019:
- return Qt::Key_VolumeDown;
+ case 0x000000a5: // KEYCODE_INFO
+ return Qt::Key_Info;
- case 0x000000a4: // KEYCODE_VOLUME_MUTE
- return Qt::Key_VolumeMute;
+ case 0x000000a6: // KEYCODE_CHANNEL_UP
+ return Qt::Key_ChannelUp;
- case 0x00000018:
- return Qt::Key_VolumeUp;
+ case 0x000000a7: // KEYCODE_CHANNEL_DOWN
+ return Qt::Key_ChannelDown;
- case 0x00000011: // KEYCODE_STAR
- return Qt::Key_Asterisk;
+ case 0x000000a8: // KEYCODE_ZOOM_IN
+ return Qt::Key_ZoomIn;
- case 0x00000012: // KEYCODE_POUND
- return Qt::Key_NumberSign;
+ case 0x000000a9: // KEYCODE_ZOOM_OUT
+ return Qt::Key_ZoomOut;
- case 0x00000050: // KEYCODE_FOCUS
- return Qt::Key_CameraFocus;
+ case 0x000000aa: // KEYCODE_TV
+ case 0x000000ab: // KEYCODE_WINDOW
+ return 0;
- case 0x00000070: // KEYCODE_FORWARD_DEL
- return Qt::Key_Delete;
+ case 0x000000ac: // KEYCODE_GUIDE
+ return Qt::Key_Guide;
- case 0x00000080: // KEYCODE_MEDIA_CLOSE
- return Qt::Key_Close;
+ case 0x000000ad: // KEYCODE_DVR
+ return 0;
- case 0x00000081: // KEYCODE_MEDIA_EJECT
- return Qt::Key_Eject;
+ case 0x000000ae: // KEYCODE_BOOKMARK
+ return Qt::Key_AddFavorite;
- case 0x00000082: // KEYCODE_MEDIA_RECORD
- return Qt::Key_MediaRecord;
+ case 0x000000af: // KEYCODE_CAPTIONS
+ return Qt::Key_Subtitle;
- case 0x000000b7: // KEYCODE_PROG_RED
- return Qt::Key_Red;
+ case 0x000000b0: // KEYCODE_SETTINGS
+ return Qt::Key_Settings;
- case 0x000000b8: // KEYCODE_PROG_GREEN
- return Qt::Key_Green;
+ case 0x000000b1: // KEYCODE_TV_POWER
+ case 0x000000b2: // KEYCODE_TV_INPUT
+ case 0x000000b3: // KEYCODE_STB_POWER
+ case 0x000000b4: // KEYCODE_STB_INPUT
+ case 0x000000b5: // KEYCODE_AVR_POWER
+ case 0x000000b6: // KEYCODE_AVR_INPUT
+ return 0;
- case 0x000000b9: // KEYCODE_PROG_YELLOW
- return Qt::Key_Yellow;
+ case 0x000000b7: // KEYCODE_PROG_RED
+ return Qt::Key_Red;
- case 0x000000ba: // KEYCODE_PROG_BLUE
- return Qt::Key_Blue;
+ case 0x000000b8: // KEYCODE_PROG_GREEN
+ return Qt::Key_Green;
- case 0x000000a5: // KEYCODE_INFO
- return Qt::Key_Info;
+ case 0x000000b9: // KEYCODE_PROG_YELLOW
+ return Qt::Key_Yellow;
- case 0x000000a6: // KEYCODE_CHANNEL_UP
- return Qt::Key_ChannelUp;
+ case 0x000000ba: // KEYCODE_PROG_BLUE
+ return Qt::Key_Blue;
- case 0x000000a7: // KEYCODE_CHANNEL_DOWN
- return Qt::Key_ChannelDown;
+ // 0x000000bb: // KEYCODE_APP_SWITCH is not sent by the Android O.S.
- case 0x000000a8: // KEYCODE_ZOOM_IN
- return Qt::Key_ZoomIn;
+ // BUTTON_1--KEYCODE_BUTTON_16 0x000000bc -- 0x000000cb
- case 0x000000a9: // KEYCODE_ZOOM_OUT
- return Qt::Key_ZoomOut;
+ case 0x000000cc: // KEYCODE_LANGUAGE_SWITCH
+ case 0x000000cd: // KEYCODE_MANNER_MODE do we need such a thing?
+ case 0x000000ce: // KEYCODE_3D_MODE
+ case 0x000000cf: // KEYCODE_CONTACTS
+ return 0;
- case 0x000000ac: // KEYCODE_GUIDE
- return Qt::Key_Guide;
+ case 0x000000d0: // KEYCODE_CALENDAR
+ return Qt::Key_Calendar;
- case 0x000000af: // KEYCODE_CAPTIONS
- return Qt::Key_Subtitle;
+ case 0x000000d1: // KEYCODE_MUSIC
+ return Qt::Key_Music;
- case 0x000000b0: // KEYCODE_SETTINGS
- return Qt::Key_Settings;
+ case 0x000000d2: // KEYCODE_CALCULATOR
+ return Qt::Key_Calculator;
- case 0x000000d0: // KEYCODE_CALENDAR
- return Qt::Key_Calendar;
+ // 0x000000d3 -- 0x000000da some japanese specific keys, someone who understand what is about should check !
- case 0x000000d1: // KEYCODE_MUSIC
- return Qt::Key_Music;
+ // 0x000000db: // KEYCODE_ASSIST not delivered to applications.
- case 0x000000d2: // KEYCODE_CALCULATOR
- return Qt::Key_Calculator;
+ case 0x000000dc: // KEYCODE_BRIGHTNESS_DOWN
+ return Qt::Key_KeyboardBrightnessDown;
- case 0x00000000: // KEYCODE_UNKNOWN
- return Qt::Key_unknown;
+ case 0x000000dd: // KEYCODE_BRIGHTNESS_UP
+ return Qt::Key_KeyboardBrightnessUp;
- case 0x00000053: // KEYCODE_NOTIFICATION ?!?!?
- case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!?
- case 0x00000044: // KEYCODE_GRAVE ?!?!?
- return Qt::Key_Any;
+ case 0x000000de: // KEYCODE_MEDIA_AUDIO_TRACK
+ return Qt::Key_AudioCycleTrack;
- default:
- return 0;
+ default:
+ qWarning() << "Unhandled key code " << key << "!";
+ return 0;
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index 289480c625..152a06c99d 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -71,7 +71,8 @@ bool QAndroidPlatformOpenGLContext::needsFBOReadBackWorkaroud()
const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
needsWorkaround =
qstrcmp(rendererString, "Mali-400 MP") == 0
- || qstrcmp(rendererString, "Adreno (TM) 200") == 0;
+ || qstrcmp(rendererString, "Adreno (TM) 200") == 0
+ || qstrcmp(rendererString, "GC1000 core") == 0;
set = true;
}
diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp
index 1fe80b28b1..8fc8b312f5 100644
--- a/src/plugins/platforms/cocoa/messages.cpp
+++ b/src/plugins/platforms/cocoa/messages.cpp
@@ -90,6 +90,14 @@ QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption)
|| caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Exit"), Qt::CaseInsensitive)) {
return QPlatformMenuItem::QuitRole;
}
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Cut"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::CutRole;
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Copy"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::CopyRole;
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Paste"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::PasteRole;
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Select All"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::SelectAllRole;
return QPlatformMenuItem::NoRole;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index 86bb5323a7..a78901bfb1 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -79,7 +79,7 @@ namespace QCocoaAccessible {
NSString *macRole(QAccessibleInterface *interface);
bool shouldBeIgnored(QAccessibleInterface *interface);
-NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface);
+NSArray *unignoredChildren(QAccessibleInterface *interface);
NSString *getTranslatedAction(const QString &qtAction);
NSMutableArray *createTranslatedActionsList(const QStringList &qtActions);
QString translateAction(NSString *nsAction);
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 990acd5301..72045a1bbb 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -55,19 +55,31 @@ QCocoaAccessibility::~QCocoaAccessibility()
void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
- QAccessible::Id interfaceId = event->uniqueId();
- if (!interfaceId)
+ QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: event->uniqueId()];
+ if (!element) {
+ qWarning() << "QCocoaAccessibility::notifyAccessibilityUpdate: invalid element";
return;
+ }
switch (event->type()) {
- case QAccessible::ValueChanged:
- case QAccessible::TextInserted :
- case QAccessible::TextRemoved :
- case QAccessible::TextUpdated : {
- QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId : interfaceId parent : nil];
- [element autorelease];
- NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification);
- break; }
+ case QAccessible::Focus: {
+ NSAccessibilityPostNotification(element, NSAccessibilityFocusedUIElementChangedNotification);
+ break;
+ }
+ case QAccessible::StateChanged:
+ case QAccessible::ValueChanged:
+ case QAccessible::TextInserted:
+ case QAccessible::TextRemoved:
+ case QAccessible::TextUpdated:
+ NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification);
+ break;
+ case QAccessible::TextCaretMoved:
+ case QAccessible::TextSelectionChanged:
+ NSAccessibilityPostNotification(element, NSAccessibilitySelectedTextChangedNotification);
+ break;
+ case QAccessible::NameChanged:
+ NSAccessibilityPostNotification(element, NSAccessibilityTitleChangedNotification);
+ break;
default:
break;
}
@@ -218,7 +230,7 @@ bool shouldBeIgnored(QAccessibleInterface *interface)
return false;
}
-NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface)
+NSArray *unignoredChildren(QAccessibleInterface *interface)
{
int numKids = interface->childCount();
// qDebug() << "Children for: " << axid << iface << " are: " << numKids;
@@ -231,9 +243,12 @@ NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface)
QAccessible::Id childId = QAccessible::uniqueId(child);
//qDebug() << " kid: " << childId << child;
- QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId:childId parent:parentObject];
- [kids addObject: element];
- [element release];
+
+ QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: childId];
+ if (element)
+ [kids addObject: element];
+ else
+ qWarning() << "QCocoaAccessibility: invalid child";
}
return NSAccessibilityUnignoredChildren(kids);
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
index c207cbee2d..babaab5ae2 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
@@ -52,12 +52,11 @@
@interface QCocoaAccessibleElement : NSObject {
NSString *role;
- NSObject *parent;
QAccessible::Id axid;
}
-- (id)initWithId:(QAccessible::Id)anId parent:(id)aParent;
-+ (QCocoaAccessibleElement *)createElementWithId:(QAccessible::Id)anId parent:(id)aParent;
+- (id)initWithId:(QAccessible::Id)anId;
++ (QCocoaAccessibleElement *)elementWithId:(QAccessible::Id)anId;
@end
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 0b674b8d2f..1df4230385 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -41,6 +41,8 @@
#include "qcocoaaccessibilityelement.h"
#include "qcocoaaccessibility.h"
#include "qcocoahelpers.h"
+#include "qcocoawindow.h"
+#include "private/qaccessiblecache_p.h"
#include <QtGui/qaccessible.h>
@@ -48,7 +50,7 @@
@implementation QCocoaAccessibleElement
-- (id)initWithId:(QAccessible::Id)anId parent:(id)aParent
+- (id)initWithId:(QAccessible::Id)anId
{
Q_ASSERT((int)anId < 0);
self = [super init];
@@ -57,15 +59,35 @@
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
Q_ASSERT(iface);
role = QCocoaAccessible::macRole(iface);
- parent = aParent;
}
return self;
}
-+ (QCocoaAccessibleElement *)createElementWithId:(QAccessible::Id)anId parent:(id)aParent
++ (id)elementWithId:(QAccessible::Id)anId
{
- return [[self alloc] initWithId:anId parent:aParent];
+ Q_ASSERT(anId);
+ if (!anId)
+ return nil;
+
+ QAccessibleCache *cache = QAccessibleCache::instance();
+
+ QCocoaAccessibleElement *element = cache->elementForId(anId);
+ if (!element) {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(anId);
+ Q_ASSERT(iface);
+ if (!iface)
+ return nil;
+ element = [[self alloc] initWithId:anId];
+ cache->insertElement(anId, element);
+ }
+ return element;
+}
+
+- (void)invalidate {
+ axid = 0;
+ NSAccessibilityPostNotification(self, NSAccessibilityUIElementDestroyedNotification);
+ [self release];
}
- (void)dealloc {
@@ -98,6 +120,10 @@
return [NSNumber numberWithInt: newlines];
}
+- (BOOL) accessibilityNotifiesWhenDestroyed {
+ return YES;
+}
+
- (NSArray *)accessibilityAttributeNames {
static NSArray *defaultAttributes = nil;
@@ -116,6 +142,7 @@
NSAccessibilityTopLevelUIElementAttribute,
NSAccessibilityPositionAttribute,
NSAccessibilitySizeAttribute,
+ NSAccessibilityTitleAttribute,
NSAccessibilityDescriptionAttribute,
NSAccessibilityEnabledAttribute,
nil];
@@ -144,6 +171,26 @@
return [attributes autorelease];
}
+- (id)parentElement {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface)
+ return nil;
+
+ if (QWindow *window = iface->window()) {
+ QCocoaWindow *win = static_cast<QCocoaWindow*>(window->handle());
+ return win->qtView();
+ }
+
+ QAccessibleInterface *parent = iface->parent();
+ if (!parent) {
+ qWarning() << "INVALID PARENT FOR INTERFACE: " << iface;
+ return nil;
+ }
+
+ QAccessible::Id parentId = QAccessible::uniqueId(parent);
+ return [QCocoaAccessibleElement elementWithId: parentId];
+}
+
- (id)accessibilityAttributeValue:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) {
@@ -156,19 +203,19 @@
} else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
return NSAccessibilityRoleDescription(role, nil);
} else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
- return QCocoaAccessible::unignoredChildren(self, iface);
+ return QCocoaAccessible::unignoredChildren(iface);
} else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
// Just check if the app thinks we're focused.
id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute];
return [NSNumber numberWithBool:[focusedElement isEqual:self]];
} else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) {
- return NSAccessibilityUnignoredAncestor(parent);
+ return NSAccessibilityUnignoredAncestor([self parentElement]);
} else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) {
// We're in the same window as our parent.
- return [parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+ return [[self parentElement] accessibilityAttributeValue:NSAccessibilityWindowAttribute];
} else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) {
// We're in the same top level element as our parent.
- return [parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+ return [[self parentElement] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
} else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
QPoint qtPosition = iface->rect().topLeft();
QSize qtSize = iface->rect().size();
@@ -176,8 +223,10 @@
} else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
QSize qtSize = iface->rect().size();
return [NSValue valueWithSize: NSMakeSize(qtSize.width(), qtSize.height())];
- } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
+ } else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) {
return QCFString::toNSString(iface->text(QAccessible::Name));
+ } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
+ return QCFString::toNSString(iface->text(QAccessible::Description));
} else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) {
return [NSNumber numberWithBool:!iface->state().disabled];
} else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
@@ -400,20 +449,26 @@
return NSAccessibilityUnignoredAncestor(self);
}
- QAccessibleInterface *childInterface = iface->childAt(point.x, qt_mac_flipYCoordinate(point.y));
-
+ int y = qt_mac_flipYCoordinate(point.y);
+ QAccessibleInterface *childInterface = iface->childAt(point.x, y);
// No child found, meaning we hit this element.
- if (!childInterface) {
-// qDebug() << "Hit test returns: " << id << iface;
+ if (!childInterface)
return NSAccessibilityUnignoredAncestor(self);
- }
+
+ // find the deepest child at the point
+ QAccessibleInterface *childOfChildInterface = 0;
+ do {
+ childOfChildInterface = childInterface->childAt(point.x, y);
+ if (childOfChildInterface)
+ childInterface = childOfChildInterface;
+ } while (childOfChildInterface);
QAccessible::Id childId = QAccessible::uniqueId(childInterface);
// hit a child, forward to child accessible interface.
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childId parent:self];
- [accessibleElement autorelease];
-
- return [accessibleElement accessibilityHitTest:point];
+ QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childId];
+ if (accessibleElement)
+ return NSAccessibilityUnignoredAncestor(accessibleElement);
+ return NSAccessibilityUnignoredAncestor(self);
}
- (id)accessibilityFocusedUIElement {
@@ -423,17 +478,15 @@
qWarning() << "FocusedUIElement for INVALID";
return nil;
}
+
QAccessibleInterface *childInterface = iface->focusChild();
if (childInterface) {
QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
- // FIXME: parent could be wrong
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self];
- [accessibleElement autorelease];
- return accessibleElement;
+ QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childAxid];
+ return NSAccessibilityUnignoredAncestor(accessibleElement);
}
- // no focus found
- return nil;
+ return NSAccessibilityUnignoredAncestor(self);
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index 592bfc8e50..b81b9a0b1c 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -308,8 +308,7 @@ NSCursor *QCocoaCursor::createCursorFromBitmap(const QBitmap *bitmap, const QBit
NSCursor *QCocoaCursor::createCursorFromPixmap(const QPixmap pixmap, const QPoint hotspot)
{
- NSPoint hotSpot = NSMakePoint(hotspot.x() / pixmap.devicePixelRatio(),
- hotspot.y() / pixmap.devicePixelRatio());
+ NSPoint hotSpot = NSMakePoint(hotspot.x(), hotspot.y());
NSImage *nsimage;
if (pixmap.devicePixelRatio() > 1.0) {
QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio();
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 8728ab8764..2b7b8109ad 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -52,6 +52,7 @@
#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include "qcocoahelpers.h"
+#include "qcocoamenubar.h"
#include <qregexp.h>
#include <qbuffer.h>
#include <qdebug.h>
@@ -225,6 +226,7 @@ static QString strippedText(QString s)
|| [self panel:nil shouldShowFilename:filepath];
[self updateProperties];
+ QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mOpenPanel setAllowedFileTypes:nil];
[mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
@@ -250,7 +252,9 @@ static QString strippedText(QString s)
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
+ QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
mReturnCode = [mSavePanel runModal];
+ QCocoaMenuBar::resetKnownMenuItemsToQt();
QAbstractEventDispatcher::instance()->interrupt();
return (mReturnCode == NSOKButton);
@@ -269,6 +273,7 @@ static QString strippedText(QString s)
|| [self panel:nil shouldShowFilename:filepath];
[self updateProperties];
+ QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
[mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""];
@@ -583,6 +588,7 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_selectionChanged(const QSt
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
{
+ QCocoaMenuBar::resetKnownMenuItemsToQt();
if (accepted) {
emit accept();
} else {
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index a73944c07c..9850f83dea 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -74,7 +74,7 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
{
NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
for (int i=0; i<list.size(); ++i){
- [result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))];
+ [result addObject:list[i].toNSString()];
}
return result;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 24adc7a95b..9c4f86d893 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -80,6 +80,7 @@ public:
qreal refreshRate() const { return m_refreshRate; }
QString name() const { return m_name; }
QPlatformCursor *cursor() const { return m_cursor; }
+ QWindow *topLevelAt(const QPoint &point) const;
QList<QPlatformScreen *> virtualSiblings() const { return m_siblings; }
// ----------------------------------------------------
@@ -138,6 +139,8 @@ public:
void setToolbar(QWindow *window, NSToolbar *toolbar);
NSToolbar *toolbar(QWindow *window) const;
void clearToolbars();
+ void setWindow(NSWindow* nsWindow, QCocoaWindow *window);
+ QCocoaWindow *window(NSWindow *window);
private:
static QCocoaIntegration *mInstance;
@@ -156,6 +159,7 @@ private:
QScopedPointer<QCocoaKeyMapper> mKeyboardMapper;
QHash<QWindow *, NSToolbar *> mToolbars;
+ QHash<NSWindow *, QCocoaWindow*> mWindows;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 412818ae47..c4398622e8 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -81,12 +81,16 @@ QCocoaScreen::~QCocoaScreen()
NSScreen *QCocoaScreen::osScreen() const
{
- return [[NSScreen screens] objectAtIndex:m_screenIndex];
+ NSArray *screens = [NSScreen screens];
+ return ((NSUInteger)m_screenIndex < [screens count]) ? [screens objectAtIndex:m_screenIndex] : nil;
}
void QCocoaScreen::updateGeometry()
{
NSScreen *nsScreen = osScreen();
+ if (!nsScreen)
+ return;
+
NSRect frameRect = [nsScreen frame];
if (m_screenIndex == 0) {
@@ -143,7 +147,8 @@ qreal QCocoaScreen::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- return qreal([osScreen() backingScaleFactor]);
+ NSScreen * screen = osScreen();
+ return qreal(screen ? [screen backingScaleFactor] : 1.0);
} else
#endif
{
@@ -151,6 +156,24 @@ qreal QCocoaScreen::devicePixelRatio() const
}
}
+QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
+{
+ // Get a z-ordered list of windows. Iterate through it until
+ // we find a window which contains the point.
+ for (NSWindow *nsWindow in [NSApp orderedWindows]) {
+ QCocoaWindow *cocoaWindow = QCocoaIntegration::instance()->window(nsWindow);
+ if (!cocoaWindow)
+ continue;
+ QWindow *window = cocoaWindow->window();
+ if (!window->isTopLevel())
+ continue;
+ if (window->geometry().contains(point))
+ return window;
+ }
+
+ return QPlatformScreen::topLevelAt(point);
+}
+
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const
@@ -495,6 +518,16 @@ NSToolbar *QCocoaIntegration::toolbar(QWindow *window) const
return mToolbars.value(window);
}
+void QCocoaIntegration::setWindow(NSWindow* nsWindow, QCocoaWindow *window)
+{
+ mWindows.insert(nsWindow, window);
+}
+
+QCocoaWindow *QCocoaIntegration::window(NSWindow *window)
+{
+ return mWindows.value(window);
+}
+
void QCocoaIntegration::clearToolbars()
{
QHash<QWindow *, NSToolbar *>::const_iterator it = mToolbars.constBegin();
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 35e8fdebb4..6acc062eb9 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -269,7 +269,6 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before);
- SET_COCOA_MENU_ANCESTOR(menuItem, this);
cocoaItem->sync();
if (beforeItem) {
int index = m_menuItems.indexOf(beforeItem);
@@ -315,6 +314,7 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
} else {
[m_nativeMenu addItem: item->nsItem()];
}
+ SET_COCOA_MENU_ANCESTOR(item, this);
}
void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index 7a1bda74a4..fa02a7870b 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -67,9 +67,13 @@ public:
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
+ static void redirectKnownMenuItemsToFirstResponder();
+ static void resetKnownMenuItemsToQt();
static void updateMenuBarImmediately();
QList<QCocoaMenuItem*> merged() const;
+ NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r);
+
private:
static QCocoaWindow *findWindowForMenubar();
static QCocoaMenuBar *findGlobalMenubar();
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 7335deb800..ffc0fabdce 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -205,6 +205,59 @@ QCocoaMenuBar *QCocoaMenuBar::findGlobalMenubar()
return NULL;
}
+void QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder()
+{
+ // QTBUG-17291: http://forums.macrumors.com/showthread.php?t=1249452
+ // When a dialog is opened, shortcuts for actions inside the dialog (cut, paste, ...)
+ // continue to go through the same menu items which claimed those shortcuts.
+ // They are not keystrokes which we can intercept in any other way; the OS intercepts them.
+ // The menu items had to be created by the application. That's why we need roles
+ // to identify those "special" menu items which can be useful even when non-Qt
+ // native widgets are in focus. When the native widget is focused it will be the
+ // first responder, so the menu item needs to have its target be the first responder;
+ // this is done by setting it to nil.
+
+ // This function will find all menu items on all menus which have
+ // "special" roles, set the target and also set the standard actions which
+ // apply to those roles. But afterwards it is necessary to call
+ // resetKnownMenuItemsToQt() to put back the target and action so that
+ // those menu items will go back to invoking their associated QActions.
+ foreach (QCocoaMenuBar *mb, static_menubars)
+ foreach (QCocoaMenu *m, mb->m_menus)
+ foreach (QCocoaMenuItem *i, m->items()) {
+ bool known = true;
+ switch (i->effectiveRole()) {
+ case QPlatformMenuItem::CutRole:
+ [i->nsItem() setAction:@selector(cut:)];
+ break;
+ case QPlatformMenuItem::CopyRole:
+ [i->nsItem() setAction:@selector(copy:)];
+ break;
+ case QPlatformMenuItem::PasteRole:
+ [i->nsItem() setAction:@selector(paste:)];
+ break;
+ case QPlatformMenuItem::SelectAllRole:
+ [i->nsItem() setAction:@selector(selectAll:)];
+ break;
+ // We may discover later that there are other roles/actions which
+ // are meaningful to standard native widgets; they can be added.
+ default:
+ known = false;
+ break;
+ }
+ if (known)
+ [i->nsItem() setTarget:nil];
+ }
+}
+
+void QCocoaMenuBar::resetKnownMenuItemsToQt()
+{
+ // Undo the effect of redirectKnownMenuItemsToFirstResponder():
+ // set the menu items' actions to itemFired and their targets to
+ // the QCocoaMenuDelegate.
+ updateMenuBarImmediately();
+}
+
void QCocoaMenuBar::updateMenuBarImmediately()
{
QCocoaAutoReleasePool pool;
@@ -321,3 +374,13 @@ QPlatformMenu *QCocoaMenuBar::menuForTag(quintptr tag) const
return 0;
}
+
+NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r)
+{
+ foreach (QCocoaMenu *m, m_menus)
+ foreach (QCocoaMenuItem *i, m->items())
+ if (i->effectiveRole() == r)
+ return i->nsItem();
+ return Q_NULLPTR;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index b0169b9746..61706c19bc 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -98,6 +98,8 @@ public:
inline bool isSeparator() const { return m_isSeparator; }
QCocoaMenu *menu() const { return m_menu; }
+ MenuRole effectiveRole() const;
+
private:
QString mergeText();
QKeySequence mergeAccel();
@@ -112,6 +114,7 @@ private:
bool m_isSeparator;
QFont m_font;
MenuRole m_role;
+ MenuRole m_detectedRole;
QKeySequence m_shortcut;
bool m_checked;
bool m_merged;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 2246d2ce46..58fe07bc62 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -227,7 +227,8 @@ NSMenuItem *QCocoaMenuItem::sync()
if (depth == 3 || !menubar)
break; // Menu item too deep in the hierarchy, or not connected to any menubar
- switch (detectMenuRole(m_text)) {
+ m_detectedRole = detectMenuRole(m_text);
+ switch (m_detectedRole) {
case QPlatformMenuItem::AboutRole:
if (m_text.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1)
mergeItem = [loader aboutMenuItem];
@@ -241,6 +242,8 @@ NSMenuItem *QCocoaMenuItem::sync()
mergeItem = [loader quitMenuItem];
break;
default:
+ if (m_detectedRole >= CutRole && m_detectedRole < RoleCount && menubar)
+ mergeItem = menubar->itemForRole(m_detectedRole);
if (!m_text.isEmpty())
m_textSynced = true;
break;
@@ -249,7 +252,7 @@ NSMenuItem *QCocoaMenuItem::sync()
}
default:
- qWarning() << Q_FUNC_INFO << "unsupported role" << (int) m_role;
+ qWarning() << Q_FUNC_INFO << "menu item" << m_text << "has unsupported role" << (int)m_role;
}
if (mergeItem) {
@@ -374,3 +377,11 @@ void QCocoaMenuItem::syncModalState(bool modal)
else
[m_native setEnabled:m_enabled];
}
+
+QPlatformMenuItem::MenuRole QCocoaMenuItem::effectiveRole() const
+{
+ if (m_role > TextHeuristicRole)
+ return m_role;
+ else
+ return m_detectedRole;
+}
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 29fc0fb674..60bc3b5a55 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -115,14 +115,13 @@ QT_END_NAMESPACE
showAllItem = [[appMenu itemWithTitle:@"Show All"] retain];
// Get the names in the nib to match the app name set by Qt.
- const NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qt_mac_applicationName()));
+ const NSString *appName = qt_mac_applicationName().toNSString();
[quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
withString:const_cast<NSString *>(appName)]];
[hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
withString:const_cast<NSString *>(appName)]];
[aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
withString:const_cast<NSString *>(appName)]];
- [appName release];
// Disable the items that don't do anything. If someone associates a QAction with them
// They should get synced back in.
[preferencesItem setEnabled:NO];
diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
index 05d4c19112..8151d31449 100644
--- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm
+++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
@@ -136,9 +136,76 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q
return ret;
}
+// This handler is special: It supports converting public.rtf top text/html,
+// but not the other way around.
+class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime {
+public:
+ QMacPasteboardMimeRtfText() : QMacInternalPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeRtfText::convertorName()
+{
+ return QLatin1String("Rtf");
+}
+
+QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime)
+{
+ if (mime == QLatin1String("text/html"))
+ return QLatin1String("public.rtf");
+ return QString();
+}
+
+QString QMacPasteboardMimeRtfText::mimeFor(QString flav)
+{
+ if (flav == QLatin1String("public.rtf"))
+ return QLatin1String("text/html");
+ return QString();
+}
+
+bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav)
+{
+ return flavorFor(mime) == flav;
+}
+
+QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor)
+{
+ if (!canConvert(mimeType, flavor))
+ return QVariant();
+ if (data.count() > 1)
+ qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data");
+
+ // Convert Rtf to Html.
+ NSAttributedString *string = [[NSAttributedString alloc] initWithRTF:data.at(0).toNSData() documentAttributes:NULL];
+ NSError *error;
+ NSRange range = NSMakeRange(0,[string length]);
+ NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
+ NSData *htmldata = [string dataFromRange:range documentAttributes:dict error:&error];
+ [string release];
+ return QByteArray::fromNSData(htmldata);
+}
+
+QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor)
+{
+ Q_UNUSED(mime);
+ Q_UNUSED(data);
+ Q_UNUSED(flavor);
+
+ qWarning("QMacPasteboardMimeRtfText: Conversion from Html to Rtf is not supported");
+ QList<QByteArray> ret;
+ return ret;
+}
+
void QCocoaMimeTypes::initializeMimeTypes()
{
new QMacPasteboardMimeTiff;
+ new QMacPasteboardMimeRtfText;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index efdd433d8f..54e45a1d99 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -133,16 +133,23 @@ private:
// deregisters.
static void registerTouchWindow(QWindow *window, bool enable);
- // Request a unified title and toolbar look for the window.
+ // Enable the unified title and toolbar area for a window.
+ static void setContentBorderEnabled(QWindow *window, bool enable);
+
+ // Set the size of the unified title and toolbar area.
static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness);
- // Request a unified title and toolbar look for the window by registering
- // an area. Multiple callers can register areas and the platform plugin
+ // Set the size for a unified toolbar content border area.
+ // Multiple callers can register areas and the platform plugin
// will extend the "unified" area to cover them.
static void registerContentBorderArea(QWindow *window, quintptr identifer, int upper, int lower);
- // Enable the unified title and toolbar area.
- static void enableContentBorderArea(QWindow *window, bool enable);
+ // Enables or disiables a content border area.
+ static void setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable);
+
+ // Returns true if the given coordinate is inside the current
+ // content border.
+ static bool testContentBorderPosition(QWindow *window, int position);
// Sets a NSToolbar instance for the given QWindow. The
// toolbar will be attached to the native NSWindow when
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index d6a5be8d52..e09c31231d 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -127,10 +127,14 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness);
if (resource.toLower() == "registercontentborderarea")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerContentBorderArea);
- if (resource.toLower() == "enablecontentborderarea")
- return NativeResourceForIntegrationFunction(QCocoaNativeInterface::enableContentBorderArea);
+ if (resource.toLower() == "setcontentborderareaenabled")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderAreaEnabled);
+ if (resource.toLower() == "setcontentborderenabled")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderEnabled);
if (resource.toLower() == "setnstoolbar")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar);
+ if (resource.toLower() == "testcontentborderposition")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::testContentBorderPosition);
return 0;
}
@@ -301,14 +305,24 @@ void QCocoaNativeInterface::registerContentBorderArea(QWindow *window, quintptr
cocoaWindow->registerContentBorderArea(identifier, upper, lower);
}
-void QCocoaNativeInterface::enableContentBorderArea(QWindow *window, bool enable)
+void QCocoaNativeInterface::setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable)
{
if (!window)
return;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
if (cocoaWindow)
- cocoaWindow->enableContentBorderArea(enable);
+ cocoaWindow->setContentBorderAreaEnabled(identifier, enable);
+}
+
+void QCocoaNativeInterface::setContentBorderEnabled(QWindow *window, bool enable)
+{
+ if (!window)
+ return;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->setContentBorderEnabled(enable);
}
void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
@@ -320,4 +334,15 @@ void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
cocoaWindow->updateNSToolbar();
}
+bool QCocoaNativeInterface::testContentBorderPosition(QWindow *window, int position)
+{
+ if (!window)
+ return false;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ return cocoaWindow->testContentBorderAreaPosition(position);
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
index 3061e84470..57d5c800e0 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
@@ -171,15 +171,18 @@ QPrint::DeviceState QCocoaPrintDevice::state() const
QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const
{
- QCFString key;
+ CFStringRef key;
double width;
double height;
- QCFString localizedName;
+ CFStringRef localizedName;
if (PMPaperGetPPDPaperName(paper, &key) == noErr
&& PMPaperGetWidth(paper, &width) == noErr
&& PMPaperGetHeight(paper, &height) == noErr
&& PMPaperCreateLocalizedName(paper, m_printer, &localizedName) == noErr) {
- return(QPlatformPrintDevice::createPageSize(key, QSize(width, height), localizedName));
+ QPageSize pageSize = QPlatformPrintDevice::createPageSize(QString::fromCFString(key),QSize(width, height),
+ QString::fromCFString(localizedName));
+ CFRelease(localizedName);
+ return pageSize;
}
return QPageSize();
}
@@ -216,10 +219,11 @@ QPageSize QCocoaPrintDevice::defaultPageSize() const
QPageSize pageSize;
PMPageFormat pageFormat;
PMPaper paper;
- if (PMCreatePageFormat(&pageFormat) == noErr
- && PMSessionDefaultPageFormat(m_session, pageFormat) == noErr
- && PMGetPageFormatPaper(pageFormat, &paper) == noErr) {
- pageSize = createPageSize(paper);
+ if (PMCreatePageFormat(&pageFormat) == noErr) {
+ if (PMSessionDefaultPageFormat(m_session, pageFormat) == noErr
+ && PMGetPageFormatPaper(pageFormat, &paper) == noErr) {
+ pageSize = createPageSize(paper);
+ }
PMRelease(pageFormat);
}
return pageSize;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index b7a6a14d4a..bb5c0c1974 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -211,7 +211,9 @@ public:
void registerTouch(bool enable);
void setContentBorderThickness(int topThickness, int bottomThickness);
void registerContentBorderArea(quintptr identifier, int upper, int lower);
- void enableContentBorderArea(bool enable);
+ void setContentBorderAreaEnabled(quintptr identifier, bool enable);
+ void setContentBorderEnabled(bool enable);
+ bool testContentBorderAreaPosition(int position) const;
void applyContentBorderThickness(NSWindow *window);
void updateNSToolbar();
@@ -270,6 +272,7 @@ public: // for QNSView
bool m_geometryUpdateExposeAllowed;
bool m_isExposed;
QRect m_exposedGeometry;
+ qreal m_exposedDevicePixelRatio;
int m_registerTouchCount;
bool m_resizableTransientParent;
bool m_hiddenByClipping;
@@ -289,7 +292,8 @@ public: // for QNSView
NSApplicationPresentationOptions m_presentationOptions;
struct BorderRange {
- BorderRange(int u, int l) : upper(u), lower(l) { }
+ BorderRange(quintptr i, int u, int l) : identifier(i), upper(u), lower(l) { }
+ quintptr identifier;
int upper;
int lower;
bool operator<(BorderRange const& right) const {
@@ -297,6 +301,7 @@ public: // for QNSView
}
};
QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
+ QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index b27e1b03db..5def64ee0a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -261,6 +261,8 @@ static bool isMouseEvent(NSEvent *ev)
{
[self close];
+ QCocoaIntegration::instance()->setWindow(self, 0);
+
if (self.helper.grabbingMouse) {
self.helper.releaseOnMouseUp = YES;
} else {
@@ -327,6 +329,7 @@ static bool isMouseEvent(NSEvent *ev)
{
[self.helper detachFromPlatformWindow];
[self close];
+ QCocoaIntegration::instance()->setWindow(self, 0);
[self release];
}
@@ -619,11 +622,13 @@ void QCocoaWindow::setVisible(bool visible)
// update the window geometry if there is a parent.
setGeometry(window()->geometry());
- // Register popup windows so that the parent window can
- // close them when needed.
- if (window()->type() == Qt::Popup) {
+ // Register popup windows so that the parent window can close them when needed.
+ if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) {
// qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup);
parentCocoaWindow->m_activePopupWindow = window();
+ }
+
+ if (window()->type() == Qt::Popup) {
// QTBUG-30266: a window should not be resizable while a transient popup is open
// Since this isn't a native popup, the window manager doesn't close the popup when you click outside
NSUInteger parentStyleMask = [parentCocoaWindow->m_nsWindow styleMask];
@@ -1210,11 +1215,18 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
{
bool wasNSWindowChild = m_isNSWindowChild;
- // TODO Set value for m_isNSWindowChild here
+ m_isNSWindowChild = parentWindow && (window()->property("_q_platform_MacUseNSWindow").toBool());
bool needsNSWindow = m_isNSWindowChild || !parentWindow;
QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow;
m_parentCocoaWindow = const_cast<QCocoaWindow *>(static_cast<const QCocoaWindow *>(parentWindow));
+ if (m_parentCocoaWindow && m_isNSWindowChild) {
+ QWindow *parentQWindow = m_parentCocoaWindow->window();
+ if (!parentQWindow->property("_q_platform_MacUseNSWindow").toBool()) {
+ parentQWindow->setProperty("_q_platform_MacUseNSWindow", QVariant(true));
+ m_parentCocoaWindow->recreateWindow(m_parentCocoaWindow->m_parentCocoaWindow);
+ }
+ }
bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
@@ -1400,6 +1412,8 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
applyContentBorderThickness(createdWindow);
+ QCocoaIntegration::instance()->setWindow(createdWindow, this);
+
return createdWindow;
}
@@ -1466,7 +1480,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) {
if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) {
- [m_nsWindow performZoom : m_nsWindow]; // toggles
+ [m_nsWindow zoom : m_nsWindow]; // toggles
m_effectivelyMaximized = !m_effectivelyMaximized;
} else if (!(newState & Qt::WindowMaximized)) {
// it would be nice to change the target geometry that toggleFullScreen will animate toward
@@ -1582,28 +1596,17 @@ void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickne
void QCocoaWindow::registerContentBorderArea(quintptr identifier, int upper, int lower)
{
- m_contentBorderAreas.insert(identifier, BorderRange(upper, lower));
-
- // Find consecutive registered border areas, starting from the top.
- QList<BorderRange> ranges = m_contentBorderAreas.values();
- std::sort(ranges.begin(), ranges.end());
- m_topContentBorderThickness = 0;
- foreach (BorderRange range, ranges) {
- // Is this sub-range adjacent to or overlaping the
- // existing total border area range? If so merge
- // it into the total range,
- if (range.upper <= (m_topContentBorderThickness + 1))
- m_topContentBorderThickness = qMax(m_topContentBorderThickness, range.lower);
- else
- break;
- }
+ m_contentBorderAreas.insert(identifier, BorderRange(identifier, upper, lower));
+ applyContentBorderThickness(m_nsWindow);
+}
- m_bottomContentBorderThickness = 0; // (not supported)
- if (m_drawContentBorderGradient)
- applyContentBorderThickness(m_nsWindow);
+void QCocoaWindow::setContentBorderAreaEnabled(quintptr identifier, bool enable)
+{
+ m_enabledContentBorderAreas.insert(identifier, enable);
+ applyContentBorderThickness(m_nsWindow);
}
-void QCocoaWindow::enableContentBorderArea(bool enable)
+void QCocoaWindow::setContentBorderEnabled(bool enable)
{
m_drawContentBorderGradient = enable;
applyContentBorderThickness(m_nsWindow);
@@ -1619,17 +1622,33 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
return;
}
- [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
+ // Find consecutive registered border areas, starting from the top.
+ QList<BorderRange> ranges = m_contentBorderAreas.values();
+ std::sort(ranges.begin(), ranges.end());
+ int effectiveTopContentBorderThickness = m_topContentBorderThickness;
+ foreach (BorderRange range, ranges) {
+ // Skip disiabled ranges (typically hidden tool bars)
+ if (!m_enabledContentBorderAreas.value(range.identifier, false))
+ continue;
- if (m_topContentBorderThickness > 0) {
- [window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMaxYEdge];
- [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
+ // Is this sub-range adjacent to or overlaping the
+ // existing total border area range? If so merge
+ // it into the total range,
+ if (range.upper <= (effectiveTopContentBorderThickness + 1))
+ effectiveTopContentBorderThickness = qMax(effectiveTopContentBorderThickness, range.lower);
+ else
+ break;
}
- if (m_bottomContentBorderThickness > 0) {
- [window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMinYEdge];
- [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
- }
+ int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness;
+
+ [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
+
+ [window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge];
+ [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
+
+ [window setContentBorderThickness:effectiveBottomContentBorderThickness forEdge:NSMinYEdge];
+ [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
}
void QCocoaWindow::updateNSToolbar()
@@ -1646,6 +1665,12 @@ void QCocoaWindow::updateNSToolbar()
[m_nsWindow setShowsToolbarButton:YES];
}
+bool QCocoaWindow::testContentBorderAreaPosition(int position) const
+{
+ return m_nsWindow && m_drawContentBorderGradient &&
+ 0 <= position && position < [m_nsWindow contentBorderThicknessForEdge: NSMaxYEdge];
+}
+
qreal QCocoaWindow::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
@@ -1685,6 +1710,7 @@ void QCocoaWindow::exposeWindow()
if (!m_isExposed) {
m_isExposed = true;
m_exposedGeometry = geometry();
+ m_exposedDevicePixelRatio = devicePixelRatio();
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
}
@@ -1710,11 +1736,12 @@ void QCocoaWindow::updateExposedGeometry()
if (!isWindowExposable())
return;
- if (m_exposedGeometry == geometry())
+ if (m_exposedGeometry == geometry() && m_exposedDevicePixelRatio == devicePixelRatio())
return;
m_isExposed = true;
m_exposedGeometry = geometry();
+ m_exposedDevicePixelRatio = devicePixelRatio();
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index 9368b65866..6549f127b6 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -305,6 +305,11 @@ QMacPasteboard::setMimeData(QMimeData *mime_src)
QString mimeType = formats.at(f);
for (QList<QMacInternalPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) {
QMacInternalPasteboardMime *c = (*it);
+ // Hack: The Rtf handler converts incoming Rtf to Html. We do
+ // not want to convert outgoing Html to Rtf but instead keep
+ // posting it as Html. Skip the Rtf handler here.
+ if (c->convertorName() == QStringLiteral("Rtf"))
+ continue;
QString flavor(c->flavorFor(mimeType));
if (!flavor.isEmpty()) {
QVariant mimeData = static_cast<QMacMimeData*>(mime_src)->variantData(mimeType);
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 1197aa9148..0b9683a3ef 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -329,6 +329,7 @@ static QTouchDevice *touchDevice = 0;
if (m_window) {
NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
if (screenIndex != NSNotFound) {
+ m_platformWindow->updateExposedGeometry();
QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen());
}
@@ -371,8 +372,9 @@ static QTouchDevice *touchDevice = 0;
{
m_backingStore = backingStore;
m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio();
- QRect br = region.boundingRect();
- [self setNeedsDisplayInRect:NSMakeRect(br.x(), br.y(), br.width(), br.height())];
+ foreach (QRect rect, region.rects()) {
+ [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
+ }
}
- (BOOL) hasMask
@@ -1647,6 +1649,21 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
}
}
+static QWindow *findEventTargetWindow(QWindow *candidate)
+{
+ while (candidate) {
+ if (!(candidate->flags() & Qt::WindowTransparentForInput))
+ return candidate;
+ candidate = candidate->parent();
+ }
+ return candidate;
+}
+
+static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint point)
+{
+ return target->mapFromGlobal(source->mapToGlobal(point));
+}
+
- (NSDragOperation) draggingSourceOperationMaskForLocal:(BOOL)isLocal
{
Q_UNUSED(isLocal);
@@ -1676,16 +1693,18 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
+ QWindow *target = findEventTargetWindow(m_window);
+
// update these so selecting move/copy/link works
QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]];
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
if ([sender draggingSource] != nil) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- response = QWindowSystemInterface::handleDrag(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
- response = QWindowSystemInterface::handleDrag(m_window, &mimeData, qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
}
return qt_mac_mapDropAction(response.acceptedAction());
@@ -1693,16 +1712,20 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
+ QWindow *target = findEventTargetWindow(m_window);
+
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
// Send 0 mime data to indicate drag exit
- QWindowSystemInterface::handleDrag(m_window, 0 ,qt_windowPoint, Qt::IgnoreAction);
+ QWindowSystemInterface::handleDrag(target, 0, mapWindowCoordinates(m_window, target, qt_windowPoint), Qt::IgnoreAction);
}
// called on drop, send the drop to Qt and return if it was accepted.
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
+ QWindow *target = findEventTargetWindow(m_window);
+
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
@@ -1710,10 +1733,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
if ([sender draggingSource] != nil) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- response = QWindowSystemInterface::handleDrop(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrop(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
- response = QWindowSystemInterface::handleDrop(m_window, &mimeData, qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrop(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
}
if (response.isAccepted()) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
@@ -1726,6 +1749,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
{
Q_UNUSED(img);
Q_UNUSED(operation);
+ QWindow *target = findEventTargetWindow(m_window);
// keep our state, and QGuiApplication state (buttons member) in-sync,
// or future mouse events will be processed incorrectly
@@ -1738,7 +1762,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
NSPoint screenPoint = [window convertBaseToScreen :point];
QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
- QWindowSystemInterface::handleMouseEvent(m_window, qtWindowPoint, qtScreenPoint, m_buttons);
+ QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_window, target, qtWindowPoint), qtScreenPoint, m_buttons);
}
@end
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index 31e3e343b9..d18a01b11c 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -59,8 +59,7 @@
return nil;
QAccessible::Id childId = QAccessible::uniqueId(m_window->accessibleRoot());
- QCocoaAccessibleElement *child = [QCocoaAccessibleElement createElementWithId: childId parent: self];
- return [child autorelease];
+ return [QCocoaAccessibleElement elementWithId: childId];
}
// The QNSView is a container that the user does not interact directly with:
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index f1f9f5469c..9d40d166af 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -81,15 +81,14 @@ QQnxEglWindow::~QQnxEglWindow()
void QQnxEglWindow::createEGLSurface()
{
- // Fetch the surface size from the window and update
- // the window's buffers before we create the EGL surface
- const QSize surfaceSize = requestedBufferSize();
- if (!surfaceSize.isValid()) {
+ if (!m_requestedBufferSize.isValid()) {
qWarning("QQNX: Trying to create 0 size EGL surface. "
"Please set a valid window size before calling QOpenGLContext::makeCurrent()");
return;
}
- setBufferSize(surfaceSize);
+
+ // update the window's buffers before we create the EGL surface
+ setBufferSize(m_requestedBufferSize);
const EGLint eglSurfaceAttrs[] =
{
@@ -99,9 +98,10 @@ void QQnxEglWindow::createEGLSurface()
qEglWindowDebug() << "Creating EGL surface" << platformOpenGLContext()->getEglDisplay()
<< platformOpenGLContext()->getEglConfig();
+
// Create EGL surface
- m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay()
- , platformOpenGLContext()->getEglConfig(),
+ m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay(),
+ platformOpenGLContext()->getEglConfig(),
(EGLNativeWindowType) nativeHandle(), eglSurfaceAttrs);
if (m_eglSurface == EGL_NO_SURFACE) {
const EGLenum error = QQnxGLContext::checkEGLError("eglCreateWindowSurface");
@@ -171,11 +171,6 @@ void QQnxEglWindow::setGeometry(const QRect &rect)
QQnxWindow::setGeometry(newGeometry);
}
-QSize QQnxEglWindow::requestedBufferSize() const
-{
- return m_requestedBufferSize;
-}
-
void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
{
// This function does not take ownership of the platform gl context.
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h
index a6a223c58e..cd98f9369d 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.h
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.h
@@ -65,9 +65,6 @@ public:
void setGeometry(const QRect &rect);
- // Called by QQnxGLContext::createSurface()
- QSize requestedBufferSize() const;
-
protected:
int pixelFormat() const;
void resetBuffers();
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 42318729b1..2e0febff20 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -353,37 +353,39 @@ void QQnxWindow::setBufferSize(const QSize &size)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
- // Set window buffer size
// libscreen fails when creating empty buffers
const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
+ int format = pixelFormat();
+
+ if (nonEmptySize == m_bufferSize || format == -1)
+ return;
+
+ Q_SCREEN_CRITICALERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format),
+ "Failed to set window format");
+
+ if (m_bufferSize.isValid()) {
+ // destroy buffers first, if resized
+ Q_SCREEN_CRITICALERROR(screen_destroy_window_buffers(m_window),
+ "Failed to destroy window buffers");
+ }
int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
"Failed to set window buffer size");
- // Create window buffers if they do not exist
- if (m_bufferSize.isEmpty()) {
- val[0] = pixelFormat();
- if (val[0] == -1) // The platform GL context was not set yet on the window, so we can't procede
- return;
-
- Q_SCREEN_CRITICALERROR(
- screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val),
- "Failed to set window format");
+ Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
+ "Failed to create window buffers");
- Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
- "Failed to create window buffers");
+ // check if there are any buffers available
+ int bufferCount = 0;
+ Q_SCREEN_CRITICALERROR(
+ screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
+ "Failed to query render buffer count");
- // check if there are any buffers available
- int bufferCount = 0;
- Q_SCREEN_CRITICALERROR(
- screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
- "Failed to query render buffer count");
-
- if (bufferCount != MAX_BUFFER_COUNT) {
- qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d. You might experience problems.",
- MAX_BUFFER_COUNT, bufferCount);
- }
+ if (bufferCount != MAX_BUFFER_COUNT) {
+ qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d.",
+ MAX_BUFFER_COUNT, bufferCount);
}
// Set the transparency. According to QNX technical support, setting the window
diff --git a/src/plugins/platforms/windows/qplatformfunctions_wince.h b/src/plugins/platforms/windows/qplatformfunctions_wince.h
index 30fc66563e..65ce466086 100644
--- a/src/plugins/platforms/windows/qplatformfunctions_wince.h
+++ b/src/plugins/platforms/windows/qplatformfunctions_wince.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -293,8 +293,8 @@ inline void OleUninitialize()
inline DWORD GetGlyphOutline( HDC /*hdc*/, UINT /*uChar*/, INT /*fuFormat*/, GLYPHMETRICS * /*lpgm*/,
DWORD /*cjBuffer*/, LPVOID /*pvBuffer*/, CONST MAT2 * /*lpmat2*/ )
{
- qFatal("GetGlyphOutline not supported under Windows CE. Please try using freetype fontrendering, by"
- "passing -platform windows:freetype as arguments to the application.");
+ qFatal("GetGlyphOutline() not supported under Windows CE. Please try using freetype font-rendering, by "
+ "passing the command line argument -platform windows:fontengine=freetype to the application.");
return GDI_ERROR;
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index e7e4028079..eaa4eca84e 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -711,6 +711,8 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
minorDot = version.size();
result.version = (version.mid(0, majorDot).toInt() << 8)
+ version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
+ } else {
+ result.version = 0x0200;
}
result.profile = QSurfaceFormat::NoProfile;
if (result.version < 0x0300) {
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 1579797f85..57d6bc580b 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -94,14 +94,23 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI
, m_gc_window(0)
{
Q_XCB_NOOP(connection());
- m_xcb_image = xcb_image_create_native(xcb_connection(),
- size.width(),
- size.height(),
- XCB_IMAGE_FORMAT_Z_PIXMAP,
- depth,
- 0,
- ~0,
- 0);
+
+ const xcb_setup_t *setup = xcb_get_setup(xcb_connection());
+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
+ for (; fmt != fmtend; ++fmt)
+ if (fmt->depth == depth)
+ break;
+
+ Q_ASSERT(fmt != fmtend);
+
+ m_xcb_image = xcb_image_create(size.width(), size.height(),
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ fmt->scanline_pad,
+ fmt->depth, fmt->bits_per_pixel, 0,
+ QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
+ XCB_IMAGE_ORDER_MSB_FIRST,
+ 0, ~0, 0);
const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
if (!segmentSize)
@@ -209,10 +218,13 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
// at least 16384 bytes. That should be enough for quite large images.
Q_ASSERT(rows_per_put > 0);
+ // Convert the image to the native byte order.
+ xcb_image_t *converted_image = xcb_image_native(xcb_connection(), m_xcb_image, 1);
+
while (height > 0) {
int rows = std::min(height, rows_per_put);
- xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows,
+ xcb_image_t *subimage = xcb_image_subimage(converted_image, src_x, src_y, width, rows,
0, 0, 0);
xcb_image_put(xcb_connection(),
window,
@@ -228,6 +240,9 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
target_y += rows;
height -= rows;
}
+
+ if (converted_image != m_xcb_image)
+ xcb_image_destroy(converted_image);
}
Q_XCB_NOOP(connection());
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 66b8401ea2..f5f6c712c5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -93,10 +93,37 @@
QT_BEGIN_NAMESPACE
#ifdef XCB_USE_XLIB
+static const char * const xcbConnectionErrors[] = {
+ "No error", /* Error 0 */
+ "I/O error", /* XCB_CONN_ERROR */
+ "Unsupported extension used", /* XCB_CONN_CLOSED_EXT_NOTSUPPORTED */
+ "Out of memory", /* XCB_CONN_CLOSED_MEM_INSUFFICIENT */
+ "Maximum allowed requested length exceeded", /* XCB_CONN_CLOSED_REQ_LEN_EXCEED */
+ "Failed to parse display string", /* XCB_CONN_CLOSED_PARSE_ERR */
+ "No such screen on display", /* XCB_CONN_CLOSED_INVALID_SCREEN */
+ "Error during FD passing" /* XCB_CONN_CLOSED_FDPASSING_FAILED */
+};
+
static int nullErrorHandler(Display *, XErrorEvent *)
{
return 0;
}
+
+static int ioErrorHandler(Display *dpy)
+{
+ xcb_connection_t *conn = XGetXCBConnection(dpy);
+ if (conn != NULL) {
+ /* Print a message with a textual description of the error */
+ int code = xcb_connection_has_error(conn);
+ const char *str = "Unknown error";
+ int arrayLength = sizeof(xcbConnectionErrors) / sizeof(xcbConnectionErrors[0]);
+ if (code >= 0 && code < arrayLength)
+ str = xcbConnectionErrors[code];
+
+ qWarning("The X11 connection broke: %s (code %d)", str, code);
+ }
+ return _XDefaultIOError(dpy);
+}
#endif
QXcbScreen* QXcbConnection::findOrCreateScreen(QList<QXcbScreen *>& newScreens,
@@ -284,6 +311,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_connection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
XSetErrorHandler(nullErrorHandler);
+ XSetIOErrorHandler(ioErrorHandler);
m_xlib_display = dpy;
}
#else
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 92b24f4722..69601f44d4 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -663,23 +663,17 @@ void QXcbKeyboard::clearXKBConfig()
memset(&xkb_names, 0, sizeof(xkb_names));
}
-void QXcbKeyboard::printKeymapError(const QString &error) const
+void QXcbKeyboard::printKeymapError(const char *error) const
{
- qWarning() << "Qt: " << error;
- // check if XKB config root is a valid path
- const QDir xkbRoot = qEnvironmentVariableIsSet("QT_XKB_CONFIG_ROOT")
- ? QString::fromLocal8Bit(qgetenv("QT_XKB_CONFIG_ROOT"))
- : DFLT_XKB_CONFIG_ROOT;
- if (!xkbRoot.exists() || xkbRoot.dirName() != "xkb") {
- qWarning() << "Set QT_XKB_CONFIG_ROOT to provide a valid XKB configuration data path, current search paths: "
- << xkbRoot.path() << ". Use ':' as separator to provide several search paths.";
- return;
+ qWarning() << error;
+ if (xkb_context) {
+ qWarning() << "Current XKB configuration data search paths are: ";
+ for (unsigned int i = 0; i < xkb_context_num_include_paths(xkb_context); ++i)
+ qWarning() << xkb_context_include_path_get(xkb_context, i);
}
- qWarning() << "_XKB_RULES_NAMES property contains:" << "\nrules : " << xkb_names.rules <<
- "\nmodel : " << xkb_names.model << "\nlayout : " << xkb_names.layout <<
- "\nvariant : " << xkb_names.variant << "\noptions : " << xkb_names.options <<
- "\nIf this looks like a valid keyboard layout information then you might need to "
- "update XKB configuration data on the system (http://cgit.freedesktop.org/xkeyboard-config/).";
+ qWarning() << "Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, "
+ "add ':' as separator to provide several search paths and/or make sure that XKB configuration data "
+ "directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ .";
}
void QXcbKeyboard::updateKeymap()
@@ -696,7 +690,7 @@ void QXcbKeyboard::updateKeymap()
xkb_context = xkb_context_new((xkb_context_flags)0);
}
if (!xkb_context) {
- printKeymapError("Failed to create XKB context!");
+ printKeymapError("Qt: Failed to create XKB context!");
m_config = false;
return;
}
@@ -731,8 +725,7 @@ void QXcbKeyboard::updateKeymap()
if (xkb_keymap) {
new_state = xkb_state_new(xkb_keymap);
} else {
- // failed to compile from RMLVO, give a verbose error message
- printKeymapError("Qt: Failed to compile a keymap!");
+ printKeymapError("Failed to compile a keymap!");
m_config = false;
return;
}
@@ -863,7 +856,7 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
return QList<int>();
QList<int> result;
- int baseQtKey = keysymToQtKey(sym, modifiers, keysymToUnicode(sym));
+ int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode()));
result += (baseQtKey + modifiers); // The base key is _always_ valid, of course
xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift");
@@ -910,7 +903,7 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
continue;
Qt::KeyboardModifiers mods = modifiers & ~neededMods;
- qtKey = keysymToQtKey(sym, mods, keysymToUnicode(sym));
+ qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode()));
if (qtKey == baseQtKey)
continue;
@@ -986,10 +979,10 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
, xkb_context(0)
, xkb_keymap(0)
, xkb_state(0)
- , core_device_id(0)
{
memset(&xkb_names, 0, sizeof(xkb_names));
#ifndef QT_NO_XKB
+ core_device_id = 0;
if (connection->hasXKB()) {
updateVModMapping();
updateVModToRModMapping();
@@ -1326,7 +1319,8 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
}
Qt::KeyboardModifiers modifiers = translateModifiers(state);
- QString string = keysymToUnicode(sym);
+
+ QString string = lookupString(xkb_state, code);
int count = string.size();
string.truncate(count);
@@ -1389,16 +1383,12 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
}
}
-QString QXcbKeyboard::keysymToUnicode(xcb_keysym_t sym) const
+QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
{
QByteArray chars;
- int bytes;
- chars.resize(7);
- bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
- if (bytes == -1)
- qWarning("QXcbKeyboard::handleKeyEvent - buffer too small");
- chars.resize(bytes-1);
-
+ chars.resize(1 + xkb_state_key_get_utf8(state, code, 0, 0));
+ // equivalent of XLookupString
+ xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
return QString::fromUtf8(chars);
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index 36ce1ea2f0..11b7429aca 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -48,10 +48,7 @@
#include <xkbcommon/xkbcommon.h>
#ifndef QT_NO_XKB
-// note: extern won't be needed from libxkbcommon 0.4.1 and above
-extern "C" {
#include <xkbcommon/xkbcommon-x11.h>
-}
#endif
#include <QEvent>
@@ -79,9 +76,9 @@ public:
void updateXKBMods();
quint32 xkbModMask(quint16 state);
void updateXKBStateFromCore(quint16 state);
+#ifndef QT_NO_XKB
// when XKEYBOARD is present on the X server
int coreDeviceId() const { return core_device_id; }
-#ifndef QT_NO_XKB
void updateXKBState(xcb_xkb_state_notify_event_t *state);
#endif
@@ -89,10 +86,10 @@ protected:
void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
void resolveMaskConflicts();
- QString keysymToUnicode(xcb_keysym_t sym) const;
+ QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
int keysymToQtKey(xcb_keysym_t keysym) const;
int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const;
- void printKeymapError(const QString &error) const;
+ void printKeymapError(const char *error) const;
void readXKBConfig();
void clearXKBConfig();
@@ -134,9 +131,11 @@ private:
xkb_mod_index_t mod5;
};
_xkb_mods xkb_mods;
+#ifndef QT_NO_XKB
// when XKEYBOARD is present on the X server
_mod_masks vmod_masks;
int core_device_id;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index bed6eb59dc..5a2002f1d4 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1174,7 +1174,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
void QXcbWindow::setTransparentForMouseEvents(bool transparent)
{
- if (transparent == m_transparent)
+ if (!connection()->hasXFixes() || transparent == m_transparent)
return;
xcb_rectangle_t rectangle;
diff --git a/src/plugins/platformthemes/gtk2/gtk2.pro b/src/plugins/platformthemes/gtk2/gtk2.pro
index bb02192f91..73c156f82b 100644
--- a/src/plugins/platformthemes/gtk2/gtk2.pro
+++ b/src/plugins/platformthemes/gtk2/gtk2.pro
@@ -1,6 +1,7 @@
TARGET = qgtk2
PLUGIN_TYPE = platformthemes
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QGtk2ThemePlugin
load(qt_plugin)