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>
This commit is contained in:
parent
203ce7c5ce
commit
e276fc11fa
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user