From 8fd9fe209934ac92210ed3b81723ad5e21a98a30 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 18 Oct 2013 12:42:42 +0200 Subject: Android: Fix repaint on rotation After f89f099c55576992b39a8021aace64ff32747624, we no longer post a geometry-change and expose event when calling setGeometry, which the Android plugin depended on. This caused the window to stay the same size when it was resized by orientation changes. We put back the events in the code that calls setGeometry() instead. Task-number: QTBUG-32878 Change-Id: I449515dda07c839e0991c5a7031a972ca9c74dff Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/src/androidjnimain.cpp | 15 +++------------ src/plugins/platforms/android/src/androidjnimain.h | 1 - .../android/src/opengl/qandroidopenglcontext.cpp | 2 ++ .../android/src/opengl/qandroidopenglplatformwindow.cpp | 5 ++++- .../platforms/android/src/opengl/qeglfshooks_android.cpp | 2 +- 5 files changed, 10 insertions(+), 15 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 5c9ca798a8..34413ae509 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -247,17 +247,6 @@ namespace QtAndroid m_surfaceMutex.unlock(); return m_nativeWindow; } - - QSize nativeWindowSize() - { - if (m_nativeWindow == 0) - return QAndroidPlatformIntegration::defaultDesktopSize(); - - int width = ANativeWindow_getWidth(m_nativeWindow); - int height = ANativeWindow_getHeight(m_nativeWindow); - - return QSize(width, height); - } #endif void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration) @@ -564,7 +553,9 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface) m_waitForWindowSemaphore.release(); if (m_androidPlatformIntegration) { - QSize size = QtAndroid::nativeWindowSize(); + // Use the desktop size. + // On some devices, the getters for the native window size gives wrong values + QSize size = QAndroidPlatformIntegration::defaultDesktopSize(); QPlatformScreen *screen = m_androidPlatformIntegration->screen(); QRect geometry(QPoint(0, 0), size); diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h index 9a3d8a9607..b530aac884 100644 --- a/src/plugins/platforms/android/src/androidjnimain.h +++ b/src/plugins/platforms/android/src/androidjnimain.h @@ -75,7 +75,6 @@ namespace QtAndroid void flushImage(const QPoint &pos, const QImage &image, const QRect &rect); #else EGLNativeWindowType nativeWindow(bool waitToCreate = true); - QSize nativeWindowSize(); #endif QWindow *topLevelWindowAt(const QPoint &globalPos); diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp index 9d6d4003f7..6431914812 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp @@ -71,6 +71,8 @@ void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface) if (size.isValid()) { QRect geometry(QPoint(0, 0), size); window->setGeometry(geometry); + QWindowSystemInterface::handleGeometryChange(window->window(), geometry); + QWindowSystemInterface::handleExposeEvent(window->window(), QRegion(geometry)); window->scheduleResize(QSize()); } window->unlock(); diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp index 4934047af9..258a0968e8 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp @@ -41,6 +41,7 @@ #include "qandroidopenglplatformwindow.h" #include "androidjnimain.h" +#include "qandroidplatformintegration.h" #include QT_BEGIN_NAMESPACE @@ -110,7 +111,9 @@ void QAndroidOpenGLPlatformWindow::resetSurface() { lock(); - scheduleResize(QtAndroid::nativeWindowSize()); + // Use the desktop size. + // On some devices, the getters for the native window size gives wrong values + scheduleResize(QAndroidPlatformIntegration::defaultDesktopSize()); QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event unlock(); } diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp index 338966eb40..e7e53e72a2 100644 --- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp +++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp @@ -82,7 +82,7 @@ EGLNativeDisplayType QEglFSAndroidHooks::platformDisplay() const QSize QEglFSAndroidHooks::screenSize() const { - return QtAndroid::nativeWindowSize(); + return QAndroidPlatformIntegration::defaultDesktopSize(); } QSizeF QEglFSAndroidHooks::physicalScreenSize() const -- cgit v1.2.3 From 9a369a25ddfac9352cabde65c8476c7433dc6c3a Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 21 Oct 2013 14:53:16 +0200 Subject: Accessibility: Make it possible to send events with no QObject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Icbb9d15ec52ff5f7718eaf3600cab140971274aa Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/cocoa/qcocoaaccessibility.mm | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index e135f36e78..f43beb1bb5 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -56,12 +56,8 @@ QCocoaAccessibility::~QCocoaAccessibility() void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) { - QObject *object = event->object(); - if (!object) - return; - - QAccessibleInterface *interface = event->accessibleInterface(); - if (!interface) + QAccessible::Id interfaceId = event->uniqueId(); + if (!interfaceId) return; switch (event->type()) { @@ -69,7 +65,7 @@ void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event) case QAccessible::TextInserted : case QAccessible::TextRemoved : case QAccessible::TextUpdated : { - QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId : QAccessible::uniqueId(interface) parent : nil]; + QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId : interfaceId parent : nil]; [element autorelease]; NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification); break; } -- cgit v1.2.3 From c1815a7b3f842041b88dafc3b3c0ffeff3e6cb10 Mon Sep 17 00:00:00 2001 From: Morten Johan Sorvig Date: Fri, 25 Oct 2013 08:41:19 +0200 Subject: Fix compile warnings on 10.6 Apple clang 3.0 complains about missing function declarations. Add them. Change-Id: Ib9c3c238c94e8649844cf3e67a659875ad549ecb Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm | 1 + src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm | 1 + src/plugins/platforms/cocoa/qcocoamenu.mm | 1 + 3 files changed, 3 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm index d90d77ec1d..be2bab8ce7 100644 --- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm @@ -82,6 +82,7 @@ static NSButton *macCreateButton(const char *text, NSView *superview) BOOL mDialogIsExecuting; BOOL mResultSet; }; +- (void)restoreOriginalContentView; - (void)relayout; - (void)updateQtColor; - (void)finishOffWithCode:(NSInteger)code; diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm index 91fb52eb6d..dc22da0983 100644 --- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm @@ -121,6 +121,7 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) BOOL mDialogIsExecuting; BOOL mResultSet; }; +- (void)restoreOriginalContentView; - (void)relayout; - (void)relayoutToContentSize:(NSSize)frameSize; - (void)updateQtFont; diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 14b8dee101..16b02a93f5 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -84,6 +84,7 @@ static inline QCocoaMenuLoader *getMenuLoader() } - (id) initWithMenu:(QCocoaMenu*) m; +- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier; @end -- cgit v1.2.3 From fcebbaeba37422780afd58a1a63954bdbf1a67e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Boya=20Garc=C3=ADa?= Date: Wed, 16 Oct 2013 17:34:52 +0200 Subject: Fix virtual key mapping on MS Windows In order to map MS Windows virtual keys to Qt keys without messing with dead keys now I use the built-in keyMap structure of QWindowsKeyMapper and assert every cell in the keymap is properly updated. In order to guarantee this even when the user changes the keyboard layout, WndProc now manages the WM_INPUTLANGCHANGE message, which is handled by QWindowsKeyMapper, resetting the layout structure. I don't fully understand yet some things about QWindowsKeyMapper, i.e. how QWindowsKeyMapper::updatePossibleKeyCodes workarounds the dead key issue with ToAscii; but it seems to work fine in all the tests I've done. Any further testing is highly appreciated, though. [ChangeLog][[QtGui][Platform Specific Changes][Windows] Fixed virtual key mapping on Windows. Task-number: QTBUG-33409 Task-number: QTBUG-8764 Task-number: QTBUG-10032 Change-Id: I4f7709a90906b03f4504deea1ff5c361e9f94b3f Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qtwindowsglobal.h | 5 +++ src/plugins/platforms/windows/qwindowscontext.cpp | 1 + .../platforms/windows/qwindowskeymapper.cpp | 47 +++++++++------------- 3 files changed, 26 insertions(+), 27 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index f6ed9447ef..7b574b0a56 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -93,6 +93,7 @@ enum WindowsEventType // Simplify event types NonClientHitTest = NonClientEventFlag + 2, KeyEvent = KeyEventFlag + 1, KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1, + KeyboardLayoutChangeEvent = KeyEventFlag + 2, InputMethodKeyEvent = InputMethodEventFlag + KeyEventFlag + 1, InputMethodKeyDownEvent = InputMethodEventFlag + KeyEventFlag + KeyDownEventFlag + 1, ClipboardEvent = ClipboardEventFlag + 1, @@ -165,6 +166,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::InputMethodKeyEvent; case WM_IME_KEYDOWN: return QtWindows::InputMethodKeyDownEvent; +#ifdef WM_INPUTLANGCHANGE + case WM_INPUTLANGCHANGE: + return QtWindows::KeyboardLayoutChangeEvent; +#endif // WM_INPUTLANGCHANGE case WM_TOUCH: return QtWindows::TouchEvent; case WM_CHANGECBCHAIN: diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 85b03673ac..174b3312d2 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -842,6 +842,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::KeyEvent: case QtWindows::InputMethodKeyEvent: case QtWindows::InputMethodKeyDownEvent: + case QtWindows::KeyboardLayoutChangeEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) return platformSessionManager()->isInterractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); #else diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 47c136991a..994128738b 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -574,7 +574,7 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg) { unsigned char kbdBuffer[256]; // Will hold the complete keyboard state GetKeyboardState(kbdBuffer); - quint32 scancode = (msg.lParam >> 16) & 0xfff; + const quint32 scancode = (msg.lParam >> 16) & 0xff; updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam); } @@ -742,12 +742,21 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd, const MSG &msg, LRESULT *result) { *result = 0; + + // Reset layout map when system keyboard layout is changed + if (msg.message == WM_INPUTLANGCHANGE) { + deleteLayouts(); + return true; + } + + // Add this key to the keymap if it is not present yet. + updateKeyMap(msg); + MSG peekedMsg; // consume dead chars?(for example, typing '`','a' resulting in a-accent). if (PeekMessage(&peekedMsg, hwnd, 0, 0, PM_NOREMOVE) && peekedMsg.message == WM_DEADCHAR) return true; - if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) - updateKeyMap(msg); + return translateKeyEventInternal(widget, msg, false); } @@ -755,9 +764,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms { const int msgType = msg.message; - const quint32 scancode = (msg.lParam >> 16) & 0xfff; - const quint32 vk_key = MapVirtualKey(scancode, 1); - const bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9); + const quint32 scancode = (msg.lParam >> 16) & 0xff; + const quint32 vk_key = msg.wParam; quint32 nModifiers = 0; QWindow *receiver = m_keyGrabber ? m_keyGrabber : window; @@ -786,10 +794,6 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms state |= (nModifiers & AltAny ? int(Qt::AltModifier) : 0); state |= (nModifiers & MetaAny ? int(Qt::MetaModifier) : 0); - // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey - const bool isDeadKey = isADeadKey(msg.wParam, state) - || MapVirtualKey(msg.wParam, 2) & 0x80000000; - // A multi-character key or a Input method character // not found by our look-ahead if (msgType == WM_CHAR || msgType == WM_IME_CHAR) { @@ -849,23 +853,12 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms return true; // Translate VK_* (native) -> Key_* (Qt) keys - // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change - // the internal state of the keyboard driver, resulting in that dead keys no longer works. - // ..also if we're typing numbers on the keypad, while holding down the Alt modifier. - int code = 0; - if (isNumpad && (nModifiers & AltAny)) { - code = winceKeyBend(msg.wParam); - } else if (!isDeadKey) { - // QTBUG-8764, QTBUG-10032 - // Can't call toKeyOrUnicode because that would call ToUnicode, and, if a dead key - // is pressed at the moment, Windows would NOT use it to compose a character for the next - // WM_CHAR event. - - // Instead, use MapVirtualKey, which will provide adequate values. - code = MapVirtualKey(msg.wParam, MAPVK_VK_TO_CHAR); - if (code < 0x20 || code == 0x7f) // The same logic as in toKeyOrUnicode() - code = winceKeyBend(msg.wParam); - } + int modifiersIndex = 0; + modifiersIndex |= (nModifiers & ShiftAny ? 0x1 : 0); + modifiersIndex |= (nModifiers & ControlAny ? 0x2 : 0); + modifiersIndex |= (nModifiers & AltAny ? 0x4 : 0); + + int code = keyLayout[vk_key].qtKey[modifiersIndex]; // Invert state logic: // If the key actually pressed is a modifier key, then we remove its modifier key from the -- cgit v1.2.3 From c15e8517ef877a141df7cd5d4767d19ac81e7c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Luis=20Boya=20Garc=C3=ADa?= Date: Wed, 23 Oct 2013 12:34:02 +0200 Subject: Fix bug in updatePossibleKeyCodes() with dead keys and modifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it was until now, QWindowsKeyMapper::updatePossibleKeyCodes() tested using ToUnicode for which characters produce a key with every possible combination of modifiers. Calling ToUnicode with a dead key is dangerous, because MS Windows keeps it in the driver buffer, so if you call ToUnicode with acute key and then you press a, you get an á. To prevent this, updatePossibleKeyCodes() checked if the key that was being tested was a dead key. If true, it inserted an space and then repeated the key in order to reset the system internal buffers to the same state they were before the call. The problem with this is if the dead key is really two keys (like ^ or ´ in US International keyboard layout) and you press one of those keys without the modifier to make it a dead key (i.e. 6 in US International): Since updatePossibleKeyCodes() only tests for the key that was pressed it gets 6 is not a dead key, and thus it does not execute the workaround. Thus, the next time the user presses 'a' they get 'â' instead because updatePossibleKeyCodes() set the dead key on the keyboard buffer and did not run the workaround. This patch makes updatePossibleKeyCodes() run the workaround if any possible combination of modifiers with the key being examinated makes a dead key. Task-number: QTBUG-33591 Change-Id: I8c0b27586f7c62798986258b1b84aa90e4c5d64c Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowskeymapper.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 994128738b..02795283b2 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -635,8 +635,8 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 } keyLayout[vk_key].qtKey[8] = fallbackKey; - // If this vk_key a Dead Key - if (MapVirtualKey(vk_key, 2) & 0x80000000) { + // If this vk_key makes a dead key with any combination of modifiers + if (keyLayout[vk_key].deadkeys) { // Push a Space, then the original key through the low-level ToAscii functions. // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of // the keyboard driver By doing the following, we set the keyboard driver state back to what -- cgit v1.2.3 From a0da5290ff1898c456e34e03cc7a994984172880 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 25 Oct 2013 14:43:42 +0100 Subject: QWindowsKeyMapper: Added some comments about functionality + cleanup Change-Id: Ieabdea7601ea0eba08eac701b2fdf27b4cd2ff45 Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowskeymapper.cpp | 38 ++++++++-------------- src/plugins/platforms/windows/qwindowskeymapper.h | 2 -- 2 files changed, 14 insertions(+), 26 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 02795283b2..e2594207fe 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -97,6 +97,8 @@ struct KeyRecord { QString text; }; +// We need to record the pressed keys in order to decide, whether the key event is an autorepeat +// event. As soon as its state changes, the chain of autorepeat events will be broken. static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers... struct KeyRecorder { @@ -503,12 +505,6 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, return code == Qt::Key_unknown ? 0 : code; } -int qt_translateKeyCode(int vk) -{ - int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk); - return code == Qt::Key_unknown ? 0 : code; -} - static inline int asciiToKeycode(char a, int state) { if (a >= 'a' && a <= 'z') @@ -554,12 +550,8 @@ void QWindowsKeyMapper::changeKeyboard() keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight; } -void QWindowsKeyMapper::clearRecordedKeys() -{ - key_recorder.clearKeys(); -} - - +// Helper function that is used when obtaining the list of characters that can be produced by one key and +// every possible combination of modifiers inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt) { kbd[VK_LSHIFT ] = (shift ? 0x80 : 0); @@ -570,6 +562,7 @@ inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt) kbd[VK_MENU ] = (alt ? 0x80 : 0); } +// Adds the msg's key to keyLayout if it is not yet present there void QWindowsKeyMapper::updateKeyMap(const MSG &msg) { unsigned char kbdBuffer[256]; // Will hold the complete keyboard state @@ -578,6 +571,9 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg) updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam); } +// Fills keyLayout for that vk_key. Values are all characters one can type using that key +// (in connection with every combination of modifiers) and whether these "characters" are +// dead keys. void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode, quint32 vk_key) { @@ -598,6 +594,10 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 buffer[VK_RCONTROL] = 0; buffer[VK_LMENU ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph + // keyLayout contains the actual characters which can be written using the vk_key together with the + // different modifiers. '2' together with shift will for example cause the character + // to be @ for a US key layout (thus keyLayout[vk_key].qtKey[1] will be @). In addition to that + // it stores whether the resulting key is a dead key as these keys have to be handled later. bool isDeadKey = false; keyLayout[vk_key].deadkeys = 0; keyLayout[vk_key].dirty = false; @@ -635,7 +635,8 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 } keyLayout[vk_key].qtKey[8] = fallbackKey; - // If this vk_key makes a dead key with any combination of modifiers + // If one of the values inserted into the keyLayout above, can be considered a dead key, we have + // to run the workaround below. if (keyLayout[vk_key].deadkeys) { // Push a Space, then the original key through the low-level ToAscii functions. // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of @@ -661,17 +662,6 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 } } -bool QWindowsKeyMapper::isADeadKey(unsigned int vk_key, unsigned int modifiers) -{ - if ((vk_key < NumKeyboardLayoutItems) && keyLayout[vk_key].exists) { - for (size_t i = 0; i < NumMods; ++i) { - if (uint(ModsTbl[i]) == modifiers) - return bool(keyLayout[vk_key].deadkeys & 1< Date: Thu, 24 Oct 2013 11:32:15 +0200 Subject: eglfs: Perform initialization in initialize() instead of the constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move (almost) everything to initialize(). Doing so allows the QEglFSScreen constructor, the hooks' platformInit() and others to perform tasks that need the event dispatcher. Task-number: QTBUG-34208 Change-Id: If64e3d1691c41752c53968f8d4fb063b45345680 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 47 ++++++++++++----------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 67f0c35ed7..8a526dbff5 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -79,30 +79,9 @@ QT_BEGIN_NAMESPACE QEglFSIntegration::QEglFSIntegration() : mFontDb(new QGenericUnixFontDatabase) , mServices(new QGenericUnixServices) + , mScreen(0) , mInputContext(0) { - QEglFSHooks::hooks()->platformInit(); - - EGLint major, minor; - - if (!eglBindAPI(EGL_OPENGL_ES_API)) { - qWarning("Could not bind GL_ES API\n"); - qFatal("EGL error"); - } - - mDisplay = eglGetDisplay(QEglFSHooks::hooks() ? QEglFSHooks::hooks()->platformDisplay() : EGL_DEFAULT_DISPLAY); - if (mDisplay == EGL_NO_DISPLAY) { - qWarning("Could not open egl display\n"); - qFatal("EGL error"); - } - - if (!eglInitialize(mDisplay, &major, &minor)) { - qWarning("Could not initialize egl display\n"); - qFatal("EGL error"); - } - - mScreen = new QEglFSScreen(mDisplay); - screenAdded(mScreen); } QEglFSIntegration::~QEglFSIntegration() @@ -166,7 +145,31 @@ QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const void QEglFSIntegration::initialize() { + QEglFSHooks::hooks()->platformInit(); + + EGLint major, minor; + + if (!eglBindAPI(EGL_OPENGL_ES_API)) { + qWarning("Could not bind GL_ES API\n"); + qFatal("EGL error"); + } + + mDisplay = eglGetDisplay(QEglFSHooks::hooks() ? QEglFSHooks::hooks()->platformDisplay() : EGL_DEFAULT_DISPLAY); + if (mDisplay == EGL_NO_DISPLAY) { + qWarning("Could not open egl display\n"); + qFatal("EGL error"); + } + + if (!eglInitialize(mDisplay, &major, &minor)) { + qWarning("Could not initialize egl display\n"); + qFatal("EGL error"); + } + + mScreen = new QEglFSScreen(mDisplay); + screenAdded(mScreen); + mInputContext = QPlatformInputContextFactory::create(); + createInputHandlers(); } -- cgit v1.2.3 From 684a952edbf5ec5bd70c7edae7c8eff8e87cf2de Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Sun, 27 Oct 2013 10:20:32 +0200 Subject: Android: Don't crash if the screen is not yet initialized. Change-Id: I4751c2dec5780f42b348a8a8ea628f65d548dcec Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/src/androidjnimain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 34413ae509..abfc2fa19c 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -559,8 +559,10 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface) QPlatformScreen *screen = m_androidPlatformIntegration->screen(); QRect geometry(QPoint(0, 0), size); - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry); - QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry); + if (screen) { + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry); + QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry); + } if (!sameNativeWindow) { m_surfaceMutex.unlock(); -- cgit v1.2.3 From 6ea7336e4aed916c5c9602c51d7d9646a289e83b Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 29 Oct 2013 12:16:30 +0100 Subject: eglfs: Make backingstore handle unexpected scenarios gracefully On platforms other than Android eglfs does not allow having multiple windows when one of the windows is OpenGL. On Android however this has to be handled silently, without aborting the application. The backingstore lacked the necessary checks so QGLWidget-based apps were crashing. This is now corrected. Task-number: QTBUG-34412 Change-Id: Ifb469fa9ef391b24aed3942430c0347276809ba5 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/eglfs/qeglfsbackingstore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp index 8de8268616..9de5960fdb 100644 --- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp +++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp @@ -113,7 +113,7 @@ void QEglFSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo #endif QEglFSWindow *rootWin = m_window->screen()->rootWindow(); - if (!rootWin) + if (!rootWin || !rootWin->isRaster()) return; m_window->create(); @@ -132,7 +132,7 @@ void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents Q_UNUSED(staticContents); QEglFSWindow *rootWin = m_window->screen()->rootWindow(); - if (!rootWin) + if (!rootWin || !rootWin->isRaster()) return; m_image = QImage(size, QImage::Format_RGB32); -- cgit v1.2.3 From 4d5bf32c20078dc4fb186e9a7b4969f01ebdc7e5 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 28 Oct 2013 12:22:50 +0100 Subject: Re-enable NonFullScreenWindows on Android This flag was created because the eglfs plugin did not support non-fullscreen raster windows. Now that it does, we can remove it again. Turns out this also fixes several issues with positioning and sizing of dialogs due to bugs in the implementation of the flag. Task-number: QTBUG-33846, QTBUG-33499, QTBUG-32537, QTBUG-32297, QTBUG-31457 Change-Id: I3902ae57d49d77e3c1046ec57b6f6926f70ec6a4 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/src/qandroidplatformintegration.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index a3db421de9..e48a3c9ebe 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -123,7 +123,6 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const switch (cap) { case ThreadedPixmaps: return true; case ApplicationState: return true; - case NonFullScreenWindows: return false; case NativeWidgets: return false; default: #ifndef ANDROID_PLUGIN_OPENGL -- cgit v1.2.3 From 5dfda7a556485ff07448f5bc2006ac4132e33e7d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 11 Oct 2013 12:03:02 +0200 Subject: Cocoa: Fix mouse event coordinates transform to window space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We pass the mouse screen coordinates that we convert to window space instead of the other way around. This makes sure the original mouse coordinates are not bound to any moving window. Task-number: QTBUG-29583 Task-number: QTBUG-32221 Change-Id: I8f9ada6e8c0d20af8e85e88ee39190d23e58977f Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 43 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index f90fc6b205..8f839384df 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -496,7 +496,7 @@ static QTouchDevice *touchDevice = 0; return YES; } -- (void)convertFromEvent:(NSEvent *)event toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint +- (void)convertFromScreen:(NSPoint)mouseLocation toWindowPoint:(QPointF *)qtWindowPoint andScreenPoint:(QPointF *)qtScreenPoint { // Calculate the mouse position in the QWindow and Qt screen coordinate system, // starting from coordinates in the NSWindow coordinate system. @@ -516,23 +516,22 @@ static QTouchDevice *touchDevice = 0; // NSView and QWindow are equal coordinate systems: the QWindow covers the // entire NSView, and we've set the NSView's isFlipped property to true. - NSPoint nsWindowPoint = [event locationInWindow]; // NSWindow coordinates - - NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil]; // NSView/QWindow coordinates - *qtWindowPoint = QPointF(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates - NSWindow *window = [self window]; + NSPoint nsWindowPoint; // Use convertRectToScreen if available (added in 10.7). #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if ([window respondsToSelector:@selector(convertRectToScreen:)]) { - NSRect screenRect = [window convertRectToScreen : NSMakeRect(nsWindowPoint.x, nsWindowPoint.y, 0, 0)]; // OS X screen coordinates - *qtScreenPoint = QPointF(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y)); // Qt screen coordinates + if ([window respondsToSelector:@selector(convertRectFromScreen:)]) { + NSRect windowRect = [window convertRectFromScreen:NSMakeRect(mouseLocation.x, mouseLocation.y, 1, 1)]; + nsWindowPoint = windowRect.origin; // NSWindow coordinates } else #endif { - NSPoint screenPoint = [window convertBaseToScreen : NSMakePoint(nsWindowPoint.x, nsWindowPoint.y)]; - *qtScreenPoint = QPointF(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y)); + nsWindowPoint = [window convertScreenToBase:mouseLocation]; // NSWindow coordinates } + NSPoint nsViewPoint = [self convertPoint: nsWindowPoint fromView: nil]; // NSView/QWindow coordinates + *qtWindowPoint = QPointF(nsViewPoint.x, nsViewPoint.y); // NSView/QWindow coordinates + + *qtScreenPoint = QPointF(mouseLocation.x, qt_mac_flipYCoordinate(mouseLocation.y)); // Qt screen coordinates } - (void)resetMouseButtons @@ -546,7 +545,7 @@ static QTouchDevice *touchDevice = 0; QPointF qtWindowPoint; QPointF qtScreenPoint; - [self convertFromEvent:theEvent toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint]; ulong timestamp = [theEvent timestamp] * 1000; QCocoaDrag* nativeDrag = static_cast(QGuiApplicationPrivate::platformIntegration()->drag()); @@ -688,7 +687,7 @@ static QTouchDevice *touchDevice = 0; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint.toPoint()); // Top-level windows generate enter-leave events for sub-windows. @@ -722,7 +721,7 @@ static QTouchDevice *touchDevice = 0; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:theEvent toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; m_platformWindow->m_underMouseWindow = m_platformWindow->childWindowAt(windowPoint.toPoint()); QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_underMouseWindow, windowPoint, screenPoint); } @@ -812,7 +811,7 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash) QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent: theEvent toWindowPoint: &windowPoint andScreenPoint: &screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint: &windowPoint andScreenPoint: &screenPoint]; uint deviceId = [theEvent deviceID]; if (!tabletDeviceDataHash->contains(deviceId)) { @@ -985,7 +984,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::ZoomNativeGesture, [event magnification], windowPoint, screenPoint); } @@ -1000,7 +999,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SmartZoomNativeGesture, zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint); zoomIn = !zoomIn; @@ -1015,7 +1014,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::RotateNativeGesture, -[event rotation], windowPoint, screenPoint); } @@ -1028,7 +1027,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; qreal angle = 0.0f; if ([event deltaX] == 1) @@ -1052,7 +1051,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::BeginNativeGesture, windowPoint, screenPoint); } @@ -1065,7 +1064,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const NSTimeInterval timestamp = [event timestamp]; QPointF windowPoint; QPointF screenPoint; - [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::EndNativeGesture, windowPoint, screenPoint); } @@ -1125,7 +1124,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) QPointF qt_windowPoint; QPointF qt_screenPoint; - [self convertFromEvent:theEvent toWindowPoint:&qt_windowPoint andScreenPoint:&qt_screenPoint]; + [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qt_windowPoint andScreenPoint:&qt_screenPoint]; NSTimeInterval timestamp = [theEvent timestamp]; ulong qt_timestamp = timestamp * 1000; -- cgit v1.2.3 From cf239f69e1873573da1d17d1eeed326686f7cbef Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Fri, 18 Oct 2013 18:36:23 -0300 Subject: QNX: Manage foreign mmrenderer windows Manage and correctly set the z-order of a foreign created mmrenderer window by QtMultimedia Task-number: QTBUG-33816 Change-Id: I46273b945bf10991462fa72eb1ec8d00b0648988 Reviewed-by: Thomas McGuire --- src/plugins/platforms/qnx/qqnxnativeinterface.cpp | 9 +++ src/plugins/platforms/qnx/qqnxnativeinterface.h | 1 + src/plugins/platforms/qnx/qqnxscreen.cpp | 77 +++++++++++++++++++++-- src/plugins/platforms/qnx/qqnxscreen.h | 1 + src/plugins/platforms/qnx/qqnxwindow.cpp | 37 +++++++++-- src/plugins/platforms/qnx/qqnxwindow.h | 10 +++ 6 files changed, 125 insertions(+), 10 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp index 4dd3444832..8958a5c1e2 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -42,6 +42,7 @@ #include "qqnxnativeinterface.h" #include "qqnxscreen.h" +#include "qqnxwindow.h" #include #include @@ -70,4 +71,12 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q return 0; } +void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) +{ + if (name == QStringLiteral("mmRendererWindowName")) { + QQnxWindow *qnxWindow = static_cast(window); + qnxWindow->setMMRendererWindowName(value.toString()); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h index 6692da2576..b61f6a56cc 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.h +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h @@ -51,6 +51,7 @@ class QQnxNativeInterface : public QPlatformNativeInterface public: void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen); + void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index dd8cf2131a..3dab2b3bc9 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -119,6 +119,38 @@ static QSize determineScreenSize(screen_display_t display, bool primaryScreen) { #endif } +static QQnxWindow *findMultimediaWindow(const QList windows, + const QByteArray &mmWindowId) +{ + Q_FOREACH (QQnxWindow *sibling, windows) { + if (sibling->mmRendererWindowName() == mmWindowId) + return sibling; + + QQnxWindow *mmWindow = findMultimediaWindow(sibling->children(), mmWindowId); + + if (mmWindow) + return mmWindow; + } + + return 0; +} + +static QQnxWindow *findMultimediaWindow(const QList windows, + screen_window_t mmWindowId) +{ + Q_FOREACH (QQnxWindow *sibling, windows) { + if (sibling->mmRendererWindow() == mmWindowId) + return sibling; + + QQnxWindow *mmWindow = findMultimediaWindow(sibling->children(), mmWindowId); + + if (mmWindow) + return mmWindow; + } + + return 0; +} + QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen) : m_screenContext(screenContext), m_display(display), @@ -585,6 +617,19 @@ void QQnxScreen::addUnderlayWindow(screen_window_t window) updateHierarchy(); } +void QQnxScreen::addMultimediaWindow(const QByteArray &id, screen_window_t window) +{ + // find the QnxWindow this mmrenderer window is related to + QQnxWindow *mmWindow = findMultimediaWindow(m_childWindows, id); + + if (!mmWindow) + return; + + mmWindow->setMMRendererWindow(window); + + updateHierarchy(); +} + void QQnxScreen::removeOverlayOrUnderlayWindow(screen_window_t window) { const int numRemoved = m_overlays.removeAll(window) + m_underlays.removeAll(window); @@ -610,17 +655,35 @@ void QQnxScreen::newWindowCreated(void *window) zorder = 0; } + char windowNameBuffer[256] = { 0 }; + QByteArray windowName; + + if (screen_get_window_property_cv(windowHandle, SCREEN_PROPERTY_ID_STRING, + sizeof(windowNameBuffer) - 1, windowNameBuffer) != 0) { + qWarning("QQnx: Failed to get id for window, errno=%d", errno); + } + + windowName = QByteArray(windowNameBuffer); + if (display == nativeDisplay()) { // A window was created on this screen. If we don't know about this window yet, it means // it was not created by Qt, but by some foreign library like the multimedia renderer, which // creates an overlay window when playing a video. // - // Treat all foreign windows as overlays or underlays here. + // Treat all foreign windows as overlays, underlays or as windows + // created by the BlackBerry QtMultimedia plugin. // - // Assume that if a foreign window already has a Z-Order both negative and + // In the case of the BlackBerry QtMultimedia plugin, we need to + // "attach" the foreign created mmrenderer window to the correct + // platform window (usually the one belonging to QVideoWidget) to + // ensure proper z-ordering. + // + // Otherwise, assume that if a foreign window already has a Z-Order both negative and // less than the default Z-Order installed by mmrender on windows it creates, // the windows should be treated as an underlay. Otherwise, we treat it as an overlay. - if (!findWindow(windowHandle)) { + if (!windowName.isEmpty() && windowName.startsWith("BbVideoWindowControl")) { + addMultimediaWindow(windowName, windowHandle); + } else if (!findWindow(windowHandle)) { if (zorder <= MAX_UNDERLAY_ZORDER) addUnderlayWindow(windowHandle); else @@ -634,7 +697,13 @@ void QQnxScreen::windowClosed(void *window) { Q_ASSERT(thread() == QThread::currentThread()); const screen_window_t windowHandle = reinterpret_cast(window); - removeOverlayOrUnderlayWindow(windowHandle); + + QQnxWindow *mmWindow = findMultimediaWindow(m_childWindows, windowHandle); + + if (mmWindow) + mmWindow->clearMMRendererWindow(); + else + removeOverlayOrUnderlayWindow(windowHandle); } void QQnxScreen::windowGroupStateChanged(const QByteArray &id, Qt::WindowState state) diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index e11030ea0a..014f7905f3 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -119,6 +119,7 @@ private: void resizeWindows(const QRect &previousScreenGeometry); void addOverlayWindow(screen_window_t window); void addUnderlayWindow(screen_window_t window); + void addMultimediaWindow(const QByteArray &id, screen_window_t window); void removeOverlayOrUnderlayWindow(screen_window_t window); QWindow *topMostChildWindow() const; diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 3969a09098..749a336fcc 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -77,7 +77,8 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context) m_parentWindow(0), m_visible(false), m_exposed(true), - m_windowState(Qt::WindowNoState) + m_windowState(Qt::WindowNoState), + m_mmRendererWindow(0) { qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size(); int result; @@ -489,6 +490,22 @@ void QQnxWindow::gainedFocus() QWindowSystemInterface::handleWindowActivated(window()); } +void QQnxWindow::setMMRendererWindowName(const QString &name) +{ + m_mmRendererWindowName = name; +} + +void QQnxWindow::setMMRendererWindow(screen_window_t handle) +{ + m_mmRendererWindow = handle; +} + +void QQnxWindow::clearMMRendererWindow() +{ + m_mmRendererWindowName.clear(); + m_mmRendererWindow = 0; +} + QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle) { if (m_window == windowHandle) @@ -583,17 +600,25 @@ void QQnxWindow::initWindow() void QQnxWindow::updateZorder(int &topZorder) { - errno = 0; - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, &topZorder); - topZorder++; + updateZorder(m_window, topZorder); - if (result != 0) - qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, m_window); + if (m_mmRendererWindow) + updateZorder(m_mmRendererWindow, topZorder); Q_FOREACH (QQnxWindow *childWindow, m_childWindows) childWindow->updateZorder(topZorder); } +void QQnxWindow::updateZorder(screen_window_t window, int &topZorder) +{ + errno = 0; + int result = screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder); + topZorder++; + + if (result != 0) + qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, window); +} + void QQnxWindow::applyWindowState() { switch (m_windowState) { diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index f96280848a..52d22235a2 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -99,6 +99,9 @@ public: void propagateSizeHints(); void gainedFocus(); + void setMMRendererWindowName(const QString &name); + void setMMRendererWindow(screen_window_t handle); + void clearMMRendererWindow(); QQnxScreen *screen() const { return m_screen; } const QList& children() const { return m_childWindows; } @@ -107,6 +110,10 @@ public: void minimize(); + QString mmRendererWindowName() const { return m_mmRendererWindowName; } + + screen_window_t mmRendererWindow() const { return m_mmRendererWindow; } + virtual WindowType windowType() const = 0; protected: virtual int pixelFormat() const = 0; @@ -123,6 +130,7 @@ private: void setOffset(const QPoint &setOffset); void updateVisibility(bool parentVisible); void updateZorder(int &topZorder); + void updateZorder(screen_window_t window, int &zOrder); void applyWindowState(); screen_window_t m_window; @@ -135,6 +143,8 @@ private: bool m_exposed; QRect m_unmaximizedGeometry; Qt::WindowState m_windowState; + QString m_mmRendererWindowName; + screen_window_t m_mmRendererWindow; }; QT_END_NAMESPACE -- cgit v1.2.3 From 9087d4ed7bd81b97de90e0aa1844e9944c9d9be6 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 28 Oct 2013 10:29:02 +0100 Subject: Don't support threaded GL on chromium (virtual box GL) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I84f89450e3fce1cbbafd19dbf4509b1911e06b19 Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qglxintegration.cpp | 32 +++++++++++++++++++++++++++ src/plugins/platforms/xcb/qglxintegration.h | 6 +++++ src/plugins/platforms/xcb/qxcbintegration.cpp | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index cbfbdf495f..2c418cbebe 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -408,6 +408,38 @@ bool QGLXContext::isValid() const return m_context != 0; } +bool QGLXContext::m_queriedDummyContext = false; +bool QGLXContext::m_supportsThreading = true; + +void QGLXContext::queryDummyContext() +{ + if (m_queriedDummyContext) + return; + m_queriedDummyContext = true; + + static bool skip = qEnvironmentVariableIsSet("QT_OPENGL_NO_SANITY_CHECK"); + if (skip) + return; + + QOffscreenSurface surface; + surface.create(); + QOpenGLContext context; + context.create(); + context.makeCurrent(&surface); + + const char *renderer = (const char *) glGetString(GL_RENDERER); + if (QByteArray(renderer).contains("Chromium")) + m_supportsThreading = false; + else + m_supportsThreading = true; +} + +bool QGLXContext::supportsThreading() +{ + if (!m_queriedDummyContext) + queryDummyContext(); + return m_supportsThreading; +} QGLXPbuffer::QGLXPbuffer(QOffscreenSurface *offscreenSurface) : QPlatformOffscreenSurface(offscreenSurface) diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index 7116b2389d..dcc7fe8855 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -72,12 +72,18 @@ public: GLXContext glxContext() const { return m_context; } + static bool supportsThreading(); + static void queryDummyContext(); + private: QXcbScreen *m_screen; GLXContext m_context; GLXContext m_shareContext; QSurfaceFormat m_format; bool m_isPBufferCurrent; + + static bool m_queriedDummyContext; + static bool m_supportsThreading; }; diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 5168bd818b..6b5ea93638 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -278,7 +278,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const #else case OpenGL: return false; #endif - case ThreadedOpenGL: return m_connections.at(0)->supportsThreadedRendering(); + case ThreadedOpenGL: return m_connections.at(0)->supportsThreadedRendering() && QGLXContext::supportsThreading(); case WindowMasks: return true; case MultipleWindows: return true; case ForeignWindows: return true; -- cgit v1.2.3 From aceb854bbb6582cbdecb4da94b64782c76a653cb Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Mon, 28 Oct 2013 17:11:10 +0100 Subject: Different native Cocoa menu fixes. - Fix location of NSMenu when no NSView is given. - Fix shortcut when given in text with tab. Change-Id: Iec21cf3d12084db1e70c1a8779d5482c78285796 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamenu.mm | 26 +++++++++++++++----------- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 4 ++++ 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 16b02a93f5..329c7a264a 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -466,17 +466,21 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatf nsPos.y = screen->availableVirtualSize().height() - nsPos.y; } - // Finally, we need to synthesize an event. - NSEvent *menuEvent = [NSEvent mouseEventWithType:NSRightMouseDown - location:nsPos - modifierFlags:0 - timestamp:0 - windowNumber:view ? view.window.windowNumber : 0 - context:nil - eventNumber:0 - clickCount:1 - pressure:1.0]; - [NSMenu popUpContextMenu:m_nativeMenu withEvent:menuEvent forView:view]; + if (view) { + // Finally, we need to synthesize an event. + NSEvent *menuEvent = [NSEvent mouseEventWithType:NSRightMouseDown + location:nsPos + modifierFlags:0 + timestamp:0 + windowNumber:view ? view.window.windowNumber : 0 + context:nil + eventNumber:0 + clickCount:1 + pressure:1.0]; + [NSMenu popUpContextMenu:m_nativeMenu withEvent:menuEvent forView:view]; + } else { + [m_nativeMenu popUpMenuPositioningItem:nsItem atLocation:nsPos inView:0]; + } } // The calls above block, and also swallow any mouse release event, diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 013f9931ff..3bba1ee1d5 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -338,6 +338,8 @@ QString QCocoaMenuItem::mergeText() return qt_mac_applicationmenu_string(4); } else if (m_native == [loader quitMenuItem]) { return qt_mac_applicationmenu_string(5).arg(qt_mac_applicationName()); + } else if (m_text.contains('\t')) { + return m_text.left(m_text.indexOf('\t')); } return m_text; } @@ -349,6 +351,8 @@ QKeySequence QCocoaMenuItem::mergeAccel() return QKeySequence(QKeySequence::Preferences); else if (m_native == [loader quitMenuItem]) return QKeySequence(QKeySequence::Quit); + else if (m_text.contains('\t')) + return QKeySequence(m_text.mid(m_text.indexOf('\t') + 1), QKeySequence::NativeText); return m_shortcut; } -- cgit v1.2.3 From ac693bf7541552fad9cb216e200c85b441fcde58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 25 Oct 2013 14:19:10 +0200 Subject: Add QGuiApplication::sync() function This will allow applications to make sure Qt has the same state as the window system at any given point. The use of this function is discouraged but it is very useful for auto tests. Change-Id: I691bff365fc391e9d7213f2607008983505bb774 Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/xcb/qxcbintegration.cpp | 8 ++++++++ src/plugins/platforms/xcb/qxcbintegration.h | 1 + 2 files changed, 9 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 6b5ea93638..d794065d45 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -282,6 +282,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const case WindowMasks: return true; case MultipleWindows: return true; case ForeignWindows: return true; + case SyncState: return true; default: return QPlatformIntegration::hasCapability(cap); } } @@ -458,4 +459,11 @@ QPlatformSessionManager *QXcbIntegration::createPlatformSessionManager(const QSt } #endif +void QXcbIntegration::sync() +{ + for (int i = 0; i < m_connections.size(); i++) { + m_connections.at(i)->sync(); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 79fb1965c4..6ae23125c8 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -106,6 +106,7 @@ public: QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const Q_DECL_OVERRIDE; #endif + void sync(); private: QList m_connections; -- cgit v1.2.3 From 43002e25723e923f035f1507eb5b66312ab708cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Fri, 25 Oct 2013 12:02:21 +0200 Subject: Silence the _COMPIZ_DECOR_* warnings on Ubuntu Earliest occurrence is to my knowledge in 12.04. It is still unclear how to act on those messages Change-Id: I7da48281c6bec973448a1d4cd800d445a80695a2 Reviewed-by: Gatis Paeglis Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qxcbconnection.cpp | 5 ++++- src/plugins/platforms/xcb/qxcbconnection.h | 4 ++++ src/plugins/platforms/xcb/qxcbwindow.cpp | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index e6ef6b2a09..cc8c42f96b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1438,7 +1438,10 @@ static const char * xcb_atomnames = { #if XCB_USE_MAEMO_WINDOW_PROPERTIES "_MEEGOTOUCH_ORIENTATION_ANGLE\0" #endif - "_XSETTINGS_SETTINGS\0" // \0\0 terminates loop. + "_XSETTINGS_SETTINGS\0" + "_COMPIZ_DECOR_PENDING\0" + "_COMPIZ_DECOR_REQUEST\0" + "_COMPIZ_DECOR_DELETE_PIXMAP\0" // \0\0 terminates loop. }; QXcbAtom::Atom QXcbConnection::qatom(xcb_atom_t xatom) const diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 0e52b2ec46..ff7a6dd606 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -277,6 +277,10 @@ namespace QXcbAtom { #endif _XSETTINGS_SETTINGS, + _COMPIZ_DECOR_PENDING, + _COMPIZ_DECOR_REQUEST, + _COMPIZ_DECOR_DELETE_PIXMAP, + NPredefinedAtoms, _QT_SETTINGS_TIMESTAMP = NPredefinedAtoms, diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index aa53093868..c1650f6576 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1549,6 +1549,10 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even || event->type == atom(QXcbAtom::WM_CHANGE_STATE)) { // Ignore _NET_ACTIVE_WINDOW, _NET_WM_STATE, MANAGER which are relate to tray icons // and other messages. + } else if (event->type == atom(QXcbAtom::_COMPIZ_DECOR_PENDING) + || event->type == atom(QXcbAtom::_COMPIZ_DECOR_REQUEST) + || event->type == atom(QXcbAtom::_COMPIZ_DECOR_DELETE_PIXMAP)) { + //silence the _COMPIZ messages for now } else { qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type); } -- cgit v1.2.3 From 105e228d1c733e20787fd80e669be22064149c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 30 Oct 2013 10:44:40 +0100 Subject: xcb: Act on the _NET_ACTIVE_WINDOW event It happens that we don't get a focus inn event for top level windows when focus goes from a window mapped. But we do get a _NET_ACTIVE_WINDOW event. Task-number: QTBUG-34426 Change-Id: Id1d9eb708a968e0e8934e56dec19abe2dd203bc7 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qxcbwindow.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c1650f6576..dd404d044d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1544,10 +1544,13 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even #endif } else if (event->type == atom(QXcbAtom::_XEMBED)) { handleXEmbedMessage(event); - } else if (event->type == atom(QXcbAtom::MANAGER) || event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW) - || event->type == atom(QXcbAtom::_NET_WM_STATE) || event->type == atom(QXcbAtom::MANAGER) + } else if (event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW)) { + connection()->setFocusWindow(this); + QWindowSystemInterface::handleWindowActivated(window()); + } else if (event->type == atom(QXcbAtom::MANAGER) + || event->type == atom(QXcbAtom::_NET_WM_STATE) || event->type == atom(QXcbAtom::WM_CHANGE_STATE)) { - // Ignore _NET_ACTIVE_WINDOW, _NET_WM_STATE, MANAGER which are relate to tray icons + // Ignore _NET_WM_STATE, MANAGER which are relate to tray icons // and other messages. } else if (event->type == atom(QXcbAtom::_COMPIZ_DECOR_PENDING) || event->type == atom(QXcbAtom::_COMPIZ_DECOR_REQUEST) -- cgit v1.2.3 From f1927370cbb89438c95d56e9fb4556e7c2f4f666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lind?= Date: Wed, 30 Oct 2013 12:06:17 +0100 Subject: xcb: Compilefix #ifdef glx code Change-Id: I4204cab76b2621318dda909d24ceb2abab6e0ba3 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qxcbintegration.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index d794065d45..ecbf28bab9 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -278,7 +278,11 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const #else case OpenGL: return false; #endif +#if defined(XCB_USE_GLX) case ThreadedOpenGL: return m_connections.at(0)->supportsThreadedRendering() && QGLXContext::supportsThreading(); +#else + case ThreadedOpenGL: return m_connections.at(0)->supportsThreadedRendering(); +#endif case WindowMasks: return true; case MultipleWindows: return true; case ForeignWindows: return true; -- cgit v1.2.3 From b280182053a8ccd912eb165b59928e88a6d62c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Tue, 29 Oct 2013 15:06:34 +0100 Subject: Android: Don't rely on QIcon::isNull() to validate icon data. QIcon::isNull() only checks if it has a valid d pointer and not if it actually contains any image data. The result is that the QImage create from the icon would be invalid, and later cause an exception to be thrown. To avoid this we should check the QImage as well. Task-number: QTBUG-34416 Change-Id: I9dd0a2387d73bfc2c27ceb9df247ddc186dd659f Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/src/androidjnimenu.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp index bb180347c1..8964995832 100644 --- a/src/plugins/platforms/android/src/androidjnimenu.cpp +++ b/src/plugins/platforms/android/src/androidjnimenu.cpp @@ -197,16 +197,18 @@ namespace QtAndroidMenu env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked); env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled); - if (!icon.isNull()) { + if (!icon.isNull()) { // isNull() only checks the d pointer, not the actual image data. int sz = qMax(36, qgetenv("QT_ANDROID_APP_ICON_SIZE").toInt()); QImage img = icon.pixmap(QSize(sz,sz), enabled ? QIcon::Normal : QIcon::Disabled, QIcon::On).toImage(); - env->CallObjectMethod(menuItem, - setIconMenuItemMethodID, - createBitmapDrawable(createBitmap(img, env), env)); + if (!img.isNull()) { // Make sure we have a valid image. + env->CallObjectMethod(menuItem, + setIconMenuItemMethodID, + createBitmapDrawable(createBitmap(img, env), env)); + } } env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible); -- cgit v1.2.3 From 769abe8d2f34fdd5c67f82cd104187c4ca377f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 29 Oct 2013 15:56:24 +0100 Subject: iOS: Fix logic for determining whether to exit the root event loop Instead of trying to hook into various places where we might be in a situation where the root event loop should exit, and then enabling the runloop-observer, we always keep the observer active, and then do the relevant checks whenever the run-loop exits. The reason for checking if the event loop is running is that iOS will enter and exit the root runloop as part of normal operation, eg due to flicking a scroll view and switching the runloop mode, so we need to ensure that we're actually supposed to exit the root event loop. Change-Id: I9b84b47ee45e0c9e2b1d2ebb5a432ea92700b324 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioseventdispatcher.h | 2 -- src/plugins/platforms/ios/qioseventdispatcher.mm | 38 +++++------------------- 2 files changed, 8 insertions(+), 32 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioseventdispatcher.h b/src/plugins/platforms/ios/qioseventdispatcher.h index f2272ecd68..5caa7f5d2d 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.h +++ b/src/plugins/platforms/ios/qioseventdispatcher.h @@ -54,11 +54,9 @@ public: explicit QIOSEventDispatcher(QObject *parent = 0); bool processEvents(QEventLoop::ProcessEventsFlags flags) Q_DECL_OVERRIDE; - void interrupt() Q_DECL_OVERRIDE; void handleRunLoopExit(CFRunLoopActivity activity); - void checkIfEventLoopShouldExit(); void interruptEventLoopExec(); private: diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index 3dd9c7ad9f..51eb10d385 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -446,6 +446,8 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo if (!m_processEventCallsAfterExec && (flags & QEventLoop::EventLoopExec)) { ++m_processEventCallsAfterExec; + m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes); + // We set a new jump point here that we can return to when the event loop // is asked to exit, so that we can return from QEventLoop::exec(). switch (setjmp(processEventExitJumpPoint)) { @@ -475,44 +477,18 @@ bool __attribute__((returns_twice)) QIOSEventDispatcher::processEvents(QEventLoo if (m_processEventCallsAfterExec) --m_processEventCallsAfterExec; - // If we're running with nested event loops and the application is quit, - // then the forwarded interrupt call will happen while our processEvent - // counter is still 2, and we won't detect that we're about to fall down - // to the root iOS run-loop. We do an extra check here to catch that case. - checkIfEventLoopShouldExit(); - return processedEvents; } -void QIOSEventDispatcher::interrupt() -{ - QEventDispatcherCoreFoundation::interrupt(); - - if (!rootLevelRunLoopIntegration()) - return; - - // If an interrupt happens as part of a non-nested event loop, that is, - // by processing an event or timer in the root iOS run-loop, we'll be - // able to detect it here. - checkIfEventLoopShouldExit(); -} - -void QIOSEventDispatcher::checkIfEventLoopShouldExit() -{ - if (m_processEventCallsAfterExec == 1) { - qEventDispatcherDebug() << "Hit root runloop level, watching for runloop exit"; - m_runLoopExitObserver.addToMode(kCFRunLoopCommonModes); - } -} - void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity) { Q_UNUSED(activity); Q_ASSERT(activity == kCFRunLoopExit); - m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes); - - interruptEventLoopExec(); + if (m_processEventCallsAfterExec == 1 && !QThreadData::current()->eventLoops.top()->isRunning()) { + qEventDispatcherDebug() << "Root runloop level exited"; + interruptEventLoopExec(); + } } void QIOSEventDispatcher::interruptEventLoopExec() @@ -521,6 +497,8 @@ void QIOSEventDispatcher::interruptEventLoopExec() --m_processEventCallsAfterExec; + m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes); + // We re-set applicationProcessEventsReturnPoint here so that future // calls to QEventLoop::exec() will end up back here after entering // processEvents, instead of back in didFinishLaunchingWithOptions. -- cgit v1.2.3 From 44e68b90266336d3d46279eddcbb2a4a775f0d2a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 30 Oct 2013 13:19:26 +0200 Subject: Windows: Do not use blend function for GL windows with alpha. Task-number: QTBUG-34376 Change-Id: I81a5ee6ff14e5472eb1f3846577d86b615be34e0 Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1909e0313b..d3d381ae28 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -305,7 +305,7 @@ bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool has #endif // Q_OS_WINCE } -static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal level) +static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bool openGL, qreal level) { #ifdef Q_OS_WINCE // WINCE does not support that feature and microsoft explicitly warns to use those calls Q_UNUSED(hwnd); @@ -314,8 +314,8 @@ static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qr Q_UNUSED(level); #else if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) { - if (hasAlpha && (flags & Qt::FramelessWindowHint)) { - // Windows with alpha: Use blend function to update. + if (hasAlpha && !openGL && (flags & Qt::FramelessWindowHint)) { + // Non-GL windows with alpha: Use blend function to update. BLENDFUNCTION blend = {AC_SRC_OVER, 0, (BYTE)(255.0 * level), AC_SRC_ALPHA}; QWindowsContext::user32dll.updateLayeredWindow(hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA); } else { @@ -661,7 +661,7 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLe EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED); } - setWindowOpacity(hwnd, flags, hasAlpha, opacityLevel); + setWindowOpacity(hwnd, flags, hasAlpha, isGL, opacityLevel); } else { // child. SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags); } @@ -1745,7 +1745,9 @@ void QWindowsWindow::setOpacity(qreal level) if (m_opacity != level) { m_opacity = level; if (m_data.hwnd) - setWindowOpacity(m_data.hwnd, m_data.flags, window()->format().hasAlpha(), level); + setWindowOpacity(m_data.hwnd, m_data.flags, + window()->format().hasAlpha(), testFlag(OpenGLSurface), + level); } } -- cgit v1.2.3 From a316bdadc0200cf1a0e60562364f84c0f49d1488 Mon Sep 17 00:00:00 2001 From: Kari P Date: Thu, 24 Oct 2013 08:56:30 +0300 Subject: Mac: Modify Qt::SizeAllCursor to look like arrows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Mac, Qt::SizeAllCursor showed a spreadsheet cell selection cursor. It has been changed to look like it looks in the Qt Documentation. Task-number: QTBUG-27577 Change-Id: I2d50ab0d813137366b56cb30b8784ecf70392d4e Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/images/sizeallcursor.png | Bin 0 -> 703 bytes src/plugins/platforms/cocoa/qcocoacursor.mm | 4 ++-- src/plugins/platforms/cocoa/qcocoaresources.qrc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 src/plugins/platforms/cocoa/images/sizeallcursor.png (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/images/sizeallcursor.png b/src/plugins/platforms/cocoa/images/sizeallcursor.png new file mode 100644 index 0000000000..bb5381ba32 Binary files /dev/null and b/src/plugins/platforms/cocoa/images/sizeallcursor.png differ diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index e5b41e7a88..d734c36d6f 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -218,8 +218,8 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor) return createCursorFromPixmap(pixmap, hotspot); break; } case Qt::SizeAllCursor: { - QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/pluscursor.png")); - return createCursorFromPixmap(pixmap, hotspot); + QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/sizeallcursor.png")); + return createCursorFromPixmap(pixmap, QPoint(8, 8)); break; } case Qt::BusyCursor: { QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/waitcursor.png")); diff --git a/src/plugins/platforms/cocoa/qcocoaresources.qrc b/src/plugins/platforms/cocoa/qcocoaresources.qrc index 392300bb03..9e0640db7d 100644 --- a/src/plugins/platforms/cocoa/qcocoaresources.qrc +++ b/src/plugins/platforms/cocoa/qcocoaresources.qrc @@ -4,7 +4,7 @@ images/forbiddencursor.png images/spincursor.png images/waitcursor.png -images/pluscursor.png +images/sizeallcursor.png images/leopard-unified-toolbar-on.png -- cgit v1.2.3 From eb64c765e3aa37da1373360c557e23aa29a2db48 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 30 Oct 2013 09:36:44 +0100 Subject: iOS: clear focus object when resigning first responder status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of deactivating the window when we resign first responder status, we now leave it focused, and tell it to clear its focus object instead. This will work better with the rest of Qt, which expects a window to have focus when its in front. Change-Id: I6fcc232467af306b791a834f4843bfd2786b206f Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index dbeec5f5f2..74a56b0934 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -48,6 +48,7 @@ #include "qiosviewcontroller.h" #include "qiosintegration.h" #include +#include #include #import @@ -256,7 +257,10 @@ - (BOOL)resignFirstResponder { - QWindowSystemInterface::handleWindowActivated(0); + // Resigning first responed status means that the virtual keyboard was closed, or + // some other view became first responder. In either case we clear the focus object to + // avoid blinking cursors in line edits etc: + static_cast(QObjectPrivate::get(m_qioswindow->window()))->clearFocusObject(); return [super resignFirstResponder]; } -- cgit v1.2.3 From fecc820c582f604babbbaabb86ecd0c1f51c3487 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 28 Oct 2013 12:50:59 +0100 Subject: iOS: bugfix touch events when not using alien MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that 130ee40b broke touch handling for non-alien QWindows. For those cases, a QWindow that is a child of another QWindow will get its own UIView to back it up. The current code did not take this into account when calculating the global coordinates of touch events. Instead we need to search for the top level QWindow it might be inside before we find the view that acts as the "desktop" for it. Change-Id: Ie3c19bf86c92fa3f247a0764116830e91b8322d2 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 74a56b0934..5a2a1122ec 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -151,9 +151,16 @@ - (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state { - // We deliver touch events with global coordinates. But global in this respect means - // the coordinate system where this QWindow lives. And that is our superview. - CGSize parentSize = self.superview.frame.size; + // We deliver touch events in global coordinates. But global in this respect + // means the same coordinate system that we use for describing the geometry + // of the top level QWindow we're inside. And that would be the coordinate + // system of the superview of the UIView that backs that window: + QPlatformWindow *topLevel = m_qioswindow; + while (QPlatformWindow *topLevelParent = topLevel->parent()) + topLevel = topLevelParent; + UIView *rootView = reinterpret_cast(topLevel->winId()).superview; + CGSize rootViewSize = rootView.frame.size; + foreach (UITouch *uiTouch, m_activeTouches.keys()) { QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch]; if (![touches containsObject:uiTouch]) { @@ -161,9 +168,9 @@ } else { touchPoint.state = state; touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0; - QPoint touchPos = fromCGPoint([uiTouch locationInView:self.superview]); + QPoint touchPos = fromCGPoint([uiTouch locationInView:rootView]); touchPoint.area = QRectF(touchPos, QSize(0, 0)); - touchPoint.normalPosition = QPointF(touchPos.x() / parentSize.width, touchPos.y() / parentSize.height); + touchPoint.normalPosition = QPointF(touchPos.x() / rootViewSize.width, touchPos.y() / rootViewSize.height); } } } -- cgit v1.2.3 From d1114669e301e35cc4e9b2e4c8c4b9476180fb56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 9 Oct 2013 08:43:34 +0200 Subject: Cocoa: Improve cursor setting. Implement cursor setting in terms of [NSCursor set] and [NSView cursorUpdate] using the window tracking area. Refactor cursor conversion into QCocoaCursor:: convertCursor. Rename QCoocaWindow::m_underMouseWindow to m_enterLeaveTargetWindow since it's set according to spesific enter/leave logic. Add m_windowUnderMouse which tracks mouseEntered/mouseExited state. Task-number: QTBUG-33961 Change-Id: Id5e12594f5db365e09c9926a4c08d748a9afb935 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoacursor.h | 5 +- src/plugins/platforms/cocoa/qcocoacursor.mm | 75 ++++++++++++++++------------- src/plugins/platforms/cocoa/qcocoawindow.h | 6 ++- src/plugins/platforms/cocoa/qcocoawindow.mm | 19 ++++++++ src/plugins/platforms/cocoa/qnsview.mm | 27 ++++++++--- 5 files changed, 88 insertions(+), 44 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h index dfa1fcff81..f332240724 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.h +++ b/src/plugins/platforms/cocoa/qcocoacursor.h @@ -55,12 +55,13 @@ public: QCocoaCursor(); ~QCocoaCursor(); - virtual void changeCursor(QCursor * widgetCursor, QWindow * widget); + virtual void changeCursor(QCursor *cursor, QWindow *window); virtual QPoint pos() const; virtual void setPos(const QPoint &position); private: QHash m_cursors; - NSCursor *createCursorData(QCursor *); + NSCursor *convertCursor(QCursor *cursor); + NSCursor *createCursorData(QCursor * cursor); NSCursor *createCursorFromBitmap(const QBitmap *bitmap, const QBitmap *mask, const QPoint hotspot = QPoint()); NSCursor *createCursorFromPixmap(const QPixmap pixmap, const QPoint hotspot = QPoint()); }; diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index d734c36d6f..13f6423701 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qcocoacursor.h" +#include "qcocoawindow.h" #include "qcocoahelpers.h" #include "qcocoaautoreleasepool.h" @@ -63,82 +64,90 @@ QCocoaCursor::~QCocoaCursor() void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window) { - Q_UNUSED(window); + NSCursor * cocoaCursor = convertCursor(cursor); + if (QPlatformWindow * platformWindow = window->handle()) + static_cast(platformWindow)->setWindowCursor(cocoaCursor); +} + +QPoint QCocoaCursor::pos() const +{ + return qt_mac_flipPoint([NSEvent mouseLocation]).toPoint(); +} + +void QCocoaCursor::setPos(const QPoint &position) +{ + CGPoint pos; + pos.x = position.x(); + pos.y = position.y(); + + CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0); + CGEventPost(kCGHIDEventTap, e); + CFRelease(e); +} + +NSCursor *QCocoaCursor::convertCursor(QCursor * cursor) +{ const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + NSCursor *cocoaCursor; + // Check for a suitable built-in NSCursor first: switch (newShape) { case Qt::ArrowCursor: - [[NSCursor arrowCursor] set]; + cocoaCursor= [NSCursor arrowCursor]; break; case Qt::CrossCursor: - [[NSCursor crosshairCursor] set]; + cocoaCursor = [NSCursor crosshairCursor]; break; case Qt::IBeamCursor: - [[NSCursor IBeamCursor] set]; + cocoaCursor = [NSCursor IBeamCursor]; break; case Qt::WhatsThisCursor: //for now just use the pointing hand case Qt::PointingHandCursor: - [[NSCursor pointingHandCursor] set]; + cocoaCursor = [NSCursor pointingHandCursor]; break; case Qt::SplitVCursor: - [[NSCursor resizeUpDownCursor] set]; + cocoaCursor = [NSCursor resizeUpDownCursor]; break; case Qt::SplitHCursor: - [[NSCursor resizeLeftRightCursor] set]; + cocoaCursor = [NSCursor resizeLeftRightCursor]; break; case Qt::OpenHandCursor: - [[NSCursor openHandCursor] set]; + cocoaCursor = [NSCursor openHandCursor]; break; case Qt::ClosedHandCursor: - [[NSCursor closedHandCursor] set]; + cocoaCursor = [NSCursor closedHandCursor]; break; case Qt::DragMoveCursor: - [[NSCursor crosshairCursor] set]; + cocoaCursor = [NSCursor crosshairCursor]; break; case Qt::DragCopyCursor: - [[NSCursor crosshairCursor] set]; + cocoaCursor = [NSCursor crosshairCursor]; break; case Qt::DragLinkCursor: - [[NSCursor dragLinkCursor] set]; + cocoaCursor = [NSCursor dragLinkCursor]; break; default : { // No suitable OS cursor exist, use cursors provided // by Qt for the rest. Check for a cached cursor: - NSCursor *cocoaCursor = m_cursors.value(newShape); + cocoaCursor = m_cursors.value(newShape); if (cocoaCursor && cursor->shape() == Qt::BitmapCursor) { [cocoaCursor release]; cocoaCursor = 0; } if (cocoaCursor == 0) { cocoaCursor = createCursorData(cursor); - if (cocoaCursor == 0) { - [[NSCursor arrowCursor] set]; - return; - } + if (cocoaCursor == 0) + return [NSCursor arrowCursor]; + m_cursors.insert(newShape, cocoaCursor); } - [cocoaCursor set]; break; } } + return cocoaCursor; } -QPoint QCocoaCursor::pos() const -{ - return qt_mac_flipPoint([NSEvent mouseLocation]).toPoint(); -} - -void QCocoaCursor::setPos(const QPoint &position) -{ - CGPoint pos; - pos.x = position.x(); - pos.y = position.y(); - - CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0); - CGEventPost(kCGHIDEventTap, e); - CFRelease(e); -} // Creates an NSCursor for the given QCursor. NSCursor *QCocoaCursor::createCursorData(QCursor *cursor) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 7f0f07e912..4f5a208f43 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -154,6 +154,8 @@ public: void setMenubar(QCocoaMenuBar *mb); QCocoaMenuBar *menubar() const; + void setWindowCursor(NSCursor *cursor); + void registerTouch(bool enable); qreal devicePixelRatio() const; @@ -190,11 +192,13 @@ public: // for QNSView Qt::WindowState m_synchedWindowState; Qt::WindowModality m_windowModality; QPointer m_activePopupWindow; - QPointer m_underMouseWindow; + QPointer m_enterLeaveTargetWindow; + bool m_windowUnderMouse; bool m_inConstructor; QCocoaGLContext *m_glContext; QCocoaMenuBar *m_menubar; + NSCursor *m_windowCursor; bool m_hasModalSession; bool m_frameStrutEventsEnabled; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 845cc1202f..565594a98a 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -206,9 +206,11 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_nsWindowDelegate(0) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) + , m_windowUnderMouse(false) , m_inConstructor(true) , m_glContext(0) , m_menubar(0) + , m_windowCursor(0) , m_hasModalSession(false) , m_frameStrutEventsEnabled(false) , m_isExposed(false) @@ -1030,6 +1032,23 @@ QCocoaMenuBar *QCocoaWindow::menubar() const return m_menubar; } +void QCocoaWindow::setWindowCursor(NSCursor *cursor) +{ + // This function is called (via QCocoaCursor) by Qt to set + // the cursor for this window. It can be called for a window + // that is not currenly under the mouse pointer (for example + // for a popup window.) Qt expects the set cursor to "stick": + // it should be accociated with the window until a different + // cursor is set. + + // Cocoa has different abstractions. We can set the cursor *now*: + if (m_windowUnderMouse) + [cursor set]; + // or we can set the cursor on mouse enter/leave using tracking + // areas. This is done in QNSView, save the cursor: + m_windowCursor = cursor; +} + void QCocoaWindow::registerTouch(bool enable) { m_registerTouchCount += enable ? 1 : -1; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 8f839384df..71c4de3b69 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -671,7 +671,7 @@ static QTouchDevice *touchDevice = 0; // mouse moves delivered to it (Apple recommends keeping it OFF because there // is a performance hit). So it goes. NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp - | NSTrackingInVisibleRect | NSTrackingMouseMoved; + | NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate; NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame] options:trackingOptions owner:self @@ -680,6 +680,13 @@ static QTouchDevice *touchDevice = 0; [self addTrackingArea:ta]; } +-(void)cursorUpdate:(NSEvent *)theEvent +{ + Q_UNUSED(theEvent) + if (m_platformWindow->m_windowCursor) + [m_platformWindow->m_windowCursor set]; +} + - (void)mouseMoved:(NSEvent *)theEvent { if (m_window->flags() & Qt::WindowTransparentForInput) @@ -696,9 +703,9 @@ static QTouchDevice *touchDevice = 0; // handling mouseEnter and mouseLeave envents, since they are sent // individually to different views. if (m_platformWindow->m_nsWindow && childWindow) { - if (childWindow != m_platformWindow->m_underMouseWindow) { - QWindowSystemInterface::handleEnterLeaveEvent(childWindow, m_platformWindow->m_underMouseWindow, windowPoint, screenPoint); - m_platformWindow->m_underMouseWindow = childWindow; + if (childWindow != m_platformWindow->m_enterLeaveTargetWindow) { + QWindowSystemInterface::handleEnterLeaveEvent(childWindow, m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint); + m_platformWindow->m_enterLeaveTargetWindow = childWindow; } } @@ -712,6 +719,8 @@ static QTouchDevice *touchDevice = 0; - (void)mouseEntered:(NSEvent *)theEvent { + m_platformWindow->m_windowUnderMouse = true; + if (m_window->flags() & Qt::WindowTransparentForInput) return [super mouseEntered:theEvent]; @@ -722,12 +731,14 @@ static QTouchDevice *touchDevice = 0; QPointF windowPoint; QPointF screenPoint; [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint]; - m_platformWindow->m_underMouseWindow = m_platformWindow->childWindowAt(windowPoint.toPoint()); - QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_underMouseWindow, windowPoint, screenPoint); + m_platformWindow->m_enterLeaveTargetWindow = m_platformWindow->childWindowAt(windowPoint.toPoint()); + QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint); } - (void)mouseExited:(NSEvent *)theEvent { + m_platformWindow->m_windowUnderMouse = false; + if (m_window->flags() & Qt::WindowTransparentForInput) return [super mouseExited:theEvent]; Q_UNUSED(theEvent); @@ -736,8 +747,8 @@ static QTouchDevice *touchDevice = 0; if (!m_platformWindow->m_nsWindow) return; - QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_underMouseWindow); - m_platformWindow->m_underMouseWindow = 0; + QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_enterLeaveTargetWindow); + m_platformWindow->m_enterLeaveTargetWindow = 0; } - (void)rightMouseDown:(NSEvent *)theEvent -- cgit v1.2.3 From b7440536c788b04861591187edd071bf2c2ec137 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 31 Oct 2013 18:00:30 +0200 Subject: Android: Handle virtual keyboard visibility changes. emitInputPanelVisibleChanged when virtual keyboard visibility is changed. Task-number: QTBUG-34347 Change-Id: Iab7374db42ff8ce6f33dcc793b23f84d3c8692d5 Reviewed-by: Paul Olav Tvete --- .../platforms/android/src/androidjniinput.cpp | 31 ++++++++++++++++++++-- .../platforms/android/src/qandroidinputcontext.cpp | 5 ++++ .../platforms/android/src/qandroidinputcontext.h | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp index 30d4e69afe..27d29129f8 100644 --- a/src/plugins/platforms/android/src/androidjniinput.cpp +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -47,6 +47,10 @@ #include #include +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL +# include +#endif + using namespace QtAndroid; namespace QtAndroidInput @@ -86,6 +90,9 @@ namespace QtAndroidInput width, height, inputHints); +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints; +#endif } void resetSoftwareKeyboard() @@ -95,6 +102,9 @@ namespace QtAndroidInput return; env.jniEnv->CallStaticVoidMethod(applicationClass(), m_resetSoftwareKeyboardMethodID); +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << "@@@ RESETSOFTWAREKEYBOARD"; +#endif } void hideSoftwareKeyboard() @@ -104,6 +114,9 @@ namespace QtAndroidInput return; env.jniEnv->CallStaticVoidMethod(applicationClass(), m_hideSoftwareKeyboardMethodID); +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << "@@@ HIDESOFTWAREKEYBOARD"; +#endif } bool isSoftwareKeyboardVisible() @@ -112,7 +125,11 @@ namespace QtAndroidInput if (!env.jniEnv) return false; - return env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_isSoftwareKeyboardVisibleMethodID); + bool visibility = env.jniEnv->CallStaticBooleanMethod(applicationClass(), m_isSoftwareKeyboardVisibleMethodID); +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << "@@@ ISSOFTWAREKEYBOARDVISIBLE" << visibility; +#endif + return visibility; } @@ -511,6 +528,15 @@ namespace QtAndroidInput false); } + static void keyboardVisibilityChanged(JNIEnv */*env*/, jobject /*thiz*/, jboolean /*visibility*/) + { + QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext(); + if (inputContext) + inputContext->emitInputPanelVisibleChanged(); +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << "@@@ KEYBOARDVISIBILITYCHANGED" << inputContext; +#endif + } static JNINativeMethod methods[] = { {"touchBegin","(I)V",(void*)touchBegin}, @@ -521,7 +547,8 @@ namespace QtAndroidInput {"mouseMove", "(III)V", (void *)mouseMove}, {"longPress", "(III)V", (void *)longPress}, {"keyDown", "(III)V", (void *)keyDown}, - {"keyUp", "(III)V", (void *)keyUp} + {"keyUp", "(III)V", (void *)keyUp}, + {"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged} }; #define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.cpp b/src/plugins/platforms/android/src/qandroidinputcontext.cpp index 386c8e006a..8556e8ebf1 100644 --- a/src/plugins/platforms/android/src/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/src/qandroidinputcontext.cpp @@ -381,6 +381,11 @@ QAndroidInputContext::~QAndroidInputContext() m_textFieldID = 0; } +QAndroidInputContext *QAndroidInputContext::androidInputContext() +{ + return m_androidInputContext; +} + void QAndroidInputContext::reset() { clear(); diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.h b/src/plugins/platforms/android/src/qandroidinputcontext.h index d19dcc384b..041bd0dc49 100644 --- a/src/plugins/platforms/android/src/qandroidinputcontext.h +++ b/src/plugins/platforms/android/src/qandroidinputcontext.h @@ -80,6 +80,7 @@ public: public: QAndroidInputContext(); ~QAndroidInputContext(); + static QAndroidInputContext * androidInputContext(); bool isValid() const { return true; } void reset(); -- cgit v1.2.3 From c95e1567e9f42239bb83a64c4e5f18c48f3ee022 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 1 Nov 2013 11:01:04 +0200 Subject: Remove unused field. Fix crash on Android 4.4 Change-Id: Ibee584c0154b0b116af58477302e7e8385f0290d Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/src/androidjnimain.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index abfc2fa19c..8b29a895b1 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -111,8 +111,6 @@ static jobject m_surface = NULL; static EGLNativeWindowType m_nativeWindow = 0; static QSemaphore m_waitForWindowSemaphore; static bool m_waitForWindow = false; - -static jfieldID m_surfaceFieldID = 0; #endif @@ -763,11 +761,6 @@ static int registerNatives(JNIEnv *env) GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V"); -#ifdef ANDROID_PLUGIN_OPENGL - FIND_AND_CHECK_CLASS("android/view/Surface"); - GET_AND_CHECK_FIELD(m_surfaceFieldID, clazz, "mNativeSurface", "I"); -#endif - jmethodID methodID; GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;"); jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID); -- cgit v1.2.3 From 48dcdbe51040c50ada8f709830e66644a31fb82b Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 1 Nov 2013 11:45:21 +0200 Subject: Android: implement a simple cache mechanism for assets dirs. AAssetManager_openDir is a pretty slow operation, so we are caching the most used dir contents. Task-number: QTBUG-34464 Change-Id: If198f7dae0d6961291c992e6eb46839ba5455819 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../src/qandroidassetsfileenginehandler.cpp | 73 ++++++++++++++-------- .../android/src/qandroidassetsfileenginehandler.h | 8 ++- 2 files changed, 54 insertions(+), 27 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp index f3cb2586cc..95844fc649 100644 --- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp +++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp @@ -43,20 +43,32 @@ #include "androidjnimain.h" #include +#include + +typedef QVector FilesList; + +struct AndroidAssetDir +{ + AndroidAssetDir(AAssetDir* ad) + { + const char *fileName; + while ((fileName = AAssetDir_getNextFileName(ad))) + m_items.push_back(QString::fromUtf8(fileName)); + AAssetDir_close(ad); + } + FilesList m_items; +}; class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator { public: AndroidAbstractFileEngineIterator(QDir::Filters filters, const QStringList &nameFilters, - AAssetDir *asset, + QSharedPointer asset, const QString &path) : QAbstractFileEngineIterator(filters, nameFilters) { - AAssetDir_rewind(asset); - const char *fileName; - while ((fileName = AAssetDir_getNextFileName(asset))) - m_items << fileName; + m_items = asset->m_items; m_index = -1; m_path = path; } @@ -93,7 +105,7 @@ public: private: QString m_path; - QStringList m_items; + FilesList m_items; int m_index; }; @@ -102,12 +114,11 @@ class AndroidAbstractFileEngine: public QAbstractFileEngine public: explicit AndroidAbstractFileEngine(AAsset *asset, const QString &fileName) { - m_assetDir = 0; m_assetFile = asset; m_fileName = fileName; } - explicit AndroidAbstractFileEngine(AAssetDir *asset, const QString &fileName) + explicit AndroidAbstractFileEngine(QSharedPointer asset, const QString &fileName) { m_assetFile = 0; m_assetDir = asset; @@ -119,8 +130,6 @@ public: ~AndroidAbstractFileEngine() { close(); - if (m_assetDir) - AAssetDir_close(m_assetDir); } virtual bool open(QIODevice::OpenMode openMode) @@ -188,7 +197,7 @@ public: FileFlags flags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag); if (m_assetFile) flags |= FileType; - if (m_assetDir) + if (!m_assetDir.isNull()) flags |= DirectoryType; return type & flags; @@ -233,19 +242,19 @@ public: virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) { - if (m_assetDir) + if (!m_assetDir.isNull()) return new AndroidAbstractFileEngineIterator(filters, filterNames, m_assetDir, m_fileName); return 0; } private: AAsset *m_assetFile; - AAssetDir *m_assetDir; + QSharedPointer m_assetDir; QString m_fileName; }; -AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler() +AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler():m_assetsCache(std::max(5, qgetenv("QT_ANDROID_MAX_ASSETS_CACHE_SIZE").toInt())) { m_assetManager = QtAndroid::assetManager(); } @@ -264,25 +273,37 @@ QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &file int prefixSize=8; - m_path.clear(); + QByteArray path; if (!fileName.endsWith(QLatin1Char('/'))) { - m_path = fileName.toUtf8(); + path = fileName.toUtf8(); AAsset *asset = AAssetManager_open(m_assetManager, - m_path.constData() + prefixSize, + path.constData() + prefixSize, AASSET_MODE_BUFFER); if (asset) return new AndroidAbstractFileEngine(asset, fileName); } - if (!m_path.size()) - m_path = fileName.left(fileName.length() - 1).toUtf8(); - - AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, m_path.constData() + prefixSize); - if (assetDir) { - if (AAssetDir_getNextFileName(assetDir)) - return new AndroidAbstractFileEngine(assetDir, fileName); - else - AAssetDir_close(assetDir); + if (!path.size()) + path = fileName.left(fileName.length() - 1).toUtf8(); + + m_assetsCacheMutext.lock(); + QSharedPointer *aad = m_assetsCache.object(path); + m_assetsCacheMutext.unlock(); + if (!aad) { + AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, path.constData() + prefixSize); + if (assetDir) { + if (AAssetDir_getNextFileName(assetDir)) { + aad = new QSharedPointer(new AndroidAssetDir(assetDir)); + m_assetsCacheMutext.lock(); + m_assetsCache.insert(path, aad); + m_assetsCacheMutext.unlock(); + return new AndroidAbstractFileEngine(*aad, fileName); + } else { + AAssetDir_close(assetDir); + } + } + } else { + return new AndroidAbstractFileEngine(*aad, fileName); } return 0; } diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h index 9bff6a012e..7bd560886c 100644 --- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h +++ b/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h @@ -43,8 +43,13 @@ #define QANDROIDASSETSFILEENGINEHANDLER_H #include +#include +#include +#include + #include +struct AndroidAssetDir; class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler { public: @@ -54,7 +59,8 @@ public: private: AAssetManager *m_assetManager; - mutable QByteArray m_path; + mutable QCache> m_assetsCache; + mutable QMutex m_assetsCacheMutext; }; #endif // QANDROIDASSETSFILEENGINEHANDLER_H -- cgit v1.2.3 From efc61299bd51018df272b296b2c849071f685a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Mon, 21 Oct 2013 17:58:43 +0200 Subject: Android: Check for null pointer before calling ANativeWindow_release() Calling ANativeWindow_release() with a null pointer will cause a SIGSEGV. Task-number: QTBUG-33955 Change-Id: If7d1afa3baea04360507eec5042b4e18a0272527 Reviewed-by: Laszlo Agocs Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp index e7e53e72a2..278cd553f4 100644 --- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp +++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp @@ -120,7 +120,8 @@ EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(QPlatformWindow *plat void QEglFSAndroidHooks::destroyNativeWindow(EGLNativeWindowType window) { - ANativeWindow_release(window); + if (window != 0) + ANativeWindow_release(window); } bool QEglFSAndroidHooks::hasCapability(QPlatformIntegration::Capability capability) const -- cgit v1.2.3 From 59569fd0202c52a16860fba5634e743286a19fd2 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 31 Oct 2013 16:14:54 +0100 Subject: Android: Differ between ShowMaximized and ShowFullScreen The default is now ShowMaximized which behaves as it did before, i.e. each window will fill the screen but the status bar will be visible. Calling showFullScreen() explicitly will now hide the status bar to maximize the amount of screen real estate occupied by the application. Task-number: QTBUG-33135 Change-Id: If0d0a2ab72f8026e76818290e2b953dbc0dec156 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/opengl/opengl.pro | 6 ++- .../platforms/android/src/androidjnimain.cpp | 34 ++++++++++++ src/plugins/platforms/android/src/androidjnimain.h | 5 +- .../src/opengl/qandroidopenglplatformscreen.cpp | 59 +++++++++++++++++++++ .../src/opengl/qandroidopenglplatformscreen.h | 60 ++++++++++++++++++++++ .../src/opengl/qandroidopenglplatformwindow.cpp | 27 ++++++++++ .../src/opengl/qandroidopenglplatformwindow.h | 3 ++ .../android/src/qandroidplatformintegration.cpp | 14 ++++- .../android/src/qandroidplatformintegration.h | 4 ++ .../android/src/raster/qandroidplatformscreen.cpp | 7 +++ .../android/src/raster/qandroidplatformwindow.cpp | 37 ++++++++++++- .../android/src/raster/qandroidplatformwindow.h | 5 ++ src/plugins/platforms/eglfs/qeglfsintegration.cpp | 7 ++- src/plugins/platforms/eglfs/qeglfsintegration.h | 3 ++ src/plugins/platforms/eglfs/qeglfsscreen.cpp | 17 +++++- src/plugins/platforms/eglfs/qeglfsscreen.h | 1 + 16 files changed, 279 insertions(+), 10 deletions(-) create mode 100644 src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp create mode 100644 src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/opengl/opengl.pro b/src/plugins/platforms/android/opengl/opengl.pro index 301c8e6e4c..ea050ca3a0 100644 --- a/src/plugins/platforms/android/opengl/opengl.pro +++ b/src/plugins/platforms/android/opengl/opengl.pro @@ -20,11 +20,13 @@ INCLUDEPATH += $$PWD/../src/opengl/ HEADERS += \ $$PWD/../src/opengl/qandroidopenglcontext.h \ - $$PWD/../src/opengl/qandroidopenglplatformwindow.h + $$PWD/../src/opengl/qandroidopenglplatformwindow.h \ + $$PWD/../src/opengl/qandroidopenglplatformscreen.h SOURCES += \ $$PWD/../src/opengl/qandroidopenglcontext.cpp \ - $$PWD/../src/opengl/qandroidopenglplatformwindow.cpp + $$PWD/../src/opengl/qandroidopenglplatformwindow.cpp \ + $$PWD/../src/opengl/qandroidopenglplatformscreen.cpp include($$PWD/../../eglfs/eglfs.pri) include($$PWD/../src/src.pri) diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 8b29a895b1..9ce79f445a 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -97,6 +97,9 @@ static jmethodID m_createBitmapMethodID = 0; static jobject m_ARGB_8888_BitmapConfigValue = 0; static jobject m_RGB_565_BitmapConfigValue = 0; +jmethodID m_setFullScreenMethodID = 0; +static bool m_statusBarShowing = true; + static jclass m_bitmapDrawableClass = 0; static jmethodID m_bitmapDrawableConstructorMethodID = 0; @@ -310,6 +313,36 @@ namespace QtAndroid return m_activityObject; } + void showStatusBar() + { + if (m_statusBarShowing) + return; + + QtAndroid::AttachedJNIEnv env; + if (env.jniEnv == 0) { + qWarning("Failed to get JNI Environment."); + return; + } + + env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, false); + m_statusBarShowing = true; + } + + void hideStatusBar() + { + if (!m_statusBarShowing) + return; + + QtAndroid::AttachedJNIEnv env; + if (env.jniEnv == 0) { + qWarning("Failed to get JNI Environment."); + return; + } + + env.jniEnv->CallStaticVoidMethod(m_applicationClass, m_setFullScreenMethodID, true); + m_statusBarShowing = false; + } + void setApplicationActive() { if (m_activityActive) @@ -753,6 +786,7 @@ static int registerNatives(JNIEnv *env) jclass clazz; FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNative"); m_applicationClass = static_cast(env->NewGlobalRef(clazz)); + GET_AND_CHECK_STATIC_METHOD(m_setFullScreenMethodID, m_applicationClass, "setFullScreen", "(Z)V"); if (env->RegisterNatives(m_applicationClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed"); diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h index b530aac884..11d3573404 100644 --- a/src/plugins/platforms/android/src/androidjnimain.h +++ b/src/plugins/platforms/android/src/androidjnimain.h @@ -69,8 +69,6 @@ namespace QtAndroid void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration); void setQtThread(QThread *thread); - void setFullScreen(QWidget *widget); - #ifndef ANDROID_PLUGIN_OPENGL void flushImage(const QPoint &pos, const QImage &image, const QRect &rect); #else @@ -89,6 +87,9 @@ namespace QtAndroid void setApplicationActive(); + void showStatusBar(); + void hideStatusBar(); + jobject createBitmap(QImage img, JNIEnv *env = 0); jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0); diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp new file mode 100644 index 0000000000..821fd954df --- /dev/null +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidopenglplatformscreen.h" +#include "qandroidopenglplatformwindow.h" + +QT_BEGIN_NAMESPACE + +QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display) + : QEglFSScreen(display) +{ +} + +void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window) +{ + QAndroidOpenGLPlatformWindow *platformWindow = static_cast(window); + if (platformWindow != 0) + platformWindow->updateStatusBarVisibility(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h new file mode 100644 index 0000000000..e9251592aa --- /dev/null +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDOPENGLPLATFORMSCREEN_H +#define QANDROIDOPENGLPLATFORMSCREEN_H + +#include "qeglfsscreen.h" + +QT_BEGIN_NAMESPACE + +class QAndroidOpenGLPlatformScreen : public QEglFSScreen +{ +public: + QAndroidOpenGLPlatformScreen(EGLDisplay display); + +protected: + void topWindowChanged(QPlatformWindow *window); +}; + +QT_END_NAMESPACE + +#endif // QANDROIDOPENGLPLATFORMSCREEN_H diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp index 258a0968e8..6ed805174b 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp @@ -53,6 +53,7 @@ QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_ QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window) : QEglFSWindow(window) + , m_state(Qt::WindowNoState) { } @@ -131,12 +132,38 @@ void QAndroidOpenGLPlatformWindow::destroy() } } +void QAndroidOpenGLPlatformWindow::updateStatusBarVisibility() +{ + Qt::WindowFlags flags = window()->flags(); + bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; + if (!isNonRegularWindow) { + if (m_state & Qt::WindowFullScreen) + QtAndroid::hideStatusBar(); + else if (m_state & Qt::WindowMaximized) + QtAndroid::showStatusBar(); + } +} + void QAndroidOpenGLPlatformWindow::raise() { + updateStatusBarVisibility(); +} + +void QAndroidOpenGLPlatformWindow::setWindowState(Qt::WindowState state) +{ + if (m_state == state) + return; + + m_state = state; + if (window()->isVisible()) + updateStatusBarVisibility(); } void QAndroidOpenGLPlatformWindow::setVisible(bool visible) { + if (visible) + updateStatusBarVisibility(); + QEglFSWindow::setVisible(visible); // The Android Activity is activated before Qt is initialized, causing the application state to diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h index 9a25957ccd..e4ff0444d4 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h @@ -66,16 +66,19 @@ public: void invalidateSurface(); void resetSurface(); + void setWindowState(Qt::WindowState state); void setVisible(bool visible); void destroy(); static void updateStaticNativeWindow(); + void updateStatusBarVisibility(); private: QSize m_scheduledResize; QMutex m_lock; + Qt::WindowState m_state; static QReadWriteLock m_staticSurfaceLock; static EGLSurface m_staticSurface; diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index e48a3c9ebe..6d0ec306ab 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -61,6 +61,7 @@ # include "androidjnimenu.h" # include "qandroidopenglcontext.h" # include "qandroidopenglplatformwindow.h" +# include "qandroidopenglplatformscreen.h" # include "qeglfshooks.h" # include #endif @@ -141,7 +142,10 @@ QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(Q QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const { - return new QAndroidPlatformWindow(window); + QAndroidPlatformWindow *platformWindow = new QAndroidPlatformWindow(window); + platformWindow->setWindowState(window->windowState()); + + return platformWindow; } QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const @@ -154,6 +158,7 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind QAndroidOpenGLPlatformWindow *platformWindow = new QAndroidOpenGLPlatformWindow(window); platformWindow->create(); platformWindow->requestActivateWindow(); + platformWindow->setWindowState(window->windowState()); QtAndroidMenu::setActiveTopLevelWindow(window); return platformWindow; @@ -230,7 +235,7 @@ QPlatformServices *QAndroidPlatformIntegration::services() const QVariant QAndroidPlatformIntegration::styleHint(StyleHint hint) const { switch (hint) { - case ShowIsFullScreen: + case ShowIsMaximized: return true; default: return QPlatformIntegration::styleHint(hint); @@ -307,6 +312,11 @@ void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height) m_defaultPhysicalSizeHeight = height; } +QEglFSScreen *QAndroidPlatformIntegration::createScreen() const +{ + return new QAndroidOpenGLPlatformScreen(display()); +} + #endif void QAndroidPlatformIntegration::pauseApp() diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h index 5ebdf9e65c..3b34cdf7df 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h @@ -140,6 +140,10 @@ public: QTouchDevice *touchDevice() const { return m_touchDevice; } void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; } +#ifdef ANDROID_PLUGIN_OPENGL + QEglFSScreen *createScreen() const; +#endif + private: friend class QEglFSAndroidHooks; diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp index 0250a6122c..2e59c307c3 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp @@ -43,6 +43,7 @@ #include "qandroidplatformintegration.h" #include "androidjnimain.h" #include "androidjnimenu.h" +#include "qandroidplatformwindow.h" QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen() { @@ -57,6 +58,12 @@ QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen() void QAndroidPlatformScreen::topWindowChanged(QWindow *w) { QtAndroidMenu::setActiveTopLevelWindow(w); + + if (w != 0) { + QAndroidPlatformWindow *platformWindow = static_cast(w->handle()); + if (platformWindow != 0) + platformWindow->updateStatusBarVisibility(); + } } QRegion QAndroidPlatformScreen::doRedraw() diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp index f5fce0ae34..2dedc77027 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp @@ -44,7 +44,9 @@ #include "androidjnimain.h" #include -QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window) +QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) + : QFbWindow(window) + , m_state(Qt::WindowNoState) { } @@ -58,8 +60,41 @@ void QAndroidPlatformWindow::propagateSizeHints() //shut up warning from default implementation } +void QAndroidPlatformWindow::updateStatusBarVisibility() +{ + Qt::WindowFlags flags = window()->flags(); + bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; + if (!isNonRegularWindow) { + if (m_state & Qt::WindowFullScreen) + QtAndroid::hideStatusBar(); + else if (m_state & Qt::WindowMaximized) + QtAndroid::showStatusBar(); + } +} + +void QAndroidPlatformWindow::raise() +{ + updateStatusBarVisibility(); + QFbWindow::raise(); +} + +void QAndroidPlatformWindow::setWindowState(Qt::WindowState state) +{ + if (m_state == state) + return; + + m_state = state; + if (window()->isVisible()) + updateStatusBarVisibility(); + + QFbWindow::setWindowState(state); +} + void QAndroidPlatformWindow::setVisible(bool visible) { + if (visible) + updateStatusBarVisibility(); + QFbWindow::setVisible(visible); // The Android Activity is activated before Qt is initialized, causing the application state to diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h index 58e6451ea1..87626b982a 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h @@ -52,11 +52,16 @@ public: void propagateSizeHints(); + void raise(); + void setWindowState(Qt::WindowState state); void setVisible(bool visible); + void updateStatusBarVisibility(); public slots: void setGeometry(const QRect &rect); +private: + Qt::WindowState m_state; }; #endif // ANDROIDPLATFORMWINDOW_H diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 8a526dbff5..9f8c0747df 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -165,7 +165,7 @@ void QEglFSIntegration::initialize() qFatal("EGL error"); } - mScreen = new QEglFSScreen(mDisplay); + mScreen = createScreen(); screenAdded(mScreen); mInputContext = QPlatformInputContextFactory::create(); @@ -173,6 +173,11 @@ void QEglFSIntegration::initialize() createInputHandlers(); } +QEglFSScreen *QEglFSIntegration::createScreen() const +{ + return new QEglFSScreen(mDisplay); +} + QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const { switch (hint) diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h index a6fcfc8427..f685eec2d4 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.h +++ b/src/plugins/platforms/eglfs/qeglfsintegration.h @@ -86,6 +86,9 @@ public: QPlatformInputContext *inputContext() const { return mInputContext; } +protected: + virtual QEglFSScreen *createScreen() const; + private: void createInputHandlers(); diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp index 3f92d60aa2..758b461b3f 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp @@ -126,26 +126,34 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface) void QEglFSScreen::addWindow(QEglFSWindow *window) { - if (!m_windows.contains(window)) + if (!m_windows.contains(window)) { m_windows.append(window); + topWindowChanged(window); + } } void QEglFSScreen::removeWindow(QEglFSWindow *window) { m_windows.removeOne(window); + if (!m_windows.isEmpty()) + topWindowChanged(m_windows.last()); } void QEglFSScreen::moveToTop(QEglFSWindow *window) { m_windows.removeOne(window); m_windows.append(window); + topWindowChanged(window); } void QEglFSScreen::changeWindowIndex(QEglFSWindow *window, int newIdx) { int idx = m_windows.indexOf(window); - if (idx != -1 && idx != newIdx) + if (idx != -1 && idx != newIdx) { m_windows.move(idx, newIdx); + if (newIdx == m_windows.size() - 1) + topWindowChanged(m_windows.last()); + } } QEglFSWindow *QEglFSScreen::rootWindow() @@ -157,4 +165,9 @@ QEglFSWindow *QEglFSScreen::rootWindow() return 0; } +void QEglFSScreen::topWindowChanged(QPlatformWindow *window) +{ + Q_UNUSED(window); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h index 578a6cf20d..11d66b7e0f 100644 --- a/src/plugins/platforms/eglfs/qeglfsscreen.h +++ b/src/plugins/platforms/eglfs/qeglfsscreen.h @@ -85,6 +85,7 @@ public: protected: void setPrimarySurface(EGLSurface surface); + virtual void topWindowChanged(QPlatformWindow *window); private: friend class QEglFSWindow; -- cgit v1.2.3 From c8df30682cecc36153b536f52cdfe4d7d789959c Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Wed, 30 Oct 2013 11:03:08 +0100 Subject: Handle keyboard focus change Call QWindowSystemInterface::handleWindowActivated when a SCREEN_EVENT_PROPERTY event for he SCREEN_PROPERTY_KEYBOARD_FOCUS property is received. Change-Id: Ic2b10c5b793dd4451adac68691296f8265a71160 Reviewed-by: Andreas Holzammer Reviewed-by: Frank Osterfeld Reviewed-by: Kevin Krammer Reviewed-by: Thomas McGuire --- .../platforms/qnx/qqnxscreeneventhandler.cpp | 46 ++++++++++++++++++++++ src/plugins/platforms/qnx/qqnxscreeneventhandler.h | 2 + 2 files changed, 48 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index c869d29c99..129f149ca1 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -125,6 +125,10 @@ bool QQnxScreenEventHandler::handleEvent(screen_event_t event, int qnxType) handleDisplayEvent(event); break; + case SCREEN_EVENT_PROPERTY: + handlePropertyEvent(event); + break; + default: // event ignored qScreenEventDebug() << Q_FUNC_INFO << "unknown event" << qnxType; @@ -496,6 +500,48 @@ void QQnxScreenEventHandler::handleDisplayEvent(screen_event_t event) } } +void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event) +{ + errno = 0; + int objectType; + if (screen_get_event_property_iv(event, SCREEN_PROPERTY_OBJECT_TYPE, &objectType) != 0) + qFatal("QQNX: failed to query object type property, errno=%d", errno); + + if (objectType != SCREEN_OBJECT_TYPE_WINDOW) + return; + + errno = 0; + screen_window_t window = 0; + if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) + qFatal("QQnx: failed to query window property, errno=%d", errno); + + errno = 0; + int property; + if (screen_get_event_property_iv(event, SCREEN_PROPERTY_NAME, &property) != 0) + qFatal("QQnx: failed to query window property, errno=%d", errno); + + switch (property) { + case SCREEN_PROPERTY_KEYBOARD_FOCUS: + handleKeyboardFocusPropertyEvent(window); + break; + default: + // event ignored + qScreenEventDebug() << Q_FUNC_INFO << "Ignore property event for property: " << property; + } +} + +void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t window) +{ + errno = 0; + int focus = 0; + if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0) + qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno); + + QWindow *w = focus ? QQnxIntegration::window(window) : 0; + + QWindowSystemInterface::handleWindowActivated(w); +} + #include "moc_qqnxscreeneventhandler.cpp" QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h index 7a1af6f343..7ceb32fcec 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h @@ -72,6 +72,8 @@ private: void handleCloseEvent(screen_event_t event); void handleCreateEvent(screen_event_t event); void handleDisplayEvent(screen_event_t event); + void handlePropertyEvent(screen_event_t event); + void handleKeyboardFocusPropertyEvent(screen_window_t window); private: enum { -- cgit v1.2.3 From 84a318c74f11ffb198c394cb07f67d137b44a5df Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Mon, 28 Oct 2013 13:56:35 +0100 Subject: enable PPS keyboard implementation also for plain QNX Integrating with /pps/services/input is also the way to go for QNX. Change-Id: If2498f2c42ed4e6e0d1cadc787cc62e80940043a Reviewed-by: Rafael Roquetto Reviewed-by: Kevin Krammer Reviewed-by: Thomas McGuire --- src/plugins/platforms/qnx/qnx.pro | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index f5a4e0735f..becf5e287e 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -2,21 +2,13 @@ TARGET = qqnx QT += platformsupport-private core-private gui-private +# The PPS based platform integration is currently used for both BB10 and plain QNX +CONFIG += qqnx_pps + # Uncomment this to build with support for IMF once it becomes available in the BBNDK #CONFIG += qqnx_imf -# Uncomment this to build with support for PPS based platform integration -#CONFIG += qqnx_pps - -CONFIG(blackberry) { - CONFIG += qqnx_pps - - # Uncomment following line to enable screen event - # handling through a dedicated thread. - # CONFIG += qqnx_screeneventthread -} else { - CONFIG += qqnx_screeneventthread -} +!blackberry:CONFIG += qqnx_screeneventthread # Uncomment these to enable debugging output for various aspects of the plugin #DEFINES += QQNXBPSEVENTFILTER_DEBUG -- cgit v1.2.3 From c982fa3666385e87d968a9f2cad70cd906a3749d Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Thu, 31 Oct 2013 13:34:57 +0100 Subject: iOS: Prevent calling QWindow methods on native NSViews MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UIViews can return nil when calling qwindow, so we must check before trying to use the QWindow handle. Change-Id: I72e9ddc58ebe10a3e7ea511f2356650402ba23f4 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 5a2a1122ec..0bfda49536 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -455,7 +455,7 @@ void QIOSWindow::raiseOrLower(bool raise) for (int i = int(subviews.count) - 1; i >= 0; --i) { UIView *view = static_cast([subviews objectAtIndex:i]); - if (view.hidden || view == m_view) + if (view.hidden || view == m_view || !view.qwindow) continue; int level = static_cast(view.qwindow->handle())->m_windowLevel; if (m_windowLevel > level || (raise && m_windowLevel == level)) { -- cgit v1.2.3 From a922b94c2fa273dfc3915c840b4b8518163d06f1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 31 Oct 2013 16:41:19 +0100 Subject: Windows: Do not detect full-screen state for child windows. Introduced by a1db174ea98fab8669da498639895bac4c894baf (Fix window state handling). Task-number: QTBUG-34477 Change-Id: I4c92edddef346f9d7c4741f2f9784e9f686e9cda Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index d3d381ae28..44fd97e1aa 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1548,7 +1548,7 @@ static const QScreen *effectiveScreen(const QWindow *w) bool QWindowsWindow::isFullScreen_sys() const { - return geometry_sys() == effectiveScreen(window())->geometry(); + return window()->isTopLevel() && geometry_sys() == effectiveScreen(window())->geometry(); } /*! -- cgit v1.2.3 From 6802f34bedca25e05d1eda962b268b1936dd4d62 Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Tue, 29 Oct 2013 10:10:32 +0100 Subject: Process screen events in the main thread Screen events are still read in the screen event thread but are processed in the main thread to make it possible to support QAbstractNativeEventFilter for screen events later. Implementation is similar to the xcb platform plugin. Change-Id: I7bade3e13e51c6d70bb608727a93bbd3aabc5d47 Reviewed-by: Thomas McGuire --- .../platforms/qnx/qqnxscreeneventhandler.cpp | 39 +++++++++++++++++++++ src/plugins/platforms/qnx/qqnxscreeneventhandler.h | 15 ++++++++ .../platforms/qnx/qqnxscreeneventthread.cpp | 40 +++++++++++++++++----- src/plugins/platforms/qnx/qqnxscreeneventthread.h | 13 +++++++ 4 files changed, 98 insertions(+), 9 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index 129f149ca1..efffd26981 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -40,6 +40,9 @@ ****************************************************************************/ #include "qqnxscreeneventhandler.h" +#if defined(QQNX_SCREENEVENTTHREAD) +#include "qqnxscreeneventthread.h" +#endif #include "qqnxintegration.h" #include "qqnxkeytranslator.h" #include "qqnxscreen.h" @@ -63,6 +66,9 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration) , m_lastButtonState(Qt::NoButton) , m_lastMouseWindow(0) , m_touchDevice(0) +#if defined(QQNX_SCREENEVENTTHREAD) + , m_eventThread(0) +#endif { // Create a touch device m_touchDevice = new QTouchDevice; @@ -182,6 +188,39 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie } } +#if defined(QQNX_SCREENEVENTTHREAD) +void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread) +{ + m_eventThread = eventThread; +} + +void QQnxScreenEventHandler::processEventsFromScreenThread() +{ + if (!m_eventThread) + return; + + QQnxScreenEventArray *events = m_eventThread->lock(); + + for (int i = 0; i < events->size(); ++i) { + screen_event_t event = events->at(i); + if (!event) + continue; + (*events)[i] = 0; + + m_eventThread->unlock(); + + handleEvent(event); + screen_destroy_event(event); + + m_eventThread->lock(); + } + + events->clear(); + + m_eventThread->unlock(); +} +#endif + void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event) { // get flags of key event diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h index 7ceb32fcec..1fdb2c83cd 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h @@ -49,6 +49,9 @@ QT_BEGIN_NAMESPACE class QQnxIntegration; +#if defined(QQNX_SCREENEVENTTHREAD) +class QQnxScreenEventThread; +#endif class QQnxScreenEventHandler : public QObject { @@ -61,10 +64,19 @@ public: static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); +#if defined(QQNX_SCREENEVENTTHREAD) + void setScreenEventThread(QQnxScreenEventThread *eventThread); +#endif + Q_SIGNALS: void newWindowCreated(void *window); void windowClosed(void *window); +#if defined(QQNX_SCREENEVENTTHREAD) +private Q_SLOTS: + void processEventsFromScreenThread(); +#endif + private: void handleKeyboardEvent(screen_event_t event); void handlePointerEvent(screen_event_t event); @@ -87,6 +99,9 @@ private: screen_window_t m_lastMouseWindow; QTouchDevice *m_touchDevice; QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints]; +#if defined(QQNX_SCREENEVENTTHREAD) + QQnxScreenEventThread *m_eventThread; +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp index f3f660bc03..25a597bab9 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp @@ -61,6 +61,9 @@ QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context, QQnxScree m_screenEventHandler(screenEventHandler), m_quit(false) { + screenEventHandler->setScreenEventThread(this); + connect(this, SIGNAL(eventPending()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection); + connect(this, SIGNAL(finished()), screenEventHandler, SLOT(processEventsFromScreenThread()), Qt::QueuedConnection); } QQnxScreenEventThread::~QQnxScreenEventThread() @@ -74,20 +77,31 @@ void QQnxScreenEventThread::injectKeyboardEvent(int flags, int sym, int mod, int QQnxScreenEventHandler::injectKeyboardEvent(flags, sym, mod, scan, cap); } -void QQnxScreenEventThread::run() +QQnxScreenEventArray *QQnxScreenEventThread::lock() { - screen_event_t event; + m_mutex.lock(); + return &m_events; +} - // create screen event - errno = 0; - int result = screen_create_event(&event); - if (result) - qFatal("QQNX: failed to create screen event, errno=%d", errno); +void QQnxScreenEventThread::unlock() +{ + m_mutex.unlock(); +} +void QQnxScreenEventThread::run() +{ qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread started"; // loop indefinitely while (!m_quit) { + screen_event_t event; + + // create screen event + errno = 0; + int result = screen_create_event(&event); + if (result) + qFatal("QQNX: failed to create screen event, errno=%d", errno); + // block until screen event is available errno = 0; @@ -108,14 +122,22 @@ void QQnxScreenEventThread::run() qScreenEventThreadDebug() << Q_FUNC_INFO << "QNX user screen event"; m_quit = true; } else { - m_screenEventHandler->handleEvent(event, qnxType); + m_mutex.lock(); + m_events << event; + m_mutex.unlock(); + emit eventPending(); } } qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread stopped"; // cleanup - screen_destroy_event(event); + m_mutex.lock(); + Q_FOREACH (screen_event_t event, m_events) { + screen_destroy_event(event); + } + m_events.clear(); + m_mutex.unlock(); } void QQnxScreenEventThread::shutdown() diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.h b/src/plugins/platforms/qnx/qqnxscreeneventthread.h index 5e931819be..cbdb505b3b 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventthread.h +++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.h @@ -43,6 +43,7 @@ #define QQNXSCREENEVENTTHREAD_H #include +#include #include @@ -50,21 +51,33 @@ QT_BEGIN_NAMESPACE class QQnxScreenEventHandler; +typedef QVarLengthArray QQnxScreenEventArray; + class QQnxScreenEventThread : public QThread { + Q_OBJECT + public: QQnxScreenEventThread(screen_context_t context, QQnxScreenEventHandler *screenEventHandler); ~QQnxScreenEventThread(); static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap); + QQnxScreenEventArray *lock(); + void unlock(); + protected: void run(); +Q_SIGNALS: + void eventPending(); + private: void shutdown(); screen_context_t m_screenContext; + QMutex m_mutex; + QQnxScreenEventArray m_events; QQnxScreenEventHandler *m_screenEventHandler; bool m_quit; }; -- cgit v1.2.3 From 450d3efcb11da21e1c4f206dc57aeaddf10a1e70 Mon Sep 17 00:00:00 2001 From: Maciej Kujalowicz Date: Wed, 30 Oct 2013 13:01:21 +0100 Subject: iOS: Enable threaded OpenGL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change activates ThreadedOpenGL and ThreadedPixmaps capabilities in the iOS integration. QIOSContext is expanded with a support for a shared context. Change-Id: I56615c870a24e17850ad2748421c54e015de3ab2 Reviewed-by: Ian Dean Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioscontext.h | 4 ++++ src/plugins/platforms/ios/qioscontext.mm | 15 ++++++++++++++- src/plugins/platforms/ios/qiosintegration.mm | 3 +++ 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 082ec4794c..961661c5d3 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -66,10 +66,14 @@ public: GLuint defaultFramebufferObject(QPlatformSurface *) const; QFunctionPointer getProcAddress(const QByteArray &procName); + bool isSharing() const Q_DECL_OVERRIDE; + bool isValid() const Q_DECL_OVERRIDE; + private Q_SLOTS: void windowDestroyed(QObject *object); private: + QIOSContext *m_sharedContext; EAGLContext *m_eaglContext; QSurfaceFormat m_format; diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 0c4bee1ef0..d7b9314ae0 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -51,7 +51,10 @@ QIOSContext::QIOSContext(QOpenGLContext *context) : QPlatformOpenGLContext() - , m_eaglContext([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]) + , m_sharedContext(static_cast(context->shareHandle())) + , m_eaglContext([[EAGLContext alloc] + initWithAPI:kEAGLRenderingAPIOpenGLES2 + sharegroup:m_sharedContext ? [m_sharedContext->m_eaglContext sharegroup] : nil]) , m_format(context->format()) { m_format.setRenderableType(QSurfaceFormat::OpenGLES); @@ -203,5 +206,15 @@ QFunctionPointer QIOSContext::getProcAddress(const QByteArray& functionName) return QFunctionPointer(dlsym(RTLD_DEFAULT, functionName.constData())); } +bool QIOSContext::isValid() const +{ + return m_eaglContext; +} + +bool QIOSContext::isSharing() const +{ + return m_sharedContext; +} + #include "moc_qioscontext.cpp" diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index dcad6121be..393a9f317d 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -102,6 +102,9 @@ bool QIOSIntegration::hasCapability(Capability cap) const { switch (cap) { case OpenGL: + case ThreadedOpenGL: + return true; + case ThreadedPixmaps: return true; case MultipleWindows: return true; -- cgit v1.2.3 From d1870d90365122167d650dada6e21db9e4aca91a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 5 Nov 2013 12:58:31 +0100 Subject: Clean up QWindowsSessionManager. Fix spelling error in method name and inline simple functions. Change-Id: I7f2a67fb1951b58874b09002ee57e15e75561727 Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscontext.cpp | 8 ++--- .../platforms/windows/qwindowssessionmanager.cpp | 34 ---------------------- .../platforms/windows/qwindowssessionmanager.h | 13 ++++----- 3 files changed, 10 insertions(+), 45 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 174b3312d2..fc2bb303be 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -844,7 +844,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::InputMethodKeyDownEvent: case QtWindows::KeyboardLayoutChangeEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); #else return d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); #endif @@ -868,7 +868,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::NonClientMouseEvent: if (platformWindow->frameStrutEventsEnabled()) #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #else return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #endif @@ -888,13 +888,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::MouseEvent: case QtWindows::LeaveEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #else return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #endif case QtWindows::TouchEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); #else return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); #endif diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.cpp b/src/plugins/platforms/windows/qwindowssessionmanager.cpp index efdbb6b279..e86722f953 100644 --- a/src/plugins/platforms/windows/qwindowssessionmanager.cpp +++ b/src/plugins/platforms/windows/qwindowssessionmanager.cpp @@ -52,10 +52,6 @@ QWindowsSessionManager::QWindowsSessionManager(const QString &id, const QString { } -QWindowsSessionManager::~QWindowsSessionManager() -{ -} - bool QWindowsSessionManager::allowsInteraction() { m_blockUserInput = false; @@ -68,16 +64,6 @@ bool QWindowsSessionManager::allowsErrorInteraction() return true; } -void QWindowsSessionManager::blocksInteraction() -{ - m_blockUserInput = true; -} - -bool QWindowsSessionManager::isInterractionBlocked() const -{ - return m_blockUserInput; -} - void QWindowsSessionManager::release() { if (m_isActive) @@ -89,24 +75,4 @@ void QWindowsSessionManager::cancel() m_canceled = true; } -void QWindowsSessionManager::clearCancellation() -{ - m_canceled = false; -} - -bool QWindowsSessionManager::wasCanceled() const -{ - return m_canceled; -} - -void QWindowsSessionManager::setActive(bool active) -{ - m_isActive = active; -} - -bool QWindowsSessionManager::isActive() const -{ - return m_isActive; -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.h b/src/plugins/platforms/windows/qwindowssessionmanager.h index 3e21cbabec..0443635c35 100644 --- a/src/plugins/platforms/windows/qwindowssessionmanager.h +++ b/src/plugins/platforms/windows/qwindowssessionmanager.h @@ -60,22 +60,21 @@ class QWindowsSessionManager : public QPlatformSessionManager { public: explicit QWindowsSessionManager(const QString &id, const QString &key); - virtual ~QWindowsSessionManager(); bool allowsInteraction() Q_DECL_OVERRIDE; bool allowsErrorInteraction() Q_DECL_OVERRIDE; - void blocksInteraction(); - bool isInterractionBlocked() const; + void blocksInteraction() { m_blockUserInput = true; } + bool isInteractionBlocked() const { return m_blockUserInput; } void release() Q_DECL_OVERRIDE; void cancel() Q_DECL_OVERRIDE; - void clearCancellation(); - bool wasCanceled() const; + void clearCancellation() { m_canceled = false; } + bool wasCanceled() const { return m_canceled; } - void setActive(bool active); - bool isActive() const; + void setActive(bool active) { m_isActive = active; } + bool isActive() const { return m_isActive;} private: bool m_isActive; -- cgit v1.2.3 From 1b58d9acc493111390b31f0bffd6b2a76baca91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 4 Nov 2013 10:54:57 +0100 Subject: Remove Q_INIT_RESOURCE_EXTERN It's not providing any convenience over using Q_INIT_RESOURCE, which does its own extern, were never documented, and was added back in 2010 without any commit message justifying its existence. Change-Id: I1ca9a042d3f4fca34007d28b140661c50064f11b Reviewed-by: Simon Hausmann Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 2e42b9acda..0af635be6f 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -63,7 +63,6 @@ static void initResources() { - Q_INIT_RESOURCE_EXTERN(qcocoaresources) Q_INIT_RESOURCE(qcocoaresources); } -- cgit v1.2.3 From a199a87ad5452938482291ba5e2995e220678f7d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 4 Nov 2013 16:08:08 +0100 Subject: Cocoa: Don't hide views when reparenting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit a2bdda8e3ba32 was meant for creation only. We should not hide views on our own, particularly when Qt had not asked for that. Task-number: QTBUG-33581 Change-Id: Ib35fc78a27be1498f80aabd385e7a2185475b949 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 565594a98a..228ef9d484 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -713,7 +713,10 @@ WId QCocoaWindow::winId() const void QCocoaWindow::setParent(const QPlatformWindow *parentWindow) { // recreate the window for compatibility + bool unhideAfterRecreate = parentWindow && !m_contentViewIsToBeEmbedded && ![m_contentView isHidden]; recreateWindow(parentWindow); + if (unhideAfterRecreate) + [m_contentView setHidden:NO]; setCocoaGeometry(geometry()); } -- cgit v1.2.3 From 2eb1e28a90eaf82f4405dc65584021f16415014b Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 4 Nov 2013 16:12:38 +0100 Subject: Cocoa (OpenGL): If no view is attached, makeCurrent() should return false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie2869fae1549c3b0a8ef78702410e6ca0c980737 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 3dee137038..f709c94c6d 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -112,6 +112,8 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface) QWindow *window = static_cast(surface)->window(); setActiveWindow(window); + if (![m_context view]) + return false; [m_context makeCurrentContext]; update(); return true; -- cgit v1.2.3 From 54ed14d5c61b2f65bdcb6a0a5c6fa00a9617555d Mon Sep 17 00:00:00 2001 From: Jan Arne Petersen Date: Tue, 29 Oct 2013 10:29:34 +0100 Subject: Support native event filters for screen events Change-Id: If0af4544191c513e64f582cece4a453c1ab5c8e7 Reviewed-by: Andreas Holzammer Reviewed-by: Fabian Bumberger Reviewed-by: Kevin Krammer Reviewed-by: Frank Osterfeld Reviewed-by: Thomas McGuire --- src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index efffd26981..e0dd20c40c 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -209,7 +209,11 @@ void QQnxScreenEventHandler::processEventsFromScreenThread() m_eventThread->unlock(); - handleEvent(event); + long result = 0; + QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); + bool handled = dispatcher && dispatcher->filterNativeEvent(QByteArrayLiteral("screen_event_t"), event, &result); + if (!handled) + handleEvent(event); screen_destroy_event(event); m_eventThread->lock(); -- cgit v1.2.3 From 2c11a492fb067cf00ae298a6e2c8af4f10d21e18 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 24 Oct 2013 17:37:27 +0200 Subject: Add better version checks for accessibility We would spam the debug output on devices with api < 16 with some warnings that the super class a11y delegate could not be found and others. Instead check the runtime version before trying to load the JNI code and only load the delegate if api is new enough. Change-Id: I52286cb99924b034b9b58c53566f15030939b0c9 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/src/androidjnimain.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 9ce79f445a..3d599b8f8b 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -834,6 +834,15 @@ static int registerNatives(JNIEnv *env) return JNI_TRUE; } +jint androidApiLevel(JNIEnv *env) +{ + jclass clazz; + FIND_AND_CHECK_CLASS("android/os/Build$VERSION"); + jfieldID fieldId; + GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "SDK_INT", "I"); + return env->GetStaticIntField(clazz, fieldId); +} + Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) { typedef union { @@ -856,11 +865,17 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) || !QtAndroidInput::registerNatives(env) || !QtAndroidClipboard::registerNatives(env) || !QtAndroidMenu::registerNatives(env) - || !QtAndroidAccessibility::registerNatives(env)) { + ) { __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } + jint apiLevel = androidApiLevel(env); + if (apiLevel >= 16 && !QtAndroidAccessibility::registerNatives(env)) { + __android_log_print(ANDROID_LOG_FATAL, "Qt A11y", "registerNatives failed"); + return -1; + } + m_javaVM = vm; return JNI_VERSION_1_4; } -- cgit v1.2.3 From e7fd798af001e2c4e323f5ae90e4e994f12ccf33 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 5 Nov 2013 09:32:35 +0100 Subject: Disable threaded rendering for Intel HD 3000 cards. Task-number: QTBUG-34492 Change-Id: I1848cde3fb9517679fd54a7170ed5bee40880edc Reviewed-by: Giuseppe D'Angelo --- src/plugins/platforms/xcb/qglxintegration.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 2c418cbebe..4ac4cf21ab 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -411,6 +411,16 @@ bool QGLXContext::isValid() const bool QGLXContext::m_queriedDummyContext = false; bool QGLXContext::m_supportsThreading = true; + +// If this list grows to any significant size, change it a +// proper string table and make the implementation below use +// binary search. +static const char *qglx_threadedgl_blacklist[] = { + "Chromium", // QTBUG-32225 (initialization fails) + "Mesa DRI Intel(R) Sandybridge Mobile", // QTBUG-34492 (flickering in fullscreen) + 0 +}; + void QGLXContext::queryDummyContext() { if (m_queriedDummyContext) @@ -428,10 +438,14 @@ void QGLXContext::queryDummyContext() context.makeCurrent(&surface); const char *renderer = (const char *) glGetString(GL_RENDERER); - if (QByteArray(renderer).contains("Chromium")) - m_supportsThreading = false; - else - m_supportsThreading = true; + + m_supportsThreading = true; + for (int i = 0; qglx_threadedgl_blacklist[i]; ++i) { + if (strstr(renderer, qglx_threadedgl_blacklist[i]) != 0) { + m_supportsThreading = false; + break; + } + } } bool QGLXContext::supportsThreading() -- cgit v1.2.3 From 49a3c87175b0b9261c8c715315f3913b410f248d Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Fri, 4 Oct 2013 00:19:56 +0200 Subject: Remove two unused functions from QAccessibleTabBar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib3296a11b1bb9656f2b0c14106ea09f529311ccf Reviewed-by: Morten Johan Sørvig --- src/plugins/accessible/widgets/complexwidgets.cpp | 35 ----------------------- src/plugins/accessible/widgets/complexwidgets.h | 3 -- 2 files changed, 38 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index c0d62ccc16..b1df6d816a 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -221,41 +221,6 @@ QString QAccessibleTabBar::text(QAccessible::Text t) const return QString(); } -/*! - Selects the item with index \a child if \a on is true; otherwise - unselects it. If \a extend is true and the selection mode is not - \c Single and there is an existing selection, the selection is - extended to include all the items from the existing selection up - to and including the item with index \a child. Returns \c true if a - selection was made or extended; otherwise returns \c false. - - \sa selection(), clearSelection() -*/ -bool QAccessibleTabBar::setSelected(int child, bool on, bool extend) -{ - if (!child || !on || extend || child > tabBar()->count()) - return false; - - if (!tabBar()->isTabEnabled(child - 1)) - return false; - tabBar()->setCurrentIndex(child - 1); - return true; -} - -/*! - Returns a (possibly empty) list of indexes of the items selected - in the list box. - - \sa setSelected(), clearSelection() -*/ -QVector QAccessibleTabBar::selection() const -{ - QVector array; - if (tabBar()->currentIndex() != -1) - array +=tabBar()->currentIndex() + 1; - return array; -} - #endif // QT_NO_TABBAR #ifndef QT_NO_COMBOBOX diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h index 164bc5b6d9..00186282f3 100644 --- a/src/plugins/accessible/widgets/complexwidgets.h +++ b/src/plugins/accessible/widgets/complexwidgets.h @@ -105,9 +105,6 @@ public: int childCount() const Q_DECL_OVERRIDE; QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - bool setSelected(int child, bool on, bool extend); - QVector selection() const; - QAccessibleInterface* child(int index) const Q_DECL_OVERRIDE; int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE; -- cgit v1.2.3 From 04ad4d7de5816cf96936f0b839f85868dd688256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 5 Nov 2013 18:28:42 +0100 Subject: iOS: Remove unused QIOSWindow methods for getting effective width/height MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ifdfd5881822bf56f2c8ab0742a0e257e2bd61533 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioswindow.h | 2 -- src/plugins/platforms/ios/qioswindow.mm | 10 ---------- 2 files changed, 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 20f0aa59b6..0f7a50db04 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -74,8 +74,6 @@ public: void requestActivateWindow(); qreal devicePixelRatio() const; - int effectiveWidth() const; - int effectiveHeight() const; bool setMouseGrabEnabled(bool grab) { return grab; } bool setKeyboardGrabEnabled(bool grab) { return grab; } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 0bfda49536..25c11a210d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -505,14 +505,4 @@ qreal QIOSWindow::devicePixelRatio() const return m_devicePixelRatio; } -int QIOSWindow::effectiveWidth() const -{ - return geometry().width() * m_devicePixelRatio; -} - -int QIOSWindow::effectiveHeight() const -{ - return geometry().height() * m_devicePixelRatio; -} - QT_END_NAMESPACE -- cgit v1.2.3 From 417cf3fc535ef18e7895cb863235cc33e36669f9 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 6 Nov 2013 15:42:16 +0200 Subject: Android: Fix menu on API-11+ On API-11+ if there is no hardware menu button show the action bar. Fix menu when using the opengl android plugin. Task-number: QTBUG-32002 Change-Id: I45bd49107621e4cab85eb6411897229e20bb8281 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: BogDan Vatra --- .../platforms/android/src/androidjnimenu.cpp | 26 ++++++++++++---------- .../src/opengl/qandroidopenglplatformscreen.cpp | 2 ++ .../android/src/qandroidplatformmenubar.cpp | 2 ++ 3 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp index 8964995832..866acd3c7e 100644 --- a/src/plugins/platforms/android/src/androidjnimenu.cpp +++ b/src/plugins/platforms/android/src/androidjnimenu.cpp @@ -41,13 +41,14 @@ #include "androidjnimenu.h" #include "androidjnimain.h" -#include -#include -#include -#include #include "qandroidplatformmenubar.h" #include "qandroidplatformmenu.h" -#include +#include "qandroidplatformmenuitem.h" + +#include +#include +#include +#include using namespace QtAndroid; @@ -141,18 +142,17 @@ namespace QtAndroidMenu void setActiveTopLevelWindow(QWindow *window) { + Qt::WindowFlags flags = window->flags(); + bool isNonRegularWindow = flags & (Qt::Desktop | Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; + if (isNonRegularWindow) + return; + QMutexLocker lock(&menuBarMutex); if (activeTopLevelWindow == window) return; visibleMenuBar = 0; activeTopLevelWindow = window; -#ifdef ANDROID_PLUGIN_OPENGL - //only one toplevel window, so the menu bar always belongs to us - if (menuBars.size() == 1) { - visibleMenuBar = *menuBars.constBegin(); //since QSet doesn't have first() - } else -#endif foreach (QAndroidPlatformMenuBar *menuBar, menuBars) { if (menuBar->parentWindow() == window) { visibleMenuBar = menuBar; @@ -173,8 +173,10 @@ namespace QtAndroidMenu { QMutexLocker lock(&menuBarMutex); menuBars.remove(menuBar); - if (visibleMenuBar == menuBar) + if (visibleMenuBar == menuBar) { + visibleMenuBar = 0; resetMenuBar(); + } } static QString removeAmpersandEscapes(QString s) diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp index 821fd954df..de4075feff 100644 --- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp +++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp @@ -41,6 +41,7 @@ #include "qandroidopenglplatformscreen.h" #include "qandroidopenglplatformwindow.h" +#include "androidjnimenu.h" QT_BEGIN_NAMESPACE @@ -51,6 +52,7 @@ QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display) void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window) { + QtAndroidMenu::setActiveTopLevelWindow(window->window()); QAndroidOpenGLPlatformWindow *platformWindow = static_cast(window); if (platformWindow != 0) platformWindow->updateStatusBarVisibility(); diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp index ef1ac61356..134062fb32 100644 --- a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp @@ -79,6 +79,8 @@ void QAndroidPlatformMenuBar::syncMenu(QPlatformMenu *menu) void QAndroidPlatformMenuBar::handleReparent(QWindow *newParentWindow) { + if (m_parentWindow == newParentWindow) + return; m_parentWindow = newParentWindow; QtAndroidMenu::setMenuBar(this, newParentWindow); } -- cgit v1.2.3 From d8f7a2ddf4e098786a5dec27e11786f5ff4e0433 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 6 Nov 2013 12:43:51 +0100 Subject: EglFS: make sure resize events are delivered MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that resize events are delivered when the platform plugin overrides the geometry set in setGeometry(). This fixes a race condition where a widget was resized to its sizeHint() while the window was maximized, and the content was shown scaled on the screen. The problem is that the widget gets the wrong size from QWidget::setWindowState() (which calls adjustSize() in order to support normalGeometry). This size is used to resize the backingStore. When the QWindow is resized, it calls QEglFSWindow::setGeometry() which corrects the size to screen()->availableGeometry(), and triggers a GeometryChangeEvent since the size was corrected. This ends up in QGuiApplicationPrivate::processGeometryChangeEvent() which will not send a resize event, since the size has not changed (it is always availableGeometry()). Therefore the widget is never resized, and the backingStore remains the wrong size. Task-number: QTBUG-34421 Change-Id: Iee49c53cc529de36010db2695d838d8c2284edd4 Reviewed-by: Tor Arne Vestbø Reviewed-by: Laszlo Agocs --- src/plugins/platforms/eglfs/qeglfswindow.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 70f0e437b2..bba00da128 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -210,15 +210,17 @@ void QEglFSWindow::setVisible(bool visible) void QEglFSWindow::setGeometry(const QRect &r) { QRect rect; - if (m_flags.testFlag(HasNativeWindow)) + bool forceFullscreen = m_flags.testFlag(HasNativeWindow); + if (forceFullscreen) rect = screen()->availableGeometry(); else rect = r; QPlatformWindow::setGeometry(rect); + // if we corrected the size, trigger a resize event if (rect != r) - QWindowSystemInterface::handleGeometryChange(window(), rect); + QWindowSystemInterface::handleGeometryChange(window(), rect, r); } QRect QEglFSWindow::geometry() const -- cgit v1.2.3 From 6272a816d192b3c9b363164216bfd7a13e7370e9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 29 Oct 2013 14:11:33 +0100 Subject: iOS: set active window upon calls to requestActiveWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We did not do this from before. Instead we would activate the window when it's view became first responder. And this would happen when the input panel was told to open. That behavior is a fragile, since other layers higher up (qml) would not open the input panel unless the window was active, which also makes sense. A classic chicken and egg problem. So to play more along with how Qt is expected to work, we change behavior to instead activate the window directly when requested to do so (which also includes when the user touches the window directly). This will also work better for "keyboard" events like Key_VolumeUp, once implemented. The down side is that Qt will give focus to widgets/items (and as such, open the keyboard) whenever you touch the window. But that is easier to fix, and will be dealt with in later patches. Change-Id: I9bbeb0205e7ea3c5079100c07e40ddb1c60b476b Reviewed-by: Tor Arne Vestbø Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/ios/qioswindow.mm | 1 + 1 file changed, 1 insertion(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 25c11a210d..f1189ccd88 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -440,6 +440,7 @@ void QIOSWindow::requestActivateWindow() raise(); QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); static_cast(context)->focusViewChanged(m_view); + QWindowSystemInterface::handleWindowActivated(window()); } void QIOSWindow::raiseOrLower(bool raise) -- cgit v1.2.3 From 96d74313fe722ed55f67a89633033ed49c3dc3a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 4 Nov 2013 13:39:11 +0100 Subject: Add missing Q_INIT_RESOURCE The library needs to do Q_INIT_RESOURCE for all resources it uses internally, otherwise static linking will fail, and the user has no idea how to rectify it as the name of the missing resource is not known. The Q_INIT_RESOURCE needs to happen outside of any namespace, hence the use of static initResources() functions. Change-Id: I8f7d36b440b05809d97dd489cf8789f345633cec Reviewed-by: Thiago Macieira --- src/plugins/platforms/eglfs/qeglfsintegration.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp index 9f8c0747df..55a822b887 100644 --- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp @@ -74,6 +74,11 @@ #include +static void initResources() +{ + Q_INIT_RESOURCE(cursor); +} + QT_BEGIN_NAMESPACE QEglFSIntegration::QEglFSIntegration() @@ -82,6 +87,7 @@ QEglFSIntegration::QEglFSIntegration() , mScreen(0) , mInputContext(0) { + initResources(); } QEglFSIntegration::~QEglFSIntegration() -- cgit v1.2.3 From a94f61063a031444849fb0873f9b267a4f828597 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 5 Nov 2013 11:47:31 +0100 Subject: QNX: Fixed "normalPosition" of touch events Pixel positions have to be set in relation to screen size in pixels, not the physical size to calculate the normal position in the range 0..1. Change-Id: I6880fb64b7c3049d657fd081b564b945399b5865 Reviewed-by: Frank Osterfeld Reviewed-by: Kevin Krammer Reviewed-by: Thomas McGuire --- src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index e0dd20c40c..9db62865bb 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -432,10 +432,12 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType) if (w) { // get size of screen which contains window QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(w); - QSizeF screenSize = platformScreen->physicalSize(); + QSizeF screenSize = platformScreen->geometry().size(); // update cached position of current touch point - m_touchPoints[touchId].normalPosition = QPointF( static_cast(pos[0]) / screenSize.width(), static_cast(pos[1]) / screenSize.height() ); + m_touchPoints[touchId].normalPosition = + QPointF(static_cast(pos[0]) / screenSize.width(), + static_cast(pos[1]) / screenSize.height()); m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 ); // determine event type and update state of current touch point -- cgit v1.2.3 From f48bc3ef40ec0176497896071c487b5326cd66c1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 7 Nov 2013 10:38:56 +0100 Subject: Add a warning message when a WM_DESTROY not triggered by Qt is received. Task-number: QTBUG-34503 Change-Id: I7a1e06b34deaf8e595f4986114701480bdcf219c Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowscontext.cpp | 10 ++++++++-- src/plugins/platforms/windows/qwindowswindow.cpp | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index fc2bb303be..77cac647ba 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -783,9 +783,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::InputMethodCloseCandidateWindowEvent: // TODO: Release/regrab mouse if a popup has mouse grab. return false; - case QtWindows::ClipboardEvent: case QtWindows::DestroyEvent: - + if (!platformWindow->testFlag(QWindowsWindow::WithinDestroy)) { + qWarning() << "External WM_DESTROY received for " << platformWindow->window() + << ", parent: " << platformWindow->window()->parent() + << ", transient parent: " << platformWindow->window()->transientParent(); + } + return false; + case QtWindows::ClipboardEvent: + return false; case QtWindows::UnknownEvent: return false; case QtWindows::AccessibleObjectFromWindowRequest: diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 44fd97e1aa..2ea02cd4d4 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -929,6 +929,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : QWindowsWindow::~QWindowsWindow() { + setFlag(WithinDestroy); #ifndef Q_OS_WINCE if (testFlag(TouchRegistered)) QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd); -- cgit v1.2.3 From 6ff08b7db3d4f93b38ae769413d3f3377b3d272b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 7 Nov 2013 10:53:42 +0100 Subject: Windows: Do not set transient parent on popups. Analoguous to Window creation code. Task-number: QTBUG-34503 Change-Id: I3cf7d58999bff5b106ca9d2e2c6f550e35f9db9a Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 2ea02cd4d4..d2fb481824 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1123,6 +1123,8 @@ QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const void QWindowsWindow::updateTransientParent() const { #ifndef Q_OS_WINCE + if (window()->type() == Qt::Popup) + return; // QTBUG-34503, // a popup stays on top, no parent, see also WindowCreationData::fromWindow(). // Update transient parent. const HWND oldTransientParent = GetAncestor(m_data.hwnd, GA_PARENT) == GetDesktopWindow() ? GetAncestor(m_data.hwnd, GA_ROOTOWNER) : HWND(0); -- cgit v1.2.3 From b2f26362176b77b812de5cfbaca5d70d3d786218 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 7 Nov 2013 16:16:25 +0100 Subject: Cocoa: fix a crash in QCocoaFileDialogHelper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current directory can't be nil. Task-number: QTBUG-34561 Change-Id: I58c84da4928bd9081c916b6e5541bb86cf75ed47 Reviewed-by: Morten Johan Sørvig Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index b3bc4a8ebf..bbf5227a6c 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -461,7 +461,7 @@ static QString strippedText(QString s) Q_UNUSED(sender); if (!mHelper) return; - if ([path isEqualToString:mCurrentDir]) + if (!(path && path.length) || [path isEqualToString:mCurrentDir]) return; [mCurrentDir release]; -- cgit v1.2.3 From a301e868f7a24a7b98b22623b01be92488527c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 6 Nov 2013 15:36:30 +0100 Subject: iOS: Rename m_requestedGeometry to m_normalGeometry Matches the wording using in QWidget. Change-Id: Ifbb4e5ffa90b47a7c179cf9ec52cb46126d7bccc Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 2 +- src/plugins/platforms/ios/qioswindow.mm | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 0f7a50db04..7f4badfb68 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -83,7 +83,7 @@ public: private: UIView *m_view; - QRect m_requestedGeometry; + QRect m_normalGeometry; int m_windowLevel; qreal m_devicePixelRatio; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index f1189ccd88..9eba049f95 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -317,7 +317,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) , m_view([[EAGLView alloc] initWithQIOSWindow:this]) - , m_requestedGeometry(QPlatformWindow::geometry()) + , m_normalGeometry(QPlatformWindow::geometry()) , m_windowLevel(0) , m_devicePixelRatio(1.0) { @@ -386,7 +386,7 @@ void QIOSWindow::setGeometry(const QRect &rect) { // If the window is in fullscreen, just bookkeep the requested // geometry in case the window goes into Qt::WindowNoState later: - m_requestedGeometry = rect; + m_normalGeometry = rect; if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) return; @@ -413,7 +413,7 @@ void QIOSWindow::setWindowState(Qt::WindowState state) m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; break; } default: - m_view.frame = toCGRect(m_requestedGeometry); + m_view.frame = toCGRect(m_normalGeometry); m_view.autoresizingMask = UIViewAutoresizingNone; break; } -- cgit v1.2.3 From 24d1f584146c487c1bc16a8191c2c472da6c6f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 7 Nov 2013 12:20:28 +0100 Subject: iOS: Rename QIOSWindow's backing view from EAGLView to QUIView Matches the cocoa QNSView and highlights the relation to UIView. Change-Id: Idcdb17bff994c1e0aef099400c21915a7041e44c Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 4 +++- src/plugins/platforms/ios/qioswindow.mm | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 7f4badfb68..b60290e479 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -56,6 +56,8 @@ class QIOSWindow; QT_BEGIN_NAMESPACE +@class QUIView; + class QIOSWindow : public QPlatformWindow { public: @@ -81,7 +83,7 @@ public: WId winId() const { return WId(m_view); }; private: - UIView *m_view; + QUIView *m_view; QRect m_normalGeometry; int m_windowLevel; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 9eba049f95..2cb3fe86e1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -58,7 +58,7 @@ #include -@interface EAGLView : UIView +@interface QUIView : UIView { @public UITextAutocapitalizationType autocapitalizationType; @@ -83,7 +83,7 @@ @end -@implementation EAGLView +@implementation QUIView + (Class)layerClass { @@ -305,8 +305,8 @@ - (QWindow *)qwindow { - if ([self isKindOfClass:[EAGLView class]]) - return static_cast(self)->m_qioswindow->window(); + if ([self isKindOfClass:[QUIView class]]) + return static_cast(self)->m_qioswindow->window(); return nil; } @@ -316,7 +316,7 @@ QT_BEGIN_NAMESPACE QIOSWindow::QIOSWindow(QWindow *window) : QPlatformWindow(window) - , m_view([[EAGLView alloc] initWithQIOSWindow:this]) + , m_view([[QUIView alloc] initWithQIOSWindow:this]) , m_normalGeometry(QPlatformWindow::geometry()) , m_windowLevel(0) , m_devicePixelRatio(1.0) @@ -392,7 +392,7 @@ void QIOSWindow::setGeometry(const QRect &rect) // Since we don't support transformations on the UIView, we can set the frame // directly and let UIKit deal with translating that into bounds and center. - // Changing the size of the view will end up in a call to -[EAGLView layoutSubviews] + // Changing the size of the view will end up in a call to -[QUIView layoutSubviews] // which will update QWindowSystemInterface with the new size. m_view.frame = toCGRect(rect); } -- cgit v1.2.3 From 59be0509e087a5d4a8884a56e14a2ddbf5735ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 7 Nov 2013 13:15:31 +0100 Subject: iOS: Detect/handle cancellation of subset of touch points Change-Id: I0d345d07fe62a8c7844333bf1eed9be6d6fa432f Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2cb3fe86e1..70f4cc4267 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -226,10 +226,16 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { - Q_UNUSED(touches) // ### can a subset of the active touches be cancelled? + if (!touches) { + m_activeTouches.clear(); + } else { + for (UITouch *touch in touches) + m_activeTouches.remove(touch); + + Q_ASSERT_X(m_activeTouches.isEmpty(), Q_FUNC_INFO, + "Subset of active touches cancelled by UIKit"); + } - // Clear current touch points - m_activeTouches.clear(); m_nextTouchId = 0; // Send cancel touch event synchronously -- cgit v1.2.3 From ac7823129a529a71d2725fdeadc5eff7a2b0788a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 7 Nov 2013 13:16:48 +0100 Subject: iOS: Cancel any active touches when destroying a QIOSWindow Keeps the internal state of QtGui sane when it comes to which buttons are active, etc. Change-Id: Ic63e74d2546469e085ec46b74f4cf159dd409b07 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 70f4cc4267..fa0519a37c 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -226,6 +226,9 @@ - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + if (!touches && m_activeTouches.isEmpty()) + return; + if (!touches) { m_activeTouches.clear(); } else { @@ -238,9 +241,11 @@ m_nextTouchId = 0; + NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime]; + // Send cancel touch event synchronously QIOSIntegration *iosIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); - QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(event.timestamp * 1000), iosIntegration->touchDevice()); + QWindowSystemInterface::handleTouchCancelEvent(m_qioswindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice()); QWindowSystemInterface::flushWindowSystemEvents(); } @@ -342,6 +347,13 @@ QIOSWindow::QIOSWindow(QWindow *window) QIOSWindow::~QIOSWindow() { + // According to the UIResponder documentation, Cocoa Touch should react to system interruptions + // that "might cause the view to be removed from the window" by sending touchesCancelled, but in + // practice this doesn't seem to happen when removing the view from its superview. To ensure that + // Qt's internal state for touch and mouse handling is kept consistent, we therefor have to force + // cancellation of all touch events. + [m_view touchesCancelled:0 withEvent:0]; + [m_view removeFromSuperview]; [m_view release]; } -- cgit v1.2.3 From c934ea341e0749aef9c927ca3def68976bdc976f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 5 Nov 2013 13:16:59 +0100 Subject: Cocoa File Dialog: Remove sandbox-ufriendly file system watcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QFileSystemWatcher causes sandboxing errors since its backend uses POSIX API in a relatively liberal way. Also, Cocoa already acts as a file system watcher, and calls -[QNSOpenSavePanelDelegate panel:shouldShowFilename:] on each file. From a logical point of view, caching the directory content can be replaced by testing the current file against the filter setting. We expect Cocoa to cache results, and by using NSFileManager things should remain relatively fast. Task-number: QTBUG-34107 Change-Id: Ia872b9b1244f7b390d173a498011379b9309b3c6 Reviewed-by: Cyril Oblikov Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qcocoafiledialoghelper.mm | 93 ++++++++++++---------- 1 file changed, 49 insertions(+), 44 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index bbf5227a6c..1ad833ee44 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -61,12 +61,12 @@ #include #include #include "qcocoaautoreleasepool.h" -#include #include #include #import +#import QT_FORWARD_DECLARE_CLASS(QString) QT_FORWARD_DECLARE_CLASS(QStringList) @@ -74,30 +74,6 @@ QT_FORWARD_DECLARE_CLASS(QFileInfo) QT_FORWARD_DECLARE_CLASS(QWindow) QT_USE_NAMESPACE -class CachedEntries: public QObject { -public: - CachedEntries(QDir::Filters filters) : mFilters(filters) { - QObject::connect(&mFSWatcher, &QFileSystemWatcher::directoryChanged, this, &CachedEntries::updateDirCache); - } - QString directory() const { - const QStringList &dirs = mFSWatcher.directories(); - return (dirs.count() ? dirs[0] : QString()); - } - QStringList entries() const { - return mQDirFilterEntryList; - } - void updateDirCache(const QString &path) { - mFSWatcher.removePaths(mFSWatcher.directories()); - mFSWatcher.addPath(path); - mQDirFilterEntryList = QDir(path).entryList(mFilters); - } - -private: - QFileSystemWatcher mFSWatcher; - QStringList mQDirFilterEntryList; - QDir::Filters mFilters; -}; - typedef QSharedPointer SharedPointerFileDialogOptions; @class QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate); @@ -117,7 +93,6 @@ typedef QSharedPointer SharedPointerFileDialogOptions; int mReturnCode; SharedPointerFileDialogOptions mOptions; - CachedEntries *mCachedEntries; QString *mCurrentSelection; QStringList *mNameFilterDropDownList; QStringList *mSelectedNameFilter; @@ -164,7 +139,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); [mSavePanel setDelegate:self]; mReturnCode = -1; mHelper = helper; - mCachedEntries = new CachedEntries(mOptions->filter()); mNameFilterDropDownList = new QStringList(mOptions->nameFilters()); QString selectedVisualNameFilter = mOptions->initiallySelectedNameFilter(); mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]); @@ -197,7 +171,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate); - (void)dealloc { - delete mCachedEntries; delete mNameFilterDropDownList; delete mSelectedNameFilter; delete mCurrentSelection; @@ -308,6 +281,22 @@ static QString strippedText(QString s) }]; } +- (BOOL)isHiddenFile:(NSString *)filename isDir:(BOOL)isDir +{ + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)filename, kCFURLPOSIXPathStyle, isDir); + CFBooleanRef isHidden; + Boolean errorOrHidden = false; + if (!CFURLCopyResourcePropertyForKey(url, kCFURLIsHiddenKey, &isHidden, NULL)) { + errorOrHidden = true; + } else { + if (CFBooleanGetValue(isHidden)) + errorOrHidden = true; + CFRelease(isHidden); + } + CFRelease(url); + return errorOrHidden; +} + - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { Q_UNUSED(sender); @@ -316,8 +305,13 @@ static QString strippedText(QString s) return NO; // Always accept directories regardless of their names (unless it is a bundle): - BOOL isDir; - if ([[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isDir] && isDir) { + NSFileManager *fm = [NSFileManager defaultManager]; + NSDictionary *fileAttrs = [fm attributesOfItemAtPath:filename error:nil]; + if (!fileAttrs) + return NO; // Error accessing the file means 'no'. + NSString *fileType = [fileAttrs fileType]; + bool isDir = [fileType isEqualToString:NSFileTypeDirectory]; + if (isDir) { if ([mSavePanel treatsFilePackagesAsDirectories] == NO) { if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO) return YES; @@ -325,24 +319,35 @@ static QString strippedText(QString s) } QString qtFileName = QCFString::toQString(filename); - QFileInfo info(qtFileName.normalized(QString::NormalizationForm_C)); - QString path = info.absolutePath(); - if (mCachedEntries->directory() != path) { - mCachedEntries->updateDirCache(path); - } - // Check if the QDir filter accepts the file: - if (!mCachedEntries->entries().contains(info.fileName())) - return NO; - // No filter means accept everything - if (mSelectedNameFilter->isEmpty()) - return YES; + bool nameMatches = mSelectedNameFilter->isEmpty(); // Check if the current file name filter accepts the file: - for (int i=0; isize(); ++i) { + for (int i = 0; !nameMatches && i < mSelectedNameFilter->size(); ++i) { if (QDir::match(mSelectedNameFilter->at(i), qtFileName)) - return YES; + nameMatches = true; + } + if (!nameMatches) + return NO; + + QDir::Filters filter = mOptions->filter(); + if ((!(filter & (QDir::Dirs | QDir::AllDirs)) && isDir) + || (!(filter & QDir::Files) && [fileType isEqualToString:NSFileTypeRegular]) + || ((filter & QDir::NoSymLinks) && [fileType isEqualToString:NSFileTypeSymbolicLink])) + return NO; + + bool filterPermissions = ((filter & QDir::PermissionMask) + && (filter & QDir::PermissionMask) != QDir::PermissionMask); + if (filterPermissions) { + if ((!(filter & QDir::Readable) && [fm isReadableFileAtPath:filename]) + || (!(filter & QDir::Writable) && [fm isWritableFileAtPath:filename]) + || (!(filter & QDir::Executable) && [fm isExecutableFileAtPath:filename])) + return NO; } - return NO; + if (!(filter & QDir::Hidden) + && (qtFileName.startsWith(QLatin1Char('.')) || [self isHiddenFile:filename isDir:isDir])) + return NO; + + return YES; } - (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag -- cgit v1.2.3 From f45e12f91aa9a230e78f939d2a86398ed90d370d Mon Sep 17 00:00:00 2001 From: Maciej Kujalowicz Date: Mon, 4 Nov 2013 18:55:02 +0100 Subject: iOS: Send expose event when a window changes the geometry. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the EAGLView view changes its layout, it must send the expose event along with the geometry change. It is important to notify the render loop of the scene graph that the windows's geometry has changed. The render loop is waiting for the WM_Expose event and updates the scene's window size accordingly. See QSGRenderThread::event for reference. Without this notification, the geometry of window is updated, but the scene is rendered incorrectly, for example when the orientation of screen changes. Change-Id: If102014313de455cb1f44d772b478d2feae6dacf Reviewed-by: Morten Johan Sørvig Reviewed-by: Richard Moe Gustavsen Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 1 + 1 file changed, 1 insertion(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index fa0519a37c..f46616db1d 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -142,6 +142,7 @@ QRect geometry = fromCGRect(self.frame); m_qioswindow->QPlatformWindow::setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); + QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), geometry); // If we have a new size here we need to resize the FBO's corresponding buffers, // but we defer that to when the application calls makeCurrent. -- cgit v1.2.3 From ef6544ee27aeab20a64b4df4bd50401cefa405ef Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Sat, 9 Nov 2013 09:21:02 +0200 Subject: Android native message dialog Change-Id: Ief8c3ce3b8683c6960f046245844c1835a327d51 Reviewed-by: Shawn Rutledge --- .../platforms/android/src/androidjnimain.cpp | 4 +- .../android/src/qandroidplatformdialoghelpers.cpp | 223 +++++++++++++++++++++ .../android/src/qandroidplatformdialoghelpers.h | 77 +++++++ .../android/src/qandroidplatformtheme.cpp | 18 ++ .../platforms/android/src/qandroidplatformtheme.h | 3 + src/plugins/platforms/android/src/src.pri | 2 + 6 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp create mode 100644 src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 3d599b8f8b..3ab4eedb26 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -59,6 +59,7 @@ #include "androidjniinput.h" #include "androidjniclipboard.h" #include "androidjnimenu.h" +#include "qandroidplatformdialoghelpers.h" #include "qandroidplatformintegration.h" #include @@ -865,7 +866,8 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) || !QtAndroidInput::registerNatives(env) || !QtAndroidClipboard::registerNatives(env) || !QtAndroidMenu::registerNatives(env) - ) { + || !QtAndroidAccessibility::registerNatives(env) + || !QtAndroidDialogHelpers::registerNatives(env)) { __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp new file mode 100644 index 0000000000..f9eb34751e --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2013 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "qandroidplatformdialoghelpers.h" +#include "androidjnimain.h" + +namespace QtAndroidDialogHelpers { +static jclass g_messageDialogHelperClass = 0; + +QAndroidPlatformMessageDialogHelper::QAndroidPlatformMessageDialogHelper() + :m_buttonId(-1) + ,m_javaMessageDialog(g_messageDialogHelperClass, "(Landroid/app/Activity;)V", QtAndroid::activity()) + ,m_shown(false) +{ +} + +void QAndroidPlatformMessageDialogHelper::exec() +{ + if (!m_shown) + show(Qt::Dialog, Qt::ApplicationModal, 0); + m_loop.exec(); +} + +static QString standardButtonText(int sbutton) +{ + QString buttonText = 0; + switch (sbutton) { + case QMessageDialogOptions::Ok: + buttonText = QObject::tr("OK"); + break; + case QMessageDialogOptions::Save: + buttonText = QObject::tr("Save"); + break; + case QMessageDialogOptions::Open: + buttonText = QObject::tr("Open"); + break; + case QMessageDialogOptions::Cancel: + buttonText = QObject::tr("Cancel"); + break; + case QMessageDialogOptions::Close: + buttonText = QObject::tr("Close"); + break; + case QMessageDialogOptions::Apply: + buttonText = QObject::tr("Apply"); + break; + case QMessageDialogOptions::Reset: + buttonText = QObject::tr("Reset"); + break; + case QMessageDialogOptions::Help: + buttonText = QObject::tr("Help"); + break; + case QMessageDialogOptions::Discard: + buttonText = QObject::tr("Discard"); + break; + case QMessageDialogOptions::Yes: + buttonText = QObject::tr("Yes"); + break; + case QMessageDialogOptions::YesToAll: + buttonText = QObject::tr("Yes to All"); + break; + case QMessageDialogOptions::No: + buttonText = QObject::tr("No"); + break; + case QMessageDialogOptions::NoToAll: + buttonText = QObject::tr("No to All"); + break; + case QMessageDialogOptions::SaveAll: + buttonText = QObject::tr("Save All"); + break; + case QMessageDialogOptions::Abort: + buttonText = QObject::tr("Abort"); + break; + case QMessageDialogOptions::Retry: + buttonText = QObject::tr("Retry"); + break; + case QMessageDialogOptions::Ignore: + buttonText = QObject::tr("Ignore"); + break; + case QMessageDialogOptions::RestoreDefaults: + buttonText = QObject::tr("Restore Defaults"); + break; + } // switch + return buttonText; +} + +bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags + , Qt::WindowModality windowModality + , QWindow *parent) +{ + Q_UNUSED(windowFlags) + Q_UNUSED(windowModality) + Q_UNUSED(parent) + QSharedPointer opt = options(); + if (!opt.data()) + return false; + + m_javaMessageDialog.callMethod("setIcon", "(I)V", opt->icon()); + + QString str = opt->windowTitle(); + if (!str.isEmpty()) + m_javaMessageDialog.callMethod("setTile", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); + + str = opt->text(); + if (!str.isEmpty()) + m_javaMessageDialog.callMethod("setText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); + + str = opt->informativeText(); + if (!str.isEmpty()) + m_javaMessageDialog.callMethod("setInformativeText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); + + str = opt->detailedText(); + if (!str.isEmpty()) + m_javaMessageDialog.callMethod("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object()); + + for (int i = QMessageDialogOptions::FirstButton; i < QMessageDialogOptions::LastButton; i<<=1) { + if ( opt->standardButtons() & i ) + m_javaMessageDialog.callMethod("addButton", "(ILjava/lang/String;)V", i, QJNIObjectPrivate::fromString(standardButtonText(i)).object()); + } + + m_javaMessageDialog.callMethod("show", "(J)V", jlong(static_cast(this))); + m_shown = true; + return true; +} + +void QAndroidPlatformMessageDialogHelper::hide() +{ + m_javaMessageDialog.callMethod("hide", "()V"); + m_shown = false; +} + +void QAndroidPlatformMessageDialogHelper::dialogResult(int buttonID) +{ + m_buttonId = buttonID; + if (m_loop.isRunning()) + m_loop.exit(); + if (m_buttonId < 0) { + emit reject(); + return; + } + + QMessageDialogOptions::StandardButton standardButton = static_cast(buttonID); + QMessageDialogOptions::ButtonRole role = QMessageDialogOptions::buttonRole(standardButton); + emit clicked(standardButton, role); +} + +static void dialogResult(JNIEnv * /*env*/, jobject /*thiz*/, jlong handler, int buttonID) +{ + QObject *object = reinterpret_cast(handler); + QMetaObject::invokeMethod(object, "dialogResult", Qt::QueuedConnection, Q_ARG(int, buttonID)); +} + +static JNINativeMethod methods[] = { + {"dialogResult", "(JI)V", (void *)dialogResult} +}; + + +#define FIND_AND_CHECK_CLASS(CLASS_NAME) \ + clazz = env->FindClass(CLASS_NAME); \ + if (!clazz) { \ + __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::classErrorMsgFmt(), CLASS_NAME); \ + return false; \ + } + +bool registerNatives(JNIEnv *env) +{ + jclass clazz = QtAndroid::findClass("org/qtproject/qt5/android/QtMessageDialogHelper", env); + if (!clazz) { + __android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::classErrorMsgFmt() + , "org/qtproject/qt5/android/QtMessageDialogHelper"); + return false; + } + g_messageDialogHelperClass = static_cast(env->NewGlobalRef(clazz)); + FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/QtNativeDialogHelper"); + jclass appClass = static_cast(env->NewGlobalRef(clazz)); + + if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { + __android_log_print(ANDROID_LOG_FATAL, "Qt", "RegisterNatives failed"); + return false; + } + + return true; +} +} diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h new file mode 100644 index 0000000000..88ec91d936 --- /dev/null +++ b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2013 BogDan Vatra +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMDIALOGHELPERS_H +#define QANDROIDPLATFORMDIALOGHELPERS_H +#include +#include +#include +#include + +namespace QtAndroidDialogHelpers { + +class QAndroidPlatformMessageDialogHelper: public QPlatformMessageDialogHelper +{ + Q_OBJECT +public: + QAndroidPlatformMessageDialogHelper(); + void exec(); + bool show(Qt::WindowFlags windowFlags, + Qt::WindowModality windowModality, + QWindow *parent); + void hide(); + +public slots: + void dialogResult(int buttonID); + +private: + int m_buttonId; + QEventLoop m_loop; + QJNIObjectPrivate m_javaMessageDialog; + bool m_shown; +}; + + +bool registerNatives(JNIEnv *env); + +} + +#endif // QANDROIDPLATFORMDIALOGHELPERS_H diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp index 79fbc440fc..0ceac97e35 100644 --- a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp @@ -43,6 +43,7 @@ #include "qandroidplatformmenubar.h" #include "qandroidplatformmenu.h" #include "qandroidplatformmenuitem.h" +#include "qandroidplatformdialoghelpers.h" #include #include #include @@ -150,3 +151,20 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const return QPlatformTheme::themeHint(hint); } } + +bool QAndroidPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const +{ + if (type == MessageDialog) + return qgetenv("QT_USE_ANDROID_NATIVE_DIALOGS").toInt() == 1; + return false; +} + +QPlatformDialogHelper *QAndroidPlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const +{ + switch (type) { + case MessageDialog: + return new QtAndroidDialogHelpers::QAndroidPlatformMessageDialogHelper; + default: + return 0; + } +} diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.h b/src/plugins/platforms/android/src/qandroidplatformtheme.h index 15d2cb2000..ec259a9b0a 100644 --- a/src/plugins/platforms/android/src/qandroidplatformtheme.h +++ b/src/plugins/platforms/android/src/qandroidplatformtheme.h @@ -54,6 +54,9 @@ public: virtual const QPalette *palette(Palette type = SystemPalette) const; virtual const QFont *font(Font type = SystemFont) const; virtual QVariant themeHint(ThemeHint hint) const; + virtual bool usePlatformNativeDialog(DialogType type) const; + virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const; + private: QAndroidPlatformNativeInterface * m_androidPlatformNativeInterface; diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri index 6cc41c3e68..9b64e846f7 100644 --- a/src/plugins/platforms/android/src/src.pri +++ b/src/plugins/platforms/android/src/src.pri @@ -21,6 +21,7 @@ SOURCES += $$PWD/androidplatformplugin.cpp \ $$PWD/qandroidinputcontext.cpp \ $$PWD/qandroidplatformaccessibility.cpp \ $$PWD/qandroidplatformfontdatabase.cpp \ + $$PWD/qandroidplatformdialoghelpers.cpp \ $$PWD/qandroidplatformclipboard.cpp \ $$PWD/qandroidplatformtheme.cpp \ $$PWD/qandroidplatformmenubar.cpp \ @@ -41,6 +42,7 @@ HEADERS += $$PWD/qandroidplatformintegration.h \ $$PWD/qandroidplatformaccessibility.h \ $$PWD/qandroidplatformfontdatabase.h \ $$PWD/qandroidplatformclipboard.h \ + $$PWD/qandroidplatformdialoghelpers.h \ $$PWD/qandroidplatformtheme.h \ $$PWD/qandroidplatformmenubar.h \ $$PWD/qandroidplatformmenu.h \ -- cgit v1.2.3 From fd619946be51784dc709363324897be6af144c52 Mon Sep 17 00:00:00 2001 From: Fabian Bumberger Date: Thu, 22 Aug 2013 17:02:05 +0200 Subject: Refactor QQnxWindow This patch does following things: * Remove the root window: First window which is created will serve as a root window * Allow creation of more than one application window (with every app window having an own window group) on one screen * Fixes a bug when reparanting an EGL window Change-Id: I1afd64a813bc084c0893b958aa191d4a25c32b9d Reviewed-by: Matt Hoosier Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qnx.pro | 3 - src/plugins/platforms/qnx/qqnxeglwindow.cpp | 17 +- src/plugins/platforms/qnx/qqnxeglwindow.h | 6 +- src/plugins/platforms/qnx/qqnxintegration.cpp | 21 +- src/plugins/platforms/qnx/qqnxintegration.h | 5 +- src/plugins/platforms/qnx/qqnxrasterwindow.cpp | 16 +- src/plugins/platforms/qnx/qqnxrasterwindow.h | 7 +- src/plugins/platforms/qnx/qqnxrootwindow.cpp | 268 ------------------------- src/plugins/platforms/qnx/qqnxrootwindow.h | 85 -------- src/plugins/platforms/qnx/qqnxscreen.cpp | 74 +++---- src/plugins/platforms/qnx/qqnxscreen.h | 9 +- src/plugins/platforms/qnx/qqnxwindow.cpp | 143 +++++++------ src/plugins/platforms/qnx/qqnxwindow.h | 22 +- 13 files changed, 191 insertions(+), 485 deletions(-) delete mode 100644 src/plugins/platforms/qnx/qqnxrootwindow.cpp delete mode 100644 src/plugins/platforms/qnx/qqnxrootwindow.h (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index becf5e287e..aeacbeef69 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -25,7 +25,6 @@ CONFIG += qqnx_pps #DEFINES += QQNXNAVIGATOREVENTNOTIFIER_DEBUG #DEFINES += QQNXNAVIGATOR_DEBUG #DEFINES += QQNXRASTERBACKINGSTORE_DEBUG -#DEFINES += QQNXROOTWINDOW_DEBUG #DEFINES += QQNXSCREENEVENTTHREAD_DEBUG #DEFINES += QQNXSCREENEVENT_DEBUG #DEFINES += QQNXSCREEN_DEBUG @@ -42,7 +41,6 @@ SOURCES = main.cpp \ qqnxscreen.cpp \ qqnxwindow.cpp \ qqnxrasterbackingstore.cpp \ - qqnxrootwindow.cpp \ qqnxscreeneventhandler.cpp \ qqnxnativeinterface.cpp \ qqnxnavigatoreventhandler.cpp \ @@ -59,7 +57,6 @@ HEADERS = main.h \ qqnxscreen.h \ qqnxwindow.h \ qqnxrasterbackingstore.h \ - qqnxrootwindow.h \ qqnxscreeneventhandler.h \ qqnxnativeinterface.h \ qqnxnavigatoreventhandler.h \ diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp index e8fcdd692b..6afc3cad21 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp @@ -42,6 +42,7 @@ #include "qqnxeglwindow.h" #include "qqnxscreen.h" +#include "qqnxglcontext.h" #include @@ -55,8 +56,8 @@ QT_BEGIN_NAMESPACE -QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context) : - QQnxWindow(window, context), +QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) : + QQnxWindow(window, context, needRootWindow), m_requestedBufferSize(window->geometry().size()), m_platformOpenGLContext(0), m_newSurfaceRequested(true), @@ -98,8 +99,6 @@ void QQnxEglWindow::createEGLSurface() QQnxGLContext::checkEGLError("eglCreateWindowSurface"); qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError()); } - - screen()->onWindowPost(0); } void QQnxEglWindow::destroyEGLSurface() @@ -166,6 +165,13 @@ QSize QQnxEglWindow::requestedBufferSize() const return m_requestedBufferSize; } +void QQnxEglWindow::adjustBufferSize() +{ + const QSize windowSize = window()->size(); + if (windowSize != bufferSize()) + setBufferSize(windowSize); +} + void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext) { // This function does not take ownership of the platform gl context. @@ -175,6 +181,9 @@ void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContex int QQnxEglWindow::pixelFormat() const { + if (!m_platformOpenGLContext) //The platform GL context was not set yet + return -1; + const QSurfaceFormat format = m_platformOpenGLContext->format(); // Extract size of color channels from window format const int redSize = format.redBufferSize(); diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h index e7dae6a458..fc53afcd7a 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.h +++ b/src/plugins/platforms/qnx/qqnxeglwindow.h @@ -43,8 +43,6 @@ #define QQNXEGLWINDOW_H #include "qqnxwindow.h" -#include "qqnxglcontext.h" - #include QT_BEGIN_NAMESPACE @@ -54,7 +52,7 @@ class QQnxGLContext; class QQnxEglWindow : public QQnxWindow { public: - QQnxEglWindow(QWindow *window, screen_context_t context); + QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow); ~QQnxEglWindow(); void createEGLSurface(); @@ -70,7 +68,7 @@ public: // Called by QQnxGLContext::createSurface() QSize requestedBufferSize() const; - WindowType windowType() const Q_DECL_OVERRIDE { return EGL; } + void adjustBufferSize(); protected: int pixelFormat() const; diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 36a2194b56..52f836abbe 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -1,6 +1,6 @@ /*************************************************************************** ** -** Copyright (C) 2011 - 2012 Research In Motion +** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -122,6 +122,17 @@ static inline QQnxIntegration::Options parseOptions(const QStringList ¶mList if (!paramList.contains(QLatin1String("no-fullscreen"))) { options |= QQnxIntegration::FullScreenApplication; } + +// On Blackberry the first window is treated as a root window +#ifdef Q_OS_BLACKBERRY + if (!paramList.contains(QLatin1String("no-rootwindow"))) { + options |= QQnxIntegration::RootWindow; + } +#else + if (paramList.contains(QLatin1String("rootwindow"))) { + options |= QQnxIntegration::RootWindow; + } +#endif return options; } @@ -323,9 +334,10 @@ bool QQnxIntegration::hasCapability(QPlatformIntegration::Capability cap) const { qIntegrationDebug() << Q_FUNC_INFO; switch (cap) { + case MultipleWindows: case ThreadedPixmaps: return true; -#if defined(QT_OPENGL_ES) +#if !defined(QT_NO_OPENGL) case OpenGL: case ThreadedOpenGL: case BufferQueueingOpenGL: @@ -340,12 +352,13 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const { qIntegrationDebug() << Q_FUNC_INFO; QSurface::SurfaceType surfaceType = window->surfaceType(); + const bool needRootWindow = options() & RootWindow; switch (surfaceType) { case QSurface::RasterSurface: - return new QQnxRasterWindow(window, m_screenContext); + return new QQnxRasterWindow(window, m_screenContext, needRootWindow); #if !defined(QT_NO_OPENGL) case QSurface::OpenGLSurface: - return new QQnxEglWindow(window, m_screenContext); + return new QQnxEglWindow(window, m_screenContext, needRootWindow); #endif default: qFatal("QQnxWindow: unsupported window API"); diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index ab0d6a3156..8b5614fe4f 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -1,6 +1,6 @@ /*************************************************************************** ** -** Copyright (C) 2011 - 2012 Research In Motion +** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -84,7 +84,8 @@ class QQnxIntegration : public QPlatformIntegration public: enum Option { // Options to be passed on command line. NoOptions = 0x0, - FullScreenApplication = 0x1 + FullScreenApplication = 0x1, + RootWindow = 0x2 }; Q_DECLARE_FLAGS(Options, Option) explicit QQnxIntegration(const QStringList ¶mList); diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp index 16ff9d7519..1f974b268d 100644 --- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp @@ -54,8 +54,8 @@ QT_BEGIN_NAMESPACE -QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context) : - QQnxWindow(window, context), +QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context, bool needRootWindow) : + QQnxWindow(window, context, needRootWindow), m_currentBufferIndex(-1), m_previousBufferIndex(-1) { @@ -115,9 +115,6 @@ void QQnxRasterWindow::post(const QRegion &dirty) // Save modified region and clear scrolled region m_previousDirty = dirty; m_scrolled = QRegion(); - // Notify screen that window posted - if (screen() != 0) - screen()->onWindowPost(this); if (m_cover) m_cover->updateCover(); @@ -169,6 +166,15 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer() return m_buffers[m_currentBufferIndex]; } +void QQnxRasterWindow::adjustBufferSize() +{ + // When having a raster window we don't need any buffers, since + // Qt will draw to the parent TLW backing store. + const QSize windowSize = m_parentWindow ? QSize(1,1) : window()->size(); + if (windowSize != bufferSize()) + setBufferSize(windowSize); +} + int QQnxRasterWindow::pixelFormat() const { return screen()->nativeFormat(); diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.h b/src/plugins/platforms/qnx/qqnxrasterwindow.h index 8bd42bc320..ad34b3ccf2 100644 --- a/src/plugins/platforms/qnx/qqnxrasterwindow.h +++ b/src/plugins/platforms/qnx/qqnxrasterwindow.h @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class QQnxRasterWindow : public QQnxWindow { public: - QQnxRasterWindow(QWindow *window, screen_context_t context); + QQnxRasterWindow(QWindow *window, screen_context_t context, bool needRootWindow); void post(const QRegion &dirty); @@ -60,7 +60,7 @@ public: bool hasBuffers() const { return !bufferSize().isEmpty(); } - WindowType windowType() const Q_DECL_OVERRIDE { return Raster; } + void adjustBufferSize(); protected: int pixelFormat() const; @@ -69,6 +69,9 @@ protected: // Copies content from the previous buffer (back buffer) to the current buffer (front buffer) void blitPreviousToCurrent(const QRegion ®ion, int dx, int dy, bool flush=false); + void blitHelper(QQnxBuffer &source, QQnxBuffer &target, const QPoint &sourceOffset, + const QPoint &targetOffset, const QRegion ®ion, bool flush = false); + private: QRegion m_previousDirty; QRegion m_scrolled; diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.cpp b/src/plugins/platforms/qnx/qqnxrootwindow.cpp deleted file mode 100644 index b3f5c87176..0000000000 --- a/src/plugins/platforms/qnx/qqnxrootwindow.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqnxrootwindow.h" - -#include "qqnxscreen.h" - -#include -#include - -#if defined(QQNXROOTWINDOW_DEBUG) -#define qRootWindowDebug qDebug -#else -#define qRootWindowDebug QT_NO_QDEBUG_MACRO -#endif - -#include -#include - -static const int MAGIC_ZORDER_FOR_NO_NAV = 10; - -QQnxRootWindow::QQnxRootWindow(const QQnxScreen *screen) - : m_screen(screen), - m_window(0), - m_windowGroupName(), - m_translucent(false) -{ - qRootWindowDebug() << Q_FUNC_INFO; - // Create one top-level QNX window to act as a container for child windows - // since navigator only supports one application window - errno = 0; - int result = screen_create_window(&m_window, m_screen->nativeContext()); - int val[2]; - if (result != 0) - qFatal("QQnxRootWindow: failed to create window, errno=%d", errno); - - // Move window to proper display - errno = 0; - screen_display_t display = m_screen->nativeDisplay(); - result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window display, errno=%d", errno); - - // Make sure window is above navigator but below keyboard if running as root - // since navigator won't automatically set our z-order in this case - if (getuid() == 0) { - errno = 0; - val[0] = MAGIC_ZORDER_FOR_NO_NAV; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ZORDER, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window z-order, errno=%d", errno); - } - - // Window won't be visible unless it has some buffers so make one dummy buffer that is 1x1 - errno = 0; - val[0] = SCREEN_USAGE_NATIVE; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_USAGE, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window buffer usage, errno=%d", errno); - - errno = 0; - val[0] = m_screen->nativeFormat(); - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window pixel format, errno=%d", errno); - - errno = 0; - val[0] = 1; - val[1] = 1; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window buffer size, errno=%d", errno); - - errno = 0; - result = screen_create_window_buffers(m_window, 1); - if (result != 0) - qFatal("QQNX: failed to create window buffer, errno=%d", errno); - - // Window is always the size of the display - errno = 0; - QRect geometry = m_screen->geometry(); - val[0] = geometry.width(); - val[1] = geometry.height(); - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window size, errno=%d", errno); - - // Fill the window with solid black. Note that the LSB of the pixel value - // 0x00000000 just happens to be 0x00, so if and when this root window's - // alpha blending mode is changed from None to Source-Over, it will then - // be interpreted as transparent. - errno = 0; - val[0] = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_COLOR, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window colour, errno=%d", errno); - - // Make the window opaque - errno = 0; - val[0] = SCREEN_TRANSPARENCY_NONE; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window transparency, errno=%d", errno); - - // Set the swap interval to 1 - errno = 0; - val[0] = 1; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window swap interval, errno=%d", errno); - - // Set viewport size equal to window size but move outside buffer so the fill colour is used exclusively - errno = 0; - val[0] = geometry.width(); - val[1] = geometry.height(); - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window source size, errno=%d", errno); - - errno = 0; - val[0] = 0; - val[1] = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_POSITION, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window source position, errno=%d", errno); - - // Optionally disable the screen power save - bool ok = false; - const int disablePowerSave = qgetenv("QQNX_DISABLE_POWER_SAVE").toInt(&ok); - if (ok && disablePowerSave) { - const int mode = SCREEN_IDLE_MODE_KEEP_AWAKE; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_IDLE_MODE, &mode); - if (result != 0) - qWarning("QQnxRootWindow: failed to disable power saving mode"); - } - - createWindowGroup(); - - // Don't post yet. This will be lazily done from QQnxScreen upon first posting of - // a child window. Doing it now pre-emptively would create a flicker if one of - // the QWindow's about to be created sets its Qt::WA_TranslucentBackground flag - // and immediately triggers the buffer re-creation in makeTranslucent(). -} - -void QQnxRootWindow::makeTranslucent() -{ - if (m_translucent) - return; - - int result; - - errno = 0; - const int val = SCREEN_TRANSPARENCY_DISCARD; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, &val); - if (result != 0) { - qFatal("QQnxRootWindow: failed to set window transparency, errno=%d", errno); - } - - m_translucent = true; - post(); -} - -QQnxRootWindow::~QQnxRootWindow() -{ - // Cleanup top-level QNX window - screen_destroy_window(m_window); -} - -void QQnxRootWindow::post() const -{ - qRootWindowDebug() << Q_FUNC_INFO; - errno = 0; - screen_buffer_t buffer; - int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&buffer); - if (result != 0) - qFatal("QQnxRootWindow: failed to query window buffer, errno=%d", errno); - - errno = 0; - int dirtyRect[] = {0, 0, 1, 1}; - result = screen_post_window(m_window, buffer, 1, dirtyRect, 0); - if (result != 0) - qFatal("QQNX: failed to post window buffer, errno=%d", errno); -} - -void QQnxRootWindow::flush() const -{ - qRootWindowDebug() << Q_FUNC_INFO; - // Force immediate display update - errno = 0; - int result = screen_flush_context(m_screen->nativeContext(), 0); - if (result != 0) - qFatal("QQnxRootWindow: failed to flush context, errno=%d", errno); -} - -void QQnxRootWindow::setRotation(int rotation) -{ - qRootWindowDebug() << Q_FUNC_INFO << "angle =" << rotation; - errno = 0; - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window rotation, errno=%d", errno); -} - -void QQnxRootWindow::resize(const QSize &size) -{ - errno = 0; - int val[] = {size.width(), size.height()}; - int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window size, errno=%d", errno); - - errno = 0; - result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val); - if (result != 0) - qFatal("QQnxRootWindow: failed to set window source size, errno=%d", errno); - - // NOTE: display will update when child windows relayout and repaint -} - -void QQnxRootWindow::createWindowGroup() -{ - // Generate a random window group name - m_windowGroupName = QUuid::createUuid().toString().toLatin1(); - - // Create window group so child windows can be parented by container window - errno = 0; - int result = screen_create_window_group(m_window, m_windowGroupName.constData()); - if (result != 0) - qFatal("QQnxRootWindow: failed to create app window group, errno=%d", errno); -} diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.h b/src/plugins/platforms/qnx/qqnxrootwindow.h deleted file mode 100644 index ea7c7faace..0000000000 --- a/src/plugins/platforms/qnx/qqnxrootwindow.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** -** -** Copyright (C) 2011 - 2012 Research In Motion -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQNXROOTWINDOW_H -#define QQNXROOTWINDOW_H - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QQnxScreen; - -class QQnxRootWindow -{ -public: - QQnxRootWindow(const QQnxScreen *screen); - ~QQnxRootWindow(); - - screen_window_t nativeHandle() const { return m_window; } - - void post() const; - void flush() const; - - void setRotation(int rotation); - - void resize(const QSize &size); - - void makeTranslucent(); - - QByteArray groupName() const { return m_windowGroupName; } - -private: - void createWindowGroup(); - - const QQnxScreen *m_screen; - screen_window_t m_window; - QByteArray m_windowGroupName; - - bool m_translucent; -}; - -QT_END_NAMESPACE - -#endif // QQNXROOTWINDOW_H diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp index 3dab2b3bc9..a09d6ce1f5 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.cpp +++ b/src/plugins/platforms/qnx/qqnxscreen.cpp @@ -1,6 +1,6 @@ /*************************************************************************** ** -** Copyright (C) 2011 - 2012 Research In Motion +** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -154,8 +154,8 @@ static QQnxWindow *findMultimediaWindow(const QList windows, QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display, bool primaryScreen) : m_screenContext(screenContext), m_display(display), + m_rootWindow(0), m_primaryScreen(primaryScreen), - m_posted(false), m_keyboardHeight(0), m_nativeOrientation(Qt::PrimaryOrientation), m_coverWindow(0), @@ -292,7 +292,8 @@ void QQnxScreen::setRotation(int rotation) { qScreenDebug() << Q_FUNC_INFO << "orientation =" << rotation; // Check if rotation changed - if (m_currentRotation != rotation) { + // We only want to rotate if we are the primary screen + if (m_currentRotation != rotation && isPrimaryScreen()) { // Update rotation of root window if (rootWindow()) rootWindow()->setRotation(rotation); @@ -312,15 +313,13 @@ void QQnxScreen::setRotation(int rotation) if (isOrthogonal(m_currentRotation, rotation)) { qScreenDebug() << Q_FUNC_INFO << "resize, size =" << m_currentGeometry.size(); if (rootWindow()) - rootWindow()->resize(m_currentGeometry.size()); + rootWindow()->setGeometry(QRect(QPoint(0,0), m_currentGeometry.size())); - if (m_primaryScreen) - resizeWindows(previousScreenGeometry); + resizeWindows(previousScreenGeometry); } else { // TODO: Find one global place to flush display updates // Force immediate display update if no geometry changes required - if (rootWindow()) - rootWindow()->flush(); + screen_flush_context(nativeContext(), 0); } // Save new rotation @@ -490,6 +489,8 @@ void QQnxScreen::removeWindow(QQnxWindow *window) if (window != m_coverWindow) { const int numWindowsRemoved = m_childWindows.removeAll(window); + if (window == m_rootWindow) //We just removed the root window + m_rootWindow = 0; //TODO we need a new root window ;) if (numWindowsRemoved > 0) updateHierarchy(); } else { @@ -525,13 +526,15 @@ void QQnxScreen::updateHierarchy() QList::const_iterator it; int result; - int topZorder; + int topZorder = 0; errno = 0; - if (isPrimaryScreen()) { + if (rootWindow()) { result = screen_get_window_property_iv(rootWindow()->nativeHandle(), SCREEN_PROPERTY_ZORDER, &topZorder); - if (result != 0) - qFatal("QQnxScreen: failed to query root window z-order, errno=%d", errno); + if (result != 0) { //This can happen if we use winId in QWidgets + topZorder = 10; + qWarning("QQnxScreen: failed to query root window z-order, errno=%d", errno); + } } else { topZorder = 0; //We do not need z ordering on the secondary screen, because only one window //is supported there @@ -539,16 +542,17 @@ void QQnxScreen::updateHierarchy() topZorder++; // root window has the lowest z-order in the windowgroup + int underlayZorder = -1; // Underlays sit immediately above the root window in the z-ordering Q_FOREACH (screen_window_t underlay, m_underlays) { // Do nothing when this fails. This can happen if we have stale windows in m_underlays, // which in turn can happen because a window was removed but we didn't get a notification // yet. - screen_set_window_property_iv(underlay, SCREEN_PROPERTY_ZORDER, &topZorder); - topZorder++; + screen_set_window_property_iv(underlay, SCREEN_PROPERTY_ZORDER, &underlayZorder); + underlayZorder--; } - // Normal Qt windows come next above underlays in the z-ordering + // Normal Qt windows come next above the root window z-ordering for (it = m_childWindows.constBegin(); it != m_childWindows.constEnd(); ++it) (*it)->updateZorder(topZorder); @@ -564,20 +568,6 @@ void QQnxScreen::updateHierarchy() screen_flush_context( m_screenContext, 0 ); } -void QQnxScreen::onWindowPost(QQnxWindow *window) -{ - qScreenDebug() << Q_FUNC_INFO; - Q_UNUSED(window) - - // post app window (so navigator will show it) after first child window - // has posted; this only needs to happen once as the app window's content - // never changes - if (!m_posted && rootWindow()) { - rootWindow()->post(); - m_posted = true; - } -} - void QQnxScreen::adjustOrientation() { if (!m_primaryScreen) @@ -713,7 +703,7 @@ void QQnxScreen::windowGroupStateChanged(const QByteArray &id, Qt::WindowState s if (!rootWindow() || id != rootWindow()->groupName()) return; - QWindow * const window = topMostChildWindow(); + QWindow * const window = rootWindow()->window(); if (!window) return; @@ -728,7 +718,7 @@ void QQnxScreen::activateWindowGroup(const QByteArray &id) if (!rootWindow() || id != rootWindow()->groupName()) return; - QWindow * const window = topMostChildWindow(); + QWindow * const window = rootWindow()->window(); if (!window) return; @@ -755,18 +745,28 @@ void QQnxScreen::deactivateWindowGroup(const QByteArray &id) Q_FOREACH (QQnxWindow *childWindow, m_childWindows) childWindow->setExposed(false); - QWindowSystemInterface::handleWindowActivated(0); + QWindowSystemInterface::handleWindowActivated(rootWindow()->window()); } -QSharedPointer QQnxScreen::rootWindow() const +QQnxWindow *QQnxScreen::rootWindow() const { - // We only create the root window if we are the primary display. - if (m_primaryScreen && !m_rootWindow) - m_rootWindow = QSharedPointer(new QQnxRootWindow(this)); - return m_rootWindow; } +void QQnxScreen::setRootWindow(QQnxWindow *window) +{ + // Optionally disable the screen power save + bool ok = false; + const int disablePowerSave = qgetenv("QQNX_DISABLE_POWER_SAVE").toInt(&ok); + if (ok && disablePowerSave) { + const int mode = SCREEN_IDLE_MODE_KEEP_AWAKE; + int result = screen_set_window_property_iv(window->nativeHandle(), SCREEN_PROPERTY_IDLE_MODE, &mode); + if (result != 0) + qWarning("QQnxRootWindow: failed to disable power saving mode"); + } + m_rootWindow = window; +} + QWindow * QQnxScreen::topMostChildWindow() const { if (!m_childWindows.isEmpty()) { diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index 014f7905f3..61c47e6c72 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -44,7 +44,7 @@ #include -#include "qqnxrootwindow.h" +#include "qqnxwindow.h" #include #include @@ -91,10 +91,10 @@ public: void lowerWindow(QQnxWindow *window); void updateHierarchy(); - void onWindowPost(QQnxWindow *window); void adjustOrientation(); - QSharedPointer rootWindow() const; + QQnxWindow *rootWindow() const; + void setRootWindow(QQnxWindow*); QPlatformCursor *cursor() const; @@ -126,9 +126,8 @@ private: screen_context_t m_screenContext; screen_display_t m_display; - mutable QSharedPointer m_rootWindow; + QQnxWindow *m_rootWindow; const bool m_primaryScreen; - bool m_posted; int m_initialRotation; int m_currentRotation; diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 749a336fcc..1e58d482d4 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -1,6 +1,6 @@ /*************************************************************************** ** -** Copyright (C) 2011 - 2012 Research In Motion +** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -40,15 +40,16 @@ ****************************************************************************/ #include "qqnxwindow.h" -#if !defined(QT_NO_OPENGL) -#include "qqnxglcontext.h" -#endif #include "qqnxintegration.h" #include "qqnxscreen.h" +#include + #include #include +#include "private/qguiapplication_p.h" + #include #if defined(Q_OS_BLACKBERRY) @@ -69,12 +70,12 @@ QT_BEGIN_NAMESPACE -QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context) +QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow) : QPlatformWindow(window), m_screenContext(context), + m_parentWindow(0), m_window(0), m_screen(0), - m_parentWindow(0), m_visible(false), m_exposed(true), m_windowState(Qt::WindowNoState), @@ -83,13 +84,22 @@ QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context) qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size(); int result; - // Create child QNX window + QQnxScreen *platformScreen = static_cast(window->screen()->handle()); + + m_isTopLevel = ( needRootWindow && !platformScreen->rootWindow()) + || (!needRootWindow && !parent()) + || window->type() == Qt::CoverWindow; + errno = 0; - if (static_cast(window->screen()->handle())->isPrimaryScreen() - && window->type() != Qt::CoverWindow) { - result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW); + if (m_isTopLevel) { + result = screen_create_window(&m_window, m_screenContext); // Creates an application window + if (window->type() != Qt::CoverWindow) { + if (needRootWindow) + platformScreen->setRootWindow(this); + createWindowGroup(); + } } else { - result = screen_create_window(&m_window, m_screenContext); + result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW); } if (result != 0) qFatal("QQnxWindow: failed to create window, errno=%d", errno); @@ -116,20 +126,24 @@ QQnxWindow::~QQnxWindow() void QQnxWindow::setGeometry(const QRect &rect) { - const QRect oldGeometry = setGeometryHelper(rect); + QRect newGeometry = rect; + if (screen()->rootWindow() == this) //If this is the root window, it has to be shown fullscreen + newGeometry = screen()->geometry(); + + const QRect oldGeometry = setGeometryHelper(newGeometry); // Send a geometry change event to Qt (triggers resizeEvent() in QWindow/QWidget). // Calling flushWindowSystemEvents() here would flush input events which // could result in re-entering QQnxWindow::setGeometry() again. - QWindowSystemInterface::setSynchronousWindowsSystemEvents(true); - QWindowSystemInterface::handleGeometryChange(window(), rect); - QWindowSystemInterface::handleExposeEvent(window(), rect); + QWindowSystemInterface::setSynchronousWindowsSystemEvents(true); //This does not work + QWindowSystemInterface::handleGeometryChange(window(), newGeometry); + QWindowSystemInterface::handleExposeEvent(window(), newGeometry); QWindowSystemInterface::setSynchronousWindowsSystemEvents(false); // Now move all children. if (!oldGeometry.isEmpty()) { - const QPoint offset = rect.topLeft() - oldGeometry.topLeft(); + const QPoint offset = newGeometry.topLeft() - oldGeometry.topLeft(); Q_FOREACH (QQnxWindow *childWindow, m_childWindows) childWindow->setOffset(offset); } @@ -263,16 +277,6 @@ bool QQnxWindow::isExposed() const return m_visible && m_exposed; } -void QQnxWindow::adjustBufferSize() -{ - if (m_parentWindow) - return; - - const QSize windowSize = window()->size(); - if (windowSize != bufferSize()) - setBufferSize(windowSize); -} - void QQnxWindow::setBufferSize(const QSize &size) { qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size; @@ -291,6 +295,8 @@ void QQnxWindow::setBufferSize(const QSize &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; errno = 0; result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val); @@ -304,12 +310,6 @@ void QQnxWindow::setBufferSize(const QSize &size) qFatal("QQnxWindow: failed to create window buffers, errno=%d", errno); } - // If the child window has been configured for transparency, lazily create - // a full-screen buffer to back the root window. - if (window()->requestedFormat().hasAlpha()) { - m_screen->rootWindow()->makeTranslucent(); - } - // check if there are any buffers available int bufferCount = 0; result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount); @@ -334,6 +334,9 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) if (platformScreen == 0) { // The screen has been destroyed m_screen = 0; + Q_FOREACH (QQnxWindow *childWindow, m_childWindows) { + childWindow->setScreen(0); + } return; } @@ -343,26 +346,36 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen) if (m_screen) { qWindowDebug() << Q_FUNC_INFO << "Moving window to different screen"; m_screen->removeWindow(this); - screen_leave_window_group(m_window); + QQnxIntegration *platformIntegration = static_cast(QGuiApplicationPrivate::platformIntegration()); + + if ((platformIntegration->options() & QQnxIntegration::RootWindow)) { + screen_leave_window_group(m_window); + } } - platformScreen->addWindow(this); m_screen = platformScreen; - - // Move window to proper screen/display - errno = 0; - screen_display_t display = platformScreen->nativeDisplay(); - int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display); - if (result != 0) - qFatal("QQnxWindow: failed to set window display, errno=%d", errno); - - - if (m_screen->isPrimaryScreen() && window()->type() != Qt::CoverWindow) { - // Add window to display's window group + if (!m_parentWindow) { + platformScreen->addWindow(this); + } + if (m_isTopLevel) { + // Move window to proper screen/display errno = 0; - result = screen_join_window_group(m_window, platformScreen->windowGroupName()); + screen_display_t display = platformScreen->nativeDisplay(); + int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display); if (result != 0) - qFatal("QQnxWindow: failed to join window group, errno=%d", errno); + qFatal("QQnxWindow: failed to set window display, errno=%d", errno); + } else { + errno = 0; + int result; + if (!parent()) { + result = screen_join_window_group(m_window, platformScreen->windowGroupName()); + if (result != 0) + qFatal("QQnxWindow: failed to join window group, errno=%d", errno); + } else { + result = screen_join_window_group(m_window, static_cast(parent())->groupName().constData()); + if (result != 0) + qFatal("QQnxWindow: failed to join window group, errno=%d", errno); + } Q_FOREACH (QQnxWindow *childWindow, m_childWindows) { // Only subwindows and tooltips need necessarily be moved to another display with the window. @@ -406,20 +419,12 @@ void QQnxWindow::setParent(const QPlatformWindow *window) setScreen(m_parentWindow->m_screen); m_parentWindow->m_childWindows.push_back(this); - - // we don't need any buffers, since - // Qt will draw to the parent TLW - // backing store. - setBufferSize(QSize(1, 1)); } else { m_screen->addWindow(this); - - // recreate buffers, in case the - // window has been reparented and - // becomes a TLW - adjustBufferSize(); } + adjustBufferSize(); + m_screen->updateHierarchy(); } @@ -541,6 +546,15 @@ void QQnxWindow::minimize() #endif } +void QQnxWindow::setRotation(int rotation) +{ + qWindowDebug() << Q_FUNC_INFO << "angle =" << rotation; + errno = 0; + int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation); + if (result != 0) + qFatal("QQnxRootWindow: failed to set window rotation, errno=%d", errno); +} + void QQnxWindow::initWindow() { // Alpha channel is always pre-multiplied if present @@ -595,9 +609,24 @@ void QQnxWindow::initWindow() if (window()->parent() && window()->parent()->handle()) setParent(window()->parent()->handle()); setGeometryHelper(window()->geometry()); + if (screen()->rootWindow() == this) { + setGeometry(screen()->geometry()); + } } +void QQnxWindow::createWindowGroup() +{ + // Generate a random window group name + m_windowGroupName = QUuid::createUuid().toString().toLatin1(); + + // Create window group so child windows can be parented by container window + errno = 0; + int result = screen_create_window_group(m_window, m_windowGroupName.constData()); + if (result != 0) + qFatal("QQnxRootWindow: failed to create app window group, errno=%d", errno); +} + void QQnxWindow::updateZorder(int &topZorder) { updateZorder(m_window, topZorder); diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h index 52d22235a2..3c8070b0be 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.h +++ b/src/plugins/platforms/qnx/qqnxwindow.h @@ -66,12 +66,7 @@ class QQnxWindow : public QPlatformWindow { friend class QQnxScreen; public: - enum WindowType { - EGL, - Raster - }; - - QQnxWindow(QWindow *window, screen_context_t context); + QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow); virtual ~QQnxWindow(); void setGeometry(const QRect &rect); @@ -83,7 +78,7 @@ public: WId winId() const { return (WId)m_window; } screen_window_t nativeHandle() const { return m_window; } - void adjustBufferSize(); + virtual void adjustBufferSize() = 0; void setBufferSize(const QSize &size); QSize bufferSize() const { return m_bufferSize; } @@ -114,7 +109,10 @@ public: screen_window_t mmRendererWindow() const { return m_mmRendererWindow; } - virtual WindowType windowType() const = 0; + void setRotation(int rotation); + + QByteArray groupName() const { return m_windowGroupName; } + protected: virtual int pixelFormat() const = 0; virtual void resetBuffers() = 0; @@ -124,7 +122,10 @@ protected: screen_context_t m_screenContext; QScopedPointer m_cover; + QQnxWindow *m_parentWindow; + private: + void createWindowGroup(); QRect setGeometryHelper(const QRect &rect); void removeFromParent(); void setOffset(const QPoint &setOffset); @@ -138,13 +139,16 @@ private: QQnxScreen *m_screen; QList m_childWindows; - QQnxWindow *m_parentWindow; bool m_visible; bool m_exposed; QRect m_unmaximizedGeometry; Qt::WindowState m_windowState; QString m_mmRendererWindowName; screen_window_t m_mmRendererWindow; + + QByteArray m_windowGroupName; + + bool m_isTopLevel; }; QT_END_NAMESPACE -- cgit v1.2.3 From e6eadd6f61ae38a49a6bb355c02532cad2aacf4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 11 Nov 2013 15:38:43 +0100 Subject: iOS: Flesh out device-pixel-ratio handling in QIOSWindow We don't need to cache the device-pixel-ratio, as we can ask the UIView directly. We do need to set it though, as the default behavior of matching the screen scale does not apply for EAGL-backed views, but the ratio needs to match the current screen the view is on. Change-Id: I29e4a4fa4f4b767d86265ec899fb43a355b5c3a3 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.h | 1 - src/plugins/platforms/ios/qioswindow.mm | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index b60290e479..9ab9a3a45e 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -87,7 +87,6 @@ private: QRect m_normalGeometry; int m_windowLevel; - qreal m_devicePixelRatio; void raiseOrLower(bool raise); void updateWindowLevel(); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index f46616db1d..6d7b793f0b 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -127,6 +127,16 @@ return self; } +- (void)willMoveToWindow:(UIWindow *)newWindow +{ + // UIKIt will normally set the scale factor of a view to match the corresponding + // screen scale factor, but views backed by CAEAGLLayers need to do this manually. + self.contentScaleFactor = newWindow && newWindow.screen ? + newWindow.screen.scale : [[UIScreen mainScreen] scale]; + + // FIXME: Allow the scale factor to be customized through QSurfaceFormat. +} + - (void)layoutSubviews { // This method is the de facto way to know that view has been resized, @@ -331,19 +341,9 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_view([[QUIView alloc] initWithQIOSWindow:this]) , m_normalGeometry(QPlatformWindow::geometry()) , m_windowLevel(0) - , m_devicePixelRatio(1.0) { setParent(parent()); setWindowState(window->windowState()); - - // Retina support: get screen scale factor and set it in the content view. - // This will make framebufferObject() create a 2x frame buffer on retina - // displays. Also set m_devicePixelRatio which is used for scaling the - // paint device. - if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES) { - m_devicePixelRatio = [[UIScreen mainScreen] scale]; - [m_view setContentScaleFactor: m_devicePixelRatio]; - } } QIOSWindow::~QIOSWindow() @@ -522,7 +522,7 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio qreal QIOSWindow::devicePixelRatio() const { - return m_devicePixelRatio; + return m_view.contentScaleFactor; } QT_END_NAMESPACE -- cgit v1.2.3 From 18182a6275bb353dfb67ebc1562649e7624ccb0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 11 Nov 2013 16:33:21 +0100 Subject: iOS: Handle key window as part of QWindow activation The default UIWindow may not be the only UIWindow around in a multi screen setup. Change-Id: Ia7243190321a1416e577634bf5e010dd67d482e6 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index e06d2b8840..def6d2ff04 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -64,7 +64,7 @@ self.window.backgroundColor = [UIColor cyanColor]; #endif - [self.window makeKeyAndVisible]; + self.window.hidden = NO; return YES; } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 6d7b793f0b..23e6ad82b5 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -456,6 +456,8 @@ void QIOSWindow::requestActivateWindow() if (!window()->isTopLevel() || blockedByModal()) return; + [m_view.window makeKeyWindow]; + raise(); QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); static_cast(context)->focusViewChanged(m_view); -- cgit v1.2.3 From bb1225f5ba6f4bc5d7b8c2878d8f4ac492631c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 11 Nov 2013 15:17:56 +0100 Subject: iOS: Tie QIOSContext FBOs to corresponding QPlatformWindow, not QWindow A QWindow may be created() and destroyed() multiple times in the lifetime of the window, each time resulting in a new platform window (QIOSWindow) being created. This QIOSWindow is backed by a new UIView each time, hence it needs a new FBO and renderbuffer-mapping, since the previous renderbuffer was mapped to the old UIView. This fixes a bug where a QWindow would not render after a destroy() unless it was resized (which triggered new FBO/renderbuffers). We need to inherit QObject so that we can watch the destroyed() signal. Change-Id: I93172dd6280b86b49755bf7abddf061d7e6b66f1 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioscontext.h | 4 +++- src/plugins/platforms/ios/qioscontext.mm | 9 ++++----- src/plugins/platforms/ios/qioswindow.h | 4 +++- src/plugins/platforms/ios/qioswindow.mm | 4 +++- 4 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h index 961661c5d3..c48a0251a9 100644 --- a/src/plugins/platforms/ios/qioscontext.h +++ b/src/plugins/platforms/ios/qioscontext.h @@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE +class QIOSWindow; + class QIOSContext : public QObject, public QPlatformOpenGLContext { Q_OBJECT @@ -87,7 +89,7 @@ private: static void deleteBuffers(const FramebufferObject &framebufferObject); - mutable QHash m_framebufferObjects; + mutable QHash m_framebufferObjects; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index d7b9314ae0..7310d2904f 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -113,7 +113,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) { Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window); - QWindow *window = static_cast(surface->surface()); + QIOSWindow *window = static_cast(surface); Q_ASSERT(m_framebufferObjects.contains(window)); [EAGLContext setCurrentContext:m_eaglContext]; @@ -124,7 +124,7 @@ void QIOSContext::swapBuffers(QPlatformSurface *surface) GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const { Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window); - QWindow *window = static_cast(surface->surface()); + QIOSWindow *window = static_cast(surface); FramebufferObject &framebufferObject = m_framebufferObjects[window]; @@ -155,8 +155,7 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const } // Ensure that the FBO's buffers match the size of the layer - QIOSWindow *platformWindow = static_cast(surface); - UIView *view = reinterpret_cast(platformWindow->winId()); + UIView *view = reinterpret_cast(window->winId()); CAEAGLLayer *layer = static_cast(view.layer); if (framebufferObject.renderbufferWidth != (layer.frame.size.width * layer.contentsScale) || framebufferObject.renderbufferHeight != (layer.frame.size.height * layer.contentsScale)) { @@ -191,7 +190,7 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const void QIOSContext::windowDestroyed(QObject *object) { - QWindow *window = static_cast(object); + QIOSWindow *window = static_cast(object); if (m_framebufferObjects.contains(window)) { EAGLContext *originalContext = [EAGLContext currentContext]; [EAGLContext setCurrentContext:m_eaglContext]; diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 9ab9a3a45e..5ded589205 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -58,8 +58,10 @@ QT_BEGIN_NAMESPACE @class QUIView; -class QIOSWindow : public QPlatformWindow +class QIOSWindow : public QObject, public QPlatformWindow { + Q_OBJECT + public: explicit QIOSWindow(QWindow *window); ~QIOSWindow(); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 23e6ad82b5..215f590595 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -342,7 +342,7 @@ QIOSWindow::QIOSWindow(QWindow *window) , m_normalGeometry(QPlatformWindow::geometry()) , m_windowLevel(0) { - setParent(parent()); + setParent(QPlatformWindow::parent()); setWindowState(window->windowState()); } @@ -527,4 +527,6 @@ qreal QIOSWindow::devicePixelRatio() const return m_view.contentScaleFactor; } +#include "moc_qioswindow.cpp" + QT_END_NAMESPACE -- cgit v1.2.3 From 2afbd92274446359d278b5a1025067e20dd11df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 8 Nov 2013 09:26:37 +0100 Subject: iOS: Get rid of separate release pool for QIOSScreen We don't use separate pools anwyhere else, and this was copied straight from the UIKit plugin. Unless there's a good reason for having it in this particular place we should keep things consistent. Change-Id: I9a3f83bcc5894a2cdfd9af7818b46d6c0f8448da Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index c28d8881bf..d57e678810 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -123,8 +123,6 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(NSUInteger(screenIndex), [[UIScreen screens] count] - 1)]) , m_orientationListener(0) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - QString deviceIdentifier = deviceModelIdentifier(); if (deviceIdentifier == QStringLiteral("iPhone2,1") /* iPhone 3GS */ @@ -153,8 +151,6 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) // When in a non-mixed environment, let QScreen follow the current interface orientation: setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(qiosViewController().interfaceOrientation))); } - - [pool release]; } QIOSScreen::~QIOSScreen() -- cgit v1.2.3 From 3a7104420cc8f8eb11b3596cef310f52c350bbd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 12 Nov 2013 15:28:07 +0100 Subject: iOS: Remove background color for UIWindow and UIViewController's root view They were handy while debugging the iOS platform plugin, but should not affect users who link against debug libraries, so let's just remove them. Change-Id: I61b157e81130e5d951c22892e00f71e593082b1d Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 4 ---- src/plugins/platforms/ios/qiosviewcontroller.mm | 8 -------- 2 files changed, 12 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index def6d2ff04..4d88faba75 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -60,10 +60,6 @@ self.qiosViewController = [[[QIOSViewController alloc] init] autorelease]; self.window.rootViewController = self.qiosViewController; -#ifdef QT_DEBUG - self.window.backgroundColor = [UIColor cyanColor]; -#endif - self.window.hidden = NO; return YES; diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index d315b49776..656a86027d 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -48,14 +48,6 @@ @implementation QIOSViewController -- (void)viewDidLoad -{ -#ifdef QT_DEBUG - if (!self.nibName) - self.view.backgroundColor = [UIColor magentaColor]; -#endif -} - -(BOOL)shouldAutorotate { // Until a proper orientation and rotation API is in place, we always auto rotate. -- cgit v1.2.3 From d160f195077af1d06fd8ac1da30fd7044f6bb3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 12 Nov 2013 16:25:25 +0100 Subject: iOS: Enable clipping of subviews when QWindow has child windows QWindow::setParent() is documented to imply that the geometry of the window is in the parent's coordinate system and that the window is clipped to the parent. Instead of always enabling clipping of subviews for our UIView subclass we dynamically detect if we have QWindow children and enable/disable it on the fly. Change-Id: If83de94c55cbd19de401ab835e86bb7be5999d71 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 215f590595..e02f570634 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -137,6 +137,22 @@ // FIXME: Allow the scale factor to be customized through QSurfaceFormat. } +- (void)didAddSubview:(UIView *)subview +{ + if ([subview isKindOfClass:[QUIView class]]) + self.clipsToBounds = YES; +} + +- (void)willRemoveSubview:(UIView *)subview +{ + for (UIView *view in self.subviews) { + if (view != subview && [view isKindOfClass:[QUIView class]]) + return; + } + + self.clipsToBounds = NO; +} + - (void)layoutSubviews { // This method is the de facto way to know that view has been resized, -- cgit v1.2.3 From 3ebcbdd322c070c9bada31eceea1ea3c6ac2c0de Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 11 Nov 2013 14:40:50 +0100 Subject: Android: fix crash on exit Let's not try to dereference the null pointer. Task-number: QTBUG-34746 Change-Id: Iee79b711bd81614e36af4ab3612f9a87053a39f2 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/src/androidjnimenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp index 866acd3c7e..293af2b9cd 100644 --- a/src/plugins/platforms/android/src/androidjnimenu.cpp +++ b/src/plugins/platforms/android/src/androidjnimenu.cpp @@ -142,7 +142,7 @@ namespace QtAndroidMenu void setActiveTopLevelWindow(QWindow *window) { - Qt::WindowFlags flags = window->flags(); + Qt::WindowFlags flags = window ? window->flags() : Qt::WindowFlags(); bool isNonRegularWindow = flags & (Qt::Desktop | Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; if (isNonRegularWindow) return; -- cgit v1.2.3 From bcf5dbc8a02a42dbb300805c9a380debc3a6f2d3 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 14 Nov 2013 12:17:09 +0100 Subject: Fix jerky animations in Qt Quick for iOS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will make Qt Quick use consistent timing which prepares animation frames for the time they go to screen, rather than the current time at the time of the animation tick, which can be quite jerky in many situations. Change-Id: I1bbd4394db0c757553ee406d416fccb3ef937db8 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 393a9f317d..44ac749454 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -101,6 +101,8 @@ QIOSIntegration::~QIOSIntegration() bool QIOSIntegration::hasCapability(Capability cap) const { switch (cap) { + case BufferQueueingOpenGL: + return true; case OpenGL: case ThreadedOpenGL: return true; -- cgit v1.2.3 From 2828072d509fd052aaae18fee59d9b4f5d079717 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 12 Nov 2013 10:45:26 +0200 Subject: Android: Initialize mWindowState Use the same variable in QAndroidPlatformWindow. Task-number: QTBUG-34764 Change-Id: Idf33707e81cf7306663196f3c17735d8dc1dde5d Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../platforms/android/src/raster/qandroidplatformwindow.cpp | 8 +++----- src/plugins/platforms/android/src/raster/qandroidplatformwindow.h | 3 --- 2 files changed, 3 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp index 2dedc77027..7ff18526d9 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp @@ -46,7 +46,6 @@ QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window) - , m_state(Qt::WindowNoState) { } @@ -65,9 +64,9 @@ void QAndroidPlatformWindow::updateStatusBarVisibility() Qt::WindowFlags flags = window()->flags(); bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; if (!isNonRegularWindow) { - if (m_state & Qt::WindowFullScreen) + if (mWindowState & Qt::WindowFullScreen) QtAndroid::hideStatusBar(); - else if (m_state & Qt::WindowMaximized) + else if (mWindowState & Qt::WindowMaximized) QtAndroid::showStatusBar(); } } @@ -80,10 +79,9 @@ void QAndroidPlatformWindow::raise() void QAndroidPlatformWindow::setWindowState(Qt::WindowState state) { - if (m_state == state) + if (mWindowState == state) return; - m_state = state; if (window()->isVisible()) updateStatusBarVisibility(); diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h index 87626b982a..9e3f203201 100644 --- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h @@ -59,9 +59,6 @@ public: public slots: void setGeometry(const QRect &rect); - -private: - Qt::WindowState m_state; }; #endif // ANDROIDPLATFORMWINDOW_H -- cgit v1.2.3 From b8c93d4592837f3a4d30a543d461d432f2cd59eb Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 14 Nov 2013 15:39:28 +0100 Subject: Android: work around input method cursor position bug Since the Qt input method queries only give us information on the position within the block, moving to the same position in a different block will be interpreted as not moving. The quick fix is to send a fake position before the real one in this case. Task-number: QTBUG-34845 Change-Id: I5d62bdffc283e41d0384c60a0b69c01811caa629 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: BogDan Vatra --- .../platforms/android/src/androidjniinput.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp index 27d29129f8..8ce95532d3 100644 --- a/src/plugins/platforms/android/src/androidjniinput.cpp +++ b/src/plugins/platforms/android/src/androidjniinput.cpp @@ -67,12 +67,32 @@ namespace QtAndroidInput static QPointer m_mouseGrabber; + static int m_lastCursorPos = -1; + void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd) { AttachedJNIEnv env; if (!env.jniEnv) return; +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd; +#endif + if (candidatesStart == -1 && candidatesEnd == -1 && selStart == selEnd) { + // Qt only gives us position inside the block, so if we move to the + // same position in another block, the Android keyboard will believe + // we have not changed position, and be terribly confused. + if (selStart == m_lastCursorPos) { +#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL + qDebug() << ">>> FAKEUPDATESELECTION" << selStart+1; +#endif + env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID, + selStart+1, selEnd+1, candidatesStart, candidatesEnd); + } + m_lastCursorPos = selStart; + } else { + m_lastCursorPos = -1; + } env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID, selStart, selEnd, candidatesStart, candidatesEnd); } -- cgit v1.2.3 From 038b0dae83c8fde5f3b20b92eb51cbc3534a037b Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 4 Nov 2013 15:59:55 +0000 Subject: Update QSurfaceFormat when creating a GL context in the cocoa qpa Task-number: QTBUG-34471 Change-Id: I99f643280b8a4aaa8d63329232c0c3f4b2faed4b Reviewed-by: Gunnar Sletta --- src/plugins/platforms/cocoa/qcocoaglcontext.h | 1 + src/plugins/platforms/cocoa/qcocoaglcontext.mm | 139 +++++++++++++++++++++++++ 2 files changed, 140 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index 29affb0e4a..e1d4b602c9 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -77,6 +77,7 @@ public: private: void setActiveWindow(QWindow *window); + void updateSurfaceFormat(); NSOpenGLContext *m_context; NSOpenGLContext *m_shareContext; diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index f709c94c6d..b3695c2635 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -48,6 +48,74 @@ #import +static inline QByteArray getGlString(GLenum param) +{ + if (const GLubyte *s = glGetString(param)) + return QByteArray(reinterpret_cast(s)); + return QByteArray(); +} + +#if !defined(GL_CONTEXT_FLAGS) +#define GL_CONTEXT_FLAGS 0x821E +#endif + +#if !defined(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) +#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 +#endif + +#if !defined(GL_CONTEXT_PROFILE_MASK) +#define GL_CONTEXT_PROFILE_MASK 0x9126 +#endif + +#if !defined(GL_CONTEXT_CORE_PROFILE_BIT) +#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 +#endif + +#if !defined(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) +#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 +#endif + +static void updateFormatFromContext(QSurfaceFormat *format) +{ + Q_ASSERT(format); + + // Update the version, profile, and context bit of the format + int major = 0, minor = 0; + QByteArray versionString(getGlString(GL_VERSION)); + if (QPlatformOpenGLContext::parseOpenGLVersion(versionString, major, minor)) { + format->setMajorVersion(major); + format->setMinorVersion(minor); + } + + format->setProfile(QSurfaceFormat::NoProfile); + + Q_ASSERT(format->renderableType() == QSurfaceFormat::OpenGL); + if (format->version() < qMakePair(3, 0)) { + format->setOption(QSurfaceFormat::DeprecatedFunctions); + return; + } + + // Version 3.0 onwards - check if it includes deprecated functionality + GLint value = 0; + glGetIntegerv(GL_CONTEXT_FLAGS, &value); + if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)) + format->setOption(QSurfaceFormat::DeprecatedFunctions); + + // Debug context option not supported on OS X + + if (format->version() < qMakePair(3, 2)) + return; + + // Version 3.2 and newer have a profile + value = 0; + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); + + if (value & GL_CONTEXT_CORE_PROFILE_BIT) + format->setProfile(QSurfaceFormat::CoreProfile); + else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) + format->setProfile(QSurfaceFormat::CompatibilityProfile); +} + QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share) : m_context(nil), m_shareContext(nil), @@ -82,6 +150,8 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo int zeroOpacity = 0; [m_context setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity]; } + + updateSurfaceFormat(); } QCocoaGLContext::~QCocoaGLContext() @@ -137,6 +207,75 @@ void QCocoaGLContext::setActiveWindow(QWindow *window) [(QNSView *) cocoaWindow->contentView() setQCocoaGLContext:this]; } +void QCocoaGLContext::updateSurfaceFormat() +{ + // At present it is impossible to turn an option off on a QSurfaceFormat (see + // https://codereview.qt-project.org/#change,70599). So we have to populate + // the actual surface format from scratch + QSurfaceFormat requestedFormat = m_format; + m_format = QSurfaceFormat(); + m_format.setRenderableType(QSurfaceFormat::OpenGL); + + // CoreGL doesn't require a drawable to make the context current + CGLContextObj oldContext = CGLGetCurrentContext(); + CGLContextObj ctx = static_cast([m_context CGLContextObj]); + CGLSetCurrentContext(ctx); + + // Get the data that OpenGL provides + updateFormatFromContext(&m_format); + + // Get the data contained within the pixel format + CGLPixelFormatObj cglPixelFormat = static_cast(CGLGetPixelFormat(ctx)); + NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithCGLPixelFormatObj:cglPixelFormat]; + + int colorSize = -1; + [pixelFormat getValues:&colorSize forAttribute:NSOpenGLPFAColorSize forVirtualScreen:0]; + if (colorSize > 0) { + // This seems to return the total color buffer depth, including alpha + m_format.setRedBufferSize(colorSize / 4); + m_format.setGreenBufferSize(colorSize / 4); + m_format.setBlueBufferSize(colorSize / 4); + } + + // The pixel format always seems to return 8 for alpha. However, the framebuffer only + // seems to have alpha enabled if we requested it explicitly. I can't find any other + // attribute to check explicitly for this so we use our best guess for alpha. + int alphaSize = -1; + [pixelFormat getValues:&alphaSize forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0]; + qDebug() << "alphaSize =" << alphaSize; + if (alphaSize > 0 && requestedFormat.alphaBufferSize() > 0) + m_format.setAlphaBufferSize(alphaSize); + + int depthSize = -1; + [pixelFormat getValues:&depthSize forAttribute:NSOpenGLPFADepthSize forVirtualScreen:0]; + if (depthSize > 0) + m_format.setDepthBufferSize(depthSize); + + int stencilSize = -1; + [pixelFormat getValues:&stencilSize forAttribute:NSOpenGLPFAStencilSize forVirtualScreen:0]; + if (stencilSize > 0) + m_format.setStencilBufferSize(stencilSize); + + int samples = -1; + [pixelFormat getValues:&samples forAttribute:NSOpenGLPFASamples forVirtualScreen:0]; + if (samples > 0) + m_format.setSamples(samples); + + int doubleBuffered = -1; + [pixelFormat getValues:&doubleBuffered forAttribute:NSOpenGLPFADoubleBuffer forVirtualScreen:0]; + m_format.setSwapBehavior(doubleBuffered == 1 ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::SingleBuffer); + + int steroBuffers = -1; + [pixelFormat getValues:&steroBuffers forAttribute:NSOpenGLPFAStereo forVirtualScreen:0]; + if (steroBuffers == 1) + m_format.setOption(QSurfaceFormat::StereoBuffers); + + [pixelFormat release]; + + // Restore the original context + CGLSetCurrentContext(oldContext); +} + void QCocoaGLContext::doneCurrent() { if (m_currentWindow && m_currentWindow.data()->handle()) -- cgit v1.2.3 From 9f75292a602ba22b1a3a46f8a161020d2f847565 Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Tue, 12 Nov 2013 13:43:37 +0000 Subject: Remove side effects of QGLXContext::queryDummyContext() Task-number: QTBUG-34782 Change-Id: I411c89238b3002a118b1750af0157ccff5c78712 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/qglxintegration.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 4ac4cf21ab..d05de63c8f 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -431,6 +431,11 @@ void QGLXContext::queryDummyContext() if (skip) return; + QOpenGLContext *oldContext = QOpenGLContext::currentContext(); + QSurface *oldSurface = 0; + if (oldContext) + oldSurface = oldContext->surface(); + QOffscreenSurface surface; surface.create(); QOpenGLContext context; @@ -446,6 +451,9 @@ void QGLXContext::queryDummyContext() break; } } + + if (oldContext && oldSurface) + oldContext->makeCurrent(oldSurface); } bool QGLXContext::supportsThreading() -- cgit v1.2.3 From f3f25b14693b7211467ae39279b01c580ef8e5b4 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 12 Nov 2013 15:37:57 +0100 Subject: Avoid using GLX pbuffers on fglrx Task-number: QTBUG-34427 Change-Id: Ief4fe2fe2ab099d4ec61b6bfb2272724dfb2a800 Reviewed-by: Gunnar Sletta Reviewed-by: Sean Harmer --- src/plugins/platforms/xcb/qglxintegration.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index d05de63c8f..e6fa8fc898 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -436,11 +436,23 @@ void QGLXContext::queryDummyContext() if (oldContext) oldSurface = oldContext->surface(); - QOffscreenSurface surface; - surface.create(); + QScopedPointer surface; + const char *vendor = glXGetClientString(glXGetCurrentDisplay(), GLX_VENDOR); + if (vendor && !strcmp(vendor, "ATI")) { + QWindow *window = new QWindow; + window->resize(64, 64); + window->setSurfaceType(QSurface::OpenGLSurface); + window->create(); + surface.reset(window); + } else { + QOffscreenSurface *offSurface = new QOffscreenSurface; + offSurface->create(); + surface.reset(offSurface); + } + QOpenGLContext context; context.create(); - context.makeCurrent(&surface); + context.makeCurrent(surface.data()); const char *renderer = (const char *) glGetString(GL_RENDERER); @@ -452,6 +464,7 @@ void QGLXContext::queryDummyContext() } } + context.doneCurrent(); if (oldContext && oldSurface) oldContext->makeCurrent(oldSurface); } -- cgit v1.2.3 From 63824d2e00de53ae61158547ad01e97038160137 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 14 Nov 2013 14:11:39 +0100 Subject: Android: Support popup menus This is used by QML comboboxes, menu buttons, etc. Task-number: QTBUG-31420 Change-Id: I6d3f32fd80ce91c4be34eae636d1b95a4e251a49 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/src/qandroidplatformmenu.cpp | 10 +++++++++- src/plugins/platforms/android/src/qandroidplatformmenu.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp index 253c22a12f..1ecabb25e2 100644 --- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp @@ -141,6 +141,15 @@ bool QAndroidPlatformMenu::isVisible() const return m_isVisible; } +void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) +{ + Q_UNUSED(parentWindow); + Q_UNUSED(pos); + Q_UNUSED(item); + setVisible(true); + QtAndroidMenu::showContextMenu(this); +} + QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const { if (position < m_menuItems.size()) @@ -154,7 +163,6 @@ QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const if (menuItem->tag() == tag) return menuItem; } - return 0; } diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.h b/src/plugins/platforms/android/src/qandroidplatformmenu.h index 20236cb636..305b64168a 100644 --- a/src/plugins/platforms/android/src/qandroidplatformmenu.h +++ b/src/plugins/platforms/android/src/qandroidplatformmenu.h @@ -71,6 +71,7 @@ public: bool isEnabled() const; void setVisible(bool visible); bool isVisible() const; + void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item); QPlatformMenuItem *menuItemAt(int position) const; QPlatformMenuItem *menuItemForTag(quintptr tag) const; -- cgit v1.2.3 From 00b13e63888dad5fe9d5e07426ea34aa60e8f709 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Wed, 13 Nov 2013 17:24:21 +0100 Subject: QNX: Fixed touch event positions Touch positions reported by libscreen have to be adjusted relative to the window position to be properly interpreted by Qt. Task-number: QTBUG-34812 Change-Id: I68744dc9da95fb1d0d1704d12154fb24c148fe03 Reviewed-by: Sean Harmer --- src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index 9db62865bb..6f06797393 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -438,7 +438,14 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType) m_touchPoints[touchId].normalPosition = QPointF(static_cast(pos[0]) / screenSize.width(), static_cast(pos[1]) / screenSize.height()); - m_touchPoints[touchId].area = QRectF( pos[0], pos[1], 0.0, 0.0 ); + + m_touchPoints[touchId].area = QRectF(w->geometry().left() + windowPos[0], + w->geometry().top() + windowPos[1], 0.0, 0.0); + QWindow *parent = w->parent(); + while (parent) { + m_touchPoints[touchId].area.translate(parent->geometry().topLeft()); + parent = parent->parent(); + } // determine event type and update state of current touch point QEvent::Type type = QEvent::None; @@ -473,8 +480,8 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType) // inject event into Qt QWindowSystemInterface::handleTouchEvent(w, m_touchDevice, pointList); qScreenEventDebug() << Q_FUNC_INFO << "Qt touch, w =" << w - << ", p=(" << pos[0] << "," << pos[1] - << "), t=" << type; + << ", p=" << m_touchPoints[touchId].area.topLeft() + << ", t=" << type; } } } -- cgit v1.2.3 From 3e88ebc43dc1ca68f9f521f34584b4374452df9b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 15 Nov 2013 12:58:49 +0100 Subject: Remove stray debug output This was actually causing test failures in qtdeclarative and blocking the CI there. Change-Id: I4538342f16b6468ad60b283c19948863b20ad5d4 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 1 - 1 file changed, 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index b3695c2635..144144338f 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -242,7 +242,6 @@ void QCocoaGLContext::updateSurfaceFormat() // attribute to check explicitly for this so we use our best guess for alpha. int alphaSize = -1; [pixelFormat getValues:&alphaSize forAttribute:NSOpenGLPFAAlphaSize forVirtualScreen:0]; - qDebug() << "alphaSize =" << alphaSize; if (alphaSize > 0 && requestedFormat.alphaBufferSize() > 0) m_format.setAlphaBufferSize(alphaSize); -- cgit v1.2.3 From e3383ab646381cfca217af5ea6b059e59a837edd Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 12 Nov 2013 15:36:50 +0100 Subject: GTK theme should not claim to provide a native MessageDialog yet It was providing all possible types, but now MessageDialog is a new native dialog type, and only on Android at the moment. Task-number: QTBUG-34784 Change-Id: I2fb288c8d5e176ca4dafbbc310de2f29bbcfc000 Reviewed-by: J-P Nurmi --- src/plugins/platformthemes/gtk2/qgtk2theme.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp index f069d9f97c..812f4bc000 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2theme.cpp @@ -87,8 +87,16 @@ QVariant QGtk2Theme::themeHint(QPlatformTheme::ThemeHint hint) const bool QGtk2Theme::usePlatformNativeDialog(DialogType type) const { - Q_UNUSED(type); - return true; + switch (type) { + case ColorDialog: + return true; + case FileDialog: + return true; + case FontDialog: + return true; + default: + return false; + } } QPlatformDialogHelper *QGtk2Theme::createPlatformDialogHelper(DialogType type) const -- cgit v1.2.3 From 81f2d6eaacb905500f11d102e3f19c702535ec24 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 11 Nov 2013 10:35:33 +0100 Subject: Fix compiler warning for cast from int to id. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qcocoaapplication.mm:118:61: warning: cast to 'id' from smaller integer type 'int' [-Wint-to-pointer-cast] id a1 = ([args->arg1 isKindOfClass:[NSNumber class]]) ? (id)[args->arg1 intValue] : args->arg1; ^ qcocoaapplication.mm:119:61: warning: cast to 'id' from smaller integer type 'int' [-Wint-to-pointer-cast] id a2 = ([args->arg2 isKindOfClass:[NSNumber class]]) ? (id)[args->arg2 intValue] : args->arg2; Change-Id: Ibcf3d5d5698ff863f3c9bd65e0388ccca147f419 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaapplication.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm index c293f4cd52..551a59823c 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplication.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm @@ -115,8 +115,8 @@ QT_USE_NAMESPACE QCocoaPostMessageArgs *args = reinterpret_cast(lower | (upper << 32)); // Special case for convenience: if the argument is an NSNumber, we unbox it directly. // Use NSValue instead if this behaviour is unwanted. - id a1 = ([args->arg1 isKindOfClass:[NSNumber class]]) ? (id)[args->arg1 intValue] : args->arg1; - id a2 = ([args->arg2 isKindOfClass:[NSNumber class]]) ? (id)[args->arg2 intValue] : args->arg2; + id a1 = ([args->arg1 isKindOfClass:[NSNumber class]]) ? (id)[args->arg1 longValue] : args->arg1; + id a2 = ([args->arg2 isKindOfClass:[NSNumber class]]) ? (id)[args->arg2 longValue] : args->arg2; switch (args->argCount) { case 0: [args->target performSelector:args->selector]; -- cgit v1.2.3 From be405c86f8efac7c6bc8b749725d6d0e0499314d Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 12 Nov 2013 09:41:42 +0100 Subject: Fix the window flags for Cocoa windows This ensures that the possible window flag combinations are respected where possible in Cocoa. Task-number: QTBUG-34645 Task-number: QTBUG-31616 Change-Id: I6be8ca666b7cbc397575e97cd95ea298f52a7113 Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoawindow.mm | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 228ef9d484..c22f254aef 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -470,14 +470,12 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); } else { - // Filter flags for supported properties - flags &= Qt::WindowType_Mask | Qt::FramelessWindowHint | Qt::WindowTitleHint | - Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint; - if (flags == Qt::Window) { + if (type == Qt::Window && !(flags & Qt::CustomizeWindowHint)) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); - } else if ((flags & Qt::Dialog) == Qt::Dialog) { + } else if (type == Qt::Dialog) { if (flags & Qt::CustomizeWindowHint) { - styleMask = NSResizableWindowMask; + if (flags & Qt::WindowMaximizeButtonHint) + styleMask = NSResizableWindowMask; if (flags & Qt::WindowTitleHint) styleMask |= NSTitledWindowMask; if (flags & Qt::WindowCloseButtonHint) @@ -488,7 +486,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask; } } else if (!(flags & Qt::FramelessWindowHint)) { - if ((flags & Qt::Dialog) || (flags & Qt::WindowMaximizeButtonHint)) + if (flags & Qt::WindowMaximizeButtonHint) styleMask |= NSResizableWindowMask; if (flags & Qt::WindowTitleHint) styleMask |= NSTitledWindowMask; -- cgit v1.2.3 From cd93a2c0e14090cecbe3e83748937dcd15d98dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Fri, 15 Nov 2013 15:36:18 +0000 Subject: Windows: Fix bug where windows stopped painting after a restore. This is an improvement over 6800728d where we only fixed it if the window was in "normal" state (Qt::WindowNoState) before minimizing. With this patch, if the window was previously maximized or full-screen it will also get the expose events when being restored. Change-Id: I4a30423145e0999c5d0a5ee2a989730b83f4e3f2 Reviewed-by: Friedemann Kleint Reviewed-by: Nicolas Arnaud-Cormos --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index d2fb481824..58047124a1 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1500,6 +1500,8 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) handleHidden(); QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now. break; + case Qt::WindowMaximized: + case Qt::WindowFullScreen: case Qt::WindowNoState: { // QTBUG-17548: We send expose events when receiving WM_Paint, but for // layered windows and transient children, we won't receive any WM_Paint. -- cgit v1.2.3 From eccd365ac544c0e24da86bfaf09d24130feb2e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Nov 2013 19:42:49 +0100 Subject: iOS: Don't enable kEAGLDrawablePropertyRetainedBacking We report our swap-behavior as QSurfaceFormat::DoubleBuffer, which means there's no point in using retained backing. This was a left-over from when we reported single-buffered swaps, which didn't work to well as clients would wrongly assume swap was not needed at all. Change-Id: Id26df2f8b282892c720d48cfe85eb9e010f1500d Reviewed-by: Richard Moe Gustavsen Reviewed-by: Gunnar Sletta --- src/plugins/platforms/ios/qioswindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e02f570634..af429f9d65 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -105,7 +105,7 @@ CAEAGLLayer *eaglLayer = static_cast(self.layer); eaglLayer.opaque = TRUE; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, + [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; // Set up text input -- cgit v1.2.3 From f087ffdc53254fbab438180cd2da750d54c2be76 Mon Sep 17 00:00:00 2001 From: Jorgen Lind Date: Tue, 12 Nov 2013 10:50:42 +0100 Subject: Remove the GLES 2 dependency for eglfs and kms Change-Id: If7b80487e01db726367f5a67d2860073f60a0844 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/eglfs/qeglfsbackingstore.cpp | 1 + src/plugins/platforms/eglfs/qeglfsbackingstore.h | 3 ++- src/plugins/platforms/eglfs/qeglfscompositor.cpp | 7 ++++++- src/plugins/platforms/eglfs/qeglfscompositor.h | 6 ++++-- src/plugins/platforms/eglfs/qeglfscursor.cpp | 5 +++-- src/plugins/platforms/eglfs/qeglfscursor.h | 7 +++++-- src/plugins/platforms/kms/qkmsbackingstore.cpp | 6 ++++++ src/plugins/platforms/kms/qkmsbackingstore.h | 4 +++- src/plugins/platforms/kms/qkmsscreen.h | 3 +-- 9 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp index 9de5960fdb..03531916cf 100644 --- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp +++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp @@ -139,6 +139,7 @@ void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents m_window->create(); rootWin->screen()->rootContext()->makeCurrent(rootWin->window()); + initializeOpenGLFunctions(); if (m_texture) glDeleteTextures(1, &m_texture); diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/eglfs/qeglfsbackingstore.h index 535428aac1..9af856e8e7 100644 --- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h +++ b/src/plugins/platforms/eglfs/qeglfsbackingstore.h @@ -43,6 +43,7 @@ #define QEGLFSBACKINGSTORE_H #include +#include #include #include @@ -52,7 +53,7 @@ QT_BEGIN_NAMESPACE class QOpenGLPaintDevice; class QEglFSWindow; -class QEglFSBackingStore : public QPlatformBackingStore +class QEglFSBackingStore : public QPlatformBackingStore, public QOpenGLFunctions { public: QEglFSBackingStore(QWindow *window); diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.cpp b/src/plugins/platforms/eglfs/qeglfscompositor.cpp index 9db43a57a1..845bb5b3b5 100644 --- a/src/plugins/platforms/eglfs/qeglfscompositor.cpp +++ b/src/plugins/platforms/eglfs/qeglfscompositor.cpp @@ -53,7 +53,8 @@ static QEglFSCompositor *compositor = 0; QEglFSCompositor::QEglFSCompositor() : m_screen(0), - m_program(0) + m_program(0), + m_initialized(false) { Q_ASSERT(!compositor); m_updateTimer.setSingleShot(true); @@ -86,6 +87,10 @@ void QEglFSCompositor::renderAll() Q_ASSERT(context); context->makeCurrent(rootWin->window()); + if (!m_initialized) { + initializeOpenGLFunctions(); + m_initialized = true; + } ensureProgram(); m_program->bind(); diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.h b/src/plugins/platforms/eglfs/qeglfscompositor.h index ade2e06031..0d5daafa2c 100644 --- a/src/plugins/platforms/eglfs/qeglfscompositor.h +++ b/src/plugins/platforms/eglfs/qeglfscompositor.h @@ -42,7 +42,8 @@ #ifndef QEGLFSCOMPOSITOR_H #define QEGLFSCOMPOSITOR_H -#include +#include +#include QT_BEGIN_NAMESPACE @@ -50,7 +51,7 @@ class QEglFSScreen; class QEglFSWindow; class QOpenGLShaderProgram; -class QEglFSCompositor : public QObject +class QEglFSCompositor : public QObject, public QOpenGLFunctions { Q_OBJECT @@ -76,6 +77,7 @@ private: int m_vertexCoordEntry; int m_textureCoordEntry; int m_isRasterEntry; + bool m_initialized; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp index c00e86de35..0066426769 100644 --- a/src/plugins/platforms/eglfs/qeglfscursor.cpp +++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp @@ -79,7 +79,7 @@ void QEglFSCursor::resetResources() m_cursorAtlas.texture = 0; } -static GLuint createShader(GLenum shaderType, const char *program) +GLuint QEglFSCursor::createShader(GLenum shaderType, const char *program) { GLuint shader = glCreateShader(shaderType); glShaderSource(shader, 1 /* count */, &program, NULL /* lengths */); @@ -98,7 +98,7 @@ static GLuint createShader(GLenum shaderType, const char *program) return 0; } -static GLuint createProgram(GLuint vshader, GLuint fshader) +GLuint QEglFSCursor::createProgram(GLuint vshader, GLuint fshader) { GLuint program = glCreateProgram(); glAttachShader(program, vshader); @@ -286,6 +286,7 @@ void QEglFSCursor::draw(const QRectF &r) { if (!m_program) { // one time initialization + initializeOpenGLFunctions(); createShaderPrograms(); if (!m_cursorAtlas.texture) { diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/plugins/platforms/eglfs/qeglfscursor.h index 51a34e041d..71ff73b8f3 100644 --- a/src/plugins/platforms/eglfs/qeglfscursor.h +++ b/src/plugins/platforms/eglfs/qeglfscursor.h @@ -43,15 +43,15 @@ #define QEGLFSCURSOR_H #include +#include #include "qeglfsscreen.h" -#include QT_BEGIN_NAMESPACE class QOpenGLShaderProgram; class QEglFSScreen; -class QEglFSCursor : public QPlatformCursor +class QEglFSCursor : public QPlatformCursor, public QOpenGLFunctions { public: QEglFSCursor(QEglFSScreen *screen); @@ -78,6 +78,9 @@ protected: void draw(const QRectF &rect); void update(const QRegion ®ion); + GLuint createShader(GLenum shaderType, const char *program); + GLuint createProgram(GLuint vshader, GLuint fshader); + QEglFSScreen *m_screen; // current cursor information diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp index 29395f3b4f..fa4ef847cd 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.cpp +++ b/src/plugins/platforms/kms/qkmsbackingstore.cpp @@ -52,6 +52,7 @@ QKmsBackingStore::QKmsBackingStore(QWindow *window) , m_context(new QOpenGLContext) , m_texture(0) , m_program(0) + , m_initialized(false) { m_context->setFormat(window->requestedFormat()); m_context->setScreen(window->screen()); @@ -85,6 +86,11 @@ void QKmsBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin m_context->makeCurrent(window); + if (!m_initialized) { + initializeOpenGLFunctions(); + m_initialized = true; + } + if (!m_program) { static const char *textureVertexProgram = "attribute highp vec2 vertexCoordEntry;\n" diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h index 34ea49a346..c5f6c81d18 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.h +++ b/src/plugins/platforms/kms/qkmsbackingstore.h @@ -43,6 +43,7 @@ #define QBACKINGSTORE_KMS_H #include +#include #include QT_BEGIN_NAMESPACE @@ -50,7 +51,7 @@ QT_BEGIN_NAMESPACE class QOpenGLContext; class QOpenGLShaderProgram; -class QKmsBackingStore : public QPlatformBackingStore +class QKmsBackingStore : public QPlatformBackingStore, public QOpenGLFunctions { public: QKmsBackingStore(QWindow *window); @@ -69,6 +70,7 @@ private: uint m_texture; QOpenGLShaderProgram *m_program; QRegion m_dirty; + bool m_initialized; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/kms/qkmsscreen.h b/src/plugins/platforms/kms/qkmsscreen.h index a90d6fa051..f0c49ad11c 100644 --- a/src/plugins/platforms/kms/qkmsscreen.h +++ b/src/plugins/platforms/kms/qkmsscreen.h @@ -55,8 +55,7 @@ extern "C" { #include #include -#include -#include +#include #include -- cgit v1.2.3 From dcd71a08972e9d6de73242ce8073de89a19f7c97 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 13 Nov 2013 13:23:09 +0100 Subject: Android: Remove usage of QObject::tr() Change-Id: I948d9fc36aa52d2d247a84b5d9b2cf949b93387d Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Paul Olav Tvete --- .../android/src/qandroidplatformdialoghelpers.cpp | 57 ++++++++-------------- 1 file changed, 19 insertions(+), 38 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp index f9eb34751e..f379402e18 100644 --- a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp @@ -63,64 +63,45 @@ void QAndroidPlatformMessageDialogHelper::exec() static QString standardButtonText(int sbutton) { - QString buttonText = 0; switch (sbutton) { case QMessageDialogOptions::Ok: - buttonText = QObject::tr("OK"); - break; + return QAndroidPlatformMessageDialogHelper::tr("OK"); case QMessageDialogOptions::Save: - buttonText = QObject::tr("Save"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Save"); case QMessageDialogOptions::Open: - buttonText = QObject::tr("Open"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Open"); case QMessageDialogOptions::Cancel: - buttonText = QObject::tr("Cancel"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Cancel"); case QMessageDialogOptions::Close: - buttonText = QObject::tr("Close"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Close"); case QMessageDialogOptions::Apply: - buttonText = QObject::tr("Apply"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Apply"); case QMessageDialogOptions::Reset: - buttonText = QObject::tr("Reset"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Reset"); case QMessageDialogOptions::Help: - buttonText = QObject::tr("Help"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Help"); case QMessageDialogOptions::Discard: - buttonText = QObject::tr("Discard"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Discard"); case QMessageDialogOptions::Yes: - buttonText = QObject::tr("Yes"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Yes"); case QMessageDialogOptions::YesToAll: - buttonText = QObject::tr("Yes to All"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Yes to All"); case QMessageDialogOptions::No: - buttonText = QObject::tr("No"); - break; + return QAndroidPlatformMessageDialogHelper::tr("No"); case QMessageDialogOptions::NoToAll: - buttonText = QObject::tr("No to All"); - break; + return QAndroidPlatformMessageDialogHelper::tr("No to All"); case QMessageDialogOptions::SaveAll: - buttonText = QObject::tr("Save All"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Save All"); case QMessageDialogOptions::Abort: - buttonText = QObject::tr("Abort"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Abort"); case QMessageDialogOptions::Retry: - buttonText = QObject::tr("Retry"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Retry"); case QMessageDialogOptions::Ignore: - buttonText = QObject::tr("Ignore"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Ignore"); case QMessageDialogOptions::RestoreDefaults: - buttonText = QObject::tr("Restore Defaults"); - break; + return QAndroidPlatformMessageDialogHelper::tr("Restore Defaults"); } // switch - return buttonText; + return QString(); } bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags -- cgit v1.2.3 From 911cfc4e905c022e10932812632d8b894e9e3004 Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Fri, 15 Nov 2013 13:26:12 +0200 Subject: XCB: do not assume that sizeof(long)==4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code was using the "long" type when a 32 bit type was actually needed. This can cause bugs in those systems where "long" is 64 bits wide, such as Linux x86-64 (which is LP64). Task-number: QTBUG-34861 Change-Id: Iab289b2af3847dd62d8b4ecea51896936ca4c7a2 Reviewed-by: Friedemann Kleint Reviewed-by: Gunnar Sletta Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbwindow.cpp | 12 ++++++------ src/plugins/platforms/xcb/qxcbwindow.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index dd404d044d..e2c6932992 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -154,7 +154,7 @@ enum QX11EmbedMessageType { XEMBED_ACTIVATE_ACCELERATOR = 14 }; -const long XEMBED_VERSION = 0; +const quint32 XEMBED_VERSION = 0; // Returns \c true if we should set WM_TRANSIENT_FOR on \a w static inline bool isTransient(const QWindow *w) @@ -403,7 +403,7 @@ void QXcbWindow::create() } // set the PID to let the WM kill the application if unresponsive - long pid = getpid(); + quint32 pid = getpid(); Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32, 1, &pid)); @@ -422,7 +422,7 @@ void QXcbWindow::create() 1, &leader)); /* Add XEMBED info; this operation doesn't initiate the embedding. */ - long data[] = { XEMBED_VERSION, XEMBED_MAPPED }; + quint32 data[] = { XEMBED_VERSION, XEMBED_MAPPED }; Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::_XEMBED_INFO), atom(QXcbAtom::_XEMBED_INFO), @@ -1824,7 +1824,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev xcb_get_property_reply(xcb_connection(), get_cookie, NULL); if (reply && reply->format == 32 && reply->type == wmStateAtom) { - const long *data = (const long *)xcb_get_property_value(reply); + const quint32 *data = (const quint32 *)xcb_get_property_value(reply); if (reply->length != 0 && XCB_WM_STATE_ICONIC == data[0]) newState = Qt::WindowMinimized; } @@ -1995,8 +1995,8 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) } // Sends an XEmbed message. -void QXcbWindow::sendXEmbedMessage(xcb_window_t window, long message, - long detail, long data1, long data2) +void QXcbWindow::sendXEmbedMessage(xcb_window_t window, quint32 message, + quint32 detail, quint32 data1, quint32 data2) { xcb_client_message_event_t event; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 5601a115e9..45d44b213f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -169,8 +169,8 @@ private: void updateDoesNotAcceptFocus(bool doesNotAcceptFocus); QRect windowToWmGeometry(QRect r) const; - void sendXEmbedMessage(xcb_window_t window, long message, - long detail = 0, long data1 = 0, long data2 = 0); + void sendXEmbedMessage(xcb_window_t window, quint32 message, + quint32 detail = 0, quint32 data1 = 0, quint32 data2 = 0); void handleXEmbedMessage(const xcb_client_message_event_t *event); void create(); -- cgit v1.2.3 From f3a4bc17ab4a68941b3c5bf48a9d5288cff2a8b7 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 6 Sep 2013 11:02:46 +0200 Subject: Keep the dockwidget with the mouse when moving to another screen When you move a dockwidget from one screen to another then it needs to be kept at the same position on the new screen, i.e. with the mouse pointer. This fix ensures that this is happening including when the screens may not 100% align up with each other. Task-number: QTBUG-33369 Change-Id: If414effdd0e0415629ca31a86f8bbe382dd29f80 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/cocoa/qcocoahelpers.mm | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 197a2058af..4a5696b35e 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -599,7 +599,17 @@ NSRect qt_mac_flipRect(const QRect &rect, QWindow *window) { QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window); int flippedY = onScreen->geometry().height() - (rect.y() + rect.height()); - + QList screens = QGuiApplication::screens(); + if (screens.size() > 1) { + int height = 0; + foreach (QScreen *scr, screens) + height = qMax(height, scr->size().height()); + int difference = height - onScreen->geometry().height(); + if (difference > 0) + flippedY += difference; + else + flippedY -= difference; + } // In case of automatic positioning, try to put as much of the window onscreen as possible. if (window->isTopLevel() && qt_window_private(const_cast(window))->positionAutomatic && flippedY < 0) flippedY = onScreen->geometry().height() - onScreen->availableGeometry().height() - onScreen->availableGeometry().y(); -- cgit v1.2.3 From 711d0a16580022d9f38a782f269f5cc3af0f3af7 Mon Sep 17 00:00:00 2001 From: Arvid Nilsson Date: Tue, 12 Nov 2013 10:27:28 +0100 Subject: Add QQnxNativeInterface::nativeResourceForContext This mechanism is used by QtWebEngine to extract the platform GL context. In the QNX case, the platform context is an EGL context, so the resource you need to ask for is the "eglcontext". Compare to the xcb native interface which has a similar implementation already. Change-Id: I873eaadf96898abb24de347ac624c88cd54254cb Reviewed-by: Jocelyn Turcotte Reviewed-by: Kevin Krammer Reviewed-by: Fabian Bumberger --- src/plugins/platforms/qnx/qqnxglcontext.h | 2 ++ src/plugins/platforms/qnx/qqnxnativeinterface.cpp | 10 ++++++++++ src/plugins/platforms/qnx/qqnxnativeinterface.h | 1 + 3 files changed, 13 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h index ff57861498..2b12657da9 100644 --- a/src/plugins/platforms/qnx/qqnxglcontext.h +++ b/src/plugins/platforms/qnx/qqnxglcontext.h @@ -75,6 +75,8 @@ public: static EGLDisplay getEglDisplay(); EGLConfig getEglConfig() const { return m_eglConfig;} + EGLContext getEglContext() const { return m_eglContext; } + private: //Can be static because different displays returne the same handle static EGLDisplay ms_eglDisplay; diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp index 8958a5c1e2..6e7fc35a82 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp @@ -41,9 +41,11 @@ #include "qqnxnativeinterface.h" +#include "qqnxglcontext.h" #include "qqnxscreen.h" #include "qqnxwindow.h" +#include #include #include @@ -71,6 +73,14 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q return 0; } +void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) +{ + if (resource == "eglcontext" && context) + return static_cast(context->handle())->getEglContext(); + + return 0; +} + void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) { if (name == QStringLiteral("mmRendererWindowName")) { diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h index b61f6a56cc..dfd386214e 100644 --- a/src/plugins/platforms/qnx/qqnxnativeinterface.h +++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h @@ -51,6 +51,7 @@ class QQnxNativeInterface : public QPlatformNativeInterface public: void *nativeResourceForWindow(const QByteArray &resource, QWindow *window); void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen); + void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context); void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value); }; -- cgit v1.2.3 From 0c012b647064bd39eaf751b9a0e467fbf18441ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Nov 2013 10:52:50 +0100 Subject: iOS: Send expose events in the window's coordinate system, not the parent's Change-Id: I4aa1a354ca14864bd9898ebd331871d7b32d3ae0 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Gunnar Sletta --- src/plugins/platforms/ios/qioswindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index af429f9d65..3d1fe935e5 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -168,7 +168,7 @@ QRect geometry = fromCGRect(self.frame); m_qioswindow->QPlatformWindow::setGeometry(geometry); QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); - QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), geometry); + QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), QRect(QPoint(), geometry.size())); // If we have a new size here we need to resize the FBO's corresponding buffers, // but we defer that to when the application calls makeCurrent. -- cgit v1.2.3 From 837228151d085264e8244969349b3d68d6f9cc94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 18 Nov 2013 11:32:32 +0100 Subject: iOS: Don't keep around reference to a single QIOSViewController We might have more of them in a multi-screen setup or when implementing support for modal windows using sub-viewcontrollers. Change-Id: Ibe98273a13af981fffe2704a2c05bfd9d3f3e9e0 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationdelegate.h | 1 - src/plugins/platforms/ios/qiosapplicationdelegate.mm | 5 +---- src/plugins/platforms/ios/qiosglobal.h | 1 - src/plugins/platforms/ios/qiosglobal.mm | 11 ----------- src/plugins/platforms/ios/qiosscreen.mm | 2 +- src/plugins/platforms/ios/qioswindow.h | 1 + src/plugins/platforms/ios/qioswindow.mm | 19 +++++++++++++++++-- 7 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h index bfe31af198..617b740d6e 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.h +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -47,6 +47,5 @@ @interface QIOSApplicationDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; -@property (strong, nonatomic) QIOSViewController *qiosViewController; @end diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 4d88faba75..775074baae 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -49,7 +49,6 @@ @implementation QIOSApplicationDelegate @synthesize window; -@synthesize qiosViewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { @@ -57,8 +56,7 @@ Q_UNUSED(launchOptions); self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; - self.qiosViewController = [[[QIOSViewController alloc] init] autorelease]; - self.window.rootViewController = self.qiosViewController; + self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; self.window.hidden = NO; @@ -67,7 +65,6 @@ - (void)dealloc { - [qiosViewController release]; [window release]; [super dealloc]; } diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index fd328c9171..41b0d7f93a 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE class QPlatformScreen; bool isQtApplication(); -QIOSViewController *qiosViewController(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 9b8462a6cc..be68e4d7d5 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -58,17 +58,6 @@ bool isQtApplication() return isQt; } -QIOSViewController *qiosViewController() -{ - // If Qt controls the application, we have created a root view controller were we place top-level - // QWindows. Note that in a mixed native application, our view controller might later be removed or - // added as a child of another controller. To protect against that, we keep an explicit pointer to the - // view controller in cases where this is the controller we need to access. - static QIOSViewController *c = isQtApplication() ? - static_cast([UIApplication sharedApplication].delegate).qiosViewController : nil; - return c; -} - CGRect toCGRect(const QRect &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index d57e678810..9d01053548 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -149,7 +149,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: - setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(qiosViewController().interfaceOrientation))); + setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation([UIApplication sharedApplication].statusBarOrientation))); } } diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 5ded589205..6e8683af00 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -52,6 +52,7 @@ class QIOSWindow; @interface UIView (QIOS) @property(readonly) QWindow *qwindow; +@property(readonly) UIViewController *viewController; @end QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 3d1fe935e5..b13ce456a4 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -348,6 +348,16 @@ return nil; } +- (UIViewController *)viewController +{ + id responder = self; + while ((responder = [responder nextResponder])) { + if ([responder isKindOfClass:UIViewController.class]) + return responder; + } + return nil; +} + @end QT_BEGIN_NAMESPACE @@ -404,7 +414,7 @@ void QIOSWindow::setVisible(bool visible) requestActivateWindow(); } else { // Activate top-most visible QWindow: - NSArray *subviews = qiosViewController().view.subviews; + NSArray *subviews = m_view.viewController.view.subviews; for (int i = int(subviews.count) - 1; i >= 0; --i) { UIView *view = [subviews objectAtIndex:i]; if (!view.hidden) { @@ -460,7 +470,12 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow) UIView *parentView = reinterpret_cast(parentWindow->winId()); [parentView addSubview:m_view]; } else if (isQtApplication()) { - [qiosViewController().view addSubview:m_view]; + for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) { + if (uiWindow.screen == static_cast(screen())->uiScreen()) { + [uiWindow.rootViewController.view addSubview:m_view]; + break; + } + } } } -- cgit v1.2.3 From c3e949ac7dd9ddfc3c089061908000c5b4d9dc4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Nov 2013 19:33:57 +0100 Subject: iOS: Allow non-top-level windows to be activated As tested and assumed by tst_QWindow::isActive(). Change-Id: I8d09263ce0acc9c3390a70b4089396257197a1be Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index b13ce456a4..de56084848 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -484,12 +484,14 @@ void QIOSWindow::requestActivateWindow() // Note that several windows can be active at the same time if they exist in the same // hierarchy (transient children). But only one window can be QGuiApplication::focusWindow(). // Dispite the name, 'requestActivateWindow' means raise and transfer focus to the window: - if (!window()->isTopLevel() || blockedByModal()) + if (blockedByModal()) return; [m_view.window makeKeyWindow]; - raise(); + if (window()->isTopLevel()) + raise(); + QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); static_cast(context)->focusViewChanged(m_view); QWindowSystemInterface::handleWindowActivated(window()); -- cgit v1.2.3 From 2e2c7327dd26678d26fd7fc431a78c1d05d94411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 18 Nov 2013 18:25:24 +0100 Subject: iOS: Prepare platform screen for reacting to dynamic updates to properties Change-Id: Idb378416da2b559ed88eb5a764cacff149264f70 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 3 +- src/plugins/platforms/ios/qiosscreen.mm | 78 +++++++++++++------------ src/plugins/platforms/ios/qiosviewcontroller.mm | 9 +-- 3 files changed, 45 insertions(+), 45 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 40c7a3ccf7..e70ff4b1a9 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -72,13 +72,14 @@ public: UIScreen *uiScreen() const; - void setPrimaryOrientation(Qt::ScreenOrientation orientation); + void updateProperties(); private: UIScreen *m_uiScreen; QRect m_geometry; QRect m_availableGeometry; int m_depth; + uint m_unscaledDpi; QSizeF m_physicalSize; QIOSOrientationListener *m_orientationListener; }; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 9d01053548..2d8ff7d8e1 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -132,25 +132,14 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) m_depth = 24; } - int unscaledDpi = 163; // Regular iPhone DPI if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad && !deviceIdentifier.contains(QRegularExpression("^iPad2,[567]$")) /* excluding iPad Mini */) { - unscaledDpi = 132; - }; - - CGRect bounds = [m_uiScreen bounds]; - m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); - - CGRect frame = m_uiScreen.applicationFrame; - m_availableGeometry = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); - - const qreal millimetersPerInch = 25.4; - m_physicalSize = QSizeF(m_geometry.size()) / unscaledDpi * millimetersPerInch; - - if (isQtApplication()) { - // When in a non-mixed environment, let QScreen follow the current interface orientation: - setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation([UIApplication sharedApplication].statusBarOrientation))); + m_unscaledDpi = 132; + } else { + m_unscaledDpi = 163; // Regular iPhone DPI } + + updateProperties(); } QIOSScreen::~QIOSScreen() @@ -158,6 +147,41 @@ QIOSScreen::~QIOSScreen() [m_orientationListener release]; } +void QIOSScreen::updateProperties() +{ + UIWindow *uiWindow = 0; + for (uiWindow in [[UIApplication sharedApplication] windows]) { + if (uiWindow.screen == m_uiScreen) + break; + } + + bool inPortrait = UIInterfaceOrientationIsPortrait(uiWindow.rootViewController.interfaceOrientation); + QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds) + : QRect(m_uiScreen.bounds.origin.x, m_uiScreen.bounds.origin.y, + m_uiScreen.bounds.size.height, m_uiScreen.bounds.size.width); + + if (geometry != m_geometry) { + m_geometry = geometry; + + const qreal millimetersPerInch = 25.4; + m_physicalSize = QSizeF(m_geometry.size()) / m_unscaledDpi * millimetersPerInch; + + QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); + } + + QRect availableGeometry = geometry; + + CGSize applicationFrameSize = m_uiScreen.applicationFrame.size; + int statusBarHeight = geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width); + + availableGeometry.adjust(0, statusBarHeight, 0, 0); + + if (availableGeometry != m_availableGeometry) { + m_availableGeometry = availableGeometry; + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); + } +} + QRect QIOSScreen::geometry() const { return m_geometry; @@ -213,28 +237,6 @@ void QIOSScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask) } } -void QIOSScreen::setPrimaryOrientation(Qt::ScreenOrientation orientation) -{ - // Note that UIScreen never changes orientation, but QScreen should. To work around - // this, we let QIOSViewController call us whenever interface orientation changes, and - // use that as primary orientation. After all, the viewcontrollers geometry is what we - // place QWindows on top of. A problem with this approach is that QIOSViewController is - // not in use in a mixed environment, which results in no change to primary orientation. - // We see that as acceptable since Qt should most likely not interfere with orientation - // for that case anyway. - bool portrait = screen()->isPortrait(orientation); - if (portrait && m_geometry.width() < m_geometry.height()) - return; - - // Switching portrait/landscape means swapping width/height (and adjusting x/y): - m_geometry = QRect(0, 0, m_geometry.height(), m_geometry.width()); - m_physicalSize = QSizeF(m_physicalSize.height(), m_physicalSize.width()); - m_availableGeometry = fromPortraitToPrimary(fromCGRect(m_uiScreen.applicationFrame), this); - - QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry); - QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); -} - UIScreen *QIOSScreen::uiScreen() const { return m_uiScreen; diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 656a86027d..1d5e69beac 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -62,19 +62,16 @@ return UIInterfaceOrientationMaskAll; } -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration +- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration { Q_UNUSED(duration); + Q_UNUSED(interfaceOrientation); if (!QCoreApplication::instance()) return; // FIXME: Store orientation for later (?) - Qt::ScreenOrientation orientation = toQtScreenOrientation(UIDeviceOrientation(toInterfaceOrientation)); - if (orientation == -1) - return; - QIOSScreen *qiosScreen = static_cast(QGuiApplication::primaryScreen()->handle()); - qiosScreen->setPrimaryOrientation(orientation); + qiosScreen->updateProperties(); } @end -- cgit v1.2.3 From ce6fd574b46cb10204f6ef598ea4377639ad1516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 18 Nov 2013 18:27:37 +0100 Subject: iOS: Report native orientation of QScreen in relation to size Instead of hard-coding it to assume the properties of the main/device screen. Change-Id: I94c978d4334cae5be9d1094a0c315031e54e8e1f Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 2d8ff7d8e1..b93511d755 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -219,7 +219,9 @@ qreal QIOSScreen::devicePixelRatio() const Qt::ScreenOrientation QIOSScreen::nativeOrientation() const { - return Qt::PortraitOrientation; + // A UIScreen stays in the native orientation, regardless of rotation + return m_uiScreen.bounds.size.width >= m_uiScreen.bounds.size.height ? + Qt::LandscapeOrientation : Qt::PortraitOrientation; } Qt::ScreenOrientation QIOSScreen::orientation() const -- cgit v1.2.3 From 16ad93af4959b3c0ae96a4a0d88e25c1626f587d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 18 Nov 2013 19:21:10 +0100 Subject: iOS: Don't use auto resizing masks to deal with maximized/fullscreen It breaks down when the view-controller is fullscreen and we want to take statusbar height into account as well. Unfortunately we can't use constraints either, as it's iOS6+. The approach of managing the geometry manually is closer to what Android does as well. Change-Id: Ib521ba0f50b110c440ab68aacef5a524d5d41154 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 3 +++ src/plugins/platforms/ios/qioswindow.mm | 27 +++++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index b93511d755..de6585fd19 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -180,6 +180,9 @@ void QIOSScreen::updateProperties() m_availableGeometry = availableGeometry; QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry); } + + if (screen()) + resizeMaximizedWindows(); } QRect QIOSScreen::geometry() const diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index de56084848..2413a45e11 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -448,19 +448,26 @@ void QIOSWindow::setWindowState(Qt::WindowState state) // Perhaps setting QWindow to maximized should also mean that we'll show // the statusbar, and vice versa for fullscreen? + if (state != Qt::WindowNoState) + m_normalGeometry = geometry(); + switch (state) { + case Qt::WindowNoState: + setGeometry(m_normalGeometry); + break; case Qt::WindowMaximized: - case Qt::WindowFullScreen: { - // Since UIScreen does not take orientation into account when - // reporting geometry, we need to look at the top view instead: - CGSize fullscreenSize = m_view.window.rootViewController.view.bounds.size; - m_view.frame = CGRectMake(0, 0, fullscreenSize.width, fullscreenSize.height); - m_view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - break; } - default: - m_view.frame = toCGRect(m_normalGeometry); - m_view.autoresizingMask = UIViewAutoresizingNone; + setGeometry(screen()->availableGeometry()); break; + case Qt::WindowFullScreen: + setGeometry(screen()->geometry()); + break; + case Qt::WindowMinimized: + setGeometry(QRect()); + break; + case Qt::WindowActive: + Q_UNREACHABLE(); + default: + Q_UNREACHABLE(); } } -- cgit v1.2.3 From 982da20cf2b58dd6f42e70d406c37219ea204a78 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 7 Nov 2013 19:31:09 +0100 Subject: Remove empty QAccessible2 header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia5e9b1adf9280e6b7d7aaf8cb5b5167b694a6070 Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/android/src/androidjniaccessibility.cpp | 2 +- src/plugins/platforms/cocoa/qcocoaaccessibility.mm | 3 +-- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 3 +-- src/plugins/platforms/cocoa/qnsviewaccessibility.mm | 2 +- src/plugins/platforms/windows/accessible/iaccessible2.cpp | 2 +- src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp | 1 - src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp | 1 - 7 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.cpp index a27d9f5aed..b987c49c9c 100644 --- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/src/androidjniaccessibility.cpp @@ -46,7 +46,7 @@ #include "qguiapplication.h" #include "qwindow.h" #include "qrect.h" -#include "private/qaccessible2_p.h" +#include "QtGui/qaccessible.h" #include "qdebug.h" diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm index f43beb1bb5..1371eb3658 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm @@ -40,8 +40,7 @@ ****************************************************************************/ #include "qcocoaaccessibility.h" #include "qcocoaaccessibilityelement.h" -#include -#include +#include #include QCocoaAccessibility::QCocoaAccessibility() diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 7eae22f720..8e20a96a48 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -42,8 +42,7 @@ #include "qcocoaaccessibility.h" #include "qcocoahelpers.h" -#include -#include +#include #import diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index 86e5066fbb..e8f26aa8c4 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -47,7 +47,7 @@ #include "qcocoaaccessibilityelement.h" #include -#include +#include #include #import diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 9170c774b4..66ed9d85dc 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -44,7 +44,7 @@ #include "iaccessible2.h" #include "qwindowsaccessibility.h" -#include +#include #include #include #include diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 63b4370dc2..885bc37cff 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 93592eb969..8bb7646258 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From f1268d137ea7839b320c84314d0c2265f5a629ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 20 Nov 2013 13:03:14 +0100 Subject: Allow platform to decide default behavior for show() based on window flags The ShowIsMaximized and ShowIsFullscreen style hints were not granular enough to build a default behavior from that would be correct for all platforms. The recent Android patch that excluded dialogs from being shown maximized (Ia249e93dbbea1) has now been moved into a platform override in the Android integration plugin, leaving other platforms to the default behavior of using the style-hints. We still special case popup-windows though, as that behavior has been there for a while. Task-number: QTBUG-34969 Change-Id: Id36346d71bfc46171383ffe334592ca0b94e456f Reviewed-by: BogDan Vatra Reviewed-by: Paul Olav Tvete --- .../platforms/android/src/qandroidplatformintegration.cpp | 9 +++++++++ src/plugins/platforms/android/src/qandroidplatformintegration.h | 1 + 2 files changed, 10 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp index 6d0ec306ab..ae3e257d3c 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp @@ -242,6 +242,15 @@ QVariant QAndroidPlatformIntegration::styleHint(StyleHint hint) const } } +Qt::WindowState QAndroidPlatformIntegration::defaultWindowState(Qt::WindowFlags flags) const +{ + // Don't maximize dialogs on Android + if (flags & Qt::Dialog & ~Qt::Window) + return Qt::WindowNoState; + + return QPlatformIntegration::defaultWindowState(flags); +} + static const QLatin1String androidThemeName("android"); QStringList QAndroidPlatformIntegration::themeNames() const { diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/src/qandroidplatformintegration.h index 3b34cdf7df..bd08ad694c 100644 --- a/src/plugins/platforms/android/src/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/src/qandroidplatformintegration.h @@ -121,6 +121,7 @@ public: #endif QVariant styleHint(StyleHint hint) const; + Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const Q_DECL_OVERRIDE; QStringList themeNames() const; QPlatformTheme *createPlatformTheme(const QString &name) const; -- cgit v1.2.3 From 486889523c8fe15277e3148904509789a19d25fe Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 19 Nov 2013 15:07:25 +0100 Subject: Workaround source compatibility issue introduced by xcb 1.9.3 Previous version of the struct: typedef struct { uint8_t response_type; /**< Type of the response */ uint8_t pad0; /**< Padding */ uint16_t sequence; /**< Sequence number */ uint32_t length; uint16_t event_type; uint16_t pad1; uint32_t pad[5]; /**< Padding */ uint32_t full_sequence; /**< full sequence */ } xcb_ge_event_t; New version of it: typedef struct xcb_ge_event_t { uint8_t response_type; /**< */ uint8_t extension; /**< */ uint16_t sequence; /**< */ uint32_t length; /**< */ uint16_t event_type; /**< */ uint8_t pad0[22]; /**< */ uint32_t full_sequence; /**< */ } xcb_ge_event_t; Changes are: - "pad0" became "extension" - "pad1" and "pad" became "pad0" More details in https://bugs.freedesktop.org/show_bug.cgi?id=71502 Task-number: QTBUG-34748 Change-Id: Ibd801c11510f75fa82d5c14346b95236142487ac Reviewed-by: Uli Schlachter Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbconnection.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index cc8c42f96b..4d2735ca85 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1749,10 +1749,26 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub return true; } -bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode) +// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: +// - "pad0" became "extension" +// - "pad1" and "pad" became "pad0" +// New and old version of this struct share the following fields: +// NOTE: API might change again in the next release of xcb in which case this comment will +// need to be updated to reflect the reality. +typedef struct qt_xcb_ge_event_t { + uint8_t response_type; + uint8_t extension; + uint16_t sequence; + uint32_t length; + uint16_t event_type; +} qt_xcb_ge_event_t; + +bool QXcbConnection::xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *ev, int opCode) { - // xGenericEvent has "extension" on the second byte, xcb_ge_event_t has "pad0". - if (event->pad0 == opCode) { + qt_xcb_ge_event_t *event = (qt_xcb_ge_event_t *)ev; + // xGenericEvent has "extension" on the second byte, the same is true for xcb_ge_event_t starting from + // the xcb version 1.9.3, prior to that it was called "pad0". + if (event->extension == opCode) { // xcb event structs contain stuff that wasn't on the wire, the full_sequence field // adds an extra 4 bytes and generic events cookie data is on the wire right after the standard 32 bytes. // Move this data back to have the same layout in memory as it was on the wire -- cgit v1.2.3 From e89a9428d5a9b5e5494954dfc3ea4233563c5906 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Tue, 19 Nov 2013 09:42:33 +0100 Subject: BlackBerry: Fixed root window size On BlackBerry the first window shown is treated as root window and should be displayed full screen. The geometry has to be adjusted properly to achieve this. Task-number: QTBUG-34930 Change-Id: I6c011620116cc463e16dd352521b2b901a9f9f69 Reviewed-by: Fabian Bumberger Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxeglwindow.cpp | 12 ++++++++---- src/plugins/platforms/qnx/qqnxwindow.cpp | 11 +++++------ 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp index 6afc3cad21..b57227a60b 100644 --- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp @@ -58,12 +58,13 @@ QT_BEGIN_NAMESPACE QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) : QQnxWindow(window, context, needRootWindow), - m_requestedBufferSize(window->geometry().size()), m_platformOpenGLContext(0), m_newSurfaceRequested(true), m_eglSurface(EGL_NO_SURFACE) { initWindow(); + m_requestedBufferSize = screen()->rootWindow() == this ? + screen()->geometry().size() : window->geometry().size(); } QQnxEglWindow::~QQnxEglWindow() @@ -145,6 +146,9 @@ EGLSurface QQnxEglWindow::getSurface() void QQnxEglWindow::setGeometry(const QRect &rect) { + //If this is the root window, it has to be shown fullscreen + const QRect &newGeometry = screen()->rootWindow() == this ? screen()->geometry() : rect; + //We need to request that the GL context updates // the EGLsurface on which it is rendering. { @@ -152,11 +156,11 @@ void QQnxEglWindow::setGeometry(const QRect &rect) // setting m_requestedBufferSize and therefore extended the scope to include // that test. const QMutexLocker locker(&m_mutex); - m_requestedBufferSize = rect.size(); - if (m_platformOpenGLContext != 0 && bufferSize() != rect.size()) + m_requestedBufferSize = newGeometry.size(); + if (m_platformOpenGLContext != 0 && bufferSize() != newGeometry.size()) m_newSurfaceRequested.testAndSetRelease(false, true); } - QQnxWindow::setGeometry(rect); + QQnxWindow::setGeometry(newGeometry); } QSize QQnxEglWindow::requestedBufferSize() const diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 1e58d482d4..731e0e5ea7 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -136,7 +136,7 @@ void QQnxWindow::setGeometry(const QRect &rect) // Calling flushWindowSystemEvents() here would flush input events which // could result in re-entering QQnxWindow::setGeometry() again. - QWindowSystemInterface::setSynchronousWindowsSystemEvents(true); //This does not work + QWindowSystemInterface::setSynchronousWindowsSystemEvents(true); QWindowSystemInterface::handleGeometryChange(window(), newGeometry); QWindowSystemInterface::handleExposeEvent(window(), newGeometry); QWindowSystemInterface::setSynchronousWindowsSystemEvents(false); @@ -608,12 +608,11 @@ void QQnxWindow::initWindow() setWindowState(window()->windowState()); if (window()->parent() && window()->parent()->handle()) setParent(window()->parent()->handle()); - setGeometryHelper(window()->geometry()); - if (screen()->rootWindow() == this) { - setGeometry(screen()->geometry()); - } -} + const QRect &initialGeometry = screen()->rootWindow() == this ? + screen()->geometry() : window()->geometry(); + setGeometryHelper(initialGeometry); +} void QQnxWindow::createWindowGroup() { -- cgit v1.2.3 From cd61eacae12ed89ceb82b59d3813f5c79e778821 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 18 Nov 2013 17:35:18 +0100 Subject: Fix crash regression for ApplicationWindow on Mac This fixes a recent regression following the integration of change: 7cc1656fef21e6bdc044968a79f0a41155357c29 (Make sure menu bar has a parent window ...) As it now consistently crashes on mac in several of the Qt Quick Controls examples, it is critical that it gets into the release branch. Change-Id: If3db1025229a7f7fd4e7ecc703d5f655db73964d Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qcocoamenubar.mm | 1 + 1 file changed, 1 insertion(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 0fea55ac68..5a8664747e 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -175,6 +175,7 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow) if (newParentWindow == NULL) { m_window = NULL; } else { + newParentWindow->create(); m_window = static_cast(newParentWindow->handle()); m_window->setMenubar(this); } -- cgit v1.2.3 From eef293b1a02efaa0206f1b9c5086a15cf659ad7d Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 15 Nov 2013 14:03:17 +0200 Subject: Don't send ApplicationStateChanged, if platformIntegration is not set. Task-number: QTBUG-34868 Change-Id: Ia86877550884a3037b9ddedf5d8e227ec1ead2d6 Reviewed-by: Marc Mutz Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/src/androidjnimain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp index 3ab4eedb26..3064e5d4e2 100644 --- a/src/plugins/platforms/android/src/androidjnimain.cpp +++ b/src/plugins/platforms/android/src/androidjnimain.cpp @@ -40,6 +40,7 @@ ** ****************************************************************************/ +#include #include #include @@ -691,7 +692,7 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state { m_activityActive = (state == Qt::ApplicationActive); - if (!m_androidPlatformIntegration) + if (!m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration()) return; QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state)); -- cgit v1.2.3 From c62efb52b538063ab561cd5c8fceab206de7c427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 20 Nov 2013 17:33:48 +0100 Subject: iOS: Use custom method to lay out windows instead of resizeMaximizedWindows() Since we guard against overriding the geometry in setGeometry() when a window has a window state, we need to use a custom method to lay out windows that calls applyGeometry() instead. Change-Id: I6508e6aac6746c024a6172f709b8339b35b40994 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 1 + src/plugins/platforms/ios/qiosscreen.mm | 28 +++++++++++++++++++++++++++- src/plugins/platforms/ios/qioswindow.h | 4 ++++ src/plugins/platforms/ios/qioswindow.mm | 16 +++++++++------- 4 files changed, 41 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index e70ff4b1a9..9de62c5646 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -73,6 +73,7 @@ public: UIScreen *uiScreen() const; void updateProperties(); + void layoutWindows(); private: UIScreen *m_uiScreen; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index de6585fd19..3c054b4b04 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -182,7 +182,33 @@ void QIOSScreen::updateProperties() } if (screen()) - resizeMaximizedWindows(); + layoutWindows(); +} + +void QIOSScreen::layoutWindows() +{ + QList windows = QGuiApplication::topLevelWindows(); + + const QRect oldGeometry = screen()->geometry(); + const QRect oldAvailableGeometry = screen()->availableGeometry(); + const QRect newGeometry = geometry(); + const QRect newAvailableGeometry = availableGeometry(); + + for (int i = 0; i < windows.size(); ++i) { + QWindow *window = windows.at(i); + + if (platformScreenForWindow(window) != this) + continue; + + QIOSWindow *platformWindow = static_cast(window->handle()); + if (!platformWindow) + continue; + + if (window->windowState() & Qt::WindowFullScreen || window->geometry() == oldGeometry) + platformWindow->applyGeometry(newGeometry); + else if (window->windowState() & Qt::WindowMaximized || window->geometry() == oldAvailableGeometry) + platformWindow->applyGeometry(newAvailableGeometry); + } } QRect QIOSScreen::geometry() const diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 6e8683af00..4ebdd4635c 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -86,6 +86,8 @@ public: WId winId() const { return WId(m_view); }; private: + void applyGeometry(const QRect &rect); + QUIView *m_view; QRect m_normalGeometry; @@ -97,6 +99,8 @@ private: inline Qt::WindowType windowType() { return static_cast(int(window()->flags() & Qt::WindowType_Mask)); } inline bool windowIsPopup() { return windowType() & Qt::Popup & ~Qt::Window; } + + friend class QIOSScreen; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 2413a45e11..52851439b1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -435,6 +435,11 @@ void QIOSWindow::setGeometry(const QRect &rect) if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) return; + applyGeometry(rect); +} + +void QIOSWindow::applyGeometry(const QRect &rect) +{ // Since we don't support transformations on the UIView, we can set the frame // directly and let UIKit deal with translating that into bounds and center. // Changing the size of the view will end up in a call to -[QUIView layoutSubviews] @@ -448,21 +453,18 @@ void QIOSWindow::setWindowState(Qt::WindowState state) // Perhaps setting QWindow to maximized should also mean that we'll show // the statusbar, and vice versa for fullscreen? - if (state != Qt::WindowNoState) - m_normalGeometry = geometry(); - switch (state) { case Qt::WindowNoState: - setGeometry(m_normalGeometry); + applyGeometry(m_normalGeometry); break; case Qt::WindowMaximized: - setGeometry(screen()->availableGeometry()); + applyGeometry(screen()->availableGeometry()); break; case Qt::WindowFullScreen: - setGeometry(screen()->geometry()); + applyGeometry(screen()->geometry()); break; case Qt::WindowMinimized: - setGeometry(QRect()); + applyGeometry(QRect()); break; case Qt::WindowActive: Q_UNREACHABLE(); -- cgit v1.2.3 From 0ac9ea83f82ebf00c469d6f91a5ec12cb9306ac6 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 20 Nov 2013 20:02:21 +0100 Subject: Handle the Qt::FramelessWindowHint correctly in Cocoa This fixes a regression introduced by be405c86f8efac7c6bc8b749725d6d0e0499314d. Task-number: QTBUG-34988 Change-Id: Id825b51d4d94826819d2405bb711886db3db8bc8 Reviewed-by: Christoph Schleifenbaum Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoawindow.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index c22f254aef..4da47f4f1f 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -465,8 +465,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) { Qt::WindowType type = static_cast(int(flags & Qt::WindowType_Mask)); NSInteger styleMask = NSBorderlessWindowMask; + if (flags & Qt::FramelessWindowHint) + return styleMask; if ((type & Qt::Popup) == Qt::Popup) { - if (!windowIsPopupType(type) && !(flags & Qt::FramelessWindowHint)) + if (!windowIsPopupType(type)) styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); } else { @@ -485,7 +487,7 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) } else { styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask; } - } else if (!(flags & Qt::FramelessWindowHint)) { + } else { if (flags & Qt::WindowMaximizeButtonHint) styleMask |= NSResizableWindowMask; if (flags & Qt::WindowTitleHint) -- cgit v1.2.3 From 52fc0a95a109d2e9fa279eeb0284a8178563080b Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 9 Sep 2013 13:57:37 +0200 Subject: Look at locale aliases if initial search in compose.dir fails The file "locale.alias" (located in the same directory as "compose.dir"), contains following text: "This file contains alias name of locale. Each alias name is described within one line. The first word is the alias name (simplified locale name) the second word is full locale name." Therefore, if initial search in the compose.dir fails to find a match we make sure that a 'full locale name' was used in the initial search, if not, we try again. Task-number: QTBUG-32461 Change-Id: Ie7766658f22433524bd6e4bc829e32c6e3a0cbd0 Reviewed-by: Olivier Goffart Reviewed-by: Lars Knoll --- .../compose/generator/qtablegenerator.cpp | 64 ++++++++++++++++++---- .../compose/generator/qtablegenerator.h | 1 + 2 files changed, 55 insertions(+), 10 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index b5e3aa741e..dad34e121b 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -100,7 +100,6 @@ void TableGenerator::findComposeFile() qDebug() << "Using Compose file from: " << composeFile; #endif } - // check if user’s home directory has a file named .XCompose if (!found && cleanState()) { QString composeFile = qgetenv("HOME") + QStringLiteral("/.XCompose"); @@ -111,10 +110,12 @@ void TableGenerator::findComposeFile() qDebug() << "Using Compose file from: " << composeFile; #endif } - // check for the system provided compose files if (!found && cleanState()) { - QString table = readLocaleMappings(locale().toUpper().toUtf8()); + QByteArray loc = locale().toUpper().toUtf8(); + QString table = readLocaleMappings(loc); + if (table.isEmpty()) + table = readLocaleMappings(readLocaleAliases(loc)); if (cleanState()) { if (table.isEmpty()) @@ -177,8 +178,11 @@ QString TableGenerator::locale() const QString TableGenerator::readLocaleMappings(const QByteArray &locale) { - QFile mappings(systemComposeDir() + QLatin1String("/compose.dir")); QString file; + if (locale.isEmpty()) + return file; + + QFile mappings(systemComposeDir() + QLatin1String("/compose.dir")); if (mappings.open(QIODevice::ReadOnly)) { const int localeNameLength = locale.size(); const char * const localeData = locale.constData(); @@ -208,9 +212,8 @@ QString TableGenerator::readLocaleMappings(const QByteArray &locale) while (*line && *line != ' ' && *line != '\t' && *line != '\n') ++line; *line = '\0'; - if (localeNameLength == (line - lc) && !strncasecmp(lc, localeData, line - lc)) { - file = QString::fromUtf8(l, composeFileNameEnd - l); + file = QString::fromLocal8Bit(l, composeFileNameEnd - l); break; } } @@ -220,6 +223,47 @@ QString TableGenerator::readLocaleMappings(const QByteArray &locale) return file; } +QByteArray TableGenerator::readLocaleAliases(const QByteArray &locale) +{ + QFile aliases(systemComposeDir() + QLatin1String("/locale.alias")); + QByteArray fullLocaleName; + if (aliases.exists()) { + aliases.open(QIODevice::ReadOnly); + while (!aliases.atEnd()) { + char l[1024]; + int read = aliases.readLine(l, sizeof(l)); + char *line = l; + if (read && ((*line >= 'a' && *line <= 'z') || + (*line >= 'A' && *line <= 'Z'))) { + const char *alias = line; + while (*line && *line != ':' && *line != ' ' && *line != '\t') + ++line; + if (!*line) + continue; + *line = 0; + if (locale.size() == (line - alias) + && !strncasecmp(alias, locale.constData(), line - alias)) { + // found a match for alias, read the real locale name + ++line; + while (*line && (*line == ' ' || *line == '\t')) + ++line; + const char *fullName = line; + while (*line && *line != ' ' && *line != '\t' && *line != '\n') + ++line; + *line = 0; + fullLocaleName = fullName; +#ifdef DEBUG_GENERATOR + qDebug() << "Alias for: " << alias << "is: " << fullLocaleName; + break; +#endif + } + } + } + aliases.close(); + } + return fullLocaleName; +} + bool TableGenerator::processFile(QString composeFileName) { QFile composeFile(composeFileName); @@ -254,7 +298,7 @@ void TableGenerator::parseComposeFile(QFile *composeFile) if (*line == '<') parseKeySequence(line); else if (!strncmp(line, "include", 7)) - parseIncludeInstruction(QString::fromUtf8(line)); + parseIncludeInstruction(QString::fromLocal8Bit(line)); } composeFile->close(); @@ -308,7 +352,7 @@ ushort TableGenerator::keysymToUtf8(quint32 sym) qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16)) .arg(codec->toUnicode(chars)); #endif - return QString::fromUtf8(chars).at(0).unicode(); + return QString::fromLocal8Bit(chars).at(0).unicode(); } static inline int fromBase8(const char *s, const char *end) @@ -377,13 +421,13 @@ void TableGenerator::parseKeySequence(char *line) // handle direct text encoded in the locale if (*composeValue == '\\') ++composeValue; - elem.value = QString::fromUtf8(composeValue).at(0).unicode(); + elem.value = QString::fromLocal8Bit(composeValue).at(0).unicode(); ++composeValue; } #ifdef DEBUG_GENERATOR // find the comment - elem.comment = QString::fromUtf8(composeValueEnd + 1).trimmed(); + elem.comment = QString::fromLocal8Bit(composeValueEnd + 1).trimmed(); #endif // find the key sequence and convert to X11 keysym diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h index aa65b7b895..248c09f3ea 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h @@ -122,6 +122,7 @@ protected: ushort keysymToUtf8(quint32 sym); QString readLocaleMappings(const QByteArray &locale); + QByteArray readLocaleAliases(const QByteArray &locale); void initPossibleLocations(); bool cleanState() const { return ((m_state & NoErrors) == NoErrors); } QString locale() const; -- cgit v1.2.3 From 7879fbe4b8e6396fff199476494c1e05fb4c16e9 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 22 Nov 2013 07:38:26 +0100 Subject: Disable threaded GL for nouveau drivers. Task-number: QTCREATORBUG-10875 Change-Id: I25f3abc6ef15bba78fa9ec27de2c1e5e0bcc7fae Reviewed-by: Lars Knoll Reviewed-by: Kai Koehne --- src/plugins/platforms/xcb/qglxintegration.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index e6fa8fc898..e504d93fba 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -415,12 +415,17 @@ bool QGLXContext::m_supportsThreading = true; // If this list grows to any significant size, change it a // proper string table and make the implementation below use // binary search. -static const char *qglx_threadedgl_blacklist[] = { +static const char *qglx_threadedgl_blacklist_renderer[] = { "Chromium", // QTBUG-32225 (initialization fails) "Mesa DRI Intel(R) Sandybridge Mobile", // QTBUG-34492 (flickering in fullscreen) 0 }; +static const char *qglx_threadedgl_blacklist_vendor[] = { + "nouveau", // QTCREATORBUG-10875 (crash in creator) + 0 +}; + void QGLXContext::queryDummyContext() { if (m_queriedDummyContext) @@ -437,8 +442,8 @@ void QGLXContext::queryDummyContext() oldSurface = oldContext->surface(); QScopedPointer surface; - const char *vendor = glXGetClientString(glXGetCurrentDisplay(), GLX_VENDOR); - if (vendor && !strcmp(vendor, "ATI")) { + const char *glxvendor = glXGetClientString(glXGetCurrentDisplay(), GLX_VENDOR); + if (glxvendor && !strcmp(glxvendor, "ATI")) { QWindow *window = new QWindow; window->resize(64, 64); window->setSurfaceType(QSurface::OpenGLSurface); @@ -454,11 +459,19 @@ void QGLXContext::queryDummyContext() context.create(); context.makeCurrent(surface.data()); + m_supportsThreading = true; + const char *renderer = (const char *) glGetString(GL_RENDERER); + for (int i = 0; qglx_threadedgl_blacklist_renderer[i]; ++i) { + if (strstr(renderer, qglx_threadedgl_blacklist_renderer[i]) != 0) { + m_supportsThreading = false; + break; + } + } - m_supportsThreading = true; - for (int i = 0; qglx_threadedgl_blacklist[i]; ++i) { - if (strstr(renderer, qglx_threadedgl_blacklist[i]) != 0) { + const char *vendor = (const char *) glGetString(GL_VENDOR); + for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) { + if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) { m_supportsThreading = false; break; } -- cgit v1.2.3 From a474b1d13511858df9b99564f8b443131eb5966a Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 21 Nov 2013 15:00:01 +0100 Subject: Android: make the default font size bigger The default font size turned out to be slightly too small for comfort on touch devices. This tweaks the size from a 12-point equivalent to a 14-point equivalent. (Point sizes aren't real point sizes because of compatibility with iOS.) Change-Id: I6d970fdd5bba8199cabdf1aaaaac10d19c53c654 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Jens Bache-Wiig --- src/plugins/platforms/android/src/qandroidplatformtheme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp index 0ceac97e35..308bb70faf 100644 --- a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/src/qandroidplatformtheme.cpp @@ -125,7 +125,7 @@ const QFont *QAndroidPlatformTheme::font(Font type) const return &(it.value()); // default in case the style has not set a font - static QFont systemFont("Roboto", 12.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi + static QFont systemFont("Roboto", 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi if (type == QPlatformTheme::SystemFont) return &systemFont; return 0; -- cgit v1.2.3 From 0a170be576153b84ee6249f1a2b7cbce1ef10d84 Mon Sep 17 00:00:00 2001 From: Josh Faust Date: Mon, 10 Jun 2013 11:42:01 -0700 Subject: Fix OpenType fonts with cmap tables on Windows Task-number: QTBUG-31656 Change-Id: I5405d80f3ac1de488c44c9f1ac9ed9942ceab6b8 Reviewed-by: Konstantin Ritt Reviewed-by: Lars Knoll --- src/plugins/platforms/windows/qwindowsfontengine.cpp | 13 ++++++++++--- src/plugins/platforms/windows/qwindowsfontengine.h | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ac57a1b396..6c928119b3 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -161,12 +161,18 @@ bool QWindowsFontEngine::hasCFFTable() const return GetFontData(hdc, MAKE_TAG('C', 'F', 'F', ' '), 0, 0, 0) != GDI_ERROR; } +bool QWindowsFontEngine::hasCMapTable() const +{ + HDC hdc = m_fontEngineData->hdc; + SelectObject(hdc, hfont); + return GetFontData(hdc, MAKE_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR; +} + void QWindowsFontEngine::getCMap() { - ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE); + ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable(); - // TMPF_TRUETYPE is not set for fonts with CFF tables - cffTable = !ttf && hasCFFTable(); + cffTable = hasCFFTable(); HDC hdc = m_fontEngineData->hdc; SelectObject(hdc, hfont); @@ -374,6 +380,7 @@ HGDIOBJ QWindowsFontEngine::selectDesignFont() const { LOGFONT f = m_logfont; f.lfHeight = unitsPerEm; + f.lfWidth = 0; HFONT designFont = CreateFontIndirect(&f); return SelectObject(m_fontEngineData->hdc, designFont); } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index d783b6048c..acf84d270c 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -140,6 +140,7 @@ private: QWindowsNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform, QImage::Format mask_format); bool hasCFFTable() const; + bool hasCMapTable() const; const QSharedPointer m_fontEngineData; -- cgit v1.2.3 From 1ca27d38bc065b124a8fda6548e41f79c351e17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Nov 2013 19:36:40 +0100 Subject: iOS: Fix when and how we send geometry and expose events Geometry changes may come from Qt itself, or spontaneously from the windowing system. In both cases we deal with them through the layoutSubviews callback, which we now ensure gets called after we set a new geometry on the UIView frame, by using the setNeedsLayout message. We take care to persist the requested geometry from Qt immediately in our setGeometry() function, so that subsequent calls to QWindow::geometry() will report back the requested geometry. Clients can however not rely on this geometry until they've received a corresponding resize event, which we trigger from layoutSubviews. Since the new geometry reported in layoutSubviews may be different from what the user requested, we ensure to pass on both the new and the "old" geometry, so that Qt will send the appropriate resize and move events. Instead of building expose events on top of the existing layout mechanism provided by iOS, we hook into the more logical point, which is the display-phase. Since a EAGL view normally doesn't need to "display" anything this takes a few overrides on UIView. Once we have the hooks we need, we can distinguish between a QWindow backing needing layout, and needing displaying. Finally, we flush both the resize and expose events, as that's what iOS expects of us when asking us to layout or display. The result is that Qt is able to synchronously resize subwindows and prepare new GL rendering for the next frame. Change-Id: I4c03e3db3fe886163284ba1a342699e217e88cbb Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 85 ++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 13 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 52851439b1..14220f1139 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -153,6 +153,15 @@ self.clipsToBounds = NO; } +- (void)setNeedsDisplay +{ + [super setNeedsDisplay]; + + // We didn't implement drawRect: so we have to manually + // mark the layer as needing display. + [self.layer setNeedsDisplay]; +} + - (void)layoutSubviews { // This method is the de facto way to know that view has been resized, @@ -165,15 +174,39 @@ qWarning() << m_qioswindow->window() << "is backed by a UIView that has a transform set. This is not supported."; - QRect geometry = fromCGRect(self.frame); - m_qioswindow->QPlatformWindow::setGeometry(geometry); - QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), geometry); - QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), QRect(QPoint(), geometry.size())); + // The original geometry requested by setGeometry() might be different + // from what we end up with after applying window constraints. + QRect requestedGeometry = m_qioswindow->geometry(); + + // Persist the actual/new geometry so that QWindow::geometry() can + // be queried on the resize event. + QRect actualGeometry = fromCGRect(self.frame); + m_qioswindow->QPlatformWindow::setGeometry(actualGeometry); + + QRect previousGeometry = requestedGeometry != actualGeometry ? + requestedGeometry : qt_window_private(m_qioswindow->window())->geometry; - // If we have a new size here we need to resize the FBO's corresponding buffers, - // but we defer that to when the application calls makeCurrent. + QWindowSystemInterface::handleGeometryChange(m_qioswindow->window(), actualGeometry, previousGeometry); + QWindowSystemInterface::flushWindowSystemEvents(); + + if (actualGeometry.size() != previousGeometry.size()) { + // Trigger expose event on resize + [self setNeedsDisplay]; - [super layoutSubviews]; + // A new size means we also need to resize the FBO's corresponding buffers, + // but we defer that to when the application calls makeCurrent. + } +} + +- (void)displayLayer:(CALayer *)layer +{ + QRect geometry = fromCGRect(layer.frame); + Q_ASSERT(m_qioswindow->geometry() == geometry); + Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); + + QRegion region = self.hidden ? QRegion() : QRect(QPoint(), geometry.size()); + QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region); + QWindowSystemInterface::flushWindowSystemEvents(); } - (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state @@ -393,8 +426,8 @@ bool QIOSWindow::blockedByModal() void QIOSWindow::setVisible(bool visible) { - QPlatformWindow::setVisible(visible); m_view.hidden = !visible; + [m_view setNeedsDisplay]; if (!isQtApplication()) return; @@ -429,22 +462,48 @@ void QIOSWindow::setVisible(bool visible) void QIOSWindow::setGeometry(const QRect &rect) { - // If the window is in fullscreen, just bookkeep the requested - // geometry in case the window goes into Qt::WindowNoState later: m_normalGeometry = rect; - if (window()->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) + + if (window()->windowState() != Qt::WindowNoState) { + QPlatformWindow::setGeometry(rect); + + // The layout will realize the requested geometry was not applied, and + // send geometry-change events that match the actual geometry. + [m_view setNeedsLayout]; + + if (window()->inherits("QWidgetWindow")) { + // QWidget wrongly assumes that setGeometry resets the window + // state back to Qt::NoWindowState, so we need to inform it that + // that his is not the case by re-issuing the current window state. + QWindowSystemInterface::handleWindowStateChanged(window(), window()->windowState()); + + // It also needs to be told immediately that the geometry it requested + // did not apply, otherwise it will continue on as if it did, instead + // of waiting for a resize event. + [m_view layoutIfNeeded]; + } + return; + } applyGeometry(rect); } void QIOSWindow::applyGeometry(const QRect &rect) { + // Geometry changes are asynchronous, but QWindow::geometry() is + // expected to report back the 'requested geometry' until we get + // a callback with the updated geometry from the window system. + // The baseclass takes care of persisting this for us. + QPlatformWindow::setGeometry(rect); + // Since we don't support transformations on the UIView, we can set the frame // directly and let UIKit deal with translating that into bounds and center. - // Changing the size of the view will end up in a call to -[QUIView layoutSubviews] - // which will update QWindowSystemInterface with the new size. m_view.frame = toCGRect(rect); + + // iOS will automatically trigger -[layoutSubviews:] for resize, + // but not for move, so we force it just in case. + [m_view setNeedsLayout]; } void QIOSWindow::setWindowState(Qt::WindowState state) -- cgit v1.2.3 From ae5392a00bdd5a569250cd4e387868141cbd68e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 20 Nov 2013 17:48:49 +0100 Subject: iOS: Take position of root viewcontroller into account for geometry changes When setting the geometry on our UIView, or when reporting it back to Qt in our layoutSubviews callback, we need to take into account that the root viewcontroller may be not be positioned at 0,0 in the screen's window. Even when using the wantsFullScreenLayout property of the view controller this may be the case on iOS7 when the in-call status-bar is visible. Change-Id: I0ca706c1c9aff8ba4f3b4ccdf83dba713bd5c9c2 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 14220f1139..e835b829a8 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -178,9 +178,20 @@ // from what we end up with after applying window constraints. QRect requestedGeometry = m_qioswindow->geometry(); + QRect actualGeometry; + if (m_qioswindow->window()->isTopLevel()) { + UIWindow *uiWindow = self.window; + CGRect rootViewPositionInRelationToRootViewController = + [uiWindow.rootViewController.view convertRect:uiWindow.bounds fromView:uiWindow]; + + actualGeometry = fromCGRect(CGRectOffset([self.superview convertRect:self.frame toView:uiWindow.rootViewController.view], + -rootViewPositionInRelationToRootViewController.origin.x, -rootViewPositionInRelationToRootViewController.origin.y)); + } else { + actualGeometry = fromCGRect(self.frame); + } + // Persist the actual/new geometry so that QWindow::geometry() can // be queried on the resize event. - QRect actualGeometry = fromCGRect(self.frame); m_qioswindow->QPlatformWindow::setGeometry(actualGeometry); QRect previousGeometry = requestedGeometry != actualGeometry ? @@ -497,9 +508,20 @@ void QIOSWindow::applyGeometry(const QRect &rect) // The baseclass takes care of persisting this for us. QPlatformWindow::setGeometry(rect); - // Since we don't support transformations on the UIView, we can set the frame - // directly and let UIKit deal with translating that into bounds and center. - m_view.frame = toCGRect(rect); + if (window()->isTopLevel()) { + // The QWindow is in QScreen coordinates, which maps to a possibly rotated root-view-controller. + // Since the root-view-controller might be translated in relation to the UIWindow, we need to + // check specifically for that and compensate. + UIWindow *uiWindow = m_view.window; + CGRect rootViewPositionInRelationToRootViewController = + [uiWindow.rootViewController.view convertRect:uiWindow.bounds fromView:uiWindow]; + + m_view.frame = CGRectOffset([m_view.superview convertRect:toCGRect(rect) fromView:m_view.window.rootViewController.view], + rootViewPositionInRelationToRootViewController.origin.x, rootViewPositionInRelationToRootViewController.origin.y); + } else { + // Easy, in parent's coordinates + m_view.frame = toCGRect(rect); + } // iOS will automatically trigger -[layoutSubviews:] for resize, // but not for move, so we force it just in case. -- cgit v1.2.3 From f441d8e52360fe5c03887fa0bbce8bfda2c8ff2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Nov 2013 11:25:48 +0100 Subject: iOS: Change show() to imply maximize, and showFullScreen() to hide status bar Matches the Android behavior, and gives an easy and predictable way to show true fullscreen windows that is similar to how one would do it on a desktop platform. We keep the statusbar visibility in sync with the window state of the active window. Change-Id: Ia4b99e03f83e19f9ef56cc99b9d477cc6da4c734 Reviewed-by: Richard Moe Gustavsen --- .../platforms/ios/qiosapplicationdelegate.mm | 16 +++++++++++ src/plugins/platforms/ios/qiosintegration.mm | 2 +- src/plugins/platforms/ios/qiosscreen.h | 7 ++++- src/plugins/platforms/ios/qiosscreen.mm | 29 +++++++++++++++++++ src/plugins/platforms/ios/qiosviewcontroller.h | 1 + src/plugins/platforms/ios/qiosviewcontroller.mm | 25 ++++++++++++++++ src/plugins/platforms/ios/qioswindow.h | 2 ++ src/plugins/platforms/ios/qioswindow.mm | 33 +++++++++++++++++++--- 8 files changed, 109 insertions(+), 6 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 775074baae..e325666f69 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -58,6 +58,22 @@ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; + QSysInfo::MacVersion iosVersion = QSysInfo::MacintoshVersion; + + // We prefer to keep the root viewcontroller in fullscreen layout, so that + // we don't have to compensate for the viewcontroller position. This also + // gives us the same behavior on iOS 5/6 as on iOS 7, where full screen layout + // is the only way. + if (iosVersion < QSysInfo::MV_IOS_7_0) + self.window.rootViewController.wantsFullScreenLayout = YES; + + // Use translucent statusbar by default on iOS6 (unless the user changed the + // default in the Info.plist), so that windows placed under the stausbar are + // still visible, just like on iOS7. + if (iosVersion >= QSysInfo::MV_IOS_6_0 && iosVersion < QSysInfo::MV_IOS_7_0 + && [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault) + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent]; + self.window.hidden = NO; return YES; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 44ac749454..5c8f67bda2 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -160,7 +160,7 @@ QPlatformServices *QIOSIntegration::services() const QVariant QIOSIntegration::styleHint(StyleHint hint) const { switch (hint) { - case ShowIsFullScreen: + case ShowIsMaximized: return true; case SetFocusOnTouchRelease: return true; diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 9de62c5646..173bd11719 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -50,8 +50,10 @@ QT_BEGIN_NAMESPACE -class QIOSScreen : public QPlatformScreen +class QIOSScreen : public QObject, public QPlatformScreen { + Q_OBJECT + public: QIOSScreen(unsigned int screenIndex); ~QIOSScreen(); @@ -75,6 +77,9 @@ public: void updateProperties(); void layoutWindows(); +public slots: + void updateStatusBarVisibility(); + private: UIScreen *m_uiScreen; QRect m_geometry; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 3c054b4b04..42c3e13e7e 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -139,6 +139,8 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) m_unscaledDpi = 163; // Regular iPhone DPI } + connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSScreen::updateStatusBarVisibility); + updateProperties(); } @@ -185,6 +187,31 @@ void QIOSScreen::updateProperties() layoutWindows(); } +void QIOSScreen::updateStatusBarVisibility() +{ + QWindow *focusWindow = QGuiApplication::focusWindow(); + + // If we don't have a focus window we leave the status + // bar as is, so that the user can activate a new window + // with the same window state without the status bar jumping + // back and forth. + if (!focusWindow) + return; + + UIView *view = reinterpret_cast(focusWindow->handle()->winId()); +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_7_0) { + [view.viewController setNeedsStatusBarAppearanceUpdate]; + } else +#endif + { + QIOSViewController *viewController = static_cast(view.viewController); + [[UIApplication sharedApplication] + setStatusBarHidden:[viewController prefersStatusBarHidden] + withAnimation:UIStatusBarAnimationNone]; + } +} + void QIOSScreen::layoutWindows() { QList windows = QGuiApplication::topLevelWindows(); @@ -273,4 +300,6 @@ UIScreen *QIOSScreen::uiScreen() const return m_uiScreen; } +#include "moc_qiosscreen.cpp" + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index d5a61cb3f4..a0017808d3 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -42,5 +42,6 @@ #import @interface QIOSViewController : UIViewController +- (BOOL)prefersStatusBarHidden; @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 1d5e69beac..11ac92fea5 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -42,9 +42,11 @@ #import "qiosviewcontroller.h" #include +#include #include #include "qiosscreen.h" #include "qiosglobal.h" +#include "qioswindow.h" @implementation QIOSViewController @@ -74,5 +76,28 @@ qiosScreen->updateProperties(); } +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0) +- (UIStatusBarStyle)preferredStatusBarStyle +{ + // Since we don't place anything behind the status bare by default, we + // end up with a black area, so we have to enable the white text mode + // of the iOS7 statusbar. + return UIStatusBarStyleLightContent; + + // FIXME: Try to detect the content underneath the statusbar and choose + // an appropriate style, and/or expose Qt APIs to control the style. +} +#endif + +- (BOOL)prefersStatusBarHidden +{ + QWindow *focusWindow = QGuiApplication::focusWindow(); + if (!focusWindow) + return [UIApplication sharedApplication].statusBarHidden; + + QIOSWindow *topLevel = static_cast(focusWindow->handle())->topLevelWindow(); + return topLevel->window()->windowState() == Qt::WindowFullScreen; +} + @end diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4ebdd4635c..a5e122bda1 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -85,6 +85,8 @@ public: WId winId() const { return WId(m_view); }; + QIOSWindow *topLevelWindow() const; + private: void applyGeometry(const QRect &rect); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e835b829a8..d4e656c390 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -456,6 +456,10 @@ void QIOSWindow::setVisible(bool visible) if (visible) { requestActivateWindow(); + + if (window()->isTopLevel()) + static_cast(screen())->updateStatusBarVisibility(); + } else { // Activate top-most visible QWindow: NSArray *subviews = m_view.viewController.view.subviews; @@ -530,10 +534,6 @@ void QIOSWindow::applyGeometry(const QRect &rect) void QIOSWindow::setWindowState(Qt::WindowState state) { - // FIXME: Figure out where or how we should disable/enable the statusbar. - // Perhaps setting QWindow to maximized should also mean that we'll show - // the statusbar, and vice versa for fullscreen? - switch (state) { case Qt::WindowNoState: applyGeometry(m_normalGeometry); @@ -552,6 +552,14 @@ void QIOSWindow::setWindowState(Qt::WindowState state) default: Q_UNREACHABLE(); } + + if (window()->isTopLevel() && window()->isVisible() && window()->isActive()) { + // The window state of the QWindow is not updated until after + // we return from this method, so we have to defer any updates + // of the statusbar that depend on the current window state. + QMetaObject::invokeMethod(static_cast(screen()), + "updateStatusBarVisibility", Qt::QueuedConnection); + } } void QIOSWindow::setParent(const QPlatformWindow *parentWindow) @@ -569,6 +577,23 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow) } } +QIOSWindow *QIOSWindow::topLevelWindow() const +{ + QWindow *window = this->window(); + while (window) { + QWindow *parent = window->parent(); + if (!parent) + parent = window->transientParent(); + + if (!parent) + break; + + window = parent; + } + + return static_cast(window->handle()); +} + void QIOSWindow::requestActivateWindow() { // Note that several windows can be active at the same time if they exist in the same -- cgit v1.2.3 From c25385ae1e3da0848c2718a002ae7d037f25db94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Nov 2013 15:26:32 +0100 Subject: iOS: Fix build against iOS 5 SDK and auto-rotation on iOS 5 Change-Id: I3acc2d3780a9440bedf48db3fed0046b06300b9e Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosviewcontroller.mm | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 11ac92fea5..2e7e44d32c 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -57,12 +57,22 @@ return YES; } +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_6_0) -(NSUInteger)supportedInterfaceOrientations { // We need to tell iOS that we support all orientations in order to set // status bar orientation when application content orientation changes. return UIInterfaceOrientationMaskAll; } +#endif + +#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_6_0) +-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + Q_UNUSED(interfaceOrientation); + return YES; +} +#endif - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration { -- cgit v1.2.3 From c38225229d047eeb52a09150dff9985f0547b13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Nov 2013 17:16:27 +0100 Subject: iOS: Allow QBackingStore::flush() without beginPaint() The QBackingStore API doesn't require clients to precede flush() with a beginPaint() call, but our backingstore is backed by a GL context, so it's up to us to ensure it's current before swapping. Change-Id: Ia6119bf0e835448b1fd383d933df6f88fa4f298a Reviewed-by: Gunnar Sletta --- src/plugins/platforms/ios/qiosbackingstore.mm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 2dadc5672b..80b603bb8e 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -56,6 +56,9 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window) fmt.setDepthBufferSize(16); fmt.setStencilBufferSize(8); + // Needed to prevent QOpenGLContext::makeCurrent() from failing + window->setSurfaceType(QSurface::OpenGLSurface); + m_context->setFormat(fmt); m_context->setScreen(window->screen()); m_context->create(); @@ -69,9 +72,6 @@ QIOSBackingStore::~QIOSBackingStore() void QIOSBackingStore::beginPaint(const QRegion &) { - // Needed to prevent QOpenGLContext::makeCurrent() from failing - window()->setSurfaceType(QSurface::OpenGLSurface); - m_context->makeCurrent(window()); QIOSWindow *iosWindow = static_cast(window()->handle()); @@ -102,6 +102,8 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin // the child window overlaps a sibling window that's draws using a separate QOpenGLContext. return; } + + m_context->makeCurrent(window); m_context->swapBuffers(window); } -- cgit v1.2.3 From a4e1c15b16ef263f908ae1b5d9d8b2b8c1e21ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Nov 2013 17:28:53 +0100 Subject: iOS: Deliver resize events synchronously after setGeometry for QtWidgets QWidget::show_sys() assumes synchronous geometry behavior by trying to resize both the platform window and the backing store if the widget's view of what the geometry is doesn't match the platform window's. The problem with that is that it's the widget which is not up to date, not the window, as the widget is not waiting for resize events before applying any resize logic. Instead of trying to fix widgets, we throw our hands in the air and give QtWidgets the synchronous behavior it assumes from the platform. Change-Id: I1b9241b9b13df661dc7f41c4cb8ecd02f5572256 Reviewed-by: Gunnar Sletta Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index d4e656c390..d453058b10 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -530,6 +530,9 @@ void QIOSWindow::applyGeometry(const QRect &rect) // iOS will automatically trigger -[layoutSubviews:] for resize, // but not for move, so we force it just in case. [m_view setNeedsLayout]; + + if (window()->inherits("QWidgetWindow")) + [m_view layoutIfNeeded]; } void QIOSWindow::setWindowState(Qt::WindowState state) -- cgit v1.2.3 From 28c5c74c9b37fdf650810cebcd93944e0078cbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 21 Nov 2013 17:38:50 +0100 Subject: iOS: Re-enable kEAGLDrawablePropertyRetainedBacking Having it disabled caused issues with our backing-store implementation, which assumes that the backing store is retained, but for us is backed by a GL context. Change-Id: I18d05e226c7cf949adcd3b71801ffd845fa6d83d Reviewed-by: Gunnar Sletta Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qioswindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index d453058b10..af51218654 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -105,7 +105,7 @@ CAEAGLLayer *eaglLayer = static_cast(self.layer); eaglLayer.opaque = TRUE; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, + [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; // Set up text input -- cgit v1.2.3 From 88728897a69275299d53a094d3a5745cc6a90c6d Mon Sep 17 00:00:00 2001 From: Arvid Nilsson Date: Thu, 21 Nov 2013 11:37:31 +0100 Subject: BlackBerry: Fixed root window size, continued The previous patch removed a call to setGeometry, and now only calls setGeometryHelper. This means the screen window will be resized, but Qt won't know about our new window size. The scene graph of a QtQuick2 application would layout and render to the wrong target size. Fixed by adding a call to QWindowSystemInterface::handleGeometryChange if we decide to use a different geometry than suggested by the window. Task-number: QTBUG-34930 Change-Id: Ie91c2edc45c47f5bf1d45aed981b969fcc3f40dd Reviewed-by: Bernd Weimer Reviewed-by: Fabian Bumberger Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxwindow.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 731e0e5ea7..b25c0b5b29 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -609,9 +609,12 @@ void QQnxWindow::initWindow() if (window()->parent() && window()->parent()->handle()) setParent(window()->parent()->handle()); - const QRect &initialGeometry = screen()->rootWindow() == this ? - screen()->geometry() : window()->geometry(); - setGeometryHelper(initialGeometry); + if (screen()->rootWindow() == this) { + setGeometryHelper(screen()->geometry()); + QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry()); + } else { + setGeometryHelper(window()->geometry()); + } } void QQnxWindow::createWindowGroup() -- cgit v1.2.3 From a18daa8793ea6b2e9405e854f4b0fef66f8ceb16 Mon Sep 17 00:00:00 2001 From: Frank Osterfeld Date: Wed, 20 Nov 2013 19:06:23 +0100 Subject: QNX: Only link libclipboard when building with clipboard support In QNX 6.6, libclipboard isn't part of the base SDP, and QT_NO_CLIPBOARD is set unconditionally on plain QNX anyway. The clipboard-based implementation isn't compiled when QT_NO_CLIPBOARD is set, so only try to link libclipboard when actually building with clipboard support (BB10). Change-Id: I54eb4fadb6bf239a83884796f5758cb79a5677ef Reviewed-by: Andreas Holzammer Reviewed-by: Fabian Bumberger Reviewed-by: Rafael Roquetto Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com> --- src/plugins/platforms/qnx/qnx.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index aeacbeef69..92c8fc183a 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -132,7 +132,8 @@ CONFIG(qqnx_pps) { qqnxclipboard.h \ qqnxbuttoneventnotifier.h - LIBS += -lpps -lclipboard + LIBS += -lpps + !contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard CONFIG(qqnx_imf) { DEFINES += QQNX_IMF -- cgit v1.2.3 From ca2440e2b10368c7d8b849ee1b504a7d587dd1a9 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 21 Nov 2013 12:58:22 +0100 Subject: Add PPS configure check Plain QNX 6.5.0 does not have a libpps, the new QNX has a libpps and BlackBerry has it as well. So we need a configure check to not open another mkspec for this platform. This fixes the plain QNX 6.5.0 build. Change-Id: Id4b3876f2385bcb5f3df426945532e7e26133f24 Reviewed-by: Oswald Buddenhagen Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qnx.pro | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro index 92c8fc183a..bc7219de5c 100644 --- a/src/plugins/platforms/qnx/qnx.pro +++ b/src/plugins/platforms/qnx/qnx.pro @@ -2,9 +2,6 @@ TARGET = qqnx QT += platformsupport-private core-private gui-private -# The PPS based platform integration is currently used for both BB10 and plain QNX -CONFIG += qqnx_pps - # Uncomment this to build with support for IMF once it becomes available in the BBNDK #CONFIG += qqnx_imf -- cgit v1.2.3 From d4c548ce5c0bd8a70c82ed082bc69fd41e9c47ed Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 19 Nov 2013 12:47:03 +0100 Subject: Fixed assert in Windows key handling Certain key sequences (like press alt, press left, release left, release alt) can cause an assert in qwindowskeymapper. This behavior was introduced in change I4f7709a90906b03f4504deea1ff5c361e9f94b3f (Fix virtual key mapping on MS Windows). The place that seems to cause the new behavior is changing the bitmask for obtaining the event's scancode. With the changed bitmask releasing the alt key in the given key sequence causes the WM_KEYUP event to trigger a WM_CHAR event which should not happen there. To be honest I don't know how having the extended bit inside the scancode fixes the behavior but it seems to do and I could not find another place which might cause the breakage. Task-number: QTBUG-35005 Change-Id: Ia18c2681ea311196441a5cd15017e220ac095674 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowskeymapper.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index e2594207fe..2743ef029d 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -86,6 +86,10 @@ QWindowsKeyMapper::~QWindowsKeyMapper() #define VK_OEM_3 0xC0 #endif +// We not only need the scancode itself but also the extended bit of key messages. Thus we need +// the additional bit when masking the scancode. +enum { scancodeBitmask = 0x1ff }; + // Key recorder ------------------------------------------------------------------------[ start ] -- struct KeyRecord { KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {} @@ -567,7 +571,7 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg) { unsigned char kbdBuffer[256]; // Will hold the complete keyboard state GetKeyboardState(kbdBuffer); - const quint32 scancode = (msg.lParam >> 16) & 0xff; + const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam); } @@ -754,7 +758,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms { const int msgType = msg.message; - const quint32 scancode = (msg.lParam >> 16) & 0xff; + const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; const quint32 vk_key = msg.wParam; quint32 nModifiers = 0; -- cgit v1.2.3 From eafa224c3bfff86839581536d832cbaf8045a264 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Sun, 17 Nov 2013 01:32:24 +0100 Subject: iOS: decouple QIOSWindow and QIOSInputContext Change-Id: I85dda6fc0c6d2d11709b8bcdc0de6c0cef42d40f Reviewed-by: Lars Knoll --- src/plugins/platforms/ios/qiosinputcontext.h | 4 ++-- src/plugins/platforms/ios/qiosinputcontext.mm | 4 +++- src/plugins/platforms/ios/qioswindow.mm | 2 -- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 78c1b260e6..f03b13d002 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -61,11 +61,11 @@ public: void hideInputPanel(); bool isInputPanelVisible() const; - void focusViewChanged(UIView *view); + void focusWindowChanged(QWindow *focusWindow); private: QIOSKeyboardListener *m_keyboardListener; - UIView *m_focusView; + UIView *m_focusView; bool m_hasPendingHideRequest; }; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index d430589037..ed17dee0c9 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -101,6 +101,7 @@ QIOSInputContext::QIOSInputContext() , m_focusView(0) , m_hasPendingHideRequest(false) { + connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSInputContext::focusWindowChanged); } QIOSInputContext::~QIOSInputContext() @@ -142,8 +143,9 @@ bool QIOSInputContext::isInputPanelVisible() const return m_keyboardListener->m_keyboardVisible; } -void QIOSInputContext::focusViewChanged(UIView *view) +void QIOSInputContext::focusWindowChanged(QWindow *focusWindow) { + UIView *view = reinterpret_cast *>(focusWindow->handle()->winId()); if ([m_focusView isFirstResponder]) [view becomeFirstResponder]; [m_focusView release]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index af51218654..8124d8ffb9 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -610,8 +610,6 @@ void QIOSWindow::requestActivateWindow() if (window()->isTopLevel()) raise(); - QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); - static_cast(context)->focusViewChanged(m_view); QWindowSystemInterface::handleWindowActivated(window()); } -- cgit v1.2.3 From ab76593f18396e693f24066592244ca95e135ea2 Mon Sep 17 00:00:00 2001 From: Chris Colbert Date: Mon, 18 Nov 2013 21:49:21 -0500 Subject: Fix the ignored Qt::WA_StaticContents on Windows This restores the ability from the Qt 4.x series to honor the static contents region in the backbuffer when resizing a widget. The fix only applies when running under Windows. Task-number: QTBUG-34799 [ChangeLog][QtWidgets][Windows] Update QWidgetBackingStore and QWindowsBackingStore to support Qt::WA_StaticContents QWidgetBackingStore::staticContents() was updated for windows to *not* unconditionally return false. It now returns true if it has a non-empty static widgets list. QWindowsBackingStore::resize(...) was updated to honor the provided static contents region. It now copies the static region into the new backbuffer in a manner similar to what was done in Qt4. The difference is that this version accounts for the possibility of the new buffer having a smaller region than the old buffer. In Qt4 the ::prepareBuffer method was only called when the buffer was resized larger. Change-Id: I135ff8fb16f52759089f1e7353426303c4504db3 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/windows/qwindowsbackingstore.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index 26205eb146..55e7b85d96 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -149,7 +149,23 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) QImage::Format format = QWindowsNativeImage::systemFormat(); if (format == QImage::Format_RGB32 && rasterWindow()->window()->format().hasAlpha()) format = QImage::Format_ARGB32_Premultiplied; - m_image.reset(new QWindowsNativeImage(size.width(), size.height(), format)); + + QWindowsNativeImage *oldwni = m_image.data(); + QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); + + if (oldwni && !region.isEmpty()) { + const QImage &oldimg(oldwni->image()); + QImage &newimg(newwni->image()); + QRegion staticRegion(region); + staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height()); + staticRegion &= QRect(0, 0, newimg.width(), newimg.height()); + QPainter painter(&newimg); + painter.setCompositionMode(QPainter::CompositionMode_Source); + foreach (const QRect &rect, staticRegion.rects()) + painter.drawImage(rect, oldimg, rect); + } + + m_image.reset(newwni); } } -- cgit v1.2.3 From 953d85e049786ddb5666d03b96da57fd546b9368 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 14 Nov 2013 09:58:25 +0100 Subject: iOS: scroll screen when keyboard opens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will let QIOSInputContext scroll the root view when the virtual keyboard is open, so that the input cursor is not obscured. Change-Id: If0758f4bf04c2b8e554e0196451154def7e3cb86 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 1 + src/plugins/platforms/ios/qiosinputcontext.mm | 123 ++++++++++++++++++++++++-- src/plugins/platforms/ios/qioswindow.mm | 21 +++-- 3 files changed, 131 insertions(+), 14 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index f03b13d002..6ad2a808a6 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -62,6 +62,7 @@ public: bool isInputPanelVisible() const; void focusWindowChanged(QWindow *focusWindow); + void scrollRootView(); private: QIOSKeyboardListener *m_keyboardListener; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index ed17dee0c9..7aee1f9bd6 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -48,7 +48,12 @@ @public QIOSInputContext *m_context; BOOL m_keyboardVisible; + BOOL m_keyboardVisibleAndDocked; QRectF m_keyboardRect; + QRectF m_keyboardEndRect; + NSTimeInterval m_duration; + UIViewAnimationCurve m_curve; + UIViewController *m_viewController; } @end @@ -60,8 +65,30 @@ if (self) { m_context = context; m_keyboardVisible = NO; - // After the keyboard became undockable (iOS5), UIKeyboardWillShow/UIKeyboardWillHide - // no longer works for all cases. So listen to keyboard frame changes instead: + m_keyboardVisibleAndDocked = NO; + m_duration = 0; + m_curve = UIViewAnimationCurveEaseOut; + m_viewController = 0; + + if (isQtApplication()) { + // Get the root view controller that is on the same screen as the keyboard: + for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) { + if (uiWindow.screen == [UIScreen mainScreen]) { + m_viewController = [uiWindow.rootViewController retain]; + break; + } + } + Q_ASSERT(m_viewController); + } + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardWillShow:) + name:@"UIKeyboardWillShowNotification" object:nil]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(keyboardWillHide:) + name:@"UIKeyboardWillHideNotification" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidChangeFrame:) @@ -72,25 +99,68 @@ - (void) dealloc { + [m_viewController release]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIKeyboardWillShowNotification" object:nil]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:@"UIKeyboardWillHideNotification" object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIKeyboardDidChangeFrameNotification" object:nil]; [super dealloc]; } -- (void) keyboardDidChangeFrame:(NSNotification *)notification +- (QRectF) getKeyboardRect:(NSNotification *)notification { - CGRect frame; - [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&frame]; + // For Qt applications we rotate the keyboard rect to align with the screen + // orientation (which is the interface orientation of the root view controller). + // For hybrid apps we follow native behavior, and return the rect unmodified: + CGRect keyboardFrame = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; + if (isQtApplication()) { + UIView *view = m_viewController.view; + return fromCGRect(CGRectOffset([view convertRect:keyboardFrame fromView:view.window], 0, -view.bounds.origin.y)); + } else { + return fromCGRect(keyboardFrame); + } +} - m_keyboardRect = fromPortraitToPrimary(fromCGRect(frame), QGuiApplication::primaryScreen()->handle()); +- (void) keyboardDidChangeFrame:(NSNotification *)notification +{ + m_keyboardRect = [self getKeyboardRect:notification]; m_context->emitKeyboardRectChanged(); - BOOL visible = CGRectIntersectsRect(frame, [UIScreen mainScreen].bounds); + BOOL visible = m_keyboardRect.intersects(fromCGRect([UIScreen mainScreen].bounds)); if (m_keyboardVisible != visible) { m_keyboardVisible = visible; m_context->emitInputPanelVisibleChanged(); } + + // If the keyboard was visible and docked from before, this is just a geometry + // change (normally caused by an orientation change). In that case, update scroll: + if (m_keyboardVisibleAndDocked) + m_context->scrollRootView(); +} + +- (void) keyboardWillShow:(NSNotification *)notification +{ + // Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked. + m_keyboardVisibleAndDocked = YES; + m_keyboardEndRect = [self getKeyboardRect:notification]; + if (!m_duration) { + m_duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + m_curve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16; + } + m_context->scrollRootView(); +} + +- (void) keyboardWillHide:(NSNotification *)notification +{ + // Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked. + m_keyboardVisibleAndDocked = NO; + m_keyboardEndRect = [self getKeyboardRect:notification]; + m_context->scrollRootView(); } @end @@ -101,6 +171,8 @@ QIOSInputContext::QIOSInputContext() , m_focusView(0) , m_hasPendingHideRequest(false) { + if (isQtApplication()) + connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::scrollRootView); connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSInputContext::focusWindowChanged); } @@ -151,3 +223,40 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow) [m_focusView release]; m_focusView = [view retain]; } + +void QIOSInputContext::scrollRootView() +{ + // Scroll the root view (screen) if: + // - our backend controls the root view controller on the main screen (no hybrid app) + // - the focus object is on the same screen as the keyboard. + // - the first responder is a QUIView, and not some other foreign UIView. + // - the keyboard is docked. Otherwise the user can move the keyboard instead. + if (!isQtApplication() || !m_focusView) + return; + + UIView *view = m_keyboardListener->m_viewController.view; + qreal scrollTo = 0; + + if (m_focusView.isFirstResponder + && m_keyboardListener->m_keyboardVisibleAndDocked + && m_focusView.window == view.window) { + QRectF cursorRect = qGuiApp->inputMethod()->cursorRectangle(); + cursorRect.translate(qGuiApp->focusWindow()->geometry().topLeft()); + qreal keyboardY = m_keyboardListener->m_keyboardEndRect.y(); + int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y(); + const int margin = 20; + + if (cursorRect.bottomLeft().y() > keyboardY - margin) + scrollTo = qMin(view.bounds.size.height - keyboardY, cursorRect.y() - statusBarY - margin); + } + + if (scrollTo != view.bounds.origin.y) { + // Scroll the view the same way a UIScrollView works: by changing bounds.origin: + CGRect newBounds = view.bounds; + newBounds.origin.y = scrollTo; + [UIView animateWithDuration:m_keyboardListener->m_duration delay:0 + options:m_keyboardListener->m_curve + animations:^{ view.bounds = newBounds; } + completion:0]; + } +} diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 8124d8ffb9..7030df5d32 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -181,11 +181,14 @@ QRect actualGeometry; if (m_qioswindow->window()->isTopLevel()) { UIWindow *uiWindow = self.window; + UIView *rootView = uiWindow.rootViewController.view; CGRect rootViewPositionInRelationToRootViewController = - [uiWindow.rootViewController.view convertRect:uiWindow.bounds fromView:uiWindow]; + [rootView convertRect:uiWindow.bounds fromView:uiWindow]; - actualGeometry = fromCGRect(CGRectOffset([self.superview convertRect:self.frame toView:uiWindow.rootViewController.view], - -rootViewPositionInRelationToRootViewController.origin.x, -rootViewPositionInRelationToRootViewController.origin.y)); + actualGeometry = fromCGRect(CGRectOffset([self.superview convertRect:self.frame toView:rootView], + -rootViewPositionInRelationToRootViewController.origin.x, + -rootViewPositionInRelationToRootViewController.origin.y + + rootView.bounds.origin.y)); } else { actualGeometry = fromCGRect(self.frame); } @@ -515,13 +518,17 @@ void QIOSWindow::applyGeometry(const QRect &rect) if (window()->isTopLevel()) { // The QWindow is in QScreen coordinates, which maps to a possibly rotated root-view-controller. // Since the root-view-controller might be translated in relation to the UIWindow, we need to - // check specifically for that and compensate. + // check specifically for that and compensate. Also check if the root view has been scrolled + // as a result of the keyboard being open. UIWindow *uiWindow = m_view.window; + UIView *rootView = uiWindow.rootViewController.view; CGRect rootViewPositionInRelationToRootViewController = - [uiWindow.rootViewController.view convertRect:uiWindow.bounds fromView:uiWindow]; + [rootView convertRect:uiWindow.bounds fromView:uiWindow]; - m_view.frame = CGRectOffset([m_view.superview convertRect:toCGRect(rect) fromView:m_view.window.rootViewController.view], - rootViewPositionInRelationToRootViewController.origin.x, rootViewPositionInRelationToRootViewController.origin.y); + m_view.frame = CGRectOffset([m_view.superview convertRect:toCGRect(rect) fromView:rootView], + rootViewPositionInRelationToRootViewController.origin.x, + rootViewPositionInRelationToRootViewController.origin.y + + rootView.bounds.origin.y); } else { // Easy, in parent's coordinates m_view.frame = toCGRect(rect); -- cgit v1.2.3 From 0bfc1c8647c0137de08c5f9b44b1c7be44a44c7d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 20 Nov 2013 22:14:40 +0100 Subject: iOS: don't scroll after inputItem has moved MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the inputItem moves, it typically means that the user scrolls or flicks the focus item around. In that case we should avoid scrolling the screen, otherwise they will "cancel out" each other. Besides, when the user flicks, he takes control over the whereabouts on the screen anyway. Change-Id: Iad0762965f9dcdbcca934ce6d90a8c1413ce3ca2 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 3 +++ src/plugins/platforms/ios/qiosinputcontext.mm | 13 +++++++++++++ 2 files changed, 16 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 6ad2a808a6..3caadac29d 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -44,6 +44,7 @@ #include +#include #include QT_BEGIN_NAMESPACE @@ -60,6 +61,7 @@ public: void showInputPanel(); void hideInputPanel(); bool isInputPanelVisible() const; + void setFocusObject(QObject *object); void focusWindowChanged(QWindow *focusWindow); void scrollRootView(); @@ -67,6 +69,7 @@ public: private: QIOSKeyboardListener *m_keyboardListener; UIView *m_focusView; + QTransform m_inputItemTransform; bool m_hasPendingHideRequest; }; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 7aee1f9bd6..547f405a01 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -215,6 +215,12 @@ bool QIOSInputContext::isInputPanelVisible() const return m_keyboardListener->m_keyboardVisible; } +void QIOSInputContext::setFocusObject(QObject *) +{ + m_inputItemTransform = qApp->inputMethod()->inputItemTransform(); + scrollRootView(); +} + void QIOSInputContext::focusWindowChanged(QWindow *focusWindow) { UIView *view = reinterpret_cast *>(focusWindow->handle()->winId()); @@ -231,9 +237,16 @@ void QIOSInputContext::scrollRootView() // - the focus object is on the same screen as the keyboard. // - the first responder is a QUIView, and not some other foreign UIView. // - the keyboard is docked. Otherwise the user can move the keyboard instead. + // - the inputItem has not been moved/scrolled if (!isQtApplication() || !m_focusView) return; + if (m_inputItemTransform != qApp->inputMethod()->inputItemTransform()) { + // The inputItem has moved since the last scroll update. To avoid competing + // with the application where the cursor/inputItem should be, we bail: + return; + } + UIView *view = m_keyboardListener->m_viewController.view; qreal scrollTo = 0; -- cgit v1.2.3 From 99474206f4538799f896c9bfc8fce8d676aded26 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 22 Nov 2013 17:41:39 +0100 Subject: iOS: don't loose precision when converting CG types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CGRect and CGPoint consist of CGFloat variables. So we should convert to QRectF and QPointF rather than QRect and QPoint. Change-Id: I76f180e4064f54d5810c49b88fdbbcd914bdb686 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosglobal.h | 9 +++++---- src/plugins/platforms/ios/qiosglobal.mm | 12 ++++++------ src/plugins/platforms/ios/qiosscreen.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 8 ++++---- 4 files changed, 16 insertions(+), 15 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 41b0d7f93a..1c76d29389 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -53,10 +53,11 @@ class QPlatformScreen; bool isQtApplication(); -CGRect toCGRect(const QRect &rect); -QRect fromCGRect(const CGRect &rect); -CGPoint toCGPoint(const QPoint &point); -QPoint fromCGPoint(const CGPoint &point); +CGRect toCGRect(const QRectF &rect); +QRectF fromCGRect(const CGRect &rect); +CGPoint toCGPoint(const QPointF &point); +QPointF fromCGPoint(const CGPoint &point); + Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation); UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation); QRect fromPortraitToPrimary(const QRect &rect, QPlatformScreen *screen); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index be68e4d7d5..d749b8f514 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -58,24 +58,24 @@ bool isQtApplication() return isQt; } -CGRect toCGRect(const QRect &rect) +CGRect toCGRect(const QRectF &rect) { return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); } -QRect fromCGRect(const CGRect &rect) +QRectF fromCGRect(const CGRect &rect) { - return QRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); + return QRectF(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); } -CGPoint toCGPoint(const QPoint &point) +CGPoint toCGPoint(const QPointF &point) { return CGPointMake(point.x(), point.y()); } -QPoint fromCGPoint(const CGPoint &point) +QPointF fromCGPoint(const CGPoint &point) { - return QPoint(point.x, point.y); + return QPointF(point.x, point.y); } Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientation) diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 42c3e13e7e..b8f4e387ed 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -158,7 +158,7 @@ void QIOSScreen::updateProperties() } bool inPortrait = UIInterfaceOrientationIsPortrait(uiWindow.rootViewController.interfaceOrientation); - QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds) + QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds).toRect() : QRect(m_uiScreen.bounds.origin.x, m_uiScreen.bounds.origin.y, m_uiScreen.bounds.size.height, m_uiScreen.bounds.size.width); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 7030df5d32..d03889abb6 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -188,9 +188,9 @@ actualGeometry = fromCGRect(CGRectOffset([self.superview convertRect:self.frame toView:rootView], -rootViewPositionInRelationToRootViewController.origin.x, -rootViewPositionInRelationToRootViewController.origin.y - + rootView.bounds.origin.y)); + + rootView.bounds.origin.y)).toRect(); } else { - actualGeometry = fromCGRect(self.frame); + actualGeometry = fromCGRect(self.frame).toRect(); } // Persist the actual/new geometry so that QWindow::geometry() can @@ -214,7 +214,7 @@ - (void)displayLayer:(CALayer *)layer { - QRect geometry = fromCGRect(layer.frame); + QRect geometry = fromCGRect(layer.frame).toRect(); Q_ASSERT(m_qioswindow->geometry() == geometry); Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); @@ -242,7 +242,7 @@ } else { touchPoint.state = state; touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0; - QPoint touchPos = fromCGPoint([uiTouch locationInView:rootView]); + QPoint touchPos = fromCGPoint([uiTouch locationInView:rootView]).toPoint(); touchPoint.area = QRectF(touchPos, QSize(0, 0)); touchPoint.normalPosition = QPointF(touchPos.x() / rootViewSize.width, touchPos.y() / rootViewSize.height); } -- cgit v1.2.3 From bdf0670c0299dbefb0dbd5c5937320574233e551 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 25 Nov 2013 11:30:56 +0100 Subject: iOS: add [QUIView updateTextInputTraits] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Configure QUIView text input traits from IM hints returned by the focus object when the view becomes first responder. This will affect the layout of the virtual keyboard. Change-Id: Ib140ba69d01cc747f3ac3cdd70dd2e7daede26b0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 52 +++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index d03889abb6..e53ab189ca 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -108,15 +108,7 @@ [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; - // Set up text input - autocapitalizationType = UITextAutocapitalizationTypeNone; - autocorrectionType = UITextAutocorrectionTypeNo; - enablesReturnKeyAutomatically = NO; - keyboardAppearance = UIKeyboardAppearanceDefault; - keyboardType = UIKeyboardTypeDefault; - returnKeyType = UIReturnKeyDone; - secureTextEntry = NO; - m_nextTouchId = 0; + [self updateTextInputTraits]; if (isQtApplication()) self.hidden = YES; @@ -343,6 +335,7 @@ // user cannot type. And since the keyboard will open when a view becomes // the first responder, it's now a good time to inform QPA that the QWindow // this view backs became active: + [self updateTextInputTraits]; QWindowSystemInterface::handleWindowActivated(m_qioswindow->window()); return [super becomeFirstResponder]; } @@ -384,6 +377,47 @@ 0, QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier); } +- (void)updateTextInputTraits +{ + // Ask the current focus object what kind of input it + // expects, and configure the keyboard appropriately: + QObject *focusObject = QGuiApplication::focusObject(); + if (!focusObject) + return; + QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints); + if (!QCoreApplication::sendEvent(focusObject, &queryEvent)) + return; + if (!queryEvent.value(Qt::ImEnabled).toBool()) + return; + + Qt::InputMethodHints hints = static_cast(queryEvent.value(Qt::ImHints).toUInt()); + + self.returnKeyType = (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone; + self.secureTextEntry = BOOL(hints & Qt::ImhHiddenText); + self.autocorrectionType = (hints & Qt::ImhNoPredictiveText) ? + UITextAutocorrectionTypeNo : UITextAutocorrectionTypeDefault; + + if (hints & Qt::ImhUppercaseOnly) + self.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters; + else if (hints & Qt::ImhNoAutoUppercase) + self.autocapitalizationType = UITextAutocapitalizationTypeNone; + else + self.autocapitalizationType = UITextAutocapitalizationTypeSentences; + + if (hints & Qt::ImhUrlCharactersOnly) + self.keyboardType = UIKeyboardTypeURL; + else if (hints & Qt::ImhEmailCharactersOnly) + self.keyboardType = UIKeyboardTypeEmailAddress; + else if (hints & Qt::ImhDigitsOnly) + self.keyboardType = UIKeyboardTypeNumberPad; + else if (hints & Qt::ImhFormattedNumbersOnly) + self.keyboardType = UIKeyboardTypeDecimalPad; + else if (hints & Qt::ImhDialableCharactersOnly) + self.keyboardType = UIKeyboardTypeNumberPad; + else + self.keyboardType = UIKeyboardTypeDefault; +} + @end @implementation UIView (QIOS) -- cgit v1.2.3 From 484d6ce7764183b6d215310735eeef3e23332d1d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Sat, 16 Nov 2013 10:59:17 +0100 Subject: iOS: update keyboard layout upon focus transfer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When iOS transfers focus from one view to another, it asks the new view for its UIKeyInput properties before deciding how the keyboard should be configured. For Qt, the same QUIView is used for the whole QWindow which means that UIKit will not change the keyboard configuration just because we change the focus object in Qt, since the UIView does not change. There seems to be no way to tell UIKit that the keyboard needs to change becuse the UIKeyInput properties has changed. To work around this, we briefly resign first responder status, and grabs it again, for the same QUIView. Change-Id: I2d15cc0c928deb023e7da58ad4669b7099dce2cf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 1 + src/plugins/platforms/ios/qiosinputcontext.mm | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 3caadac29d..533ba686e1 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -71,6 +71,7 @@ private: UIView *m_focusView; QTransform m_inputItemTransform; bool m_hasPendingHideRequest; + bool m_inSetFocusObject; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 547f405a01..0e43429015 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -170,6 +170,7 @@ QIOSInputContext::QIOSInputContext() , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) , m_focusView(0) , m_hasPendingHideRequest(false) + , m_inSetFocusObject(false) { if (isQtApplication()) connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::scrollRootView); @@ -218,7 +219,22 @@ bool QIOSInputContext::isInputPanelVisible() const void QIOSInputContext::setFocusObject(QObject *) { m_inputItemTransform = qApp->inputMethod()->inputItemTransform(); - scrollRootView(); + + if (!m_focusView || !m_focusView.isFirstResponder) + return; + + // Since m_focusView is the first responder, it means that the keyboard is open and we + // should update keyboard layout. But there seem to be no way to tell it to reread the + // UITextInputTraits from m_focusView. To work around that, we quickly resign first + // responder status just to reassign it again. To not remove the focusObject in the same + // go, we need to call the super implementation of resignFirstResponder. Since the call + // will cause a 'keyboardWillHide' notification to be sendt, we also block scrollRootView + // to avoid artifacts: + m_inSetFocusObject = true; + SEL sel = @selector(resignFirstResponder); + [[m_focusView superclass] instanceMethodForSelector:sel](m_focusView, sel); + m_inSetFocusObject = false; + [m_focusView becomeFirstResponder]; } void QIOSInputContext::focusWindowChanged(QWindow *focusWindow) @@ -238,7 +254,7 @@ void QIOSInputContext::scrollRootView() // - the first responder is a QUIView, and not some other foreign UIView. // - the keyboard is docked. Otherwise the user can move the keyboard instead. // - the inputItem has not been moved/scrolled - if (!isQtApplication() || !m_focusView) + if (!isQtApplication() || !m_focusView || m_inSetFocusObject) return; if (m_inputItemTransform != qApp->inputMethod()->inputItemTransform()) { -- cgit v1.2.3 From b61928e646fbcdbc8367f9231e23b22cebf2e4fb Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 25 Nov 2013 16:53:20 +0100 Subject: iOS: close keyboard upon hitting key 'done' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0098cc4d51ca600ba48baa15ed9c16e56529b947 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e53ab189ca..66552fae4f 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -358,8 +358,11 @@ { QString string = QString::fromUtf8([text UTF8String]); int key = 0; - if ([text isEqualToString:@"\n"]) + if ([text isEqualToString:@"\n"]) { key = (int)Qt::Key_Return; + if (self.returnKeyType == UIReturnKeyDone) + [self resignFirstResponder]; + } // Send key event to window system interface QWindowSystemInterface::handleKeyEvent( -- cgit v1.2.3 From 6318a6879db56e804108b1bea08fc3dee7d3b62a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 22 Nov 2013 13:15:35 +0100 Subject: iOS: Don't enable translucent statusbar for iOS6 on iPads It's only available on iPhone/iPods. Change-Id: I61b45c84ddb2b3db46fff36286a6582406fa7d26 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index e325666f69..cf702c82af 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -58,6 +58,7 @@ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; +#if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_7_0) QSysInfo::MacVersion iosVersion = QSysInfo::MacintoshVersion; // We prefer to keep the root viewcontroller in fullscreen layout, so that @@ -67,12 +68,14 @@ if (iosVersion < QSysInfo::MV_IOS_7_0) self.window.rootViewController.wantsFullScreenLayout = YES; - // Use translucent statusbar by default on iOS6 (unless the user changed the - // default in the Info.plist), so that windows placed under the stausbar are + // Use translucent statusbar by default on iOS6 iPhones (unless the user changed + // the default in the Info.plist), so that windows placed under the stausbar are // still visible, just like on iOS7. if (iosVersion >= QSysInfo::MV_IOS_6_0 && iosVersion < QSysInfo::MV_IOS_7_0 + && [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone && [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault) [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent]; +#endif self.window.hidden = NO; -- cgit v1.2.3 From 8f324765425fdc4d2ecd9c82ec505d22f057358f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 22 Nov 2013 13:16:14 +0100 Subject: iOS: Don't warn about QBackingStore::resize() != window.size() for widgets QtWidgets uses stale geometry data to do its backingstore resizes in a lot of places, eg QWidgetPrivate::setGeometry_sys() and show_sys(). As the resize doesn't have any effect for our GL backingstore anyways we can skip the warning to keep console noise down. Change-Id: Ie578f7faf35985708fddd0bfca4a7080820192c5 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Gunnar Sletta --- src/plugins/platforms/ios/qiosbackingstore.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index 80b603bb8e..5ea5fbd8d1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -117,7 +117,7 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) // backing store and always keep the paint device's size in sync with the // window size in beginPaint(). - if (size != window()->size()) + if (size != window()->size() && !window()->inherits("QWidgetWindow")) qWarning() << "QIOSBackingStore needs to have the same size as its window"; } -- cgit v1.2.3 From 6820ac594af949527d17d0b32205377fc767f527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 25 Nov 2013 15:07:21 +0100 Subject: iOS: Prefer window states over geometry-heuristics when laying out windows A window that was resized to the full screen size of the screen would otherwise always stay in full screen, even if the window state was maximized. Change-Id: I4720f7b6ad1d85658ea96c6da0515693e8c827f3 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index b8f4e387ed..7746163357 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -231,9 +231,13 @@ void QIOSScreen::layoutWindows() if (!platformWindow) continue; - if (window->windowState() & Qt::WindowFullScreen || window->geometry() == oldGeometry) + // FIXME: Handle more complex cases of no-state and/or child windows when rotating + + if (window->windowState() & Qt::WindowFullScreen + || (window->windowState() & Qt::WindowNoState && window->geometry() == oldGeometry)) platformWindow->applyGeometry(newGeometry); - else if (window->windowState() & Qt::WindowMaximized || window->geometry() == oldAvailableGeometry) + else if (window->windowState() & Qt::WindowMaximized + || (window->windowState() & Qt::WindowNoState && window->geometry() == oldAvailableGeometry)) platformWindow->applyGeometry(newAvailableGeometry); } } -- cgit v1.2.3 From c2f08598e1cc3089505dd8037d333071da0f231f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 25 Nov 2013 15:45:43 +0100 Subject: iOS: Update statusbar visibility and screen properties before window geometry When setting a new window state. Otherwise we set the geometry based on the old screen properties, and then rely on the properties causing another window layout, which may not always happen. We also need to explicitly update the screen properties when the statusbar changes visibility, as there are no callbacks from iOS that consistently gives us that information. Change-Id: I1c3328aa3f34d294bc7db8884e611d205fd2c761 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.mm | 4 ++++ src/plugins/platforms/ios/qioswindow.mm | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 7746163357..57522cb1a3 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -205,10 +205,14 @@ void QIOSScreen::updateStatusBarVisibility() } else #endif { + bool wasHidden = [UIApplication sharedApplication].statusBarHidden; QIOSViewController *viewController = static_cast(view.viewController); [[UIApplication sharedApplication] setStatusBarHidden:[viewController prefersStatusBarHidden] withAnimation:UIStatusBarAnimationNone]; + + if ([UIApplication sharedApplication].statusBarHidden != wasHidden) + updateProperties(); } } diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 66552fae4f..0dd810bdf6 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -581,6 +581,14 @@ void QIOSWindow::applyGeometry(const QRect &rect) void QIOSWindow::setWindowState(Qt::WindowState state) { + // Update the QWindow representation straight away, so that + // we can update the statusbar visibility based on the new + // state before applying geometry changes. + qt_window_private(window())->windowState = state; + + if (window()->isTopLevel() && window()->isVisible() && window()->isActive()) + static_cast(screen())->updateStatusBarVisibility(); + switch (state) { case Qt::WindowNoState: applyGeometry(m_normalGeometry); @@ -599,14 +607,6 @@ void QIOSWindow::setWindowState(Qt::WindowState state) default: Q_UNREACHABLE(); } - - if (window()->isTopLevel() && window()->isVisible() && window()->isActive()) { - // The window state of the QWindow is not updated until after - // we return from this method, so we have to defer any updates - // of the statusbar that depend on the current window state. - QMetaObject::invokeMethod(static_cast(screen()), - "updateStatusBarVisibility", Qt::QueuedConnection); - } } void QIOSWindow::setParent(const QPlatformWindow *parentWindow) -- cgit v1.2.3 From b84072a431c83d61298b43d8669bb21d00c14f68 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 22 Nov 2013 13:02:23 +0100 Subject: Fix compiler warnings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As seen with Xcode 5.0.2. qmacclipboard.mm:108:30: warning: cast to 'void *' from smaller integer type 'int' [-Wint-to-void-pointer-cast] promiseKeeper(paste, (PasteboardItemID)promise.itemId, flavor, this); ^ qmacclipboard.mm:316:56: warning: cast to 'void *' from smaller integer type 'int' [-Wint-to-void-pointer-cast] PasteboardPutItemFlavor(paste, (PasteboardItemID)itemID, QCFString(flavor), 0, kPasteboardFlavorNoFlags); ^ Change-Id: I94b8ea2ff32d606d4cab28981b26c2ef516035dc Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qmacclipboard.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 95143fd8ea..b5c50d676f 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -105,7 +105,8 @@ QMacPasteboard::~QMacPasteboard() for (int i = 0; i < promises.count(); ++i) { const Promise &promise = promises.at(i); QCFString flavor = QCFString(promise.convertor->flavorFor(promise.mime)); - promiseKeeper(paste, (PasteboardItemID)promise.itemId, flavor, this); + NSInteger pbItemId = promise.itemId; + promiseKeeper(paste, reinterpret_cast(pbItemId), flavor, this); } if (paste) @@ -311,9 +312,9 @@ QMacPasteboard::setMimeData(QMimeData *mime_src) int numItems = c->count(mime_src); for (int item = 0; item < numItems; ++item) { - const int itemID = item+1; //id starts at 1 + const NSInteger itemID = item+1; //id starts at 1 promises.append(QMacPasteboard::Promise(itemID, c, mimeType, mimeData, item)); - PasteboardPutItemFlavor(paste, (PasteboardItemID)itemID, QCFString(flavor), 0, kPasteboardFlavorNoFlags); + PasteboardPutItemFlavor(paste, reinterpret_cast(itemID), QCFString(flavor), 0, kPasteboardFlavorNoFlags); #ifdef DEBUG_PASTEBOARD qDebug(" - adding %d %s [%s] <%s> [%d]", itemID, qPrintable(mimeType), qPrintable(flavor), qPrintable(c->convertorName()), item); -- cgit v1.2.3