diff options
Diffstat (limited to 'src/plugins/platforms/windows')
13 files changed, 105 insertions, 114 deletions
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 9170c774b4..66ed9d85dc 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -44,7 +44,7 @@ #include "iaccessible2.h" #include "qwindowsaccessibility.h" -#include <QtGui/private/qaccessible2_p.h> +#include <QtGui/qaccessible.h> #include <QtGui/qclipboard.h> #include <QtWidgets/qapplication.h> #include <QtCore/qdebug.h> diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp index 63b4370dc2..885bc37cff 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp @@ -51,7 +51,6 @@ #include <QtCore/qpointer.h> #include <QtCore/qsettings.h> #include <QtGui/qaccessible.h> -#include <QtGui/private/qaccessible2_p.h> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformintegration.h> diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 93592eb969..8bb7646258 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -54,7 +54,6 @@ #include <QtCore/qpair.h> #include <QtCore/qsettings.h> #include <QtGui/qaccessible.h> -#include <QtGui/private/qaccessible2_p.h> #include <QtGui/qguiapplication.h> #include <qpa/qplatformnativeinterface.h> #include <QtGui/qwindow.h> diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index f6ed9447ef..7b574b0a56 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -93,6 +93,7 @@ enum WindowsEventType // Simplify event types NonClientHitTest = NonClientEventFlag + 2, KeyEvent = KeyEventFlag + 1, KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1, + KeyboardLayoutChangeEvent = KeyEventFlag + 2, InputMethodKeyEvent = InputMethodEventFlag + KeyEventFlag + 1, InputMethodKeyDownEvent = InputMethodEventFlag + KeyEventFlag + KeyDownEventFlag + 1, ClipboardEvent = ClipboardEventFlag + 1, @@ -165,6 +166,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::InputMethodKeyEvent; case WM_IME_KEYDOWN: return QtWindows::InputMethodKeyDownEvent; +#ifdef WM_INPUTLANGCHANGE + case WM_INPUTLANGCHANGE: + return QtWindows::KeyboardLayoutChangeEvent; +#endif // WM_INPUTLANGCHANGE case WM_TOUCH: return QtWindows::TouchEvent; case WM_CHANGECBCHAIN: diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp index 26205eb146..55e7b85d96 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp +++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp @@ -149,7 +149,23 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion ®ion) QImage::Format format = QWindowsNativeImage::systemFormat(); if (format == QImage::Format_RGB32 && rasterWindow()->window()->format().hasAlpha()) format = QImage::Format_ARGB32_Premultiplied; - m_image.reset(new QWindowsNativeImage(size.width(), size.height(), format)); + + QWindowsNativeImage *oldwni = m_image.data(); + QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format); + + if (oldwni && !region.isEmpty()) { + const QImage &oldimg(oldwni->image()); + QImage &newimg(newwni->image()); + QRegion staticRegion(region); + staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height()); + staticRegion &= QRect(0, 0, newimg.width(), newimg.height()); + QPainter painter(&newimg); + painter.setCompositionMode(QPainter::CompositionMode_Source); + foreach (const QRect &rect, staticRegion.rects()) + painter.drawImage(rect, oldimg, rect); + } + + m_image.reset(newwni); } } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 85b03673ac..77cac647ba 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -783,9 +783,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::InputMethodCloseCandidateWindowEvent: // TODO: Release/regrab mouse if a popup has mouse grab. return false; - case QtWindows::ClipboardEvent: case QtWindows::DestroyEvent: - + if (!platformWindow->testFlag(QWindowsWindow::WithinDestroy)) { + qWarning() << "External WM_DESTROY received for " << platformWindow->window() + << ", parent: " << platformWindow->window()->parent() + << ", transient parent: " << platformWindow->window()->transientParent(); + } + return false; + case QtWindows::ClipboardEvent: + return false; case QtWindows::UnknownEvent: return false; case QtWindows::AccessibleObjectFromWindowRequest: @@ -842,8 +848,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::KeyEvent: case QtWindows::InputMethodKeyEvent: case QtWindows::InputMethodKeyDownEvent: + case QtWindows::KeyboardLayoutChangeEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); #else return d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); #endif @@ -867,7 +874,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::NonClientMouseEvent: if (platformWindow->frameStrutEventsEnabled()) #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #else return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #endif @@ -887,13 +894,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::MouseEvent: case QtWindows::LeaveEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #else return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); #endif case QtWindows::TouchEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) - return platformSessionManager()->isInterractionBlocked() ? true : d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); #else return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); #endif diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index ac57a1b396..6c928119b3 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -161,12 +161,18 @@ bool QWindowsFontEngine::hasCFFTable() const return GetFontData(hdc, MAKE_TAG('C', 'F', 'F', ' '), 0, 0, 0) != GDI_ERROR; } +bool QWindowsFontEngine::hasCMapTable() const +{ + HDC hdc = m_fontEngineData->hdc; + SelectObject(hdc, hfont); + return GetFontData(hdc, MAKE_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR; +} + void QWindowsFontEngine::getCMap() { - ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE); + ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable(); - // TMPF_TRUETYPE is not set for fonts with CFF tables - cffTable = !ttf && hasCFFTable(); + cffTable = hasCFFTable(); HDC hdc = m_fontEngineData->hdc; SelectObject(hdc, hfont); @@ -374,6 +380,7 @@ HGDIOBJ QWindowsFontEngine::selectDesignFont() const { LOGFONT f = m_logfont; f.lfHeight = unitsPerEm; + f.lfWidth = 0; HFONT designFont = CreateFontIndirect(&f); return SelectObject(m_fontEngineData->hdc, designFont); } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index d783b6048c..acf84d270c 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -140,6 +140,7 @@ private: QWindowsNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform, QImage::Format mask_format); bool hasCFFTable() const; + bool hasCMapTable() const; const QSharedPointer<QWindowsFontEngineData> m_fontEngineData; diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 47c136991a..2743ef029d 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -86,6 +86,10 @@ QWindowsKeyMapper::~QWindowsKeyMapper() #define VK_OEM_3 0xC0 #endif +// We not only need the scancode itself but also the extended bit of key messages. Thus we need +// the additional bit when masking the scancode. +enum { scancodeBitmask = 0x1ff }; + // Key recorder ------------------------------------------------------------------------[ start ] -- struct KeyRecord { KeyRecord(int c, int a, int s, const QString &t) : code(c), ascii(a), state(s), text(t) {} @@ -97,6 +101,8 @@ struct KeyRecord { QString text; }; +// We need to record the pressed keys in order to decide, whether the key event is an autorepeat +// event. As soon as its state changes, the chain of autorepeat events will be broken. static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers... struct KeyRecorder { @@ -503,12 +509,6 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer, return code == Qt::Key_unknown ? 0 : code; } -int qt_translateKeyCode(int vk) -{ - int code = winceKeyBend((vk < 0 || vk > 255) ? 0 : vk); - return code == Qt::Key_unknown ? 0 : code; -} - static inline int asciiToKeycode(char a, int state) { if (a >= 'a' && a <= 'z') @@ -554,12 +554,8 @@ void QWindowsKeyMapper::changeKeyboard() keyboardInputDirection = bidi ? Qt::RightToLeft : Qt::LeftToRight; } -void QWindowsKeyMapper::clearRecordedKeys() -{ - key_recorder.clearKeys(); -} - - +// Helper function that is used when obtaining the list of characters that can be produced by one key and +// every possible combination of modifiers inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt) { kbd[VK_LSHIFT ] = (shift ? 0x80 : 0); @@ -570,14 +566,18 @@ inline void setKbdState(unsigned char *kbd, bool shift, bool ctrl, bool alt) kbd[VK_MENU ] = (alt ? 0x80 : 0); } +// Adds the msg's key to keyLayout if it is not yet present there void QWindowsKeyMapper::updateKeyMap(const MSG &msg) { unsigned char kbdBuffer[256]; // Will hold the complete keyboard state GetKeyboardState(kbdBuffer); - quint32 scancode = (msg.lParam >> 16) & 0xfff; + const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam); } +// Fills keyLayout for that vk_key. Values are all characters one can type using that key +// (in connection with every combination of modifiers) and whether these "characters" are +// dead keys. void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode, quint32 vk_key) { @@ -598,6 +598,10 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 buffer[VK_RCONTROL] = 0; buffer[VK_LMENU ] = 0; // Use right Alt, since left Ctrl + right Alt is considered AltGraph + // keyLayout contains the actual characters which can be written using the vk_key together with the + // different modifiers. '2' together with shift will for example cause the character + // to be @ for a US key layout (thus keyLayout[vk_key].qtKey[1] will be @). In addition to that + // it stores whether the resulting key is a dead key as these keys have to be handled later. bool isDeadKey = false; keyLayout[vk_key].deadkeys = 0; keyLayout[vk_key].dirty = false; @@ -635,8 +639,9 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 } keyLayout[vk_key].qtKey[8] = fallbackKey; - // If this vk_key a Dead Key - if (MapVirtualKey(vk_key, 2) & 0x80000000) { + // If one of the values inserted into the keyLayout above, can be considered a dead key, we have + // to run the workaround below. + if (keyLayout[vk_key].deadkeys) { // Push a Space, then the original key through the low-level ToAscii functions. // We do this because these functions (ToAscii / ToUnicode) will alter the internal state of // the keyboard driver By doing the following, we set the keyboard driver state back to what @@ -661,17 +666,6 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 } } -bool QWindowsKeyMapper::isADeadKey(unsigned int vk_key, unsigned int modifiers) -{ - if ((vk_key < NumKeyboardLayoutItems) && keyLayout[vk_key].exists) { - for (size_t i = 0; i < NumMods; ++i) { - if (uint(ModsTbl[i]) == modifiers) - return bool(keyLayout[vk_key].deadkeys & 1<<i); - } - } - return false; -} - static inline QString messageKeyText(const MSG &msg) { const QChar ch = QChar((ushort)msg.wParam); @@ -742,12 +736,21 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd, const MSG &msg, LRESULT *result) { *result = 0; + + // Reset layout map when system keyboard layout is changed + if (msg.message == WM_INPUTLANGCHANGE) { + deleteLayouts(); + return true; + } + + // Add this key to the keymap if it is not present yet. + updateKeyMap(msg); + MSG peekedMsg; // consume dead chars?(for example, typing '`','a' resulting in a-accent). if (PeekMessage(&peekedMsg, hwnd, 0, 0, PM_NOREMOVE) && peekedMsg.message == WM_DEADCHAR) return true; - if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) - updateKeyMap(msg); + return translateKeyEventInternal(widget, msg, false); } @@ -755,9 +758,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms { const int msgType = msg.message; - const quint32 scancode = (msg.lParam >> 16) & 0xfff; - const quint32 vk_key = MapVirtualKey(scancode, 1); - const bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9); + const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask; + const quint32 vk_key = msg.wParam; quint32 nModifiers = 0; QWindow *receiver = m_keyGrabber ? m_keyGrabber : window; @@ -786,10 +788,6 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms state |= (nModifiers & AltAny ? int(Qt::AltModifier) : 0); state |= (nModifiers & MetaAny ? int(Qt::MetaModifier) : 0); - // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey - const bool isDeadKey = isADeadKey(msg.wParam, state) - || MapVirtualKey(msg.wParam, 2) & 0x80000000; - // A multi-character key or a Input method character // not found by our look-ahead if (msgType == WM_CHAR || msgType == WM_IME_CHAR) { @@ -849,23 +847,12 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms return true; // Translate VK_* (native) -> Key_* (Qt) keys - // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change - // the internal state of the keyboard driver, resulting in that dead keys no longer works. - // ..also if we're typing numbers on the keypad, while holding down the Alt modifier. - int code = 0; - if (isNumpad && (nModifiers & AltAny)) { - code = winceKeyBend(msg.wParam); - } else if (!isDeadKey) { - // QTBUG-8764, QTBUG-10032 - // Can't call toKeyOrUnicode because that would call ToUnicode, and, if a dead key - // is pressed at the moment, Windows would NOT use it to compose a character for the next - // WM_CHAR event. - - // Instead, use MapVirtualKey, which will provide adequate values. - code = MapVirtualKey(msg.wParam, MAPVK_VK_TO_CHAR); - if (code < 0x20 || code == 0x7f) // The same logic as in toKeyOrUnicode() - code = winceKeyBend(msg.wParam); - } + int modifiersIndex = 0; + modifiersIndex |= (nModifiers & ShiftAny ? 0x1 : 0); + modifiersIndex |= (nModifiers & ControlAny ? 0x2 : 0); + modifiersIndex |= (nModifiers & AltAny ? 0x4 : 0); + + int code = keyLayout[vk_key].qtKey[modifiersIndex]; // Invert state logic: // If the key actually pressed is a modifier key, then we remove its modifier key from the diff --git a/src/plugins/platforms/windows/qwindowskeymapper.h b/src/plugins/platforms/windows/qwindowskeymapper.h index ce6ca23708..f7d33758a0 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.h +++ b/src/plugins/platforms/windows/qwindowskeymapper.h @@ -100,9 +100,7 @@ private: QLocale keyboardInputLocale; Qt::LayoutDirection keyboardInputDirection; - void clearRecordedKeys(); void updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32 scancode, quint32 vk_key); - bool isADeadKey(unsigned int vk_key, unsigned int modifiers); void deleteLayouts(); QWindow *m_keyGrabber; diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.cpp b/src/plugins/platforms/windows/qwindowssessionmanager.cpp index efdbb6b279..e86722f953 100644 --- a/src/plugins/platforms/windows/qwindowssessionmanager.cpp +++ b/src/plugins/platforms/windows/qwindowssessionmanager.cpp @@ -52,10 +52,6 @@ QWindowsSessionManager::QWindowsSessionManager(const QString &id, const QString { } -QWindowsSessionManager::~QWindowsSessionManager() -{ -} - bool QWindowsSessionManager::allowsInteraction() { m_blockUserInput = false; @@ -68,16 +64,6 @@ bool QWindowsSessionManager::allowsErrorInteraction() return true; } -void QWindowsSessionManager::blocksInteraction() -{ - m_blockUserInput = true; -} - -bool QWindowsSessionManager::isInterractionBlocked() const -{ - return m_blockUserInput; -} - void QWindowsSessionManager::release() { if (m_isActive) @@ -89,24 +75,4 @@ void QWindowsSessionManager::cancel() m_canceled = true; } -void QWindowsSessionManager::clearCancellation() -{ - m_canceled = false; -} - -bool QWindowsSessionManager::wasCanceled() const -{ - return m_canceled; -} - -void QWindowsSessionManager::setActive(bool active) -{ - m_isActive = active; -} - -bool QWindowsSessionManager::isActive() const -{ - return m_isActive; -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.h b/src/plugins/platforms/windows/qwindowssessionmanager.h index 3e21cbabec..0443635c35 100644 --- a/src/plugins/platforms/windows/qwindowssessionmanager.h +++ b/src/plugins/platforms/windows/qwindowssessionmanager.h @@ -60,22 +60,21 @@ class QWindowsSessionManager : public QPlatformSessionManager { public: explicit QWindowsSessionManager(const QString &id, const QString &key); - virtual ~QWindowsSessionManager(); bool allowsInteraction() Q_DECL_OVERRIDE; bool allowsErrorInteraction() Q_DECL_OVERRIDE; - void blocksInteraction(); - bool isInterractionBlocked() const; + void blocksInteraction() { m_blockUserInput = true; } + bool isInteractionBlocked() const { return m_blockUserInput; } void release() Q_DECL_OVERRIDE; void cancel() Q_DECL_OVERRIDE; - void clearCancellation(); - bool wasCanceled() const; + void clearCancellation() { m_canceled = false; } + bool wasCanceled() const { return m_canceled; } - void setActive(bool active); - bool isActive() const; + void setActive(bool active) { m_isActive = active; } + bool isActive() const { return m_isActive;} private: bool m_isActive; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 1909e0313b..58047124a1 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -305,7 +305,7 @@ bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool has #endif // Q_OS_WINCE } -static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal level) +static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bool openGL, qreal level) { #ifdef Q_OS_WINCE // WINCE does not support that feature and microsoft explicitly warns to use those calls Q_UNUSED(hwnd); @@ -314,8 +314,8 @@ static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qr Q_UNUSED(level); #else if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) { - if (hasAlpha && (flags & Qt::FramelessWindowHint)) { - // Windows with alpha: Use blend function to update. + if (hasAlpha && !openGL && (flags & Qt::FramelessWindowHint)) { + // Non-GL windows with alpha: Use blend function to update. 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); } else { @@ -661,7 +661,7 @@ void WindowCreationData::initialize(HWND hwnd, bool frameChange, qreal opacityLe EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED); } - setWindowOpacity(hwnd, flags, hasAlpha, opacityLevel); + setWindowOpacity(hwnd, flags, hasAlpha, isGL, opacityLevel); } else { // child. SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags); } @@ -929,6 +929,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : QWindowsWindow::~QWindowsWindow() { + setFlag(WithinDestroy); #ifndef Q_OS_WINCE if (testFlag(TouchRegistered)) QWindowsContext::user32dll.unregisterTouchWindow(m_data.hwnd); @@ -1122,6 +1123,8 @@ QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const void QWindowsWindow::updateTransientParent() const { #ifndef Q_OS_WINCE + if (window()->type() == Qt::Popup) + return; // QTBUG-34503, // a popup stays on top, no parent, see also WindowCreationData::fromWindow(). // Update transient parent. const HWND oldTransientParent = GetAncestor(m_data.hwnd, GA_PARENT) == GetDesktopWindow() ? GetAncestor(m_data.hwnd, GA_ROOTOWNER) : HWND(0); @@ -1497,6 +1500,8 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) handleHidden(); QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now. break; + case Qt::WindowMaximized: + case Qt::WindowFullScreen: case Qt::WindowNoState: { // QTBUG-17548: We send expose events when receiving WM_Paint, but for // layered windows and transient children, we won't receive any WM_Paint. @@ -1548,7 +1553,7 @@ static const QScreen *effectiveScreen(const QWindow *w) bool QWindowsWindow::isFullScreen_sys() const { - return geometry_sys() == effectiveScreen(window())->geometry(); + return window()->isTopLevel() && geometry_sys() == effectiveScreen(window())->geometry(); } /*! @@ -1745,7 +1750,9 @@ void QWindowsWindow::setOpacity(qreal level) if (m_opacity != level) { m_opacity = level; if (m_data.hwnd) - setWindowOpacity(m_data.hwnd, m_data.flags, window()->format().hasAlpha(), level); + setWindowOpacity(m_data.hwnd, m_data.flags, + window()->format().hasAlpha(), testFlag(OpenGLSurface), + level); } } |