diff options
Diffstat (limited to 'src/plugins/platforms/windows')
46 files changed, 1046 insertions, 688 deletions
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h index e035e3924a..8621e93120 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h +++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h @@ -53,7 +53,7 @@ class QWindowsAccessibility : public QPlatformAccessibility public: QWindowsAccessibility(); static bool handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult); - void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE; + void notifyAccessibilityUpdate(QAccessibleEvent *event) override; static IAccessible *wrap(QAccessibleInterface *acc); static QWindow *windowHelper(const QAccessibleInterface *iface); }; diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp index 85aab84c2c..25b1577772 100644 --- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp +++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp @@ -1052,11 +1052,24 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accValue(VARIANT varID, BS return S_FALSE; } -HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR) +HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR value) { QAccessibleInterface *accessible = accessibleInterface(); accessibleDebugClientCalls(accessible); - return DISP_E_MEMBERNOTFOUND; + + if (!accessible || !accessible->isValid()) { + return E_FAIL; + } + + QString qstrValue = QString::fromWCharArray(value); + + if (accessible->valueInterface()) { + accessible->valueInterface()->setCurrentValue(qstrValue); + } else { + accessible->setText(QAccessible::Value, qstrValue); + } + + return S_OK; } // moz: [important] diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json index dd99e674ec..69f4a54d05 100644 --- a/src/plugins/platforms/windows/openglblacklists/default.json +++ b/src/plugins/platforms/windows/openglblacklists/default.json @@ -114,6 +114,18 @@ "features": [ "disable_desktopgl" ] - } + }, + { + "id": 10, + "description": "Intel(R) HD Graphics IronLake (Arrandale) crashes on makeCurrent QTBUG-53888", + "vendor_id": "0x8086", + "device_id": [ "0x0046" ], + "os": { + "type": "win" + }, + "features": [ + "disable_desktopgl" + ] + } ] } diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index ec6a8f62ae..a5c05bf1a3 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -56,6 +56,10 @@ # define WM_GESTURE 0x0119 #endif +#ifndef WM_DPICHANGED +# define WM_DPICHANGED 0x02E0 +#endif + QT_BEGIN_NAMESPACE namespace QtWindows @@ -96,12 +100,14 @@ enum WindowsEventType // Simplify event types FocusInEvent = WindowEventFlag + 17, FocusOutEvent = WindowEventFlag + 18, WhatsThisEvent = WindowEventFlag + 19, + DpiChangedEvent = WindowEventFlag + 21, MouseEvent = MouseEventFlag + 1, MouseWheelEvent = MouseEventFlag + 2, CursorEvent = MouseEventFlag + 3, TouchEvent = TouchEventFlag + 1, NonClientMouseEvent = NonClientEventFlag + MouseEventFlag + 1, NonClientHitTest = NonClientEventFlag + 2, + NonClientCreate = NonClientEventFlag + 3, KeyEvent = KeyEventFlag + 1, KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1, KeyboardLayoutChangeEvent = KeyEventFlag + 2, @@ -177,6 +183,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::HideEvent; case WM_SIZE: return QtWindows::ResizeEvent; + case WM_NCCREATE: + return QtWindows::NonClientCreate; case WM_NCCALCSIZE: return QtWindows::CalculateSize; case WM_NCHITTEST: @@ -263,6 +271,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI #endif case WM_GESTURE: return QtWindows::GestureEvent; + case WM_DPICHANGED: + return QtWindows::DpiChangedEvent; default: break; } diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h index 46a7fcc676..9e62266697 100644 --- a/src/plugins/platforms/windows/qwindowsbackingstore.h +++ b/src/plugins/platforms/windows/qwindowsbackingstore.h @@ -57,15 +57,15 @@ public: QWindowsBackingStore(QWindow *window); ~QWindowsBackingStore(); - QPaintDevice *paintDevice() Q_DECL_OVERRIDE; - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) Q_DECL_OVERRIDE; - void resize(const QSize &size, const QRegion &r) Q_DECL_OVERRIDE; - bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; - void beginPaint(const QRegion &) Q_DECL_OVERRIDE; + QPaintDevice *paintDevice() override; + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset) override; + void resize(const QSize &size, const QRegion &r) override; + bool scroll(const QRegion &area, int dx, int dy) override; + void beginPaint(const QRegion &) override; HDC getDC() const; - QImage toImage() const Q_DECL_OVERRIDE; + QImage toImage() const override; private: QScopedPointer<QWindowsNativeImage> m_image; diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index d4a7e27762..11cd1756e6 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -149,8 +149,7 @@ static void cleanClipboardPostRoutine() QWindowsClipboard *QWindowsClipboard::m_instance = 0; -QWindowsClipboard::QWindowsClipboard() : - m_data(0), m_clipboardViewer(0), m_nextClipboardViewer(0), m_formatListenerRegistered(false) +QWindowsClipboard::QWindowsClipboard() { QWindowsClipboard::m_instance = this; qAddPostRoutine(cleanClipboardPostRoutine); diff --git a/src/plugins/platforms/windows/qwindowsclipboard.h b/src/plugins/platforms/windows/qwindowsclipboard.h index 992d34d492..4f3e7437f6 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.h +++ b/src/plugins/platforms/windows/qwindowsclipboard.h @@ -52,8 +52,8 @@ class QWindowsClipboardRetrievalMimeData : public QWindowsInternalMimeData { public: protected: - IDataObject *retrieveDataObject() const Q_DECL_OVERRIDE; - void releaseDataObject(IDataObject *) const Q_DECL_OVERRIDE; + IDataObject *retrieveDataObject() const override; + void releaseDataObject(IDataObject *) const override; }; class QWindowsClipboard : public QPlatformClipboard @@ -64,10 +64,10 @@ public: void registerViewer(); // Call in initialization, when context is up. void cleanup(); - QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; - bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; - bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) override; + bool supportsMode(QClipboard::Mode mode) const override; + bool ownsMode(QClipboard::Mode mode) const override; inline bool clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); @@ -85,10 +85,10 @@ private: static QWindowsClipboard *m_instance; QWindowsClipboardRetrievalMimeData m_retrievalData; - QWindowsOleDataObject *m_data; - HWND m_clipboardViewer; - HWND m_nextClipboardViewer; - bool m_formatListenerRegistered; + QWindowsOleDataObject *m_data = nullptr; + HWND m_clipboardViewer = 0; + HWND m_nextClipboardViewer = 0; + bool m_formatListenerRegistered = false; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index bb9ed730a3..5745fc6d19 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -68,6 +68,7 @@ #include <QtCore/QHash> #include <QtCore/QStringList> #include <QtCore/QDebug> +#include <QtCore/QOperatingSystemVersion> #include <QtCore/QSysInfo> #include <QtCore/QScopedArrayPointer> #include <QtCore/private/qsystemlibrary_p.h> @@ -127,6 +128,28 @@ static inline QWindowsSessionManager *platformSessionManager() { } #endif +static inline int windowDpiAwareness(HWND hwnd) +{ + return QWindowsContext::user32dll.getWindowDpiAwarenessContext && QWindowsContext::user32dll.getWindowDpiAwarenessContext + ? QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext(QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd)) + : -1; +} + +// Note: This only works within WM_NCCREATE +static bool enableNonClientDpiScaling(HWND hwnd) +{ + bool result = false; + if (QWindowsContext::user32dll.enableNonClientDpiScaling && windowDpiAwareness(hwnd) == 2) { + result = QWindowsContext::user32dll.enableNonClientDpiScaling(hwnd) != FALSE; + if (!result) { + const DWORD errorCode = GetLastError(); + qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)", + hwnd, errorCode); + } + } + return result; +} + /*! \class QWindowsUser32DLL \brief Struct that contains dynamically resolved symbols of User32.dll. @@ -142,14 +165,6 @@ static inline QWindowsSessionManager *platformSessionManager() { \internal \ingroup qt-lighthouse-win */ -QWindowsUser32DLL::QWindowsUser32DLL() : - isTouchWindow(0), - registerTouchWindow(0), unregisterTouchWindow(0), - getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0), - addClipboardFormatListener(0), removeClipboardFormatListener(0), - getDisplayAutoRotationPreferences(0), setDisplayAutoRotationPreferences(0) -{ -} void QWindowsUser32DLL::init() { @@ -161,6 +176,12 @@ void QWindowsUser32DLL::init() getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences"); setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences"); + + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10) { // Appears in 10.0.14393, October 2016 + enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling"); + getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext"); + getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext"); + } } bool QWindowsUser32DLL::initTouch() @@ -176,16 +197,9 @@ bool QWindowsUser32DLL::initTouch() return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; } -QWindowsShcoreDLL::QWindowsShcoreDLL() - : getProcessDpiAwareness(0) - , setProcessDpiAwareness(0) - , getDpiForMonitor(0) -{ -} - void QWindowsShcoreDLL::init() { - if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8_1) + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1) return; QSystemLibrary library(QStringLiteral("SHCore")); getProcessDpiAwareness = (GetProcessDpiAwareness)library.resolve("GetProcessDpiAwareness"); @@ -211,14 +225,13 @@ QWindowsContext *QWindowsContext::m_instance = 0; typedef QHash<HWND, QWindowsWindow *> HandleBaseWindowHash; struct QWindowsContextPrivate { - QWindowsContextPrivate(); - unsigned m_systemInfo; + unsigned m_systemInfo = 0; QSet<QString> m_registeredWindowClassNames; HandleBaseWindowHash m_windows; - HDC m_displayContext; - int m_defaultDPI; + HDC m_displayContext = 0; + int m_defaultDPI = 96; QWindowsKeyMapper m_keyMapper; QWindowsMouseHandler m_mouseHandler; QWindowsMimeConverter m_mimeConverter; @@ -229,15 +242,13 @@ struct QWindowsContextPrivate { #endif const HRESULT m_oleInitializeResult; const QByteArray m_eventType; - QWindow *m_lastActiveWindow; - bool m_asyncExpose; + QWindow *m_lastActiveWindow = nullptr; + bool m_asyncExpose = false; }; QWindowsContextPrivate::QWindowsContextPrivate() - : m_systemInfo(0) - , m_oleInitializeResult(OleInitialize(NULL)) + : m_oleInitializeResult(OleInitialize(NULL)) , m_eventType(QByteArrayLiteral("windows_generic_MSG")) - , m_lastActiveWindow(0), m_asyncExpose(0) { QWindowsContext::user32dll.init(); QWindowsContext::shcoredll.init(); @@ -379,6 +390,11 @@ void QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreat d->m_creationContext = ctx; } +QSharedPointer<QWindowCreationContext> QWindowsContext::windowCreationContext() const +{ + return d->m_creationContext; +} + int QWindowsContext::defaultDPI() const { return d->m_defaultDPI; @@ -807,7 +823,9 @@ static inline QWindowsInputContext *windowsInputContext() bool QWindowsContext::windowsProc(HWND hwnd, UINT message, QtWindows::WindowsEventType et, - WPARAM wParam, LPARAM lParam, LRESULT *result) + WPARAM wParam, LPARAM lParam, + LRESULT *result, + QWindowsWindow **platformWindowPtr) { *result = 0; @@ -838,6 +856,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, } QWindowsWindow *platformWindow = findPlatformWindow(hwnd); + *platformWindowPtr = platformWindow; if (platformWindow) { filterResult = 0; if (QWindowSystemInterface::handleNativeEvent(platformWindow->window(), d->m_eventType, &msg, &filterResult)) { @@ -919,6 +938,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::MoveEvent: d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); return true; + case QtWindows::NonClientCreate: + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10 && d->m_creationContext->window->isTopLevel()) + enableNonClientDpiScaling(msg.hwnd); + return false; case QtWindows::CalculateSize: return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->customMargins, msg, result); case QtWindows::GeometryChangingEvent: @@ -1026,9 +1049,6 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return true; case QtWindows::ThemeChanged: { // Switch from Aero to Classic changes margins. - const Qt::WindowFlags flags = platformWindow->window()->flags(); - if ((flags & Qt::WindowType_Mask) != Qt::Desktop && !(flags & Qt::FramelessWindowHint)) - platformWindow->setFlag(QWindowsWindow::FrameDirty); if (QWindowsTheme *theme = QWindowsTheme::instance()) theme->windowsThemeChanged(platformWindow->window()); return true; @@ -1068,6 +1088,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return true; #endif } break; + case QtWindows::DpiChangedEvent: { + platformWindow->setFlag(QWindowsWindow::WithinDpiChanged); + const RECT *prcNewWindow = reinterpret_cast<RECT *>(lParam); + SetWindowPos(hwnd, NULL, prcNewWindow->left, prcNewWindow->top, + prcNewWindow->right - prcNewWindow->left, + prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE); + platformWindow->clearFlag(QWindowsWindow::WithinDpiChanged); + return true; + } #if !defined(QT_NO_SESSIONMANAGER) case QtWindows::QueryEndSessionApplicationEvent: { QWindowsSessionManager *sessionManager = platformSessionManager(); @@ -1201,6 +1230,37 @@ QTouchDevice *QWindowsContext::touchDevice() const return d->m_mouseHandler.touchDevice(); } +static inline bool isEmptyRect(const RECT &rect) +{ + return rect.right - rect.left == 0 && rect.bottom - rect.top == 0; +} + +static inline QMargins marginsFromRects(const RECT &frame, const RECT &client) +{ + return QMargins(client.left - frame.left, client.top - frame.top, + frame.right - client.right, frame.bottom - client.bottom); +} + +static RECT rectFromNcCalcSize(UINT message, WPARAM wParam, LPARAM lParam, int n) +{ + RECT result = {0, 0, 0, 0}; + if (message == WM_NCCALCSIZE && wParam) + result = reinterpret_cast<const NCCALCSIZE_PARAMS *>(lParam)->rgrc[n]; + return result; +} + +static inline bool isMinimized(HWND hwnd) +{ + WINDOWPLACEMENT windowPlacement; + windowPlacement.length = sizeof(WINDOWPLACEMENT); + return GetWindowPlacement(hwnd, &windowPlacement) && windowPlacement.showCmd == SW_SHOWMINIMIZED; +} + +static inline bool isTopLevel(HWND hwnd) +{ + return (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) == 0; +} + /*! \brief Windows functions for actual windows. @@ -1214,7 +1274,9 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR { LRESULT result; const QtWindows::WindowsEventType et = windowsEventType(message, wParam, lParam); - const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result); + QWindowsWindow *platformWindow = nullptr; + const RECT ncCalcSizeFrame = rectFromNcCalcSize(message, wParam, lParam, 0); + const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow); if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) { if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) { qCDebug(lcQpaEvents) << "EVENT: hwd=" << hwnd << eventName << hex << "msg=0x" << message @@ -1224,6 +1286,24 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR } if (!handled) result = DefWindowProc(hwnd, message, wParam, lParam); + + // Capture WM_NCCALCSIZE on top level windows and obtain the window margins by + // subtracting the rectangles before and after processing. This will correctly + // capture client code overriding the message and allow for per-monitor margins + // for High DPI (QTBUG-53255, QTBUG-40578). + if (message == WM_NCCALCSIZE && !isEmptyRect(ncCalcSizeFrame) && isTopLevel(hwnd) && !isMinimized(hwnd)) { + const QMargins margins = + marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0)); + if (margins.left() >= 0) { + if (platformWindow) { + platformWindow->setFrameMargins(margins); + } else { + const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext(); + if (!ctx.isNull()) + ctx->margins = margins; + } + } + } return result; } diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 9dfde67797..b50010321b 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -80,7 +80,6 @@ class QTouchDevice; struct QWindowsUser32DLL { - QWindowsUser32DLL(); inline void init(); inline bool initTouch(); @@ -94,30 +93,36 @@ struct QWindowsUser32DLL typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND); typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *); typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD); + typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND); + typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND); + typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int); // Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC). - IsTouchWindow isTouchWindow; - RegisterTouchWindow registerTouchWindow; - UnregisterTouchWindow unregisterTouchWindow; - GetTouchInputInfo getTouchInputInfo; - CloseTouchInputHandle closeTouchInputHandle; + IsTouchWindow isTouchWindow = nullptr; + RegisterTouchWindow registerTouchWindow = nullptr; + UnregisterTouchWindow unregisterTouchWindow = nullptr; + GetTouchInputInfo getTouchInputInfo = nullptr; + CloseTouchInputHandle closeTouchInputHandle = nullptr; // Windows Vista onwards - SetProcessDPIAware setProcessDPIAware; + SetProcessDPIAware setProcessDPIAware = nullptr; // Clipboard listeners are present on Windows Vista onwards // but missing in MinGW 4.9 stub libs. Can be removed in MinGW 5. - AddClipboardFormatListener addClipboardFormatListener; - RemoveClipboardFormatListener removeClipboardFormatListener; + AddClipboardFormatListener addClipboardFormatListener = nullptr; + RemoveClipboardFormatListener removeClipboardFormatListener = nullptr; // Rotation API - GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences; - SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences; + GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences = nullptr; + SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences = nullptr; + + EnableNonClientDpiScaling enableNonClientDpiScaling = nullptr; + GetWindowDpiAwarenessContext getWindowDpiAwarenessContext = nullptr; + GetAwarenessFromDpiAwarenessContext getAwarenessFromDpiAwarenessContext = nullptr; }; // Shell scaling library (Windows 8.1 onwards) struct QWindowsShcoreDLL { - QWindowsShcoreDLL(); void init(); inline bool isValid() const { return getProcessDpiAwareness && setProcessDpiAwareness && getDpiForMonitor; } @@ -125,9 +130,9 @@ struct QWindowsShcoreDLL { typedef HRESULT (WINAPI *SetProcessDpiAwareness)(int); typedef HRESULT (WINAPI *GetDpiForMonitor)(HMONITOR,int,UINT *,UINT *); - GetProcessDpiAwareness getProcessDpiAwareness; - SetProcessDpiAwareness setProcessDpiAwareness; - GetDpiForMonitor getDpiForMonitor; + GetProcessDpiAwareness getProcessDpiAwareness = nullptr; + SetProcessDpiAwareness setProcessDpiAwareness = nullptr; + GetDpiForMonitor getDpiForMonitor = nullptr; }; class QWindowsContext @@ -181,12 +186,14 @@ public: inline bool windowsProc(HWND hwnd, UINT message, QtWindows::WindowsEventType et, - WPARAM wParam, LPARAM lParam, LRESULT *result); + WPARAM wParam, LPARAM lParam, LRESULT *result, + QWindowsWindow **platformWindowPtr); QWindow *keyGrabber() const; void setKeyGrabber(QWindow *hwnd); void setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx); + QSharedPointer<QWindowCreationContext> windowCreationContext() const; void setTabletAbsoluteRange(int a); void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness); diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 6fff5f9ab1..df2e22733b 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -104,9 +104,9 @@ public: explicit QWindowsCursor(const QPlatformScreen *screen); - void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE; - QPoint pos() const Q_DECL_OVERRIDE; - void setPos(const QPoint &pos) Q_DECL_OVERRIDE; + void changeCursor(QCursor * widgetCursor, QWindow * widget) override; + QPoint pos() const override; + void setPos(const QPoint &pos) override; static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1); static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); } diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 8f1358de6c..63f78cfa63 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -66,9 +66,11 @@ #include <QtCore/QMutexLocker> #include <QtCore/QUuid> #include <QtCore/QRegularExpression> +#include <QtCore/QTemporaryFile> #include <QtCore/private/qsystemlibrary_p.h> #include <algorithm> +#include <vector> #include <QtCore/qt_windows.h> @@ -212,15 +214,6 @@ private: */ template <class BaseClass> -QWindowsDialogHelperBase<BaseClass>::QWindowsDialogHelperBase() : - m_nativeDialog(0), - m_ownerWindow(0), - m_timerId(0), - m_thread(0) -{ -} - -template <class BaseClass> void QWindowsDialogHelperBase<BaseClass>::cleanupThread() { if (m_thread) { // Thread may be running if the dialog failed to close. @@ -549,11 +542,11 @@ public: IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; } QWindowsNativeFileDialogEventHandler(QWindowsNativeFileDialogBase *nativeFileDialog) : - m_ref(1), m_nativeFileDialog(nativeFileDialog) {} + m_nativeFileDialog(nativeFileDialog) {} virtual ~QWindowsNativeFileDialogEventHandler() {} private: - long m_ref; + long m_ref = 1; QWindowsNativeFileDialogBase *m_nativeFileDialog; }; @@ -570,6 +563,235 @@ IFileDialogEvents *QWindowsNativeFileDialogEventHandler::create(QWindowsNativeFi } /*! + \class QWindowsShellItem + \brief Wrapper for IShellItem + + \sa QWindowsNativeFileDialogBase + \internal + \ingroup qt-lighthouse-win +*/ +class QWindowsShellItem +{ +public: + typedef std::vector<IShellItem *> IShellItems; + + explicit QWindowsShellItem(IShellItem *item); + + SFGAOF attributes() const { return m_attributes; } + QString normalDisplay() const // base name, usually + { return displayName(m_item, SIGDN_NORMALDISPLAY); } + QString desktopAbsoluteParsing() const + { return displayName(m_item, SIGDN_DESKTOPABSOLUTEPARSING); } + QString path() const; // Only set for 'FileSystem' (SFGAO_FILESYSTEM) items + QUrl url() const; + + bool isFileSystem() const { return (m_attributes & SFGAO_FILESYSTEM) != 0; } + bool isDir() const { return (m_attributes & SFGAO_FOLDER) != 0; } + // Copy using IFileOperation + bool canCopy() const { return (m_attributes & SFGAO_CANCOPY) != 0; } + // Supports IStream + bool canStream() const { return (m_attributes & SFGAO_STREAM) != 0; } + + bool copyData(QIODevice *out); + + static IShellItems itemsFromItemArray(IShellItemArray *items); + +#ifndef QT_NO_DEBUG_STREAM + void format(QDebug &d) const; +#endif + +private: + static QString displayName(IShellItem *item, SIGDN mode); + static QString libraryItemDefaultSaveFolder(IShellItem *item); + QUrl urlValue() const; + + IShellItem *m_item; + SFGAOF m_attributes; +}; + +QWindowsShellItem::QWindowsShellItem(IShellItem *item) + : m_item(item) + , m_attributes(0) +{ + if (FAILED(item->GetAttributes(SFGAO_CAPABILITYMASK | SFGAO_DISPLAYATTRMASK | SFGAO_CONTENTSMASK | SFGAO_STORAGECAPMASK, &m_attributes))) + m_attributes = 0; +} + +QString QWindowsShellItem::path() const +{ + if (isFileSystem()) + return QDir::cleanPath(QWindowsShellItem::displayName(m_item, SIGDN_FILESYSPATH)); + // Check for a "Library" item (Windows 7) + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7 && isDir()) + return QWindowsShellItem::libraryItemDefaultSaveFolder(m_item); + return QString(); +} + +QUrl QWindowsShellItem::urlValue() const // plain URL as returned by SIGDN_URL, not set for all items +{ + QUrl result; + const QString urlString = displayName(m_item, SIGDN_URL); + if (!urlString.isEmpty()) { + const QUrl parsed = QUrl(urlString); + if (parsed.isValid()) { + result = parsed; + } else { + qWarning("%s: Unable to decode URL \"%s\": %s", __FUNCTION__, + qPrintable(urlString), qPrintable(parsed.errorString())); + } + } + return result; +} + +QUrl QWindowsShellItem::url() const +{ + // Prefer file if existent to avoid any misunderstandings about UNC shares + const QString fsPath = path(); + if (!fsPath.isEmpty()) + return QUrl::fromLocalFile(fsPath); + const QUrl urlV = urlValue(); + if (urlV.isValid()) + return urlV; + // Last resort: encode the absolute desktop parsing id as data URL + const QString data = QStringLiteral("data:text/plain;base64,") + + QLatin1String(desktopAbsoluteParsing().toLatin1().toBase64()); + return QUrl(data); +} + +QString QWindowsShellItem::displayName(IShellItem *item, SIGDN mode) +{ + LPWSTR name = nullptr; + QString result; + if (SUCCEEDED(item->GetDisplayName(mode, &name))) { + result = QString::fromWCharArray(name); + CoTaskMemFree(name); + } + return result; +} + +QWindowsShellItem::IShellItems QWindowsShellItem::itemsFromItemArray(IShellItemArray *items) +{ + IShellItems result; + DWORD itemCount = 0; + if (FAILED(items->GetCount(&itemCount)) || itemCount == 0) + return result; + result.reserve(itemCount); + for (DWORD i = 0; i < itemCount; ++i) { + IShellItem *item = nullptr; + if (SUCCEEDED(items->GetItemAt(i, &item))) + result.push_back(item); + } + return result; +} + +bool QWindowsShellItem::copyData(QIODevice *out) +{ + if (!canCopy() || !canStream()) + return false; + IStream *istream = nullptr; + HRESULT hr = m_item->BindToHandler(NULL, BHID_Stream, IID_PPV_ARGS(&istream)); + if (FAILED(hr)) + return false; + enum : ULONG { bufSize = 102400 }; + char buffer[bufSize]; + ULONG bytesRead; + forever { + bytesRead = 0; + hr = istream->Read(buffer, bufSize, &bytesRead); // S_FALSE: EOF reached + if ((hr == S_OK || hr == S_FALSE) && bytesRead) + out->write(buffer, bytesRead); + else + break; + } + istream->Release(); + return hr == S_OK || hr == S_FALSE; +} + +// Helper for "Libraries": collections of folders appearing from Windows 7 +// on, visible in the file dialogs. + +// Load a library from a IShellItem (sanitized copy of the inline function +// SHLoadLibraryFromItem from ShObjIdl.h, which does not exist for MinGW). +static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode) +{ + // ID symbols present from Windows 7 on: + static const CLSID classId_ShellLibrary = {0xd9b3211d, 0xe57f, 0x4426, {0xaa, 0xef, 0x30, 0xa8, 0x6, 0xad, 0xd3, 0x97}}; + static const IID iId_IShellLibrary = {0x11a66efa, 0x382e, 0x451a, {0x92, 0x34, 0x1e, 0xe, 0x12, 0xef, 0x30, 0x85}}; + + IShellLibrary *helper = nullptr; + IShellLibrary *result = nullptr; + if (SUCCEEDED(CoCreateInstance(classId_ShellLibrary, NULL, CLSCTX_INPROC_SERVER, iId_IShellLibrary, reinterpret_cast<void **>(&helper)))) + if (SUCCEEDED(helper->LoadLibraryFromItem(libraryItem, mode))) + helper->QueryInterface(iId_IShellLibrary, reinterpret_cast<void **>(&result)); + if (helper) + helper->Release(); + return result; +} + +// Return default save folders of a library-type item. +QString QWindowsShellItem::libraryItemDefaultSaveFolder(IShellItem *item) +{ + QString result; + if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) { + IShellItem *item = Q_NULLPTR; + if (SUCCEEDED(library->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, reinterpret_cast<void **>(&item)))) { + result = QDir::cleanPath(QWindowsShellItem::displayName(item, SIGDN_FILESYSPATH)); + item->Release(); + } + library->Release(); + } + return result; +} + +#ifndef QT_NO_DEBUG_STREAM +void QWindowsShellItem::format(QDebug &d) const +{ + d << "attributes=0x" << hex << attributes() << dec; + if (isFileSystem()) + d << " [filesys]"; + if (isDir()) + d << " [dir]"; + if (canStream()) + d << " [stream]"; + if (canCopy()) + d << " [copyable]"; + d << ", normalDisplay=\"" << normalDisplay() + << "\", desktopAbsoluteParsing=\"" << desktopAbsoluteParsing() << '"'; + const QString pathS = path(); + if (!pathS.isEmpty()) + d << ", path=\"" << pathS << '"'; + const QUrl urlV = urlValue(); + if (urlV.isValid()) + d << "\", url=" << urlV; +} + +QDebug operator<<(QDebug d, const QWindowsShellItem &i) +{ + QDebugStateSaver saver(d); + d.nospace(); + d.noquote(); + d << "QShellItem("; + i.format(d); + d << ')'; + return d; +} + +QDebug operator<<(QDebug d, IShellItem *i) +{ + QDebugStateSaver saver(d); + d.nospace(); + d.noquote(); + d << "IShellItem(" << static_cast<const void *>(i); + if (i) { + d << ", "; + QWindowsShellItem(i).format(d); + } + d << ')'; + return d; +} +#endif // !QT_NO_DEBUG_STREAM + +/*! \class QWindowsNativeFileDialogBase \brief Windows native file dialog wrapper around IFileOpenDialog, IFileSaveDialog. @@ -590,12 +812,12 @@ public: inline static QWindowsNativeFileDialogBase *create(QFileDialogOptions::AcceptMode am, const QWindowsFileDialogSharedData &data); - void setWindowTitle(const QString &title) Q_DECL_OVERRIDE; + void setWindowTitle(const QString &title) override; inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::AcceptMode acceptMode, QFileDialogOptions::FileDialogOptions options); inline void setDirectory(const QUrl &directory); inline void updateDirectory() { setDirectory(m_data.directory()); } inline QString directory() const; - void doExec(HWND owner = 0) Q_DECL_OVERRIDE; + void doExec(HWND owner = 0) override; virtual void setNameFilters(const QStringList &f); inline void selectNameFilter(const QString &filter); inline void updateSelectedNameFilter() { selectNameFilter(m_data.selectedNameFilter()); } @@ -624,36 +846,31 @@ signals: void filterSelected(const QString & filter); public slots: - void close() Q_DECL_OVERRIDE; + void close() override; protected: explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data); bool init(const CLSID &clsId, const IID &iid); void setDefaultSuffixSys(const QString &s); inline IFileDialog * fileDialog() const { return m_fileDialog; } - static QString itemPath(IShellItem *item); - static QList<QUrl> libraryItemFolders(IShellItem *item); - static QString libraryItemDefaultSaveFolder(IShellItem *item); - static int itemPaths(IShellItemArray *items, QList<QUrl> *fileResult = 0); static IShellItem *shellItem(const QUrl &url); const QWindowsFileDialogSharedData &data() const { return m_data; } QWindowsFileDialogSharedData &data() { return m_data; } private: - IFileDialog *m_fileDialog; - IFileDialogEvents *m_dialogEvents; - DWORD m_cookie; + IFileDialog *m_fileDialog = nullptr; + IFileDialogEvents *m_dialogEvents = nullptr; + DWORD m_cookie = 0; QStringList m_nameFilters; - bool m_hideFiltersDetails; - bool m_hasDefaultSuffix; + bool m_hideFiltersDetails = false; + bool m_hasDefaultSuffix = false; QWindowsFileDialogSharedData m_data; QString m_title; }; QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data) : - m_fileDialog(0), m_dialogEvents(0), m_cookie(0), m_hideFiltersDetails(false), - m_hasDefaultSuffix(false), m_data(data) + m_data(data) { } @@ -753,7 +970,7 @@ QString QWindowsNativeFileDialogBase::directory() const QString result; IShellItem *item = 0; if (m_fileDialog && SUCCEEDED(m_fileDialog->GetFolder(&item)) && item) { - result = QWindowsNativeFileDialogBase::itemPath(item); + result = QWindowsShellItem(item).path(); item->Release(); } return result; @@ -807,113 +1024,6 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, qErrnoWarning("%s: SetOptions() failed", __FUNCTION__); } -#if defined(__IShellLibrary_INTERFACE_DEFINED__) // Windows SDK 7 - -// Helper for "Libraries": collections of folders appearing from Windows 7 -// on, visible in the file dialogs. - -// Load a library from a IShellItem (sanitized copy of the inline function -// SHLoadLibraryFromItem from ShObjIdl.h, which does not exist for MinGW). -static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode) -{ - // ID symbols present from Windows 7 on: - static const CLSID classId_ShellLibrary = {0xd9b3211d, 0xe57f, 0x4426, {0xaa, 0xef, 0x30, 0xa8, 0x6, 0xad, 0xd3, 0x97}}; - static const IID iId_IShellLibrary = {0x11a66efa, 0x382e, 0x451a, {0x92, 0x34, 0x1e, 0xe, 0x12, 0xef, 0x30, 0x85}}; - - IShellLibrary *helper = 0; - IShellLibrary *result = 0; - if (SUCCEEDED(CoCreateInstance(classId_ShellLibrary, NULL, CLSCTX_INPROC_SERVER, iId_IShellLibrary, reinterpret_cast<void **>(&helper)))) - if (SUCCEEDED(helper->LoadLibraryFromItem(libraryItem, mode))) - helper->QueryInterface(iId_IShellLibrary, reinterpret_cast<void **>(&result)); - if (helper) - helper->Release(); - return result; -} - -// Return all folders of a library-type item. -QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item) -{ - QList<QUrl> result; - if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) { - IShellItemArray *itemArray = 0; - if (SUCCEEDED(library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, reinterpret_cast<void **>(&itemArray)))) { - QWindowsNativeFileDialogBase::itemPaths(itemArray, &result); - itemArray->Release(); - } - library->Release(); - } - return result; -} - -// Return default save folders of a library-type item. -QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *item) -{ - QString result; - if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) { - IShellItem *item = 0; - if (SUCCEEDED(library->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, reinterpret_cast<void **>(&item)))) { - result = QWindowsNativeFileDialogBase::itemPath(item); - item->Release(); - } - library->Release(); - } - return result; -} - -#else // __IShellLibrary_INTERFACE_DEFINED__ - -QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *) -{ - return QList<QUrl>(); -} - -QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *) -{ - return QString(); -} - -#endif // !__IShellLibrary_INTERFACE_DEFINED__ - -QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item) -{ - SFGAOF attributes = 0; - // Check whether it has a file system representation? - if (FAILED(item->GetAttributes(SFGAO_FILESYSTEM, &attributes))) - return QString(); - if (attributes & SFGAO_FILESYSTEM) { - LPWSTR name = 0; - QString result; - if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &name))) { - result = QDir::cleanPath(QString::fromWCharArray(name)); - CoTaskMemFree(name); - } - return result; - } - // Check for a "Library" item - if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) - return QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(item); - return QString(); -} - -int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items, - QList<QUrl> *result /* = 0 */) -{ - DWORD itemCount = 0; - if (result) - result->clear(); - if (FAILED(items->GetCount(&itemCount))) - return 0; - if (result && itemCount) { - result->reserve(itemCount); - for (DWORD i = 0; i < itemCount; ++i) { - IShellItem *item = 0; - if (SUCCEEDED(items->GetItemAt(i, &item))) - result->push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item))); - } - } - return itemCount; -} - // Split a list of name filters into description and actual filters struct FilterSpec { @@ -1011,6 +1121,13 @@ void QWindowsNativeFileDialogBase::setDefaultSuffixSys(const QString &s) m_fileDialog->SetDefaultExtension(wSuffix); } +static inline IFileDialog2 *getFileDialog2(IFileDialog *fileDialog) +{ + IFileDialog2 *result; + return SUCCEEDED(fileDialog->QueryInterface(IID_IFileDialog2, reinterpret_cast<void **>(&result))) + ? result : nullptr; +} + void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel l, const QString &text) { wchar_t *wText = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(text.utf16())); @@ -1021,8 +1138,13 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel case QFileDialogOptions::Accept: m_fileDialog->SetOkButtonLabel(wText); break; - case QFileDialogOptions::LookIn: case QFileDialogOptions::Reject: + if (IFileDialog2 *dialog2 = getFileDialog2(m_fileDialog)) { + dialog2->SetCancelButtonLabel(wText); + dialog2->Release(); + } + break; + case QFileDialogOptions::LookIn: case QFileDialogOptions::FileType: case QFileDialogOptions::DialogLabelCount: break; @@ -1087,7 +1209,7 @@ QString QWindowsNativeFileDialogBase::selectedNameFilter() const void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item) { if (item) { - const QUrl directory = QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)); + const QUrl directory = QWindowsShellItem(item).url(); m_data.setDirectory(directory); emit directoryEntered(directory); } @@ -1165,9 +1287,9 @@ class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase public: explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data) : QWindowsNativeFileDialogBase(data) {} - void setNameFilters(const QStringList &f) Q_DECL_OVERRIDE; - QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - QList<QUrl> dialogResult() const Q_DECL_OVERRIDE; + void setNameFilters(const QStringList &f) override; + QList<QUrl> selectedFiles() const override; + QList<QUrl> dialogResult() const override; }; // Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo". @@ -1210,7 +1332,7 @@ QList<QUrl> QWindowsNativeSaveFileDialog::dialogResult() const QList<QUrl> result; IShellItem *item = 0; if (SUCCEEDED(fileDialog()->GetResult(&item)) && item) - result.push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item))); + result.append(QWindowsShellItem(item).url()); return result; } @@ -1220,7 +1342,7 @@ QList<QUrl> QWindowsNativeSaveFileDialog::selectedFiles() const IShellItem *item = 0; const HRESULT hr = fileDialog()->GetCurrentSelection(&item); if (SUCCEEDED(hr) && item) { - result.push_back(QUrl::fromLocalFile(QWindowsNativeSaveFileDialog::itemPath(item))); + result.append(QWindowsShellItem(item).url()); item->Release(); } return result; @@ -1241,20 +1363,69 @@ class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase public: explicit QWindowsNativeOpenFileDialog(const QWindowsFileDialogSharedData &data) : QWindowsNativeFileDialogBase(data) {} - QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - QList<QUrl> dialogResult() const Q_DECL_OVERRIDE; + QList<QUrl> selectedFiles() const override; + QList<QUrl> dialogResult() const override; private: inline IFileOpenDialog *openFileDialog() const { return static_cast<IFileOpenDialog *>(fileDialog()); } }; +// Helpers for managing a list of temporary copies of items with no +// file system representation (SFGAO_FILESYSTEM unset, for example devices +// using MTP) returned by IFileOpenDialog. This emulates the behavior +// of the Win32 API GetOpenFileName() used in Qt 4 (QTBUG-57070). + +Q_GLOBAL_STATIC(QStringList, temporaryItemCopies) + +static void cleanupTemporaryItemCopies() +{ + for (const QString &file : qAsConst(*temporaryItemCopies())) + QFile::remove(file); +} + +static QString createTemporaryItemCopy(QWindowsShellItem &qItem) +{ + if (!qItem.canCopy() || !qItem.canStream()) + return QString(); + QString pattern = qItem.normalDisplay(); + const int lastDot = pattern.lastIndexOf(QLatin1Char('.')); + const QString placeHolder = QStringLiteral("_XXXXXX"); + if (lastDot >= 0) + pattern.insert(lastDot, placeHolder); + else + pattern.append(placeHolder); + + QTemporaryFile targetFile(QDir::tempPath() + QLatin1Char('/') + pattern); + targetFile.setAutoRemove(false); + if (!targetFile.open() || !qItem.copyData(&targetFile)) + return QString(); + const QString result = targetFile.fileName(); + if (temporaryItemCopies()->isEmpty()) + qAddPostRoutine(cleanupTemporaryItemCopies); + temporaryItemCopies()->append(result); + return result; +} + QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const { QList<QUrl> result; IShellItemArray *items = 0; - if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items) - QWindowsNativeFileDialogBase::itemPaths(items, &result); + if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items) { + for (IShellItem *item : QWindowsShellItem::itemsFromItemArray(items)) { + QWindowsShellItem qItem(item); + const QString path = qItem.path(); + if (path.isEmpty()) { + const QString temporaryCopy = createTemporaryItemCopy(qItem); + if (temporaryCopy.isEmpty()) + qWarning() << "Unable to create a local copy of" << qItem; + else + result.append(QUrl::fromLocalFile(temporaryCopy)); + } else { + result.append(qItem.url()); + } + } + } return result; } @@ -1263,8 +1434,16 @@ QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const QList<QUrl> result; IShellItemArray *items = 0; const HRESULT hr = openFileDialog()->GetSelectedItems(&items); - if (SUCCEEDED(hr) && items) - QWindowsNativeFileDialogBase::itemPaths(items, &result); + if (SUCCEEDED(hr) && items) { + for (IShellItem *item : QWindowsShellItem::itemsFromItemArray(items)) { + const QWindowsShellItem qItem(item); + const QUrl url = qItem.url(); + if (url.isValid()) + result.append(url); + else + qWarning().nospace() << __FUNCTION__<< ": Unable to obtain URL of " << qItem; + } + } return result; } @@ -1309,19 +1488,19 @@ class QWindowsFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDi { public: QWindowsFileDialogHelper() {} - virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const Q_DECL_OVERRIDE { return false; } - virtual bool defaultNameFilterDisables() const Q_DECL_OVERRIDE + bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const override { return false; } + bool defaultNameFilterDisables() const override { return false; } - virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; - virtual QUrl directory() const Q_DECL_OVERRIDE; - virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE; - virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - virtual void setFilter() Q_DECL_OVERRIDE; - virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE; - virtual QString selectedNameFilter() const Q_DECL_OVERRIDE; + void setDirectory(const QUrl &directory) override; + QUrl directory() const override; + void selectFile(const QUrl &filename) override; + QList<QUrl> selectedFiles() const override; + void setFilter() override; + void selectNameFilter(const QString &filter) override; + QString selectedNameFilter() const override; private: - QWindowsNativeDialogBase *createNativeDialog() Q_DECL_OVERRIDE; + QWindowsNativeDialogBase *createNativeDialog() override; inline QWindowsNativeFileDialogBase *nativeFileDialog() const { return static_cast<QWindowsNativeFileDialogBase *>(nativeDialog()); } @@ -1357,6 +1536,8 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog() result->setLabelText(QFileDialogOptions::FileName, opts->labelText(QFileDialogOptions::FileName)); if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept)) result->setLabelText(QFileDialogOptions::Accept, opts->labelText(QFileDialogOptions::Accept)); + if (opts->isLabelExplicitlySet(QFileDialogOptions::Reject)) + result->setLabelText(QFileDialogOptions::Reject, opts->labelText(QFileDialogOptions::Reject)); result->updateDirectory(); result->updateSelectedNameFilter(); const QList<QUrl> initialSelection = opts->initiallySelectedFiles(); @@ -1447,13 +1628,13 @@ public: static QWindowsXpNativeFileDialog *create(const OptionsPtr &options, const QWindowsFileDialogSharedData &data); - void setWindowTitle(const QString &t) Q_DECL_OVERRIDE { m_title = t; } - void doExec(HWND owner = 0) Q_DECL_OVERRIDE; + void setWindowTitle(const QString &t) override { m_title = t; } + void doExec(HWND owner = 0) override; int existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam); public slots: - void close() Q_DECL_OVERRIDE {} + void close() override {} private: typedef BOOL (APIENTRY *PtrGetOpenFileNameW)(LPOPENFILENAMEW); @@ -1689,19 +1870,19 @@ class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFile { public: QWindowsXpFileDialogHelper() {} - bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const Q_DECL_OVERRIDE { return false; } - bool defaultNameFilterDisables() const Q_DECL_OVERRIDE + bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const override { return false; } + bool defaultNameFilterDisables() const override { return true; } - void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; - QUrl directory() const Q_DECL_OVERRIDE; - void selectFile(const QUrl &url) Q_DECL_OVERRIDE; - QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE; - void setFilter() Q_DECL_OVERRIDE {} - void selectNameFilter(const QString &) Q_DECL_OVERRIDE; - QString selectedNameFilter() const Q_DECL_OVERRIDE; + void setDirectory(const QUrl &directory) override; + QUrl directory() const override; + void selectFile(const QUrl &url) override; + QList<QUrl> selectedFiles() const override; + void setFilter() override {} + void selectNameFilter(const QString &) override; + QString selectedNameFilter() const override; private: - QWindowsNativeDialogBase *createNativeDialog() Q_DECL_OVERRIDE; + QWindowsNativeDialogBase *createNativeDialog() override; inline QWindowsXpNativeFileDialog *nativeFileDialog() const { return static_cast<QWindowsXpNativeFileDialog *>(nativeDialog()); } @@ -1773,13 +1954,13 @@ public: explicit QWindowsNativeColorDialog(const SharedPointerColor &color); - void setWindowTitle(const QString &) Q_DECL_OVERRIDE {} + void setWindowTitle(const QString &) override {} public slots: - void close() Q_DECL_OVERRIDE {} + void close() override {} private: - void doExec(HWND owner = 0) Q_DECL_OVERRIDE; + void doExec(HWND owner = 0) override; COLORREF m_customColors[CustomColorCount]; QPlatformDialogHelper::DialogCode m_code; diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h index b3101a1419..55f112c57a 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -69,19 +69,19 @@ public: typedef QSharedPointer<QWindowsNativeDialogBase> QWindowsNativeDialogBasePtr; ~QWindowsDialogHelperBase() { cleanupThread(); } - void exec() Q_DECL_OVERRIDE; + void exec() override; bool show(Qt::WindowFlags windowFlags, - Qt::WindowModality windowModality, - QWindow *parent) Q_DECL_OVERRIDE; - void hide() Q_DECL_OVERRIDE; + Qt::WindowModality windowModality, + QWindow *parent) override; + void hide() override; virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; } protected: - QWindowsDialogHelperBase(); + QWindowsDialogHelperBase() {} QWindowsNativeDialogBase *nativeDialog() const; inline bool hasNativeDialog() const { return m_nativeDialog; } - void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *) override; private: virtual QWindowsNativeDialogBase *createNativeDialog() = 0; @@ -91,9 +91,9 @@ private: void cleanupThread(); QWindowsNativeDialogBasePtr m_nativeDialog; - HWND m_ownerWindow; - int m_timerId; - QThread *m_thread; + HWND m_ownerWindow = 0; + int m_timerId = 0; + QThread *m_thread = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 26a5131927..550415e889 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -84,7 +84,7 @@ public: void setPixmap(const QPixmap &p); protected: - void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE + void paintEvent(QPaintEvent *) override { QPainter painter(this); painter.drawPixmap(0, 0, m_pixmap); @@ -190,6 +190,20 @@ static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState) return modifiers; } +static inline Qt::MouseButtons toQtMouseButtons(DWORD keyState) +{ + Qt::MouseButtons buttons = Qt::NoButton; + + if (keyState & MK_LBUTTON) + buttons |= Qt::LeftButton; + if (keyState & MK_RBUTTON) + buttons |= Qt::RightButton; + if (keyState & MK_MBUTTON) + buttons |= Qt::MidButton; + + return buttons; +} + /*! \class QWindowsOleDropSource \brief Implementation of IDropSource @@ -405,16 +419,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) break; } - // grfKeyState is broken on CE & some Windows XP versions, - // therefore we need to check the state manually - if ((GetAsyncKeyState(VK_LBUTTON) == 0) - && (GetAsyncKeyState(VK_MBUTTON) == 0) - && (GetAsyncKeyState(VK_RBUTTON) == 0)) { - hr = ResultFromScode(DRAGDROP_S_DROP); - break; - } - - const Qt::MouseButtons buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState); + const Qt::MouseButtons buttons = toQtMouseButtons(grfKeyState); if (m_currentButtons == Qt::NoButton) { m_currentButtons = buttons; } else { @@ -489,8 +494,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) \ingroup qt-lighthouse-win */ -QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) : - m_refs(1), m_window(w), m_chosenEffect(0), m_lastKeyState(0) +QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) : m_window(w) { qCDebug(lcQpaMime) << __FUNCTION__ << this << w; } @@ -538,7 +542,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState, QWindowsDrag *windowsDrag = QWindowsDrag::instance(); const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect); QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState); - QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState); + QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState); const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions); @@ -682,10 +686,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, bool QWindowsDrag::m_canceled = false; -QWindowsDrag::QWindowsDrag() : - m_dropDataObject(0), m_cachedDropTargetHelper(0) -{ -} +QWindowsDrag::QWindowsDrag() = default; QWindowsDrag::~QWindowsDrag() { diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h index e81bc7dc61..983f3a67b4 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.h +++ b/src/plugins/platforms/windows/qwindowsdrag.h @@ -54,7 +54,7 @@ class QPlatformScreen; class QWindowsDropMimeData : public QWindowsInternalMimeData { public: QWindowsDropMimeData() {} - IDataObject *retrieveDataObject() const Q_DECL_OVERRIDE; + IDataObject *retrieveDataObject() const override; }; class QWindowsOleDropTarget : public IDropTarget @@ -77,12 +77,12 @@ public: private: void handleDrag(QWindow *window, DWORD grfKeyState, const QPoint &, LPDWORD pdwEffect); - ULONG m_refs; + ULONG m_refs = 1; QWindow *const m_window; QRect m_answerRect; QPoint m_lastPoint; - DWORD m_chosenEffect; - DWORD m_lastKeyState; + DWORD m_chosenEffect = 0; + DWORD m_lastKeyState = 0; }; class QWindowsDrag : public QPlatformDrag @@ -91,12 +91,12 @@ public: QWindowsDrag(); virtual ~QWindowsDrag(); - QMimeData *platformDropData() Q_DECL_OVERRIDE { return &m_dropData; } + QMimeData *platformDropData() override { return &m_dropData; } - Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE; + Qt::DropAction drag(QDrag *drag) override; static QWindowsDrag *instance(); - void cancelDrag() Q_DECL_OVERRIDE { QWindowsDrag::m_canceled = true; } + void cancelDrag() override { QWindowsDrag::m_canceled = true; } static bool isCanceled() { return QWindowsDrag::m_canceled; } IDataObject *dropDataObject() const { return m_dropDataObject; } @@ -110,9 +110,9 @@ private: static bool m_canceled; QWindowsDropMimeData m_dropData; - IDataObject *m_dropDataObject; + IDataObject *m_dropDataObject = nullptr; - IDropTargetHelper* m_cachedDropTargetHelper; + IDropTargetHelper* m_cachedDropTargetHelper = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index a4738dc100..4632c9c157 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -384,8 +384,6 @@ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext, QPlatformOpenGLContext *share) : m_staticContext(staticContext) , m_eglDisplay(staticContext->display()) - , m_api(EGL_OPENGL_ES_API) - , m_swapInterval(-1) { if (!m_staticContext) return; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 48a19f81e5..47878a7169 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -117,12 +117,12 @@ public: EGLDisplay display() const { return m_display; } - QWindowsOpenGLContext *createContext(QOpenGLContext *context) Q_DECL_OVERRIDE; - void *moduleHandle() const Q_DECL_OVERRIDE { return libGLESv2.moduleHandle(); } - QOpenGLContext::OpenGLModuleType moduleType() const Q_DECL_OVERRIDE { return QOpenGLContext::LibGLES; } + QWindowsOpenGLContext *createContext(QOpenGLContext *context) override; + void *moduleHandle() const override { return libGLESv2.moduleHandle(); } + QOpenGLContext::OpenGLModuleType moduleType() const override { return QOpenGLContext::LibGLES; } - void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE; - void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE; + void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) override; + void destroyWindowSurface(void *nativeSurface) override; QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat); @@ -145,18 +145,18 @@ public: QPlatformOpenGLContext *share); ~QWindowsEGLContext(); - bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void doneCurrent() Q_DECL_OVERRIDE; - void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; - QFunctionPointer getProcAddress(const char *procName) Q_DECL_OVERRIDE; + bool makeCurrent(QPlatformSurface *surface) override; + void doneCurrent() override; + void swapBuffers(QPlatformSurface *surface) override; + QFunctionPointer getProcAddress(const char *procName) override; - QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; } - bool isSharing() const Q_DECL_OVERRIDE { return m_shareContext != EGL_NO_CONTEXT; } - bool isValid() const Q_DECL_OVERRIDE { return m_eglContext != EGL_NO_CONTEXT; } + QSurfaceFormat format() const override { return m_format; } + bool isSharing() const override { return m_shareContext != EGL_NO_CONTEXT; } + bool isValid() const override { return m_eglContext != EGL_NO_CONTEXT; } - void *nativeContext() const Q_DECL_OVERRIDE { return m_eglContext; } - void *nativeDisplay() const Q_DECL_OVERRIDE { return m_eglDisplay; } - void *nativeConfig() const Q_DECL_OVERRIDE { return m_eglConfig; } + void *nativeContext() const override { return m_eglContext; } + void *nativeDisplay() const override { return m_eglDisplay; } + void *nativeConfig() const override { return m_eglConfig; } private: EGLConfig chooseConfig(const QSurfaceFormat &format); @@ -167,8 +167,8 @@ private: EGLDisplay m_eglDisplay; EGLConfig m_eglConfig; QSurfaceFormat m_format; - EGLenum m_api; - int m_swapInterval; + EGLenum m_api = EGL_OPENGL_ES_API; + int m_swapInterval = -1; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.h b/src/plugins/platforms/windows/qwindowsgdiintegration.h index 46af20a083..ec67a99bc9 100644 --- a/src/plugins/platforms/windows/qwindowsgdiintegration.h +++ b/src/plugins/platforms/windows/qwindowsgdiintegration.h @@ -51,9 +51,9 @@ public: explicit QWindowsGdiIntegration(const QStringList ¶mList); virtual ~QWindowsGdiIntegration(); - QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE; - QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE; - QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformNativeInterface *nativeInterface() const override; + QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const override; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; private: QScopedPointer<QWindowsGdiIntegrationPrivate> d; diff --git a/src/plugins/platforms/windows/qwindowsgdinativeinterface.h b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h index f0464bc823..c86d3cbb47 100644 --- a/src/plugins/platforms/windows/qwindowsgdinativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h @@ -48,7 +48,7 @@ class QWindowsGdiNativeInterface : public QWindowsNativeInterface { Q_OBJECT public: - void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE; + void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) override; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index c1eb664324..751807e897 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -825,13 +825,6 @@ static inline QOpenGLContextData createDummyWindowOpenGLContextData() \ingroup qt-lighthouse-win */ -QWindowsOpenGLContextFormat::QWindowsOpenGLContextFormat() : - profile(QSurfaceFormat::NoProfile), - version(0), - options(0) -{ -} - QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current() { QWindowsOpenGLContextFormat result; diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index 048b22bbf7..dfaa428520 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -73,24 +73,23 @@ struct QWindowsOpenGLAdditionalFormat struct QOpenGLContextData { QOpenGLContextData(HGLRC r, HWND h, HDC d) : renderingContext(r), hwnd(h), hdc(d) {} - QOpenGLContextData() : renderingContext(0), hwnd(0), hdc(0) {} + QOpenGLContextData() {} - HGLRC renderingContext; - HWND hwnd; - HDC hdc; + HGLRC renderingContext = 0; + HWND hwnd = 0; + HDC hdc = 0; }; class QOpenGLStaticContext; struct QWindowsOpenGLContextFormat { - QWindowsOpenGLContextFormat(); static QWindowsOpenGLContextFormat current(); void apply(QSurfaceFormat *format) const; - QSurfaceFormat::OpenGLContextProfile profile; - int version; //! majorVersion<<8 + minorVersion - QSurfaceFormat::FormatOptions options; + QSurfaceFormat::OpenGLContextProfile profile = QSurfaceFormat::NoProfile; + int version = 0; //! majorVersion<<8 + minorVersion + QSurfaceFormat::FormatOptions options = 0; }; #ifndef QT_NO_DEBUG_STREAM @@ -195,22 +194,22 @@ class QWindowsGLContext : public QWindowsOpenGLContext public: explicit QWindowsGLContext(QOpenGLStaticContext *staticContext, QOpenGLContext *context); ~QWindowsGLContext(); - bool isSharing() const Q_DECL_OVERRIDE { return m_context->shareHandle(); } - bool isValid() const Q_DECL_OVERRIDE { return m_renderingContext && !m_lost; } - QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_obtainedFormat; } + bool isSharing() const override { return m_context->shareHandle(); } + bool isValid() const override { return m_renderingContext && !m_lost; } + QSurfaceFormat format() const override { return m_obtainedFormat; } - void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; + void swapBuffers(QPlatformSurface *surface) override; - bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE; - void doneCurrent() Q_DECL_OVERRIDE; + bool makeCurrent(QPlatformSurface *surface) override; + void doneCurrent() override; typedef void (*GL_Proc) (); - QFunctionPointer getProcAddress(const char *procName) Q_DECL_OVERRIDE; + QFunctionPointer getProcAddress(const char *procName) override; HGLRC renderingContext() const { return m_renderingContext; } - void *nativeContext() const Q_DECL_OVERRIDE { return m_renderingContext; } + void *nativeContext() const override { return m_renderingContext; } private: inline void releaseDCs(); diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 8adbd494c4..e7ebf73d5d 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -166,15 +166,8 @@ Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp HIMC QWindowsInputContext::m_defaultContext = 0; -QWindowsInputContext::CompositionContext::CompositionContext() : - hwnd(0), haveCaret(false), position(0), isComposing(false), - factor(1) -{ -} - QWindowsInputContext::QWindowsInputContext() : m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")), - m_endCompositionRecursionGuard(false), m_languageId(currentInputLanguageId()), m_locale(qt_localeFromLCID(m_languageId)) { diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h index a7fa2c4f94..617ef30cef 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.h +++ b/src/plugins/platforms/windows/qwindowsinputcontext.h @@ -57,15 +57,13 @@ class QWindowsInputContext : public QPlatformInputContext struct CompositionContext { - CompositionContext(); - - HWND hwnd; - bool haveCaret; + HWND hwnd = 0; + bool haveCaret = false; QString composition; - int position; - bool isComposing; + int position = 0; + bool isComposing = false; QPointer<QObject> focusObject; - qreal factor; + qreal factor = 1; }; public: explicit QWindowsInputContext(); @@ -73,13 +71,13 @@ public: static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled); - bool hasCapability(Capability capability) const Q_DECL_OVERRIDE; - QLocale locale() const Q_DECL_OVERRIDE { return m_locale; } + bool hasCapability(Capability capability) const override; + QLocale locale() const override { return m_locale; } - void reset() Q_DECL_OVERRIDE; - void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; - void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE; - void setFocusObject(QObject *object) Q_DECL_OVERRIDE; + void reset() override; + void update(Qt::InputMethodQueries) override; + void invokeAction(QInputMethod::Action, int cursorPosition) override; + void setFocusObject(QObject *object) override; bool startComposition(HWND hwnd); bool composition(HWND hwnd, LPARAM lParam); @@ -104,7 +102,7 @@ private: const DWORD m_WM_MSIME_MOUSE; static HIMC m_defaultContext; CompositionContext m_compositionContext; - bool m_endCompositionRecursionGuard; + bool m_endCompositionRecursionGuard = false; LCID m_languageId; QLocale m_locale; }; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 3f74fd5296..5a3020387a 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -129,9 +129,9 @@ struct QWindowsIntegrationPrivate explicit QWindowsIntegrationPrivate(const QStringList ¶mList); ~QWindowsIntegrationPrivate(); - unsigned m_options; + unsigned m_options = 0; QWindowsContext m_context; - QPlatformFontDatabase *m_fontDatabase; + QPlatformFontDatabase *m_fontDatabase = nullptr; #ifndef QT_NO_CLIPBOARD QWindowsClipboard m_clipboard; # ifndef QT_NO_DRAGANDDROP @@ -209,8 +209,6 @@ static inline unsigned parseOptions(const QStringList ¶mList, } QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mList) - : m_options(0) - , m_fontDatabase(0) { Q_INIT_RESOURCE(openglblacklists); diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index a668470993..7647b0f4a6 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -70,34 +70,34 @@ public: explicit QWindowsIntegration(const QStringList ¶mList); virtual ~QWindowsIntegration(); - bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const override; - QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformWindow *createPlatformWindow(QWindow *window) const override; #ifndef QT_NO_OPENGL - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; - QOpenGLContext::OpenGLModuleType openGLModuleType() Q_DECL_OVERRIDE; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; + QOpenGLContext::OpenGLModuleType openGLModuleType() override; static QWindowsStaticOpenGLContext *staticOpenGLContext(); #endif - QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE; - void initialize() Q_DECL_OVERRIDE; + QAbstractEventDispatcher *createEventDispatcher() const override; + void initialize() override; #ifndef QT_NO_CLIPBOARD - QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE; + QPlatformClipboard *clipboard() const override; # ifndef QT_NO_DRAGANDDROP - QPlatformDrag *drag() const Q_DECL_OVERRIDE; + QPlatformDrag *drag() const override; # endif #endif // !QT_NO_CLIPBOARD - QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; + QPlatformInputContext *inputContext() const override; #ifndef QT_NO_ACCESSIBILITY - QPlatformAccessibility *accessibility() const Q_DECL_OVERRIDE; + QPlatformAccessibility *accessibility() const override; #endif - QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE; - QStringList themeNames() const Q_DECL_OVERRIDE; - QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE; - QPlatformServices *services() const Q_DECL_OVERRIDE; - QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE; + QPlatformFontDatabase *fontDatabase() const override; + QStringList themeNames() const override; + QPlatformTheme *createPlatformTheme(const QString &name) const override; + QPlatformServices *services() const override; + QVariant styleHint(StyleHint hint) const override; - Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; - QList<int> possibleKeys(const QKeyEvent *e) const Q_DECL_OVERRIDE; + Qt::KeyboardModifiers queryKeyboardModifiers() const override; + QList<int> possibleKeys(const QKeyEvent *e) const override; static QWindowsIntegration *instance() { return m_instance; } @@ -106,10 +106,10 @@ public: unsigned options() const; - void beep() const Q_DECL_OVERRIDE; + void beep() const override; #if !defined(QT_NO_SESSIONMANAGER) - QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const Q_DECL_OVERRIDE; + QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override; #endif protected: diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.h b/src/plugins/platforms/windows/qwindowsinternalmimedata.h index 4d775b1f21..a7df1ee6e0 100644 --- a/src/plugins/platforms/windows/qwindowsinternalmimedata.h +++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.h @@ -52,9 +52,9 @@ class QDebug; // Implementation in qwindowsclipboard.cpp. class QWindowsInternalMimeData : public QInternalMimeData { public: - bool hasFormat_sys(const QString &mimetype) const Q_DECL_OVERRIDE; - QStringList formats_sys() const Q_DECL_OVERRIDE; - QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const Q_DECL_OVERRIDE; + bool hasFormat_sys(const QString &mimetype) const override; + QStringList formats_sys() const override; + QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const override; protected: virtual IDataObject *retrieveDataObject() const = 0; diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index b84b586f7c..24c2df86d4 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -144,13 +144,11 @@ struct KeyRecord { static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers... struct KeyRecorder { - KeyRecorder() : nrecs(0) {} - inline KeyRecord *findKey(int code, bool remove); inline void storeKey(int code, int ascii, int state, const QString& text); inline void clearKeys(); - int nrecs; + int nrecs = 0; KeyRecord deleted_record; // A copy of last entry removed from records[] KeyRecord records[QT_MAX_KEY_RECORDINGS]; }; @@ -973,7 +971,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms state = state ^ Qt::ShiftModifier; else if (code == Qt::Key_Alt) state = state ^ Qt::AltModifier; - + else if (code == 0 && modifiersIndex != 0) + code = keyLayout[vk_key].qtKey[0]; // If the bit 24 of lParm is set you received a enter, // otherwise a Return. (This is the extended key bit) if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000)) diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 30d438a127..71fd12d71b 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -893,14 +893,14 @@ public: QWindowsMimeHtml(); // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE; + bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override; + bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override; + QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override; // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE; - QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE; + bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override; + QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override; + QString mimeForFormat(const FORMATETC &formatetc) const override; private: int CF_HTML; @@ -1025,14 +1025,14 @@ class QWindowsMimeImage : public QWindowsMime public: QWindowsMimeImage(); // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE; + bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override; + bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override; + QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override; // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE; - QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE; + bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override; + QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override; + QString mimeForFormat(const FORMATETC &formatetc) const override; private: bool hasOriginalDIBV5(IDataObject *pDataObj) const; UINT CF_PNG; @@ -1179,14 +1179,14 @@ public: QBuiltInMimes(); // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE; + bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override; + bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override; + QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override; // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE; - QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE; + bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override; + QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override; + QString mimeForFormat(const FORMATETC &formatetc) const override; private: QMap<int, QString> outFormats; @@ -1299,14 +1299,14 @@ public: QLastResortMimes(); // for converting from Qt - bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE; - bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE; - QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE; + bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override; + bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override; + QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override; // for converting to Qt - bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE; - QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE; - QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE; + bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override; + QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override; + QString mimeForFormat(const FORMATETC &formatetc) const override; private: QMap<int, QString> formats; @@ -1496,9 +1496,7 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const \sa QWindowsMime */ -QWindowsMimeConverter::QWindowsMimeConverter() : m_internalMimeCount(0) -{ -} +QWindowsMimeConverter::QWindowsMimeConverter() = default; QWindowsMimeConverter::~QWindowsMimeConverter() { diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h index 4c0cbf9f31..1ed2aa933f 100644 --- a/src/plugins/platforms/windows/qwindowsmime.h +++ b/src/plugins/platforms/windows/qwindowsmime.h @@ -96,7 +96,7 @@ private: void ensureInitialized() const; mutable QList<QWindowsMime *> m_mimes; - mutable int m_internalMimeCount; + mutable int m_internalMimeCount = 0; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index e4025fe60d..34c34fd28e 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -185,14 +185,7 @@ static inline QTouchDevice *createTouchDevice() \ingroup qt-lighthouse-win */ -QWindowsMouseHandler::QWindowsMouseHandler() : - m_windowUnderMouse(0), - m_trackedWindow(0), - m_touchDevice(Q_NULLPTR), - m_leftButtonDown(false), - m_previousCaptureWindow(0) -{ -} +QWindowsMouseHandler::QWindowsMouseHandler() = default; QTouchDevice *QWindowsMouseHandler::ensureTouchDevice() { @@ -421,7 +414,7 @@ static bool isValidWheelReceiver(QWindow *candidate) { if (candidate) { const QWindow *toplevel = QWindowsWindow::topLevelOf(candidate); - if (toplevel->type() == Qt::ForeignWindow) + if (toplevel->handle() && toplevel->handle()->isForeignWindow()) return true; if (const QWindowsWindow *ww = QWindowsWindow::windowsWindowOf(toplevel)) return !ww->testFlag(QWindowsWindow::BlockedByModal); diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h index bd36d9f44c..86f18a0482 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.h +++ b/src/plugins/platforms/windows/qwindowsmousehandler.h @@ -88,9 +88,9 @@ private: QPointer<QWindow> m_trackedWindow; QHash<DWORD, int> m_touchInputIDToTouchPointID; QHash<int, QPointF> m_lastTouchPositions; - QTouchDevice *m_touchDevice; - bool m_leftButtonDown; - QWindow *m_previousCaptureWindow; + QTouchDevice *m_touchDevice = nullptr; + bool m_leftButtonDown = false; + QWindow *m_previousCaptureWindow = nullptr; }; Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index eaa6e45b9f..d750eef19d 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qwindowsnativeinterface.h" +#include "qwindowsclipboard.h" #include "qwindowswindow.h" #include "qwindowscontext.h" #include "qwindowscursor.h" @@ -45,6 +46,7 @@ #include "qwindowsopengltester.h" #include "qwindowsintegration.h" #include "qwindowsmime.h" +#include "qwin10helpers.h" #include <QtGui/QWindow> #include <QtGui/QOpenGLContext> @@ -108,6 +110,7 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc } break; case QWindow::OpenGLSurface: + case QWindow::OpenVGSurface: break; } qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData()); @@ -252,14 +255,23 @@ QFont QWindowsNativeInterface::logFontToQFont(const void *logFont, int verticalD return QWindowsFontDatabase::LOGFONT_to_QFont(*reinterpret_cast<const LOGFONT *>(logFont), verticalDpi); } +bool QWindowsNativeInterface::isTabletMode() +{ +#if QT_CONFIG(clipboard) + if (const QWindowsClipboard *clipboard = QWindowsClipboard::instance()) + return qt_windowsIsTabletMode(clipboard->clipboardViewer()); +#endif + return false; +} + QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &function) const { if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier()) return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic); else if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier()) return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic); - else if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier()) - return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior); + else if (function == QWindowsWindowFunctions::isTabletModeIdentifier()) + return QFunctionPointer(QWindowsNativeInterface::isTabletMode); return Q_NULLPTR; } diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index 9fc43ddcce..d085a4afb3 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -68,13 +68,13 @@ class QWindowsNativeInterface : public QPlatformNativeInterface Q_PROPERTY(QVariant gpu READ gpu STORED false) public: - void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; + void *nativeResourceForIntegration(const QByteArray &resource) override; #ifndef QT_NO_OPENGL - void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE; + void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override; #endif - void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE; + void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override; #ifndef QT_NO_CURSOR - void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) Q_DECL_OVERRIDE; + void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) override; #endif Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate, const QString &windowName, @@ -92,17 +92,19 @@ public: QVariant gpu() const; - QVariantMap windowProperties(QPlatformWindow *window) const Q_DECL_OVERRIDE; - QVariant windowProperty(QPlatformWindow *window, const QString &name) const Q_DECL_OVERRIDE; - QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE; - void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) Q_DECL_OVERRIDE; + QVariantMap windowProperties(QPlatformWindow *window) const override; + QVariant windowProperty(QPlatformWindow *window, const QString &name) const override; + QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override; + void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) override; static QWindowsWindowFunctions::WindowActivationBehavior windowActivationBehavior() { return QWindowsNativeInterface::m_windowActivationBehavior; } static void setWindowActivationBehavior(QWindowsWindowFunctions::WindowActivationBehavior b) { QWindowsNativeInterface::m_windowActivationBehavior = b; } - QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; + static bool isTabletMode(); + + QFunctionPointer platformFunction(const QByteArray &function) const override; private: static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior; diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp index a1a8c0b499..9b71061aa5 100644 --- a/src/plugins/platforms/windows/qwindowsole.cpp +++ b/src/plugins/platforms/windows/qwindowsole.cpp @@ -74,9 +74,8 @@ QT_BEGIN_NAMESPACE */ QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) : - m_refs(1), data(mimeData), - CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)), - performedEffect(DROPEFFECT_NONE) + data(mimeData), + CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)) { qCDebug(lcQpaMime) << __FUNCTION__ << mimeData->formats(); } @@ -267,8 +266,7 @@ QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*) \ingroup qt-lighthouse-win */ -QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) : - m_dwRefs(1), m_nIndex(0), m_isNull(false) +QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) { if (QWindowsContext::verbose > 1) qCDebug(lcQpaMime) << __FUNCTION__ << fmtetcs; @@ -285,8 +283,7 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) } } -QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) : - m_dwRefs(1), m_nIndex(0), m_isNull(false) +QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) { if (QWindowsContext::verbose > 1) qCDebug(lcQpaMime) << __FUNCTION__; diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h index dc31c793e9..643011272b 100644 --- a/src/plugins/platforms/windows/qwindowsole.h +++ b/src/plugins/platforms/windows/qwindowsole.h @@ -82,10 +82,10 @@ public: STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise); private: - ULONG m_refs; + ULONG m_refs = 1; QPointer<QMimeData> data; - int CF_PERFORMEDDROPEFFECT; - DWORD performedEffect; + const int CF_PERFORMEDDROPEFFECT; + DWORD performedEffect = DROPEFFECT_NONE; }; class QWindowsOleEnumFmtEtc : public IEnumFORMATETC @@ -111,10 +111,10 @@ public: private: bool copyFormatEtc(LPFORMATETC dest, const FORMATETC *src) const; - ULONG m_dwRefs; - ULONG m_nIndex; + ULONG m_dwRefs = 1; + ULONG m_nIndex = 0; QVector<LPFORMATETC> m_lpfmtetcs; - bool m_isNull; + bool m_isNull = false; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 39e20b55d1..e3fec59dd5 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -51,16 +51,14 @@ class QVariant; struct GpuDescription { - GpuDescription() : vendorId(0), deviceId(0), revision(0), subSysId(0) {} - static GpuDescription detect(); QString toString() const; QVariant toVariant() const; - uint vendorId; - uint deviceId; - uint revision; - uint subSysId; + uint vendorId = 0; + uint deviceId = 0; + uint revision = 0; + uint subSysId = 0; QVersionNumber driverVersion; QByteArray driverName; QByteArray description; diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index c70323c06f..24fb12d27a 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -56,13 +56,6 @@ QT_BEGIN_NAMESPACE -QWindowsScreenData::QWindowsScreenData() : - dpi(96, 96), depth(32), format(QImage::Format_ARGB32_Premultiplied), - flags(VirtualDesktop), orientation(Qt::LandscapeOrientation), - refreshRateHz(60) -{ -} - static inline QDpi deviceDPI(HDC hdc) { return QDpi(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY)); @@ -89,6 +82,7 @@ static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data) if (GetMonitorInfo(hMonitor, &info) == FALSE) return false; + data->hMonitor = hMonitor; data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1)); data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1)); data->name = QString::fromWCharArray(info.szDevice); @@ -423,10 +417,7 @@ QPlatformScreen::SubpixelAntialiasingType QWindowsScreen::subpixelAntialiasingTy \ingroup qt-lighthouse-win */ -QWindowsScreenManager::QWindowsScreenManager() : - m_lastDepth(-1), m_lastHorizontalResolution(0), m_lastVerticalResolution(0) -{ -} +QWindowsScreenManager::QWindowsScreenManager() = default; /*! \brief Triggers synchronization of screens (WM_DISPLAYCHANGE). diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index 02a9dc3bc3..9a8997326b 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -59,18 +59,17 @@ struct QWindowsScreenData LockScreen = 0x4 // Temporary screen existing during user change, etc. }; - QWindowsScreenData(); - QRect geometry; QRect availableGeometry; - QDpi dpi; + QDpi dpi{96, 96}; QSizeF physicalSizeMM; - int depth; - QImage::Format format; - unsigned flags; + int depth = 32; + QImage::Format format = QImage::Format_ARGB32_Premultiplied; + unsigned flags = VirtualDesktop; QString name; - Qt::ScreenOrientation orientation; - qreal refreshRateHz; + Qt::ScreenOrientation orientation = Qt::LandscapeOrientation; + qreal refreshRateHz = 60; + HMONITOR hMonitor = nullptr; }; class QWindowsScreen : public QPlatformScreen @@ -82,23 +81,23 @@ public: explicit QWindowsScreen(const QWindowsScreenData &data); - QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; } - QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; } - int depth() const Q_DECL_OVERRIDE { return m_data.depth; } - QImage::Format format() const Q_DECL_OVERRIDE { return m_data.format; } - QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_data.physicalSizeMM; } - QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_data.dpi; } - qreal pixelDensity() const Q_DECL_OVERRIDE; - qreal devicePixelRatio() const Q_DECL_OVERRIDE { return 1.0; } - qreal refreshRate() const Q_DECL_OVERRIDE { return m_data.refreshRateHz; } - QString name() const Q_DECL_OVERRIDE { return m_data.name; } - Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_data.orientation; } - QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE; - QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE; + QRect geometry() const override { return m_data.geometry; } + QRect availableGeometry() const override { return m_data.availableGeometry; } + int depth() const override { return m_data.depth; } + QImage::Format format() const override { return m_data.format; } + QSizeF physicalSize() const override { return m_data.physicalSizeMM; } + QDpi logicalDpi() const override { return m_data.dpi; } + qreal pixelDensity() const override; + qreal devicePixelRatio() const override { return 1.0; } + qreal refreshRate() const override { return m_data.refreshRateHz; } + QString name() const override { return m_data.name; } + Qt::ScreenOrientation orientation() const override { return m_data.orientation; } + QList<QPlatformScreen *> virtualSiblings() const override; + QWindow *topLevelAt(const QPoint &point) const override; static QWindow *windowAt(const QPoint &point, unsigned flags); - QPixmap grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const Q_DECL_OVERRIDE; - QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE; + QPixmap grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const override; + QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const override; static Qt::ScreenOrientation orientationPreference(); static bool setOrientationPreference(Qt::ScreenOrientation o); @@ -106,7 +105,7 @@ public: inline void handleChanges(const QWindowsScreenData &newData); #ifndef QT_NO_CURSOR - QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor.data(); } + QPlatformCursor *cursor() const override { return m_cursor.data(); } const CursorPtr &cursorPtr() const { return m_cursor; } #else QPlatformCursor *cursor() const { return 0; } @@ -140,9 +139,9 @@ private: void removeScreen(int index); WindowsScreenList m_screens; - int m_lastDepth; - WORD m_lastHorizontalResolution; - WORD m_lastVerticalResolution; + int m_lastDepth = -1; + WORD m_lastHorizontalResolution = 0; + WORD m_lastVerticalResolution = 0; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.cpp b/src/plugins/platforms/windows/qwindowssessionmanager.cpp index 2db9e44388..500fdc750c 100644 --- a/src/plugins/platforms/windows/qwindowssessionmanager.cpp +++ b/src/plugins/platforms/windows/qwindowssessionmanager.cpp @@ -44,9 +44,6 @@ QT_BEGIN_NAMESPACE QWindowsSessionManager::QWindowsSessionManager(const QString &id, const QString &key) : QPlatformSessionManager(id, key) - , m_isActive(false) - , m_blockUserInput(false) - , m_canceled(false) { } diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.h b/src/plugins/platforms/windows/qwindowssessionmanager.h index 25d0636650..4c4256f2b0 100644 --- a/src/plugins/platforms/windows/qwindowssessionmanager.h +++ b/src/plugins/platforms/windows/qwindowssessionmanager.h @@ -59,15 +59,15 @@ class QWindowsSessionManager : public QPlatformSessionManager public: explicit QWindowsSessionManager(const QString &id, const QString &key); - bool allowsInteraction() Q_DECL_OVERRIDE; - bool allowsErrorInteraction() Q_DECL_OVERRIDE; + bool allowsInteraction() override; + bool allowsErrorInteraction() override; void blocksInteraction() { m_blockUserInput = true; } bool isInteractionBlocked() const { return m_blockUserInput; } - void release() Q_DECL_OVERRIDE; + void release() override; - void cancel() Q_DECL_OVERRIDE; + void cancel() override; void clearCancellation() { m_canceled = false; } bool wasCanceled() const { return m_canceled; } @@ -75,9 +75,9 @@ public: bool isActive() const { return m_isActive;} private: - bool m_isActive; - bool m_blockUserInput; - bool m_canceled; + bool m_isActive = false; + bool m_blockUserInput = false; + bool m_canceled = false; Q_DISABLE_COPY(QWindowsSessionManager) }; diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h index 2c05dcddfc..97eceaf2cc 100644 --- a/src/plugins/platforms/windows/qwindowstabletsupport.h +++ b/src/plugins/platforms/windows/qwindowstabletsupport.h @@ -57,9 +57,6 @@ class QRect; struct QWindowsWinTab32DLL { - QWindowsWinTab32DLL() : wTOpen(0), wTClose(0), wTInfo(0), wTEnable(0), wTOverlap(0), wTPacketsGet(0), wTGet(0), - wTQueueSizeGet(0), wTQueueSizeSet(0) {} - bool init(); typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL); @@ -72,15 +69,15 @@ struct QWindowsWinTab32DLL typedef int (API *PtrWTQueueSizeGet)(HCTX); typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int); - PtrWTOpen wTOpen; - PtrWTClose wTClose; - PtrWTInfo wTInfo; - PtrWTEnable wTEnable; - PtrWTOverlap wTOverlap; - PtrWTPacketsGet wTPacketsGet; - PtrWTGet wTGet; - PtrWTQueueSizeGet wTQueueSizeGet; - PtrWTQueueSizeSet wTQueueSizeSet; + PtrWTOpen wTOpen = nullptr; + PtrWTClose wTClose = nullptr; + PtrWTInfo wTInfo = nullptr; + PtrWTEnable wTEnable = nullptr; + PtrWTOverlap wTOverlap = nullptr; + PtrWTPacketsGet wTPacketsGet = nullptr; + PtrWTGet wTGet = nullptr; + PtrWTQueueSizeGet wTQueueSizeGet = nullptr; + PtrWTQueueSizeSet wTQueueSizeSet = nullptr; }; struct QWindowsTabletDeviceData diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index ed12c8124e..4ae1a751e9 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -61,6 +61,9 @@ #include <QtCore/QTextStream> #include <QtCore/QSysInfo> #include <QtCore/QCache> +#include <QtCore/QThread> +#include <QtCore/QMutex> +#include <QtCore/QWaitCondition> #include <QtGui/QColor> #include <QtGui/QPalette> #include <QtGui/QGuiApplication> @@ -127,40 +130,114 @@ static inline QColor getSysColor(int index) // QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system // models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the // behavior by running it in a thread. -class ShGetFileInfoFunction + +struct QShGetFileInfoParams +{ + QShGetFileInfoParams(const QString &fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) + : fileName(fn), attributes(a), flags(f), info(i), result(r) + { } + + const QString &fileName; + const DWORD attributes; + const UINT flags; + SHFILEINFO *const info; + bool *const result; +}; + +class QShGetFileInfoThread : public QThread { public: - explicit ShGetFileInfoFunction(const wchar_t *fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) : - m_fileName(fn), m_attributes(a), m_flags(f), m_info(i), m_result(r) {} + explicit QShGetFileInfoThread() + : QThread(), m_params(nullptr) + { + connect(this, &QThread::finished, this, &QObject::deleteLater); + } - void operator()() const + void run() override { + m_init = CoInitializeEx(NULL, COINIT_MULTITHREADED); + + QMutexLocker readyLocker(&m_readyMutex); + while (!m_cancelled.load()) { + if (!m_params && !m_cancelled.load() + && !m_readyCondition.wait(&m_readyMutex, 1000)) + continue; + + if (m_params) { + const QString fileName = m_params->fileName; + SHFILEINFO info; #ifndef Q_OS_WINCE - const UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + const UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); #endif - *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags); + const bool result = SHGetFileInfo(reinterpret_cast<const wchar_t *>(fileName.utf16()), + m_params->attributes, &info, sizeof(SHFILEINFO), + m_params->flags); #ifndef Q_OS_WINCE - SetErrorMode(oldErrorMode); + SetErrorMode(oldErrorMode); #endif + m_doneMutex.lock(); + if (!m_cancelled.load()) { + *m_params->result = result; + memcpy(m_params->info, &info, sizeof(SHFILEINFO)); + } + m_params = nullptr; + + m_doneCondition.wakeAll(); + m_doneMutex.unlock(); + } + } + + if (m_init != S_FALSE) + CoUninitialize(); + } + + bool runWithParams(QShGetFileInfoParams *params, unsigned long timeOutMSecs) + { + QMutexLocker doneLocker(&m_doneMutex); + + m_readyMutex.lock(); + m_params = params; + m_readyCondition.wakeAll(); + m_readyMutex.unlock(); + + return m_doneCondition.wait(&m_doneMutex, timeOutMSecs); + } + + void cancel() + { + QMutexLocker doneLocker(&m_doneMutex); + m_cancelled.store(1); + m_readyCondition.wakeAll(); } private: - const wchar_t *m_fileName; - const DWORD m_attributes; - const UINT m_flags; - SHFILEINFO *const m_info; - bool *m_result; + HRESULT m_init; + QShGetFileInfoParams *m_params; + QAtomicInt m_cancelled; + QWaitCondition m_readyCondition; + QWaitCondition m_doneCondition; + QMutex m_readyMutex; + QMutex m_doneMutex; }; -static bool shGetFileInfoBackground(QWindowsThreadPoolRunner &r, - const wchar_t *fileName, DWORD attributes, +static bool shGetFileInfoBackground(const QString &fileName, DWORD attributes, SHFILEINFO *info, UINT flags, unsigned long timeOutMSecs = 5000) { + static QShGetFileInfoThread *getFileInfoThread = nullptr; + if (!getFileInfoThread) { + getFileInfoThread = new QShGetFileInfoThread; + getFileInfoThread->start(); + } + bool result = false; - if (!r.run(ShGetFileInfoFunction(fileName, attributes, info, flags, &result), timeOutMSecs)) { - qWarning().noquote() << "ShGetFileInfoBackground() timed out for " - << QString::fromWCharArray(fileName); + QShGetFileInfoParams params(fileName, attributes, info, flags, &result); + if (!getFileInfoThread->runWithParams(¶ms, timeOutMSecs)) { + // Cancel and reset getFileInfoThread. It'll + // be reinitialized the next time we get called. + getFileInfoThread->cancel(); + getFileInfoThread = nullptr; + qWarning().noquote() << "SHGetFileInfo() timed out for " << fileName; return false; } return result; @@ -315,7 +392,6 @@ const char *QWindowsTheme::name = "windows"; QWindowsTheme *QWindowsTheme::m_instance = 0; QWindowsTheme::QWindowsTheme() - : m_threadPoolRunner(new QWindowsThreadPoolRunner) { m_instance = this; std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0)); @@ -718,10 +794,8 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info) class QWindowsFileIconEngine : public QAbstractFileIconEngine { public: - explicit QWindowsFileIconEngine(const QFileInfo &info, - QPlatformTheme::IconOptions opts, - const QSharedPointer<QWindowsThreadPoolRunner> &runner) : - QAbstractFileIconEngine(info, opts), m_threadPoolRunner(runner) {} + explicit QWindowsFileIconEngine(const QFileInfo &info, QPlatformTheme::IconOptions opts) : + QAbstractFileIconEngine(info, opts) {} QList<QSize> availableSizes(QIcon::Mode = QIcon::Normal, QIcon::State = QIcon::Off) const override { return QWindowsTheme::instance()->availableFileIconSizes(); } @@ -729,9 +803,6 @@ public: protected: QString cacheKey() const override; QPixmap filePixmap(const QSize &size, QIcon::Mode mode, QIcon::State) override; - -private: - const QSharedPointer<QWindowsThreadPoolRunner> m_threadPoolRunner; }; QString QWindowsFileIconEngine::cacheKey() const @@ -797,10 +868,8 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon SHGFI_ICON|iconSize|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX; const bool val = cacheableDirIcon && useDefaultFolderIcon - ? shGetFileInfoBackground(*m_threadPoolRunner.data(), L"dummy", FILE_ATTRIBUTE_DIRECTORY, - &info, flags | SHGFI_USEFILEATTRIBUTES) - : shGetFileInfoBackground(*m_threadPoolRunner.data(), reinterpret_cast<const wchar_t *>(filePath.utf16()), 0, - &info, flags); + ? shGetFileInfoBackground(QString::fromWCharArray(L"dummy"), FILE_ATTRIBUTE_DIRECTORY, &info, flags | SHGFI_USEFILEATTRIBUTES) + : shGetFileInfoBackground(filePath, 0, &info, flags); // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases if (val && info.hIcon) { @@ -844,7 +913,7 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon QIcon QWindowsTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const { - return QIcon(new QWindowsFileIconEngine(fileInfo, iconOptions, m_threadPoolRunner)); + return QIcon(new QWindowsFileIconEngine(fileInfo, iconOptions)); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index 0384899efa..a3019ff6eb 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -40,7 +40,6 @@ #ifndef QWINDOWSTHEME_H #define QWINDOWSTHEME_H -#include "qwindowsthreadpoolrunner.h" #include <qpa/qplatformtheme.h> #include <QtCore/QSharedPointer> @@ -58,15 +57,15 @@ public: static QWindowsTheme *instance() { return m_instance; } - bool usePlatformNativeDialog(DialogType type) const Q_DECL_OVERRIDE; - QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const Q_DECL_OVERRIDE; - QVariant themeHint(ThemeHint) const Q_DECL_OVERRIDE; - const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE + bool usePlatformNativeDialog(DialogType type) const override; + QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override; + QVariant themeHint(ThemeHint) const override; + const QPalette *palette(Palette type = SystemPalette) const override { return m_palettes[type]; } - const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE + const QFont *font(Font type = SystemFont) const override { return m_fonts[type]; } - QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE; + QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override; QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = 0) const override; @@ -88,7 +87,6 @@ private: static QWindowsTheme *m_instance; QPalette *m_palettes[NPalettes]; QFont *m_fonts[NFonts]; - const QSharedPointer<QWindowsThreadPoolRunner> m_threadPoolRunner; QList<QSize> m_fileIconSizes; }; diff --git a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h index 0361aa90f5..ad71987ec8 100644 --- a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h +++ b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h @@ -63,7 +63,7 @@ class QWindowsThreadPoolRunner explicit Runnable(QMutex *m, QWaitCondition *c, RunnableFunction f) : m_mutex(m), m_condition(c), m_function(f) {} - void run() Q_DECL_OVERRIDE + void run() override { m_function(); m_mutex->lock(); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 48835f26a6..40229d00af 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -118,6 +118,35 @@ static QByteArray debugWinExStyle(DWORD exStyle) return rc; } +static QByteArray debugWinSwpPos(UINT flags) +{ + QByteArray rc = "0x"; + rc += QByteArray::number(flags, 16); + if (flags & SWP_FRAMECHANGED) + rc += " SWP_FRAMECHANGED"; + if (flags & SWP_HIDEWINDOW) + rc += " SWP_HIDEWINDOW"; + if (flags & SWP_NOACTIVATE) + rc += " SWP_NOACTIVATE"; + if (flags & SWP_NOCOPYBITS) + rc += " SWP_NOCOPYBITS"; + if (flags & SWP_NOMOVE) + rc += " SWP_NOMOVE"; + if (flags & SWP_NOOWNERZORDER) + rc += " SWP_NOOWNERZORDER"; + if (flags & SWP_NOREDRAW) + rc += " SWP_NOREDRAW"; + if (flags & SWP_NOSENDCHANGING) + rc += " SWP_NOSENDCHANGING"; + if (flags & SWP_NOSIZE) + rc += " SWP_NOSIZE"; + if (flags & SWP_NOZORDER) + rc += " SWP_NOZORDER"; + if (flags & SWP_SHOWWINDOW) + rc += " SWP_SHOWWINDOW"; + return rc; +} + static inline QSize qSizeOfRect(const RECT &rect) { return QSize(rect.right -rect.left, rect.bottom - rect.top); @@ -141,8 +170,9 @@ QDebug operator<<(QDebug d, const RECT &r) { QDebugStateSaver saver(d); d.nospace(); - d << "RECT: left/top=" << r.left << ',' << r.top - << " right/bottom=" << r.right << ',' << r.bottom; + d << "RECT(left=" << r.left << ", top=" << r.top + << ", right=" << r.right << ", bottom=" << r.bottom + << " (" << r.right - r.left << 'x' << r.bottom - r.top << "))"; return d; } @@ -152,12 +182,23 @@ QDebug operator<<(QDebug d, const POINT &p) return d; } +QDebug operator<<(QDebug d, const WINDOWPOS &wp) +{ + QDebugStateSaver saver(d); + d.nospace(); + d.noquote(); + d << "WINDOWPOS(flags=" << debugWinSwpPos(wp.flags) << ", hwnd=" + << wp.hwnd << ", hwndInsertAfter=" << wp.hwndInsertAfter << ", x=" << wp.x + << ", y=" << wp.y << ", cx=" << wp.cx << ", cy=" << wp.cy << ')'; + return d; +} + QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p) { QDebugStateSaver saver(d); d.nospace(); - d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0]) - << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]); + d << "NCCALCSIZE_PARAMS(rgrc=[" << p.rgrc[0] << ' ' << p.rgrc[1] << ' ' + << p.rgrc[2] << "], lppos=" << *p.lppos << ')'; return d; } @@ -177,6 +218,7 @@ QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp) { QDebugStateSaver saver(d); d.nospace(); + d.noquote(); d << "WINDOWPLACEMENT(flags=0x" << hex << wp.flags << dec << ", showCmd=" << wp.showCmd << ", ptMinPosition=" << wp.ptMinPosition << ", ptMaxPosition=" << wp.ptMaxPosition << ", rcNormalPosition=" << wp.rcNormalPosition; @@ -939,9 +981,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, DWORD style_, DWORD exStyle_) : geometryHint(w, cm), window(w), style(style_), exStyle(exStyle_), requestedGeometry(geometry), obtainedGeometry(geometry), - margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm), - frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT), - frameWidth(CW_USEDEFAULT), frameHeight(CW_USEDEFAULT) + margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm) { // Geometry of toplevels does not consider window frames. // TODO: No concept of WA_wasMoved yet that would indicate a @@ -994,17 +1034,8 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) : QWindowsBaseWindow(aWindow), m_data(data), - m_flags(WithinCreate), - m_hdc(0), - m_windowState(Qt::WindowNoState), - m_opacity(1.0), m_cursor(new CursorHandle), - m_dropTarget(0), - m_savedStyle(0), - m_format(aWindow->requestedFormat()), - m_iconSmall(0), - m_iconBig(0), - m_surface(0) + m_format(aWindow->requestedFormat()) { // Clear the creation context as the window can be found in QWindowsContext's map. QWindowsContext::instance()->setWindowCreationContext(QSharedPointer<QWindowCreationContext>()); @@ -1095,7 +1126,7 @@ void QWindowsWindow::updateDropSite(bool topLevel) // if the parent window is a foreign window wrapped via QWindow::fromWinId, we need to enable the drop site // on the first child window const QWindow *parent = window()->parent(); - if (parent && (parent->type() == Qt::ForeignWindow)) + if (parent && parent->handle() && parent->handle()->isForeignWindow()) parentIsEmbedded = true; } @@ -1216,18 +1247,14 @@ bool QWindowsWindow::isActive() const return false; } -bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const +bool QWindowsWindow::isAncestorOf(const QPlatformWindow *child) const { - if (parentWindow) { - const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(parentWindow); - const HWND hwnd = ww->handle(); - if (!IsChild(hwnd, m_data.hwnd)) - return false; - } - - if (!m_data.embedded && parent()) - return parent()->isEmbedded(); + const QWindowsWindow *childWindow = static_cast<const QWindowsWindow *>(child); + return IsChild(m_data.hwnd, childWindow->handle()); +} +bool QWindowsWindow::isEmbedded() const +{ return m_data.embedded; } @@ -1471,18 +1498,22 @@ void QWindowsWindow::handleResized(int wParam) case SIZE_MAXHIDE: // Some other window affected. case SIZE_MAXSHOW: return; - case SIZE_MINIMIZED: - handleWindowStateChange(Qt::WindowMinimized); + case SIZE_MINIMIZED: // QTBUG-53577, prevent state change events during programmatic state change + if (!testFlag(WithinSetStyle)) + handleWindowStateChange(Qt::WindowMinimized); return; case SIZE_MAXIMIZED: - handleWindowStateChange(Qt::WindowMaximized); + if (!testFlag(WithinSetStyle)) + handleWindowStateChange(Qt::WindowMaximized); handleGeometryChange(); break; case SIZE_RESTORED: - if (isFullScreen_sys()) - handleWindowStateChange(Qt::WindowFullScreen); - else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen)) - handleWindowStateChange(Qt::WindowNoState); + if (!testFlag(WithinSetStyle)) { + if (isFullScreen_sys()) + handleWindowStateChange(Qt::WindowFullScreen); + else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen)) + handleWindowStateChange(Qt::WindowNoState); + } handleGeometryChange(); break; } @@ -1490,9 +1521,6 @@ void QWindowsWindow::handleResized(int wParam) void QWindowsWindow::handleGeometryChange() { - //Prevent recursive resizes for Windows CE - if (testFlag(WithinSetStyle)) - return; const QRect previousGeometry = m_data.geometry; m_data.geometry = geometry_sys(); QPlatformWindow::setGeometry(m_data.geometry); @@ -1505,10 +1533,16 @@ void QWindowsWindow::handleGeometryChange() && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) { fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); } - if (previousGeometry.topLeft() != m_data.geometry.topLeft()) { - QPlatformScreen *newScreen = screenForGeometry(m_data.geometry); - if (newScreen != screen()) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); + if (!parent() && previousGeometry.topLeft() != m_data.geometry.topLeft()) { + HMONITOR hMonitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONULL); + QPlatformScreen *currentScreen = screen(); + const auto screens = QWindowsContext::instance()->screenManager().screens(); + auto newScreenIt = std::find_if(screens.begin(), screens.end(), [&](QWindowsScreen *s) { + return s->data().hMonitor == hMonitor + && s->data().flags & QWindowsScreenData::VirtualDesktop; + }); + if (newScreenIt != screens.end() && *newScreenIt != currentScreen) + QWindowSystemInterface::handleWindowScreenChanged(window(), (*newScreenIt)->screen()); } if (testFlag(SynchronousGeometryChangeEvent)) QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); @@ -1659,7 +1693,6 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt, QWindowsWindowData result = m_data; result.flags = creationData.flags; result.embedded = creationData.embedded; - setFlag(FrameDirty); return result; } @@ -1667,7 +1700,6 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) { qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << "\n from " << m_windowState << " to " << state; - setFlag(FrameDirty); m_windowState = state; QWindowSystemInterface::handleWindowStateChanged(window(), state); switch (state) { @@ -1744,8 +1776,6 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) const bool visible = isVisible(); - setFlag(FrameDirty); - if ((oldState == Qt::WindowFullScreen) != (newState == Qt::WindowFullScreen)) { if (newState == Qt::WindowFullScreen) { #ifndef Q_FLATTEN_EXPOSE @@ -1839,7 +1869,6 @@ void QWindowsWindow::setStyle(unsigned s) const { qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << debugWinStyle(s); setFlag(WithinSetStyle); - setFlag(FrameDirty); SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s); clearFlag(WithinSetStyle); } @@ -1848,7 +1877,6 @@ void QWindowsWindow::setExStyle(unsigned s) const { qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << this << ' ' << window() << " 0x" << QByteArray::number(s, 16); - setFlag(FrameDirty); SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s); } @@ -1904,22 +1932,17 @@ bool QWindowsWindow::handleGeometryChanging(MSG *message) const return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins); } -QMargins QWindowsWindow::frameMargins() const +void QWindowsWindow::setFrameMargins(const QMargins &newMargins) { - // Frames are invalidated by style changes (window state, flags). - // As they are also required for geometry calculations in resize - // event sequences, introduce a dirty flag mechanism to be able - // to cache results. - if (testFlag(FrameDirty)) { - // Always skip calculating style-dependent margins for windows claimed to be frameless. - // This allows users to remove the margins by handling WM_NCCALCSIZE with WS_THICKFRAME set - // to ensure Areo snap still works (QTBUG-40578). - m_data.frame = m_data.flags & Qt::FramelessWindowHint - ? QMargins(0, 0, 0, 0) - : QWindowsGeometryHint::frame(style(), exStyle()); - clearFlag(FrameDirty); + if (m_data.frame != newMargins) { + qCDebug(lcQpaWindows) << __FUNCTION__ << window() << m_data.frame << "->" << newMargins; + m_data.frame = newMargins; } - return m_data.frame + m_data.customMargins; +} + +QMargins QWindowsWindow::frameMargins() const +{ + return m_data.frame; } void QWindowsWindow::setOpacity(qreal level) @@ -2091,8 +2114,12 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled) void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const { - const QWindowsGeometryHint hint(window(), m_data.customMargins); - hint.applyToMinMaxInfo(m_data.hwnd, mmi); + // We don't apply the min/max size hint as we change the dpi, because we did not adjust the + // QScreen of the window yet so we don't have the min/max with the right ratio + if (!testFlag(QWindowsWindow::WithinDpiChanged)) { + const QWindowsGeometryHint hint(window(), m_data.customMargins); + hint.applyToMinMaxInfo(m_data.hwnd, mmi); + } if ((testFlag(WithinMaximize) || (window()->windowState() == Qt::WindowMinimized)) && (m_data.flags & Qt::FramelessWindowHint)) { @@ -2335,7 +2362,6 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) const QPoint topLeft = currentFrameGeometry.topLeft(); QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins; newFrame.moveTo(topLeft); - setFlag(FrameDirty); qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins << currentFrameGeometry << "->" << newFrame; SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED); diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 924f242e6e..10cfc18dff 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -89,22 +89,20 @@ struct QWindowCreationContext QRect obtainedGeometry; QMargins margins; QMargins customMargins; // User-defined, additional frame for WM_NCCALCSIZE - int frameX; // Passed on to CreateWindowEx(), including frame. - int frameY; - int frameWidth; - int frameHeight; + int frameX = CW_USEDEFAULT; // Passed on to CreateWindowEx(), including frame. + int frameY = CW_USEDEFAULT; + int frameWidth = CW_USEDEFAULT; + int frameHeight = CW_USEDEFAULT; }; struct QWindowsWindowData { - QWindowsWindowData() : hwnd(0), embedded(false) {} - Qt::WindowFlags flags; QRect geometry; QMargins frame; // Do not use directly for windows, see FrameDirty. QMargins customMargins; // User-defined, additional frame for NCCALCSIZE - HWND hwnd; - bool embedded; + HWND hwnd = 0; + bool embedded = false; static QWindowsWindowData create(const QWindow *w, const QWindowsWindowData ¶meters, @@ -116,11 +114,11 @@ class QWindowsBaseWindow : public QPlatformWindow public: explicit QWindowsBaseWindow(QWindow *window) : QPlatformWindow(window) {} - WId winId() const Q_DECL_OVERRIDE { return WId(handle()); } - QRect geometry() const Q_DECL_OVERRIDE { return geometry_sys(); } - QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMargins_sys(); } - QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; - QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; + WId winId() const override { return WId(handle()); } + QRect geometry() const override { return geometry_sys(); } + QMargins frameMargins() const override { return frameMargins_sys(); } + QPoint mapToGlobal(const QPoint &pos) const override; + QPoint mapFromGlobal(const QPoint &pos) const override; using QPlatformWindow::screenForGeometry; @@ -152,11 +150,11 @@ public: explicit QWindowsDesktopWindow(QWindow *window) : QWindowsBaseWindow(window), m_hwnd(GetDesktopWindow()) {} - QMargins frameMargins() const Q_DECL_OVERRIDE { return QMargins(); } - bool isTopLevel() const Q_DECL_OVERRIDE { return true; } + QMargins frameMargins() const override { return QMargins(); } + bool isTopLevel() const override { return true; } protected: - HWND handle() const Q_DECL_OVERRIDE { return m_hwnd; } + HWND handle() const override { return m_hwnd; } private: const HWND m_hwnd; @@ -167,15 +165,15 @@ class QWindowsForeignWindow : public QWindowsBaseWindow public: explicit QWindowsForeignWindow(QWindow *window, HWND hwnd); - void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE; - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE { setGeometry_sys(rect); } - void setVisible(bool visible) Q_DECL_OVERRIDE; - void raise() Q_DECL_OVERRIDE { raise_sys(); } - void lower() Q_DECL_OVERRIDE { lower_sys(); } - void setWindowTitle(const QString &title) Q_DECL_OVERRIDE { setWindowTitle_sys(title); } + void setParent(const QPlatformWindow *window) override; + void setGeometry(const QRect &rect) override { setGeometry_sys(rect); } + void setVisible(bool visible) override; + void raise() override { raise_sys(); } + void lower() override { lower_sys(); } + void setWindowTitle(const QString &title) override { setWindowTitle_sys(title); } protected: - HWND handle() const Q_DECL_OVERRIDE { return m_hwnd; } + HWND handle() const override { return m_hwnd; } private: const HWND m_hwnd; @@ -189,7 +187,6 @@ public: { AutoMouseCapture = 0x1, //! Automatic mouse capture on button press. WithinSetParent = 0x2, - FrameDirty = 0x4, //! Frame outdated by setStyle, recalculate in next query. OpenGLSurface = 0x10, OpenGL_ES2 = 0x20, OpenGLDoubleBuffered = 0x40, @@ -208,7 +205,8 @@ public: MaximizeToFullScreen = 0x80000, InputMethodDisabled = 0x100000, Compositing = 0x200000, - HasBorderInFullScreen = 0x400000 + HasBorderInFullScreen = 0x400000, + WithinDpiChanged = 0x800000, }; QWindowsWindow(QWindow *window, const QWindowsWindowData &data); @@ -216,52 +214,54 @@ public: using QPlatformWindow::screenForGeometry; - QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; } - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; - QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; } - QRect normalGeometry() const Q_DECL_OVERRIDE; + QSurfaceFormat format() const override { return m_format; } + void setGeometry(const QRect &rect) override; + QRect geometry() const override { return m_data.geometry; } + QRect normalGeometry() const override; - void setVisible(bool visible) Q_DECL_OVERRIDE; + void setVisible(bool visible) override; bool isVisible() const; - bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); } - bool isActive() const Q_DECL_OVERRIDE; - bool isEmbedded(const QPlatformWindow *parentWindow = 0) const Q_DECL_OVERRIDE; - QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; - QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE; + bool isExposed() const override { return testFlag(Exposed); } + bool isActive() const override; + bool isAncestorOf(const QPlatformWindow *child) const override; + bool isEmbedded() const override; + QPoint mapToGlobal(const QPoint &pos) const override; + QPoint mapFromGlobal(const QPoint &pos) const override; - void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; - void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE; + void setWindowFlags(Qt::WindowFlags flags) override; + void setWindowState(Qt::WindowState state) override; - void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE; + void setParent(const QPlatformWindow *window) override; - void setWindowTitle(const QString &title) Q_DECL_OVERRIDE; - void raise() Q_DECL_OVERRIDE { raise_sys(); } - void lower() Q_DECL_OVERRIDE { lower_sys(); } + void setWindowTitle(const QString &title) override; + void raise() override { raise_sys(); } + void lower() override { lower_sys(); } - void windowEvent(QEvent *event) Q_DECL_OVERRIDE; + void windowEvent(QEvent *event) override; - void propagateSizeHints() Q_DECL_OVERRIDE; + void propagateSizeHints() override; static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp); bool handleGeometryChanging(MSG *message) const; - QMargins frameMargins() const Q_DECL_OVERRIDE; + QMargins frameMargins() const override; + void setFrameMargins(const QMargins &newMargins); - void setOpacity(qreal level) Q_DECL_OVERRIDE; - void setMask(const QRegion ®ion) Q_DECL_OVERRIDE; + void setOpacity(qreal level) override; + void setMask(const QRegion ®ion) override; qreal opacity() const { return m_opacity; } - void requestActivateWindow() Q_DECL_OVERRIDE; + void requestActivateWindow() override; - bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE; - bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE; + bool setKeyboardGrabEnabled(bool grab) override; + bool setMouseGrabEnabled(bool grab) override; inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; } - bool startSystemResize(const QPoint &pos, Qt::Corner corner) Q_DECL_OVERRIDE; + bool startSystemResize(const QPoint &pos, Qt::Corner corner) override; - void setFrameStrutEventsEnabled(bool enabled) Q_DECL_OVERRIDE; - bool frameStrutEventsEnabled() const Q_DECL_OVERRIDE { return testFlag(FrameStrutEventsEnabled); } + void setFrameStrutEventsEnabled(bool enabled) override; + bool frameStrutEventsEnabled() const override { return testFlag(FrameStrutEventsEnabled); } // QWindowsBaseWindow overrides - HWND handle() const Q_DECL_OVERRIDE { return m_data.hwnd; } - bool isTopLevel() const Q_DECL_OVERRIDE; + HWND handle() const override { return m_data.hwnd; } + bool isTopLevel() const override; QMargins customMargins() const { return m_data.customMargins; } void setCustomMargins(const QMargins &m); @@ -301,14 +301,14 @@ public: void setEnabled(bool enabled); bool isEnabled() const; - void setWindowIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void setWindowIcon(const QIcon &icon) override; void *surface(void *nativeConfig, int *err); - void invalidateSurface() Q_DECL_OVERRIDE; + void invalidateSurface() override; void aboutToMakeCurrent(); - void setAlertState(bool enabled) Q_DECL_OVERRIDE; - bool isAlertState() const Q_DECL_OVERRIDE { return testFlag(AlertState); } + void setAlertState(bool enabled) override; + bool isAlertState() const override { return testFlag(AlertState); } void alertWindow(int durationMs = 0); void stopAlertWindow(); @@ -335,20 +335,20 @@ private: void fireExpose(const QRegion ®ion, bool force=false); mutable QWindowsWindowData m_data; - mutable unsigned m_flags; - HDC m_hdc; - Qt::WindowState m_windowState; - qreal m_opacity; + mutable unsigned m_flags = WithinCreate; + HDC m_hdc = 0; + Qt::WindowState m_windowState = Qt::WindowNoState; + qreal m_opacity = 1; #ifndef QT_NO_CURSOR CursorHandlePtr m_cursor; #endif - QWindowsOleDropTarget *m_dropTarget; - unsigned m_savedStyle; + QWindowsOleDropTarget *m_dropTarget = nullptr; + unsigned m_savedStyle = 0; QRect m_savedFrameGeometry; const QSurfaceFormat m_format; - HICON m_iconSmall; - HICON m_iconBig; - void *m_surface; + HICON m_iconSmall = 0; + HICON m_iconBig = 0; + void *m_surface = nullptr; }; #ifndef QT_NO_DEBUG_STREAM @@ -357,6 +357,7 @@ QDebug operator<<(QDebug d, const POINT &); QDebug operator<<(QDebug d, const MINMAXINFO &i); QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p); QDebug operator<<(QDebug d, const WINDOWPLACEMENT &); +QDebug operator<<(QDebug d, const WINDOWPOS &); #endif // !QT_NO_DEBUG_STREAM // ---------- QWindowsGeometryHint inline functions. @@ -385,15 +386,14 @@ QPoint QWindowsGeometryHint::mapFromGlobal(const QWindow *w, const QPoint &p) inline QWindowsWindow *QWindowsWindow::windowsWindowOf(const QWindow *w) { - QWindowsWindow *result = Q_NULLPTR; - if (w) { - const Qt::WindowType type = w->type(); - if (type != Qt::Desktop && type != Qt::ForeignWindow) { - if (QPlatformWindow *pw = w->handle()) - result = static_cast<QWindowsWindow *>(pw); - } - } - return result; + if (!w || !w->handle()) + return nullptr; + + const Qt::WindowType type = w->type(); + if (type == Qt::Desktop || w->handle()->isForeignWindow()) + return nullptr; + + return static_cast<QWindowsWindow *>(w->handle()); } void *QWindowsWindow::userDataOf(HWND hwnd) diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 20e0b81da9..7d3ecc8aa2 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -99,5 +99,5 @@ RESOURCES += $$PWD/openglblacklists.qrc qtConfig(accessibility): include($$PWD/accessible/accessible.pri) -DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME} -DEFINES *= LIBGLESV2_NAME=$${LIBGLESV2_NAME} +DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME} +DEFINES *= LIBGLESV2_NAME=$${LIBQTANGLE_NAME} |