summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowswindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows/qwindowswindow.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp260
1 files changed, 111 insertions, 149 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 54d1908e8b..923040fd71 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
@@ -10,9 +10,9 @@
** 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.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** 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
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@@ -38,6 +38,7 @@
#include "qwindowsscreen.h"
#include "qwindowsscaling.h"
#include "qwindowsintegration.h"
+#include "qwindowsopenglcontext.h"
#ifdef QT_NO_CURSOR
# include "qwindowscursor.h"
#endif
@@ -105,31 +106,16 @@ static QByteArray debugWinExStyle(DWORD exStyle)
return rc;
}
-static QByteArray debugWindowStates(Qt::WindowStates s)
-{
-
- QByteArray rc = "0x";
- rc += QByteArray::number(int(s), 16);
- if (s & Qt::WindowMinimized)
- rc += " WindowMinimized";
- if (s & Qt::WindowMaximized)
- rc += " WindowMaximized";
- if (s & Qt::WindowFullScreen)
- rc += " WindowFullScreen";
- if (s & Qt::WindowActive)
- rc += " WindowActive";
- return rc;
-}
-
#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO
QDebug operator<<(QDebug d, const MINMAXINFO &i)
{
- d.nospace() << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ','
- << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x
- << ',' << i.ptMaxPosition.y << " mintrack="
- << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y
- << " maxtrack=" << i.ptMaxTrackSize.x << ','
- << i.ptMaxTrackSize.y;
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "MINMAXINFO maxSize=" << i.ptMaxSize.x << ','
+ << i.ptMaxSize.y << " maxpos=" << i.ptMaxPosition.x
+ << ',' << i.ptMaxPosition.y << " mintrack="
+ << i.ptMinTrackSize.x << ',' << i.ptMinTrackSize.y
+ << " maxtrack=" << i.ptMaxTrackSize.x << ',' << i.ptMaxTrackSize.y;
return d;
}
#endif // !Q_OS_WINCE
@@ -154,18 +140,20 @@ static inline RECT RECTfromQRect(const QRect &rect)
QDebug operator<<(QDebug d, const RECT &r)
{
- d.nospace() << "RECT: left/top=" << r.left << ',' << r.top
- << " right/bottom=" << r.right << ',' << r.bottom;
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "RECT: left/top=" << r.left << ',' << r.top
+ << " right/bottom=" << r.right << ',' << r.bottom;
return d;
}
#ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_NCCALCSIZE
QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
{
- qDebug().nospace() << "NCCALCSIZE_PARAMS "
- << qrectFromRECT(p.rgrc[0])
- << ' ' << qrectFromRECT(p.rgrc[1]) << ' '
- << qrectFromRECT(p.rgrc[2]);
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0])
+ << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]);
return d;
}
#endif // !Q_OS_WINCE
@@ -432,13 +420,18 @@ struct WindowCreationData
QDebug operator<<(QDebug debug, const WindowCreationData &d)
{
- debug.nospace() << QWindowsWindow::debugWindowFlags(d.flags)
- << " topLevel=" << d.topLevel << " popup="
- << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop
- << " embedded=" << d.embedded
- << " tool=" << d.tool << " style=" << debugWinStyle(d.style)
- << " exStyle=" << debugWinExStyle(d.exStyle)
- << " parent=" << d.parentHandle;
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug.noquote();
+ debug << "WindowCreationData: " << d.flags
+ << "\n topLevel=" << d.topLevel;
+ if (d.parentHandle)
+ debug << " parent=" << d.parentHandle;
+ debug << " popup=" << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop
+ << " embedded=" << d.embedded << " tool=" << d.tool
+ << "\n style=" << debugWinStyle(d.style);
+ if (d.exStyle)
+ debug << "\n exStyle=" << debugWinExStyle(d.exStyle);
return debug;
}
@@ -555,13 +548,9 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
}
if (flags & Qt::WindowSystemMenuHint)
style |= WS_SYSMENU;
- else if (dialog) {
- // QTBUG-2027, dialogs without system menu.
- style |= WS_SYSMENU;
- if (!(flags & Qt::FramelessWindowHint)) {
- style |= WS_BORDER;
- exStyle |= WS_EX_DLGMODALFRAME;
- }
+ else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
+ style |= WS_SYSMENU | WS_BORDER; // QTBUG-2027, dialogs without system menu.
+ exStyle |= WS_EX_DLGMODALFRAME;
}
if (flags & Qt::WindowMinimizeButtonHint)
style |= WS_MINIMIZEBOX;
@@ -633,8 +622,8 @@ QWindowsWindowData
QWindowsContext::instance()->setWindowCreationContext(context);
qCDebug(lcQpaWindows).nospace()
- << "CreateWindowEx: " << w << *this << " class=" <<windowClassName << " title=" << title
- << "\nrequested: " << rect << ": "
+ << "CreateWindowEx: " << w << " class=" << windowClassName << " title=" << title
+ << '\n' << *this << "\nrequested: " << rect << ": "
<< context->frameWidth << 'x' << context->frameHeight
<< '+' << context->frameX << '+' << context->frameY
<< " custom margins: " << context->customMargins;
@@ -650,7 +639,7 @@ QWindowsWindowData
#endif
qCDebug(lcQpaWindows).nospace()
<< "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
- << context->obtainedGeometry << context->margins;
+ << context->obtainedGeometry << ' ' << context->margins;
if (!result.hwnd) {
qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
@@ -751,9 +740,9 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle)
qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__);
const QMargins result(qAbs(rect.left), qAbs(rect.top),
qAbs(rect.right), qAbs(rect.bottom));
- qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style= 0x"
- << QString::number(style, 16) << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
-
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style="
+ << showbase << hex << style << " exStyle=" << exStyle << dec << noshowbase
+ << ' ' << rect << ' ' << result;
return result;
}
@@ -872,12 +861,12 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
}
qCDebug(lcQpaWindows).nospace()
- << __FUNCTION__ << ' ' << w << geometry
- << " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w)
- << " frame: " << frameWidth << 'x' << frameHeight << '+'
+ << __FUNCTION__ << ' ' << w << ' ' << geometry
+ << " pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w)
+ << " frame=" << frameWidth << 'x' << frameHeight << '+'
<< frameX << '+' << frameY
- << " min" << geometryHint.minimumSize << " max" << geometryHint.maximumSize
- << " custom margins " << customMargins;
+ << " min=" << geometryHint.minimumSize << " max=" << geometryHint.maximumSize
+ << " custom margins=" << customMargins;
}
/*!
@@ -935,16 +924,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
#endif // QT_NO_OPENGL
updateDropSite(window()->isTopLevel());
-#ifndef Q_OS_WINCE
- if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)
- && aWindow->type() != Qt::ForeignWindow) {
- if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0)) {
- setFlag(TouchRegistered);
- } else {
- qErrnoWarning("RegisterTouchWindow() failed for window '%s'.", qPrintable(aWindow->objectName()));
- }
- }
-#endif // !Q_OS_WINCE
+ registerTouchWindow();
setWindowState(aWindow->windowState());
const qreal opacity = qt_window_private(aWindow)->opacity;
if (!qFuzzyCompare(opacity, qreal(1.0)))
@@ -1098,7 +1078,8 @@ QWindowsWindowData
void QWindowsWindow::setVisible(bool visible)
{
- qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd << visible;
+ const QWindow *win = window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << win << m_data.hwnd << visible;
if (m_data.hwnd) {
if (visible) {
show_sys();
@@ -1106,11 +1087,13 @@ void QWindowsWindow::setVisible(bool visible)
// When the window is layered, we won't get WM_PAINT, and "we" are in control
// over the rendering of the window
// There is nobody waiting for this, so we don't need to flush afterwards.
- if (isLayered()) {
- QWindow *w = window();
- fireExpose(QRect(0, 0, w->width(), w->height()));
- }
+ if (isLayered())
+ fireExpose(QRect(0, 0, win->width(), win->height()));
+ // QTBUG-44928, QTBUG-7386: This is to resolve the problem where popups are
+ // opened from the system tray and not being implicitly activated
+ if (win->type() == Qt::Popup && !win->parent() && !QGuiApplication::focusWindow())
+ SetForegroundWindow(m_data.hwnd);
} else {
if (hasMouseCapture())
setMouseGrabEnabled(false);
@@ -1447,10 +1430,10 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
const QMargins margins = frameMarginsDp();
const QRect frameGeometry = rect + margins;
- qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
- << " \n from " << geometry_sys() << " frame: "
- << margins << " to " <<rect
- << " new frame: " << frameGeometry;
+ qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window()
+ << "\n from " << geometry_sys() << " frame: "
+ << margins << " to " <<rect
+ << " new frame: " << frameGeometry;
bool result = false;
#ifndef Q_OS_WINCE
@@ -1471,8 +1454,8 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
result = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
frameGeometry.width(), frameGeometry.height(), true);
}
- qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window()
- << " \n resulting " << result << geometry_sys();
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << window()
+ << "\n resulting " << result << geometry_sys();
}
QRect QWindowsWindow::frameGeometry_sys() const
@@ -1554,8 +1537,7 @@ void QWindowsWindow::setWindowTitle(const QString &title)
void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
- << QWindowsWindow::debugWindowFlags(m_data.flags)
- << "\n to: " << QWindowsWindow::debugWindowFlags(flags);
+ << m_data.flags << "\n to: " << flags;
const QRect oldGeometry = geometryDp();
if (m_data.flags != flags) {
m_data.flags = flags;
@@ -1573,8 +1555,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
handleGeometryChange();
qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << "\n returns: "
- << QWindowsWindow::debugWindowFlags(m_data.flags)
- << " geometry " << oldGeometry << "->" << newGeometry;
+ << m_data.flags << " geometry " << oldGeometry << "->" << newGeometry;
}
QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
@@ -1595,8 +1576,7 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window()
- << "\n from " << debugWindowStates(m_windowState)
- << " to " << debugWindowStates(state);
+ << "\n from " << m_windowState << " to " << state;
setFlag(FrameDirty);
m_windowState = state;
QWindowSystemInterface::handleWindowStateChanged(window(), state);
@@ -1665,7 +1645,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
if (oldState == newState)
return;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
- << " from " << debugWindowStates(oldState) << " to " << debugWindowStates(newState);
+ << " from " << oldState << " to " << newState;
const bool visible = isVisible();
@@ -1766,7 +1746,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
ShowWindow(m_data.hwnd, (newState == Qt::WindowMinimized) ? SW_MINIMIZE :
(newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
}
- qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() << debugWindowStates(newState);
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() << newState;
}
void QWindowsWindow::setStyle(unsigned s) const
@@ -2159,8 +2139,8 @@ void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
#ifndef QT_NO_CURSOR
if (c.handle() != m_cursor.handle()) {
const bool apply = applyNewCursor(window());
- qCDebug(lcQpaWindows) <<window() << __FUNCTION__
- << "Shape=" << c.cursor().shape() << " doApply=" << apply;
+ qCDebug(lcQpaWindows) << window() << __FUNCTION__
+ << c.cursor().shape() << " doApply=" << apply;
m_cursor = c;
if (apply)
applyCursor();
@@ -2227,62 +2207,6 @@ void QWindowsWindow::setEnabled(bool enabled)
setStyle(newStyle);
}
-QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf)
-{
- const int iwf = int(wf);
- QByteArray rc = "0x";
- rc += QByteArray::number(iwf, 16);
- rc += " [";
-
- switch ((iwf & Qt::WindowType_Mask)) {
- case Qt::Widget:
- rc += " Widget";
- break;
- case Qt::Window:
- rc += " Window";
- break;
- case Qt::Dialog:
- rc += " Dialog";
- break;
- case Qt::Sheet:
- rc += " Sheet";
- break;
- case Qt::Popup:
- rc += " Popup";
- break;
- case Qt::Tool:
- rc += " Tool";
- break;
- case Qt::ToolTip:
- rc += " ToolTip";
- break;
- case Qt::SplashScreen:
- rc += " SplashScreen";
- break;
- case Qt::Desktop:
- rc += " Desktop";
- break;
- case Qt::SubWindow:
- rc += " SubWindow";
- break;
- }
- if (iwf & Qt::MSWindowsFixedSizeDialogHint) rc += " MSWindowsFixedSizeDialogHint";
- if (iwf & Qt::MSWindowsOwnDC) rc += " MSWindowsOwnDC";
- if (iwf & Qt::FramelessWindowHint) rc += " FramelessWindowHint";
- if (iwf & Qt::WindowTitleHint) rc += " WindowTitleHint";
- if (iwf & Qt::WindowSystemMenuHint) rc += " WindowSystemMenuHint";
- if (iwf & Qt::WindowMinimizeButtonHint) rc += " WindowMinimizeButtonHint";
- if (iwf & Qt::WindowMaximizeButtonHint) rc += " WindowMaximizeButtonHint";
- if (iwf & Qt::WindowContextHelpButtonHint) rc += " WindowContextHelpButtonHint";
- if (iwf & Qt::WindowShadeButtonHint) rc += " WindowShadeButtonHint";
- if (iwf & Qt::WindowStaysOnTopHint) rc += " WindowStaysOnTopHint";
- if (iwf & Qt::CustomizeWindowHint) rc += " CustomizeWindowHint";
- if (iwf & Qt::WindowStaysOnBottomHint) rc += " WindowStaysOnBottomHint";
- if (iwf & Qt::WindowCloseButtonHint) rc += " WindowCloseButtonHint";
- rc += ']';
- return rc;
-}
-
static HICON createHIcon(const QIcon &icon, int xSize, int ySize)
{
if (!icon.isNull()) {
@@ -2342,20 +2266,58 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
}
}
-void *QWindowsWindow::surface(void *nativeConfig)
+void *QWindowsWindow::surface(void *nativeConfig, int *err)
{
#ifdef QT_NO_OPENGL
+ Q_UNUSED(nativeConfig)
return 0;
#else
if (!m_surface) {
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
- m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig);
+ m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err);
}
return m_surface;
#endif
}
+void QWindowsWindow::invalidateSurface()
+{
+#ifndef QT_NO_OPENGL
+ if (m_surface) {
+ if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
+ staticOpenGLContext->destroyWindowSurface(m_surface);
+ m_surface = 0;
+ }
+#endif // QT_NO_OPENGL
+}
+
+void QWindowsWindow::setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes)
+{
+ if (!window->handle())
+ return;
+ static_cast<QWindowsWindow *>(window->handle())->registerTouchWindow(touchTypes);
+}
+
+void QWindowsWindow::registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes)
+{
+#ifndef Q_OS_WINCE
+ if ((QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)
+ && window()->type() != Qt::ForeignWindow) {
+ ULONG touchFlags = 0;
+ const bool ret = QWindowsContext::user32dll.isTouchWindow(m_data.hwnd, &touchFlags);
+ // Return if it is not a touch window or the flags are already set by a hook
+ // such as HCBT_CREATEWND
+ if (ret || touchFlags != 0)
+ return;
+ if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, (ULONG)touchTypes))
+ setFlag(TouchRegistered);
+ else
+ qErrnoWarning("RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
+ }
+#endif // !Q_OS_WINCE
+}
+
void QWindowsWindow::aboutToMakeCurrent()
{
#ifndef QT_NO_OPENGL