summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorSergio Ahumada <sergio.ahumada@digia.com>2013-09-02 15:07:53 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-02 16:26:21 +0200
commit0a3eb0fe443f8158d81d97cde8f0c9a9632fb9f0 (patch)
tree7bbdc72a7e30e23fc66a610ff7e3cd298711e5b1 /src/plugins/platforms
parentcee7380c0470dc591e2aafb3225641d4194ab05c (diff)
parent190fa97c83472863fd886e86f626ab8196ed51b3 (diff)
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm7
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm4
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxrootwindow.cpp31
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp68
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h3
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp39
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp3
14 files changed, 124 insertions, 70 deletions
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
index d20bab7c5b..f9262c69f6 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
@@ -69,7 +69,6 @@ void QAndroidOpenGLPlatformWindow::invalidateSurface()
{
QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
QWindowSystemInterface::flushWindowSystemEvents();
- QEglFSWindow::invalidateSurface();
m_window = 0;
m_surface = 0;
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 2ac9a5dac9..9a661ffe5a 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -594,6 +594,7 @@ void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions()
if (info.session) {
[NSApp endModalSession:info.session];
info.session = 0;
+ [(NSWindow*) info.nswindow release];
}
}
currentModalSessionCached = 0;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 20f767e240..46d3b7329e 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1010,7 +1010,12 @@ qreal QCocoaWindow::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- return qreal([[m_contentView window] backingScaleFactor]);
+ NSWindow* window = [m_contentView window];
+ if (window) {
+ return qreal([window backingScaleFactor]);
+ } else {
+ return 1.0;
+ }
} else
#endif
{
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index e529e445ad..51c3953af1 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -285,6 +285,10 @@ static QTouchDevice *touchDevice = 0;
Qt::WindowState newState = notificationName == NSWindowDidMiniaturizeNotification ?
Qt::WindowMinimized : Qt::WindowNoState;
[self notifyWindowStateChanged:newState];
+ // NSWindowDidOrderOnScreenAndFinishAnimatingNotification is private API, and not
+ // emitted in 10.6, so we bring back the old behavior for that case alone.
+ if (newState == Qt::WindowNoState && QSysInfo::QSysInfo::MacintoshVersion == QSysInfo::MV_10_6)
+ m_platformWindow->exposeWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
m_platformWindow->obscureWindow();
} else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
index 133bf02fee..4c36a97ab6 100644
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
@@ -226,9 +226,14 @@ bool QQnxBpsEventFilter::handleNavigatorEvent(bps_event_t *event)
break;
case NAVIGATOR_WINDOW_THUMBNAIL:
m_navigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowMinimized);
+#if defined(Q_OS_BLACKBERRY_TABLET)
+ m_navigatorEventHandler->handleWindowGroupActivated(id);
+#endif
break;
case NAVIGATOR_WINDOW_INVISIBLE:
+#if defined(Q_OS_BLACKBERRY_TABLET)
m_navigatorEventHandler->handleWindowGroupDeactivated(id);
+#endif
break;
}
diff --git a/src/plugins/platforms/qnx/qqnxrootwindow.cpp b/src/plugins/platforms/qnx/qqnxrootwindow.cpp
index ff5866d1b7..b3f5c87176 100644
--- a/src/plugins/platforms/qnx/qqnxrootwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrootwindow.cpp
@@ -188,35 +188,8 @@ void QQnxRootWindow::makeTranslucent()
int result;
errno = 0;
- result = screen_destroy_window_buffers(m_window);
- if (result != 0) {
- qFatal("QQnxRootWindow: failed to destroy window buffer, errno=%d", errno);
- }
-
- QRect geometry = m_screen->geometry();
- errno = 0;
- int val[2];
- val[0] = geometry.width();
- val[1] = geometry.height();
- 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);
- }
-
- // Install an alpha channel on the root window.
- //
- // This is necessary in order to avoid interfering with any particular
- // toplevel widget's QQnxWindow window instance from showing transparent
- // if it desires.
- errno = 0;
- val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
+ 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);
}
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 45e565f24f..9b9576c88b 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -432,15 +432,27 @@ QQnxBuffer &QQnxWindow::renderBuffer()
// Get all buffers available for rendering
errno = 0;
screen_buffer_t buffers[MAX_BUFFER_COUNT];
- const int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
+ int result = screen_get_window_property_pv(m_window, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
if (result != 0)
qFatal("QQnxWindow: failed to query window buffers, errno=%d", errno);
- // Wrap each buffer
+ // Wrap each buffer and clear
for (int i = 0; i < MAX_BUFFER_COUNT; ++i) {
m_buffers[i] = QQnxBuffer(buffers[i]);
+
+ // Clear Buffer
+ errno = 0;
+ int bg[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END };
+ result = screen_fill(m_screen->nativeContext(), buffers[i], bg);
+ if (result != 0)
+ qFatal("QQnxWindow: failed to clear window buffer, errno=%d", errno);
}
+ errno = 0;
+ result = screen_flush_blits(m_screen->nativeContext(), 0);
+ if (result != 0)
+ qFatal("QQnxWindow: failed to flush blits, errno=%d", errno);
+
// Use the first available render buffer
m_currentBufferIndex = 0;
m_previousBufferIndex = -1;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index fc2ba454df..754d7a0288 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -395,6 +395,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
return true;
case MultipleWindows:
return true;
+ case ForeignWindows:
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index f616972aa0..530ebc38b7 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -98,35 +98,39 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM
WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p);
QWindowsScreenData data;
data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
+ data.name = QString::fromWCharArray(info.szDevice);
+ if (data.name == QLatin1String("WinDisc")) {
+ data.flags |= QWindowsScreenData::LockScreen;
+ } else {
#ifdef Q_OS_WINCE
- //Windows CE, just supports one Display and expects to get only DISPLAY,
- //instead of DISPLAY0 and so on, which are passed by info.szDevice
- HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
+ //Windows CE, just supports one Display and expects to get only DISPLAY,
+ //instead of DISPLAY0 and so on, which are passed by info.szDevice
+ HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
#else
- HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL);
+ HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL);
#endif
- if (hdc) {
- data.dpi = deviceDPI(hdc);
- data.depth = GetDeviceCaps(hdc, BITSPIXEL);
- data.format = data.depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
- data.physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
- const int refreshRate = GetDeviceCaps(hdc, VREFRESH);
- if (refreshRate > 1) // 0,1 means heardware default.
- data.refreshRateHz = refreshRate;
- DeleteDC(hdc);
- } else {
- qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.",
- __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
- data.dpi.first);
- }
+ if (hdc) {
+ data.dpi = deviceDPI(hdc);
+ data.depth = GetDeviceCaps(hdc, BITSPIXEL);
+ data.format = data.depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
+ data.physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
+ const int refreshRate = GetDeviceCaps(hdc, VREFRESH);
+ if (refreshRate > 1) // 0,1 means hardware default.
+ data.refreshRateHz = refreshRate;
+ DeleteDC(hdc);
+ } else {
+ qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.",
+ __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
+ data.dpi.first);
+ } // CreateDC() failed
+ } // not lock screen
data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
data.availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
data.orientation = data.geometry.height() > data.geometry.width() ?
Qt::PortraitOrientation : Qt::LandscapeOrientation;
// EnumDisplayMonitors (as opposed to EnumDisplayDevices) enumerates only
// virtual desktop screens.
- data.name = QString::fromWCharArray(info.szDevice);
- data.flags = QWindowsScreenData::VirtualDesktop;
+ data.flags |= QWindowsScreenData::VirtualDesktop;
if (info.dwFlags & MONITORINFOF_PRIMARY) {
data.flags |= QWindowsScreenData::PrimaryScreen;
// QPlatformIntegration::screenAdded() documentation specifies that first
@@ -162,6 +166,8 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d)
nospace << " primary";
if (d.flags & QWindowsScreenData::VirtualDesktop)
nospace << " virtual desktop";
+ if (d.flags & QWindowsScreenData::LockScreen)
+ nospace << " lock screen";
return dbg;
}
@@ -392,7 +398,8 @@ static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData,
bool QWindowsScreenManager::handleScreenChanges()
{
// Look for changed monitors, add new ones
- const WindowsScreenDataList newDataList = monitorData();
+ WindowsScreenDataList newDataList = monitorData();
+ const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen);
foreach (const QWindowsScreenData &newData, newDataList) {
const int existingIndex = indexOfMonitor(m_screens, newData.name);
if (existingIndex != -1) {
@@ -405,14 +412,17 @@ bool QWindowsScreenManager::handleScreenChanges()
qDebug() << "New Monitor: " << newData;
} // exists
} // for new screens.
- // Remove deleted ones.
- for (int i = m_screens.size() - 1; i >= 0; --i) {
- if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) {
- if (QWindowsContext::verboseWindows)
- qDebug() << "Removing Monitor: " << m_screens.at(i) ->data();
- delete m_screens.takeAt(i);
- } // not found
- } // for existing screens
+ // Remove deleted ones but keep main monitors if we get only the
+ // temporary lock screen to avoid window recreation (QTBUG-33062).
+ if (!lockScreen) {
+ for (int i = m_screens.size() - 1; i >= 0; --i) {
+ if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) {
+ if (QWindowsContext::verboseWindows)
+ qDebug() << "Removing Monitor: " << m_screens.at(i) ->data();
+ delete m_screens.takeAt(i);
+ } // not found
+ } // for existing screens
+ } // not lock screen
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 216973125b..930814a17d 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -59,7 +59,8 @@ struct QWindowsScreenData
enum Flags
{
PrimaryScreen = 0x1,
- VirtualDesktop = 0x2
+ VirtualDesktop = 0x2,
+ LockScreen = 0x4 // Temporary screen existing during user change, etc.
};
QWindowsScreenData();
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index b3b07cc8dd..f3faccbc14 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -549,6 +549,18 @@ QWindowsWindow::WindowData
qDebug().nospace() << "Created desktop window " << w << result.hwnd;
return result;
}
+ if ((flags & Qt::WindowType_Mask) == Qt::ForeignWindow) {
+ result.hwnd = reinterpret_cast<HWND>(w->winId());
+ Q_ASSERT(result.hwnd);
+ const LONG_PTR style = GetWindowLongPtr(result.hwnd, GWL_STYLE);
+ const LONG_PTR exStyle = GetWindowLongPtr(result.hwnd, GWL_EXSTYLE);
+ result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd));
+ result.frame = QWindowsGeometryHint::frame(style, exStyle);
+ result.embedded = false;
+ if (QWindowsContext::verboseWindows)
+ qDebug() << "Foreign window: " << w << result.hwnd << result.geometry << result.frame;
+ return result;
+ }
const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
@@ -962,7 +974,7 @@ void QWindowsWindow::destroyWindow()
}
}
#endif // !Q_OS_WINCE
- if (m_data.hwnd != GetDesktopWindow())
+ if (m_data.hwnd != GetDesktopWindow() && window()->type() != Qt::ForeignWindow)
DestroyWindow(m_data.hwnd);
context->removeWindow(m_data.hwnd);
m_data.hwnd = 0;
@@ -1483,14 +1495,27 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
handleHidden();
QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now.
break;
- case Qt::WindowNoState:
+ case Qt::WindowNoState: {
// QTBUG-17548: We send expose events when receiving WM_Paint, but for
- // layered windows, we won't receive any WM_Paint.
- if (GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) {
- fireExpose(QRegion(0, 0, window()->width(), window()->height()));
- if (!QWindowsContext::instance()->asyncExpose())
- QWindowSystemInterface::flushWindowSystemEvents();
+ // layered windows and transient children, we won't receive any WM_Paint.
+ QWindow *w = window();
+ bool exposeEventsSent = false;
+ if (isLayered()) {
+ fireExpose(QRegion(0, 0, w->width(), w->height()));
+ exposeEventsSent = true;
}
+ foreach (QWindow *child, QGuiApplication::allWindows()) {
+ if (child != w && child->isVisible() && child->transientParent() == w) {
+ QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(child);
+ if (platformWindow->isLayered()) {
+ platformWindow->fireExpose(QRegion(0, 0, child->width(), child->height()));
+ exposeEventsSent = true;
+ }
+ }
+ }
+ if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
+ QWindowSystemInterface::flushWindowSystemEvents();
+ }
break;
default:
break;
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index d365ac4d97..f055864482 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -230,6 +230,7 @@ public:
static inline void setUserDataOf(HWND hwnd, void *ud);
static bool setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal opacity);
+ bool isLayered() const;
HDC getDC();
void releaseDC();
@@ -376,6 +377,15 @@ inline void QWindowsWindow::destroyIcon()
}
}
+inline bool QWindowsWindow::isLayered() const
+{
+#ifndef Q_OS_WINCE
+ return GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE) & WS_EX_LAYERED;
+#else
+ return false;
+#endif
+}
+
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QMargins)
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 1f2485db0d..dc677cd3be 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -306,6 +306,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
Q_XCB_NOOP(connection());
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
+ if (!platformWindow) {
+ qWarning("QXcbBackingStore::flush: QWindow has no platform window (QTBUG-32681)");
+ return;
+ }
QVector<QRect> rects = clipped.rects();
for (int i = 0; i < rects.size(); ++i)
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 3f717ae2df..e594f1fedc 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -998,8 +998,11 @@ void QXcbEventReader::run()
emit eventPending();
}
+ m_mutex.lock();
for (int i = 0; i < m_events.size(); ++i)
free(m_events.at(i));
+ m_events.clear();
+ m_mutex.unlock();
}
void QXcbEventReader::addEvent(xcb_generic_event_t *event)