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.cpp93
1 files changed, 62 insertions, 31 deletions
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 9391929c41..d565420f4f 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -44,7 +44,9 @@
#include "qwindowscontext.h"
#include "qwindowsdrag.h"
#include "qwindowsscreen.h"
-#include "qwindowscursor.h"
+#ifdef QT_NO_CURSOR
+# include "qwindowscursor.h"
+#endif
#ifdef QT_OPENGL_ES_2
# include "qwindowseglcontext.h"
@@ -209,22 +211,42 @@ static bool shouldShowMaximizeButton(Qt::WindowFlags flags)
return flags & Qt::WindowMaximizeButtonHint;
}
-static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, qreal level)
+// Set the WS_EX_LAYERED flag on a HWND if required. This is required for
+// translucent backgrounds, not fully opaque windows and for
+// Qt::WindowTransparentForInput (in combination with WS_EX_TRANSPARENT).
+bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal opacity)
+{
+#ifndef Q_OS_WINCE // maybe needs revisiting WS_EX_LAYERED
+ const LONG exStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
+ const bool needsLayered = (flags & Qt::WindowTransparentForInput)
+ || (hasAlpha && (flags & Qt::FramelessWindowHint)) || opacity < 1.0;
+ const bool isLayered = (exStyle & WS_EX_LAYERED);
+ if (needsLayered != isLayered) {
+ if (needsLayered) {
+ SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
+ } else {
+ SetWindowLong(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
+ }
+ }
+ return needsLayered;
+#else // !Q_OS_WINCE
+ Q_UNUSED(hwnd);
+ Q_UNUSED(flags);
+ Q_UNUSED(hasAlpha);
+ Q_UNUSED(opacity);
+ return false;
+#endif // Q_OS_WINCE
+}
+
+static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal level)
{
-#ifdef Q_OS_WINCE // maybe needs revisit WS_EX_LAYERED
+#ifdef Q_OS_WINCE // WINCE does not support that feature and microsoft explicitly warns to use those calls
Q_UNUSED(hwnd);
Q_UNUSED(flags);
+ Q_UNUSED(hasAlpha);
Q_UNUSED(level);
#else
- const long wl = GetWindowLong(hwnd, GWL_EXSTYLE);
- const bool isOpaque = level == 1.0 && !(flags & Qt::WindowTransparentForInput);
-
- if (isOpaque) {
- if (wl & WS_EX_LAYERED)
- SetWindowLong(hwnd, GWL_EXSTYLE, wl & ~WS_EX_LAYERED);
- } else {
- if ((wl & WS_EX_LAYERED) == 0)
- SetWindowLong(hwnd, GWL_EXSTYLE, wl | WS_EX_LAYERED);
+ if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) {
if (flags & Qt::FramelessWindowHint) {
BLENDFUNCTION blend = {AC_SRC_OVER, 0, (BYTE)(255.0 * level), AC_SRC_ALPHA};
QWindowsContext::user32dll.updateLayeredWindow(hwnd, NULL, NULL, NULL, NULL, NULL, 0, &blend, ULW_ALPHA);
@@ -271,7 +293,7 @@ struct WindowCreationData
WindowCreationData() : parentHandle(0), type(Qt::Widget), style(0), exStyle(0),
topLevel(false), popup(false), dialog(false), desktop(false),
- tool(false), embedded(false) {}
+ tool(false), embedded(false), hasAlpha(false) {}
void fromWindow(const QWindow *w, const Qt::WindowFlags flags, unsigned creationFlags = 0);
inline WindowData create(const QWindow *w, const WindowData &data, QString title) const;
@@ -290,6 +312,7 @@ struct WindowCreationData
bool desktop;
bool tool;
bool embedded;
+ bool hasAlpha;
};
QDebug operator<<(QDebug debug, const WindowCreationData &d)
@@ -308,6 +331,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
unsigned creationFlags)
{
isGL = w->surfaceType() == QWindow::OpenGLSurface;
+ hasAlpha = w->format().hasAlpha();
flags = flagsIn;
// Sometimes QWindow doesn't have a QWindow parent but does have a native parent window,
@@ -321,10 +345,12 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
if (creationFlags & ForceChild) {
topLevel = false;
- } else if (creationFlags & ForceTopLevel) {
- topLevel = true;
+ } else if (embedded) {
+ // Embedded native windows (for example Active X server windows) are by
+ // definition never toplevel, even though they do not have QWindow parents.
+ topLevel = false;
} else {
- topLevel = w->isTopLevel();
+ topLevel = (creationFlags & ForceTopLevel) ? true : w->isTopLevel();
}
if (topLevel && flags == 1) {
@@ -530,7 +556,7 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLe
EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
}
- setWindowOpacity(hwnd, flags, opacityLevel);
+ setWindowOpacity(hwnd, flags, hasAlpha, opacityLevel);
} else { // child.
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
}
@@ -770,8 +796,10 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
break;
}
}
+#ifndef Q_OS_WINCE
if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)
QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0);
+#endif // !Q_OS_WINCE
setWindowState(aWindow->windowState());
const qreal opacity = qt_window_private(aWindow)->opacity;
if (!qFuzzyCompare(opacity, qreal(1.0)))
@@ -780,8 +808,10 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
QWindowsWindow::~QWindowsWindow()
{
+#ifndef Q_OS_WINCE
if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch)
QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd);
+#endif // !Q_OS_WINCE
destroyWindow();
destroyIcon();
}
@@ -811,7 +841,7 @@ void QWindowsWindow::destroyWindow()
ShowWindow(handle, SW_SHOW);
}
}
-#endif
+#endif // !Q_OS_WINCE
if (m_data.hwnd != GetDesktopWindow())
DestroyWindow(m_data.hwnd);
QWindowsContext::instance()->removeWindow(m_data.hwnd);
@@ -821,21 +851,29 @@ void QWindowsWindow::destroyWindow()
void QWindowsWindow::registerDropSite()
{
+#ifndef QT_NO_CLIPBOARD
+# ifndef QT_NO_DRAGANDDROP
if (m_data.hwnd && !m_dropTarget) {
m_dropTarget = new QWindowsOleDropTarget(window());
RegisterDragDrop(m_data.hwnd, m_dropTarget);
CoLockObjectExternal(m_dropTarget, true, true);
}
+# endif // !QT_NO_DRAGANDDROP
+#endif // !QT_NO_CLIPBOARD
}
void QWindowsWindow::unregisterDropSite()
{
+#ifndef QT_NO_CLIPBOARD
+# ifndef QT_NO_DRAGANDDROP
if (m_data.hwnd && m_dropTarget) {
m_dropTarget->Release();
CoLockObjectExternal(m_dropTarget, false, true);
RevokeDragDrop(m_data.hwnd);
m_dropTarget = 0;
}
+# endif // !QT_NO_DRAGANDDROP
+#endif // !QT_NO_CLIPBOARD
}
// Returns topmost QWindowsWindow ancestor even if there are embedded windows in the chain.
@@ -1231,18 +1269,7 @@ void QWindowsWindow::setWindowTitle(const QString &title)
if (QWindowsContext::verboseWindows)
qDebug() << __FUNCTION__ << this << window() <<title;
if (m_data.hwnd) {
-
- QString fullTitle = title;
- if (QGuiApplicationPrivate::displayName) {
- // Append display name, if set.
- if (!fullTitle.isEmpty())
- fullTitle += QStringLiteral(" - ");
- fullTitle += *QGuiApplicationPrivate::displayName;
- } else if (fullTitle.isEmpty()) {
- // Don't let the window title be completely empty, use the app name as fallback.
- fullTitle = QCoreApplication::applicationName();
- }
-
+ const QString fullTitle = formatWindowTitle(title, QStringLiteral(" - "));
SetWindowText(m_data.hwnd, (const wchar_t*)fullTitle.utf16());
}
}
@@ -1508,7 +1535,7 @@ void QWindowsWindow::setOpacity(qreal level)
if (m_opacity != level) {
m_opacity = level;
if (m_data.hwnd)
- setWindowOpacity(m_data.hwnd, m_data.flags, level);
+ setWindowOpacity(m_data.hwnd, m_data.flags, window()->format().hasAlpha(), level);
}
}
@@ -1671,12 +1698,14 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
void QWindowsWindow::applyCursor()
{
+#ifndef QT_NO_CURSOR
if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor.
if (const QWindow *p = window()->parent())
QWindowsWindow::baseWindowOf(p)->applyCursor();
} else {
SetCursor(m_cursor.handle());
}
+#endif
}
// Check whether to apply a new cursor. Either the window in question is
@@ -1698,6 +1727,7 @@ static inline bool applyNewCursor(const QWindow *w)
void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
{
+#ifndef QT_NO_CURSOR
if (c.handle() != m_cursor.handle()) {
const bool apply = applyNewCursor(window());
if (QWindowsContext::verboseWindows)
@@ -1707,6 +1737,7 @@ void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
if (apply)
applyCursor();
}
+#endif
}
/*!