summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2014-05-09 16:53:28 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-06-03 22:31:14 +0200
commite276fc11fa8f3fab062a4db65a3b5efe13b6ef55 (patch)
tree69acb9053c4ae56c82d1f45812070a2f9be1cd09
parent203ce7c5ce36f300750607b74b2d2429be2d4959 (diff)
Windows: Emit screen changed signal of top level windows.
Detect screen changes within virtual desktop in handleGeometryChange(). Move away windows from screens being destroyed. Task-number: QTBUG-36659 Change-Id: I5bf4842cc21873a93bce0f70929308f11bd4d2fd Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp32
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h4
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp47
3 files changed, 60 insertions, 23 deletions
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 4d6b822793..bcdb8a2352 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -407,6 +407,30 @@ static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData,
return -1;
}
+void QWindowsScreenManager::removeScreen(int index)
+{
+ qCDebug(lcQpaWindows) << "Removing Monitor:" << m_screens.at(index)->data();
+ QScreen *screen = m_screens.at(index)->screen();
+ QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ // QTBUG-38650: When a screen is disconnected, Windows will automatically
+ // move the Window to another screen. This will trigger a geometry change
+ // event, but unfortunately after the screen destruction signal. To prevent
+ // QtGui from automatically hiding the QWindow, pretend all Windows move to
+ // the primary screen first (which is likely the correct, final screen).
+ if (screen != primaryScreen) {
+ unsigned movedWindowCount = 0;
+ foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
+ if (w->screen() == screen && w->handle() && w->type() != Qt::Desktop) {
+ QWindowSystemInterface::handleWindowScreenChanged(w, primaryScreen);
+ ++movedWindowCount;
+ }
+ }
+ if (movedWindowCount)
+ QWindowSystemInterface::flushWindowSystemEvents();
+ }
+ delete m_screens.takeAt(index);
+}
+
/*!
\brief Synchronizes the screen list, adds new screens, removes deleted
ones and propagates resolution changes to QWindowSystemInterface.
@@ -432,10 +456,8 @@ bool QWindowsScreenManager::handleScreenChanges()
// 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) {
- qCDebug(lcQpaWindows) << "Removing Monitor: " << m_screens.at(i) ->data();
- delete m_screens.takeAt(i);
- } // not found
+ if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1)
+ removeScreen(i);
} // 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 930814a17d..00f0b316c2 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -143,6 +143,8 @@ public:
const WindowsScreenList &screens() const { return m_screens; }
private:
+ void removeScreen(int index);
+
WindowsScreenList m_screens;
int m_lastDepth;
WORD m_lastHorizontalResolution;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 56f9119459..cfee98f624 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1366,6 +1366,25 @@ void QWindowsWindow::handleResized(int wParam)
}
}
+// Return the effective screen for full screen mode in a virtual desktop.
+static QScreen *effectiveScreen(const QWindow *w)
+{
+ QRect geometry = w->geometry();
+ if (!w->isTopLevel())
+ geometry.moveTopLeft(w->mapToGlobal(geometry.topLeft()));
+
+ QScreen *screen = w->screen();
+ if (!screen->geometry().intersects(geometry)) {
+ foreach (QScreen *sibling, screen->virtualSiblings()) {
+ if (sibling->geometry().intersects(geometry)) {
+ screen = sibling;
+ break;
+ }
+ }
+ }
+ return screen;
+}
+
void QWindowsWindow::handleGeometryChange()
{
//Prevent recursive resizes for Windows CE
@@ -1381,6 +1400,14 @@ void QWindowsWindow::handleGeometryChange()
&& !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
fireExpose(QRegion(m_data.geometry), true);
}
+ if (previousGeometry.topLeft() != m_data.geometry.topLeft()) {
+ QWindow *w = window();
+ if (w->isTopLevel()) {
+ QScreen *newScreen = effectiveScreen(w);
+ if (newScreen != w->screen())
+ QWindowSystemInterface::handleWindowScreenChanged(w, newScreen);
+ }
+ }
if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents();
@@ -1571,23 +1598,9 @@ void QWindowsWindow::setWindowState(Qt::WindowState state)
}
}
-// Return the effective screen for full screen mode in a virtual desktop.
-static const QScreen *effectiveScreen(const QWindow *w)
-{
- QPoint center = w->geometry().center();
- if (!w->isTopLevel())
- center = w->mapToGlobal(center);
- const QScreen *screen = w->screen();
- if (!screen->geometry().contains(center))
- foreach (const QScreen *sibling, screen->virtualSiblings())
- if (sibling->geometry().contains(center))
- return sibling;
- return screen;
-}
-
bool QWindowsWindow::isFullScreen_sys() const
{
- return window()->isTopLevel() && geometry_sys() == effectiveScreen(window())->geometry();
+ return window()->isTopLevel() && geometry_sys() == window()->screen()->geometry();
}
/*!
@@ -1667,7 +1680,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
setStyle(newStyle);
// Use geometry of QWindow::screen() within creation or the virtual screen the
// window is in (QTBUG-31166, QTBUG-30724).
- const QScreen *screen = testFlag(WithinCreate) ? window()->screen() : effectiveScreen(window());
+ const QScreen *screen = window()->screen();
const QRect r = screen->geometry();
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
@@ -1934,7 +1947,7 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
&& (m_data.flags & Qt::FramelessWindowHint)) {
// This block fixes QTBUG-8361: Frameless windows shouldn't cover the
// taskbar when maximized
- if (const QScreen *screen = effectiveScreen(window())) {
+ if (const QScreen *screen = window()->screen()) {
mmi->ptMaxSize.y = screen->availableGeometry().height();
// Width, because you can have the taskbar on the sides too.