summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-05-29 10:06:10 +0200
committerLiang Qi <liang.qi@qt.io>2017-05-29 10:54:41 +0200
commit6a772fd201ac738dc86e71bd82e98f65158e6335 (patch)
tree674007720f41d27b251bbcffd7a368a93f88eb96 /src/plugins/platforms
parent40206a9f6d7635bb19305d1c8d74908808e3529e (diff)
parent4c346b6e2bfab976bc9b16275b8382aee38aefa4 (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: .qmake.conf mkspecs/common/msvc-desktop.conf mkspecs/win32-g++/qmake.conf mkspecs/win32-icc/qmake.conf src/platformsupport/fontdatabases/mac/coretext.pri src/plugins/platforms/cocoa/qcocoawindow.h src/plugins/platforms/cocoa/qcocoawindow.mm Change-Id: I74a6f7705c9547ed8bbac7260eb4645543e32655
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm22
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm96
-rw-r--r--src/plugins/platforms/ios/qiostextresponder.mm11
-rw-r--r--src/plugins/platforms/qnx/qnx.pro2
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp6
-rw-r--r--src/plugins/platforms/windows/windows.pri11
10 files changed, 132 insertions, 28 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 6001a845e8..7e6bae127c 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -509,7 +509,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
// actions
- (NSArray *)accessibilityActionNames {
- NSMutableArray * nsActions = [NSMutableArray new];
+ NSMutableArray *nsActions = [[NSMutableArray new] autorelease];
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface || !iface->isValid())
return nsActions;
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index 4870ca4103..0725e9db68 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -83,7 +83,7 @@ private:
QList<QPointer<QCocoaMenu> > m_menus;
NSMenu *m_nativeMenu;
- QCocoaWindow *m_window;
+ QPointer<QCocoaWindow> m_window;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index a95ffc2f9f..82c405baa6 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -52,8 +52,7 @@ QT_BEGIN_NAMESPACE
static QList<QCocoaMenuBar*> static_menubars;
-QCocoaMenuBar::QCocoaMenuBar() :
- m_window(0)
+QCocoaMenuBar::QCocoaMenuBar()
{
static_menubars.append(this);
@@ -79,7 +78,7 @@ QCocoaMenuBar::~QCocoaMenuBar()
[m_nativeMenu release];
static_menubars.removeOne(this);
- if (m_window && m_window->menubar() == this) {
+ if (!m_window.isNull() && m_window->menubar() == this) {
m_window->setMenubar(0);
// Delete the children first so they do not cause
@@ -92,9 +91,10 @@ QCocoaMenuBar::~QCocoaMenuBar()
bool QCocoaMenuBar::needsImmediateUpdate()
{
- if (m_window && m_window->window()->isActive()) {
- return true;
- } else if (!m_window) {
+ if (!m_window.isNull()) {
+ if (m_window->window()->isActive())
+ return true;
+ } else {
// Only update if the focus/active window has no
// menubar, which means it'll be using this menubar.
// This is to avoid a modification in a parentless
@@ -221,11 +221,11 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
qDebug() << "QCocoaMenuBar" << this << "handleReparent" << newParentWindow;
#endif
- if (m_window)
- m_window->setMenubar(NULL);
+ if (!m_window.isNull())
+ m_window->setMenubar(nullptr);
- if (newParentWindow == NULL) {
- m_window = NULL;
+ if (newParentWindow == nullptr) {
+ m_window.clear();
} else {
newParentWindow->create();
m_window = static_cast<QCocoaWindow*>(newParentWindow->handle());
@@ -246,7 +246,7 @@ QCocoaWindow *QCocoaMenuBar::findWindowForMenubar()
QCocoaMenuBar *QCocoaMenuBar::findGlobalMenubar()
{
foreach (QCocoaMenuBar *mb, static_menubars) {
- if (mb->m_window == NULL)
+ if (mb->m_window.isNull())
return mb;
}
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index b06fd7d946..0833aa785f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -302,6 +302,7 @@ public: // for QNSView
bool isContentView() const;
bool isChildNSWindow() const;
+ bool alwaysShowToolWindow() const;
void removeMonitor();
NSView *m_view;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 6e06af8490..2cdcb4b503 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -291,6 +291,8 @@ static void qt_closePopups()
- (void)closeAndRelease
{
+ qCDebug(lcQpaCocoaWindow) << "closeAndRelease" << self;
+
[self close];
if (self.helper.grabbingMouse) {
@@ -315,6 +317,71 @@ static void qt_closePopups()
@synthesize helper = _helper;
++ (void)applicationActivationChanged:(NSNotification*)notification
+{
+ const id sender = self;
+ NSEnumerator<NSWindow*> *windowEnumerator = nullptr;
+ NSApplication *application = [NSApplication sharedApplication];
+
+#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12)
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSSierra) {
+ // Unfortunately there's no NSWindowListOrderedBackToFront,
+ // so we have to manually reverse the order using an array.
+ NSMutableArray *windows = [[[NSMutableArray alloc] init] autorelease];
+ [application enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack
+ usingBlock:^(NSWindow *window, BOOL *) {
+ // For some reason AppKit will give us nil-windows, skip those
+ if (!window)
+ return;
+
+ [(NSMutableArray*)windows addObject:window];
+ }
+ ];
+
+ windowEnumerator = windows.reverseObjectEnumerator;
+ } else
+#endif
+ {
+ // No way to get ordered list of windows, so fall back to unordered,
+ // list, which typically corresponds to window creation order.
+ windowEnumerator = application.windows.objectEnumerator;
+ }
+
+ for (NSWindow *window in windowEnumerator) {
+ // We're meddling with normal and floating windows, so leave others alone
+ if (!(window.level == NSNormalWindowLevel || window.level == NSFloatingWindowLevel))
+ continue;
+
+ // Windows that hide automatically will keep their NSFloatingWindowLevel,
+ // and hence be on top of the window stack. We don't want to affect these
+ // windows, as otherwise we might end up with key windows being ordered
+ // behind these auto-hidden windows when activating the application by
+ // clicking on a new tool window.
+ if (window.hidesOnDeactivate)
+ continue;
+
+ if ([window conformsToProtocol:@protocol(QNSWindowProtocol)]) {
+ QCocoaWindow *cocoaWindow = static_cast<id<QNSWindowProtocol>>(window).helper.platformWindow;
+ window.level = notification.name == NSApplicationWillResignActiveNotification ?
+ NSNormalWindowLevel : cocoaWindow->windowLevel(cocoaWindow->window()->flags());
+ }
+
+ // The documentation says that "when a window enters a new level, it’s ordered
+ // in front of all its peers in that level", but that doesn't seem to be the
+ // case in practice. To keep the order correct after meddling with the window
+ // levels, we explicitly order each window to the front. Since we are iterating
+ // the windows in back-to-front order, this is okey. The call also triggers AppKit
+ // to re-evaluate the level in relation to windows from other applications,
+ // working around an issue where our tool windows would stay on top of other
+ // application windows if activation was transferred to another application by
+ // clicking on it instead of via the application switcher or Dock. Finally, we
+ // do this re-ordering for all windows (except auto-hiding ones), otherwise we would
+ // end up triggering a bug in AppKit where the tool windows would disappear behind
+ // the application window.
+ [window orderFront:sender];
+ }
+}
+
- (id)initWithContentRect:(NSRect)contentRect
screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
@@ -328,6 +395,17 @@ static void qt_closePopups()
if (self) {
_helper = [[QNSWindowHelper alloc] initWithNSWindow:self platformWindow:qpw];
+
+ if (qpw->alwaysShowToolWindow()) {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserver:[self class] selector:@selector(applicationActivationChanged:)
+ name:NSApplicationWillResignActiveNotification object:nil];
+ [center addObserver:[self class] selector:@selector(applicationActivationChanged:)
+ name:NSApplicationWillBecomeActiveNotification object:nil];
+ });
+ }
}
return self;
}
@@ -361,6 +439,8 @@ static void qt_closePopups()
- (void)closeAndRelease
{
+ qCDebug(lcQpaCocoaWindow) << "closeAndRelease" << self;
+
[self.helper detachFromPlatformWindow];
[self close];
[self release];
@@ -1595,7 +1675,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
if (isChildNSWindow() != shouldBeChildNSWindow)
recreateReason |= ChildNSWindowChanged;
- const bool shouldBeContentView = !parentWindow || shouldBeChildNSWindow;
+ const bool shouldBeContentView = (!parentWindow && !m_viewIsEmbedded) || shouldBeChildNSWindow;
if (isContentView() != shouldBeContentView)
recreateReason |= ContentViewChanged;
@@ -1612,7 +1692,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
return;
}
- qCDebug(lcQpaCocoaWindow) << "Recreating NSWindow due to" << recreateReason;
+ qCDebug(lcQpaCocoaWindow) << "Reconfiguring NSWindow due to" << recreateReason;
QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(parentWindow);
@@ -1627,6 +1707,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
// Remove current window (if any)
if ((isContentView() && !shouldBeContentView) || (recreateReason & PanelChanged)) {
+ qCDebug(lcQpaCocoaWindow) << "Getting rid of existing window" << m_nsWindow;
[m_nsWindow closeAndRelease];
if (isChildNSWindow())
[m_view.window.parentWindow removeChildWindow:m_view.window];
@@ -1654,6 +1735,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
// Move view to new NSWindow if needed
if (newWindow) {
+ qCDebug(lcQpaCocoaWindow) << "Ensuring that view is content view for" << m_nsWindow;
[m_view setPostsFrameChangedNotifications:NO];
[newWindow setContentView:m_view];
[m_view setPostsFrameChangedNotifications:YES];
@@ -1731,6 +1813,8 @@ void QCocoaWindow::requestActivateWindow()
QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel)
{
+ qCDebug(lcQpaCocoaWindow) << "createNSWindow" << shouldBeChildNSWindow << shouldBePanel;
+
QMacAutoReleasePool pool;
QRect rect = geometry();
@@ -1778,8 +1862,7 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool sh
if (shouldBePanel) {
// Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set
- window.hidesOnDeactivate = ((type & Qt::Tool) == Qt::Tool) &&
- !qt_mac_resolveOption(false, QPlatformWindow::window(), "_q_macAlwaysShowToolWindow", "");
+ window.hidesOnDeactivate = ((type & Qt::Tool) == Qt::Tool) && !alwaysShowToolWindow();
// Make popup windows show on the same desktop as the parent full-screen window
window.collectionBehavior = NSWindowCollectionBehaviorFullScreenAuxiliary;
@@ -1805,6 +1888,11 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool sh
return window;
}
+bool QCocoaWindow::alwaysShowToolWindow() const
+{
+ return qt_mac_resolveOption(false, window(), "_q_macAlwaysShowToolWindow", "");
+}
+
void QCocoaWindow::removeMonitor()
{
if (!monitor)
diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm
index 671e0f0c28..84946a5c0f 100644
--- a/src/plugins/platforms/ios/qiostextresponder.mm
+++ b/src/plugins/platforms/ios/qiostextresponder.mm
@@ -242,11 +242,12 @@
if (platformData.value(kImePlatformDataHideShortcutsBar).toBool()) {
// According to the docs, leadingBarButtonGroups/trailingBarButtonGroups should be set to nil to hide the shortcuts bar.
// However, starting with iOS 10, the API has been surrounded with NS_ASSUME_NONNULL, which contradicts this and causes
- // compiler warnings. And assigning just an empty array causes layout asserts. Hence, we assign empty button groups instead.
- UIBarButtonItemGroup *leading = [[[UIBarButtonItemGroup alloc] initWithBarButtonItems:@[] representativeItem:nil] autorelease];
- UIBarButtonItemGroup *trailing = [[[UIBarButtonItemGroup alloc] initWithBarButtonItems:@[] representativeItem:nil] autorelease];
- self.inputAssistantItem.leadingBarButtonGroups = @[leading];
- self.inputAssistantItem.trailingBarButtonGroups = @[trailing];
+ // compiler warnings. Still it is the way to go to really hide the space reserved for that.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
+ self.inputAssistantItem.leadingBarButtonGroups = nil;
+ self.inputAssistantItem.trailingBarButtonGroups = nil;
+#pragma clang diagnostic pop
}
}
#endif
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 0b052adf0f..34be6d582e 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -78,7 +78,7 @@ qtConfig(opengles2) {
HEADERS += qqnxglcontext.h \
qqnxeglwindow.h
- QMAKE_USE += egl
+ QMAKE_USE += opengl_es2 egl
}
CONFIG(qqnx_pps) {
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 0d3076a743..d35a4f0bba 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -47,6 +47,8 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
+#include <dlfcn.h>
+
#if defined(QQNXGLCONTEXT_DEBUG)
#define qGLContextDebug qDebug
#else
@@ -262,7 +264,10 @@ QFunctionPointer QQnxGLContext::getProcAddress(const char *procName)
qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
// Lookup EGL extension function pointer
- return static_cast<QFunctionPointer>(eglGetProcAddress(procName));
+ QFunctionPointer result = static_cast<QFunctionPointer>(eglGetProcAddress(procName));
+ if (!result)
+ result = reinterpret_cast<QFunctionPointer>(dlsym(RTLD_DEFAULT, procName));
+ return result;
}
bool QQnxGLContext::isSharing() const
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 818bff2693..9ac31c45df 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -894,13 +894,15 @@ void QWindowsBaseWindow::hide_sys() // Normal hide, do not activate other window
void QWindowsBaseWindow::raise_sys()
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
- SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+ if ((window()->flags() & (Qt::WindowStaysOnTopHint | Qt::WindowStaysOnBottomHint)) == 0)
+ SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
void QWindowsBaseWindow::lower_sys()
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
- SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+ if ((window()->flags() & (Qt::WindowStaysOnTopHint | Qt::WindowStaysOnBottomHint)) == 0)
+ SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
void QWindowsBaseWindow::setWindowTitle_sys(const QString &title)
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 26f9e3aefe..933cd72a67 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -1,6 +1,8 @@
# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
LIBS += -lole32 -luser32 -lwinspool -limm32 -lwinmm -loleaut32
+QT_FOR_CONFIG += gui
+
qtConfig(opengl):!qtConfig(opengles2):!qtConfig(dynamicgl): LIBS *= -lopengl32
mingw: LIBS *= -luuid
@@ -112,5 +114,10 @@ RESOURCES += $$PWD/openglblacklists.qrc
qtConfig(accessibility): include($$PWD/accessible/accessible.pri)
-DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME}
-DEFINES *= LIBGLESV2_NAME=$${LIBQTANGLE_NAME}
+qtConfig(combined-angle-lib) {
+ DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME}
+ DEFINES *= LIBGLESV2_NAME=$${LIBQTANGLE_NAME}
+} else {
+ DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME}
+ DEFINES *= LIBGLESV2_NAME=$${LIBGLESV2_NAME}
+}