summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowscontext.cpp
Commit message (Collapse)AuthorAgeFilesLines
* ColorScheme: consolidate dark mode handling on Windows into ThemeVolker Hilsheimer14 days1-23/+1
| | | | | | | | | | | | | | | Move storage of whether dark mode is set into a static class member of QWindowsTheme, and remove QWindowsContext::isDarkMode; ask the theme instead using the colorScheme() implementation, which will return the stored value. Move the code handling settings changes into QWindowsTheme as well. Task-number: QTBUG-124490 Change-Id: I4795e80b6ab2c94701385dc84771e9ad5578cf32 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Windows: use MSG timestamps for input eventsGiuseppe D'Angelo2024-04-031-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Input events have a timestamp. When dispatching an event through QPA, a platform plugin can either provide it, or QPA will use an internal QElapsedTimer to provide a timestamp. Windows input messages do come with a timestamp already, so we can use that instead of the QPA. The two methods are not equivalent. For instance: for various reasons, Qt does not honor Windows' "double clicked" message, but uses the delta between two mouse events to establish if the second click is actually a double click. Now suppose that the user double clicks on a widget. On the first click, the application does something that freezes it for a bit (e.g. some heavy repainting or whatever). Does the second click register as a double click or not? * If we're using Qt's own timer, the answer is NO; the event is pulled from the WM queue after the freeze, given a timestamp far away from the last click, and so it will be deemed another single click * If we use the OS' timestamps, then the second click will be seen as "close" to the first click, and correctly registered as second click. This reasoning can be extended to many other QPA events, but looks like the APIs for some are missing (e.g. enter events), so I'm not tackling them here. This commit reverts ade96ff6446d4b0977d4e5f03b96b77ff8223b8b. Task-number: QTBUG-109833 Task-number: QTBUG-122226 Change-Id: I5f3fba029b44c618ef622bacdc4bcc3928e04867 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Yuhang Zhao <yuhangzhao@deepin.org>
* Windows QPA: Fix unity buildFriedemann Kleint2024-02-201-0/+2
| | | | | | | | | | Undef a macro that clashes with variables in other sources. Pick-to: 6.7 6.6 6.5 Task-number: QTBUG-109394 Change-Id: Id62f886ad64908047fc896f7e48da04759308123 Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Fix signed integer overflow in handling WM_SIZE messageWladimir Leuschner2023-11-281-1/+1
| | | | | | | | | | | | | The width and height of WM_SIZE parameters in LPARAM are unsigned ints, but were extracted as signed ints with GET_X_LPARAM and GET_Y_LPARAM, leading to signed integer overflow when using big window sizes. The width and height are now extracted with LOWORD and HIWORD. Fixes: QTBUG-119424 Pick-to: 6.6 Change-Id: Ie68716a08a686739b6464ce76319dc659fede336 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
* Rename QWSI::handleWindowActivated to QWSI::handleFocusWindowChangedTor Arne Vestbø2023-11-231-1/+1
| | | | | | | | | | | | | | | | | | | A single QWindow is QGuiApplication::focusWindow() at a time, and this window is typically also QWindow::isActive(), but other windows may also be QWindow::isActive(). For example, we treat any sibling or ancestor of the focusWindow as being QWindow::isActive() as well. In addition, in the case of non-QWindow child windows, we may have to query the platform for the activation state, which means we also need a way for the platform to reflect changes in this state through QWSI. The current API for this, QWSI::handleWindowActivated, is in practice a focus window change API, so as a first step let's rename it to better reflect what it's doing. Task-number: QTBUG-119287 Change-Id: I381baf8505dd13a4a829c961095a8d2ed120092b Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Windows: Improve hidpi style drawing and metricsMorten Sørvig2023-11-151-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Follow-up change from enabling DPI awareness, which caused some style elements (for instance check boxes) to be rendered incorrectly on non-primary displays, when there is a difference in DPI between displays. Use two approaches to get system metrics and themes: * Use forDpi() API variants and query at 96 DPI for style metrics, that are in device independent pixels. These are metrics which are used for layout calculations. * Get theme metrics at the target display DPI, and scale to device independent pixels when needed. This is used for OpenThemeData(), since this theme is used for drawing as well and needs to be in device pixels. One approach is not used any more: * Get metrics for the main display, and scale by the ratio between the main and target display. Change the theme cache to cache themes per window handle (HWND). This is required since OpenThemeData() returns theme data for a specific DPI, which means we can no longer use a shared cache. Clear the cache on theme change, DPI change, and when the window is destroyed. This handles cache invalidation when the window is moved to a different screen, and also when the DPI for a screen is changed. Move the cache implementation to QWindowsStyleSupport in QtGui, where it can be accessed by both the style and windows platform plugins. Task-number: QTBUG-110681 Change-Id: I5a4ff3a3753762bad8a51d08e51e8013bc7816a1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* cmake: use a more appropriate feature guardYuhang Zhao2023-10-101-1/+3
| | | | | | | | The factory cache registration functionality should belong to the cppwinrt feature, so guard it with appropriate QT_FEATURE_ guard. Change-Id: Icbadaa7ffb32a4e47fe3bbab90c37303fd787344 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
* Implement QWindowsKeyMapper in terms of QPlatformKeyMapperTor Arne Vestbø2023-10-091-4/+4
| | | | | Change-Id: I060ca9613d49bb85a2cf8d4f808b2b5b1c0bdcd5 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Rename QtWindows::KeyboardLayoutChangeEven -> InputLanguageChangeEventTor Arne Vestbø2023-09-291-1/+1
| | | | | | | | | | | | | | We react to WM_INPUTLANGCHANGE, and handle it by calling handleInputLanguageChanged on the input context. As input language is not the same as keyboard layout (a keyboard layout might change without the input language changing), let's be accurate about what's happening. Change-Id: I8914994a8d46485179741e010d0da5135b023668 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Andrey Butirsky <butirsky@gmail.com>
* Windows QPA: Fix restore geometry after dragging from maximisedTimothée Keller2023-04-251-0/+4
| | | | | | | | | | | | | Start tracking the window geometry before a mouse drag, so that we can revert back to that geometry when we restore from maximised. Previously, when dragging from maximised to maximised, the restore geometry would end up being the final drag place before snapping to maximised, instead of where the window was before the first maximised. Fixes: QTBUG-112814 Pick-to: 6.5 6.2 Change-Id: Ic2ddf29d6c4abdc9e8b0c5161b17aa6ee9474ea3 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* QWSI: Remove handleFrameStrutMouseEvent in favor of handleMouseEvent+typeTor Arne Vestbø2023-03-311-7/+2
| | | | | | | | | | | | | | | The handleMouseEvent function already takes a QEvent::Type, where clients pass in the corresponding mouse press/release/move type. The same applies to the handleFrameStrutMouseEvent. To avoid the chance that clients call these functions with a conflicting event type (handleFrameStrutMouseEvent with MouseButtonPress instead of NonClientAreaMouseButtonPress e.g.), we remove handleFrameStrutMouseEvent altogether and just let clients use the handleMouseEvent function directly with the correct event type. Change-Id: I4a0241c39aedac0d2d8d5163ba05cde72605959c Reviewed-by: Lars Knoll <lars@knoll.priv.no>
* Windows: Send synthetic mouse release after move/resize using right APITor Arne Vestbø2023-03-281-3/+7
| | | | | | | | | | | | | | | | | | | The end of a move or resize might happen with the mouse still inside the non-client area of the window, in which case we correctly resolved the type to QEvent::NonClientAreaMouseButtonRelease, but we sent it via QWindowSystemInterface::handleMouseEvent, which sets nonClientArea of the event to false. This in turn resulted in QGuiApplication sending a synthetic QEvent::MouseMove in case the position was out of sync, instead of the correct QEvent::NonClientAreaMouseMove. This should really be cleaned up on the QWSI level, as there is no reason to have a dedicated API for handleFrameStrutMouseEvent, when handleMouseEvent already takes an event type, but for now we fix the immediate issue in the Windows platform plugin. Pick-to: 6.5 6.2 Change-Id: I8a831f5f19adb0625b29b50ebce9c0c6514e93f3 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Windows: Don't send non-client mouse events unless frameStrutEventsEnabledTor Arne Vestbø2023-03-281-2/+6
| | | | | | | | | | During refactoring in 38504041148f2d1cffea6520ea448dd4171adb0b the logic was changed in a way that ended up sending non-client mouse events even if frameStrutEventsEnabled() was not set on the platform window. Pick-to: 6.5 6.2 Change-Id: Icbde51641020aeec99572d80859082fdcf656311 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Windows QPA: Change handling of maximised frame/title-less windowsTimothée Keller2023-03-221-1/+1
| | | | | | | | | | | | | | So far, the framele/tite-less window maximising has been done by adjusting the MINMAXINFO to prevent them from covering the taskbar. It does not work when moving the windows from one screen to another using keyboard shortcuts, since the MINMAXINFO is that of the old monitor. This moves the adjustment to the WM_SIZE message that occurs after the window has been resized. Pick-to: 6.5 6.4 6.2 Change-Id: I0d36fe5d2e8eaa0739414835b8d99a0b2ed44cf6 Reviewed-by: Yuhang Zhao <yuhangzhao@deepin.org> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Windows QPA: fix debug messageYuhang Zhao2023-02-081-7/+8
| | | | | | | | | | Before applying this patch, the debug message will contain new lines which will look rather weired, this patch fixes that. Amends commit 5e0d9a077d28802988182319ae257e9102f0344e Change-Id: I2420c04dd7e18a6556664a05ac4ef35c9b652f0c Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Revert "Windows: use MSG timestamps for input events"Oliver Wolff2023-01-301-2/+1
| | | | | | | | | | | | This reverts commit baa5888807d3db57603398ae7aa27866efdbd711. The change caused breakages in qtdeclarative's auto tests. Current assumption is that we need the system timestamps for other events as well. Reverting now to unblock CI. Fixes: QTBUG-110596 Change-Id: I9583627bc058ff0d6cadfa622eed119fb41ca4a1 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Windows QPA: rework how we set dpi awarenessYuhang Zhao2023-01-231-51/+114
| | | | | | | | | | | | | | | | | | | Qt6's minimum supported platform is Win10 1809, so it should be quite safe to use DPI_AWARENESS_CONTEXT APIs because they were introduced in Win10 1607. This patch removes the use of the PROCESS_DPI_AWARENESS APIs because they are old (introduced in Win8.1) and most importantly, they can't handle the new PMv2 and GdiScaled awareness mode. This refactor also fixed a bug: previously Qt is using GetProcessDpiAwareness() to get the dpi awareness mode of the current process, however, that API can't return PMv2, which means even if we are in PMv2 mode, it will still return PMv1 (I've confirmed that locally), and thus Qt is mishandling such cases. Eg: when judging whether to enable non-client area dpi scaling or not. Change-Id: I8a8946ba63c863f8c19c27998af2bac97db37ec7 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Windows: use MSG timestamps for input eventsGiuseppe D'Angelo2023-01-231-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Input events have a timestamp. When dispatching an event through QPA, a platform plugin can either provide it, or QPA will use an internal QElapsedTimer to provide a timestamp. Windows input messages do come with a timestamp already, so we can use that instead of the QPA. The two methods are not equivalent. For instance: for various reasons, Qt does not honor Windows' "double clicked" message, but uses the delta between two mouse events to establish if the second click is actually a double click. Now suppose that the user double clicks on a widget. On the first click, the application does something that freezes it for a bit (e.g. some heavy repainting or whatever). Does the second click register as a double click or not? * If we're using Qt's own timer, the answer is NO; the event is pulled from the WM queue after the freeze, given a timestamp far away from the last click, and so it will be deemed another single click * If we use the OS' timestamps, then the second click will be seen as "close" to the first click, and correctly registered as second click. This reasoning can be extended to many other QPA events, but looks like the APIs for some are missing (e.g. enter events), so I'm not tackling them here. Task-number: QTBUG-109833 Change-Id: I149361a844feac86cafa885c109a1903b1e49545 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Yuhang Zhao <yuhangzhao@deepin.org> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* QWindowsContext::setProcessDpi[V2]Awareness check current value before ↵Oliver Wolff2022-12-231-13/+18
| | | | | | | | | | | | | setting it Our previous assumption was that the right value was used if we ran into an "access denied" error. That error only states that the function has been called before though. The warning should be omitted if the right value has been set before. Pick-to: 6.5 Change-Id: I1379242f68e2f09bc6a25dd322fe3634622d8e8e Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* Windows QPA: Always apply system background color for top level windowYuhang Zhao2022-12-051-1/+1
| | | | | | | | | | | | | | | This is a follow-up patch of commit 2991c66b75612dfb11dbba166dd08b2376b42102 We can unset the window background brush and always draw the background ourself. Qt always paint all pixels anyway when blt'ing the backingstore, so it should be safe to do this. Since a theme might not provide a palette (e.g. when desktop setting awareness is disabled), always use the default application palette. Change-Id: I4fdc2467b3cc3999dd1acfe9411cec077ca66bd3 Reviewed-by: Yuhang Zhao <2546789017@qq.com> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Add QGuiApplication API to set a number-badge in the Dock/task barTor Arne Vestbø2022-12-021-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The API is supported on macOS, iOS, and Windows. On Android no official API exists for badging the application icon, and we don't want to take on dependencies like ShortcutBadger [1]. The macOS and iOS implementations are trivial. The same goes for the WinRT based implementation on Windows, but this API is only available for applications that have a so called "package identity", and does not seem to be stable for Windows 10. To cover the cases where this API is not available we fall back to drawing the badge manually, and set it as an overlay icon on the task bar using ITaskbarList3. The look of this badge has been tweaked to match the Windows 11/10 styles, and will pick up the user's choice of dark/light mode and accent color if available. [1] https://github.com/leolin310148/ShortcutBadger/ [ChangeLog][QtGui] Added QGuiApplication::setBadgeNumber() to inform the user about e.g. the number of unread e-mail or queued tasks. The badge will be overlaid on the application's icon in the Dock on macOS, the home screen icon on iOS, or the task bar on Windows. Task-number: QTBUG-94009 Change-Id: I6447d55177f9987b0dfcd93caf63c6167f7224c7 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Windows: centralize how we handle error messagesYuhang Zhao2022-11-161-94/+4
| | | | | | | | | | | | | | | | Currently QtBase contains multiple implementation of how to get the Win32 and COM error messages, and they are almost exactly the same, what's worse, Qt already has a private QSystemError class to do such things, so we are re-inventing the wheel in many places. This patch removes all other custom error message implementations besides the QSystemError one. And since there are a lot of places need the COM error message, move the implementation to QSystemError so that it can handle both Win32 error and COM error. Since I'm touching these lines anyway, break them into short lines if they are above the length limit. Change-Id: I1067c874011800303f0f114b5cb8830ac6810fc0 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Rename QWindowsMimeConverter to QWindowsMimeRegistry, rename filesVolker Hilsheimer2022-11-031-3/+3
| | | | | | | | | | | | The class registers converters and provides access to the converter able to handle specific formats. But it is not a converter itself. The converter would then be the implementation of the virtual interface, e.g. QWindowsMime subclasses. Task-number: QTBUG-93632 Change-Id: I150ef28e9bcead4291d72e0b0aa660be3fcd4a8a Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Proper clearing of WinRT factory cacheAndreas Buhr2022-10-311-1/+6
| | | | | | | | | | | | | | | | | | | If we use winrt's factories we have to make sure to to clear the factory cache when one of our dlls is unloaded or we will run into dangling factory entries which might result in crashes. So we have to make sure that winrt::clear_factory_cache is called on every dll unload. In order not to increase compile times and dependencies too much qfactorycacheregistration_p.h needs to be included in Qt code whenever we use winrt's factory cache. A rule of thumb being: Include qfactorycacheregistration_p.h whenever including winrt/base.h. Other Qt modules which use winrt's factories need to be updated too. Fixes: QTBUG-103611 Pick-to: 6.2 6.4 Change-Id: I7ab24e4b18bffaca653c5b7f56a66ce99212e339 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Windows QPA: suppress warning message when not neededYuhang Zhao2022-10-281-7/+11
| | | | | | | | | | | | We have done the same thing when calling SetProcessDpiAwareness(), but it's also needed for SetProcessDpiAwarenessContext(), otherwise there will always be a warning message when the user uses a manifest file to set the DPI awareness mode for the application (which is highly recommended by Microsoft). Pick-to: 6.4 Change-Id: I31894d41c89581b6edd7826cb3dabad492f6c2a8 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Port from qAsConst() to std::as_const()Marc Mutz2022-10-111-2/+2
| | | | | | | | | | | | | | | | We've been requiring C++17 since Qt 6.0, and our qAsConst use finally starts to bother us (QTBUG-99313), so time to port away from it now. Since qAsConst has exactly the same semantics as std::as_const (down to rvalue treatment, constexpr'ness and noexcept'ness), there's really nothing more to it than a global search-and-replace, with manual unstaging of the actual definition and documentation in dist/, src/corelib/doc/ and src/corelib/global/. Task-number: QTBUG-99313 Change-Id: I4c7114444a325ad4e62d0fcbfd347d2bbfb21541 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Windows: Align QWindowsWindow logging category name with other platformsTor Arne Vestbø2022-08-161-7/+7
| | | | | | | Other platforms name it singular 'qt.qpa.window'. Change-Id: I668ed67e1686605fe5f77313c7a01c31fd574c32 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Windows: Implement dark mode palette and accent color supportVolker Hilsheimer2022-07-291-7/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | Use the WinRT API to read the basic colors, and construct a usable palette from those. None of the Windows.UI.ViewManagement.UISettings APIs returns a full set of usable colors -UIElementColors returns the old system colors, or useless values. And UISettings::GetColorValue only gives access to a basic palette, where e.g. the background color is just black, which doesn't match what Windows itself uses. However, we know if we want to be dark or light, and can construct a palette from the basic colors. The most relevant color to read from the system is the accent color. In the course of doing that, refactor and clean up the code somewhat to standardize the handling, and remove hardcoded color values as much as possible. This is opt-in: unless the application is started with the QPA darkmode parameter set to 2, nothing changes. Pick-to: 6.4 Task-number: QTBUG-72028 Change-Id: If603bb34c8f7478a05aafef2552a67e1e3460d29 Reviewed-by: Marius Kittler <mariuskittler@gmx.de> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Windows: better handling of darkmode supportVolker Hilsheimer2022-07-191-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 43ef22045c6f4fbf76d5cfa4ca32160d919b9984 turned dark mode support on for both styling and window frames. However, the default palette and style support in Qt is too incomplete, resulting in unreadable UIs when using certain styles (e.g. fusion). Also the vista style is not supporting dark mode. If we don't turn on dark style support, then dark frame support doesn't look good either. However, many application developers have implement a dark theme themselves, and we should have a dark frame for those applications. So partially revert 43ef22045c6f4fbf76d5cfa4ca32160d919b9984 so that dark style support is disabled by default, and leave dark frame support on. However, only activate dark frames if the palette is dark, i.e. if the window background color in the default palette is darker than the text color (or if DarkModeStyle is explicitly turned on by running the application with -platform windows:darkmode=2). This way, dark-themed applications get a dark frame on dark Windows, and a light frame on light Windows; and light-themed applications (including default Qt applications) get a light frame all the time. Fixes: QTBUG-72028 Pick-to: 6.4 Change-Id: I61f1b1e43b2a4ba69848d5d8bec921c0790fe511 Reviewed-by: Marius Kittler <mariuskittler@gmx.de> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Windows: Account for not finding child windows when calling ↵Tor Arne Vestbø2022-07-071-0/+2
| | | | | | | | | | | | | | | | | | | | | | | ChildWindowFromPointEx The main code path of findPlatformWindowHelper had a check to verify that the resulting child was not the parent HWND handle itself, but the code path for handling QTBUG-40555 was missing this check, resulting in infinite loops when the top level window was a transparent window. We add the same kind of check to this code path, where neither the hwnd out pointer or the result out pointer is updated. This is okey since we return false and don't expect the function to continue iterating based on an updated hwnd pointer. Ideally the iteration logic should be moved into findPlatformWindowHelper instead of having the outer loop outside of the function, but that's left for another day. Fixes: QTBUG-103571 Pick-to: 6.4 6.3 6.2 5.15 Change-Id: I9465253bca52bebf9137b24d7ce36646553d8d39 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Windows: Decouple screen change monitoring from top level QWindowsTor Arne Vestbø2022-06-181-6/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The WM_DISPLAYCHANGE message it sent when displays are added, removed, or update their properties such as the scale/DPI. We were processing this message as part of QWindowsContext::windowsProc(), which meant that we would only react to display changes if there was a QWindow on screen. Just creating a QGuiApplication was insufficient to pick up changes to screens after startup. In addition, despite being documented to post messages to child windows, WM_DISPLAYCHANGE only ends up in top level windows. Presumably it's the top level window's responsibility to post the message to child windows. As a result, if a QWindow was a native child window of a foreign window, such as in audio plugins being hosted in a DAW, we would again fail to pick up display changes. We solve both these cases by decoupling the WM_DISPLAYCHANGE handling from QWindowsContext::windowsProc(), by creating a dedicated window for listening to WM_DISPLAYCHANGE. This is similar to how we already handle tray icons, power notifications, clipboard, etc -- the only difference being that since purely HWND_MESSAGE windows do not receive WM_DISPLAYCHANGE it's an actual invisible WS_TILED window. This also lets us remove the workaround for QTBUG-79248, which was doing screen updates in response to WM_DPICHANGED when detecting that there were no QWindows. Task-number: QTBUG-103383 Task-number: QTBUG-79248 Fixes: QTBUG-102343 Pick-to: 6.4 Change-Id: I905d8253069ec339b193edf05c052d21361ca3e9 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Windows QPA: Update screen on child window DPI changeMorten Sørvig2022-06-161-0/+3
| | | | | | | | | | | | | | | | | | | | | | Windows does not send WM_DPICHANGED to child windows, which means that the normal DPI change handling code does not run for QWindows which are embedded in a foreign, non-Qt, window. Add code which handles WM_DPICHANGED_AFTERPARENT. This event is sent to all child windows, but not the top-level window. Call checkForScreenChanged() here, similar to what the WM_DPICHANGED code does. This commit does not add code to resize the child window, since it is uncertain if this is the responsibility of the window which receives WM_DPICHANGED, or of each child window. Done-with: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Pick-to: 6.4 Task-number: QTBUG-103383 Change-Id: Icf85dd0afa806609dbbe0ffc36efbc5127962c39 Reviewed-by: <stefan.wastl@native-instruments.de> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Fallback to PerMonitorDpiAware if V2DpiAware is not supported by systemVladimir Belyavsky2022-06-081-10/+8
| | | | | | | | | | | | | | DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 might not be supported on some legacy Windows 10 editions (prior Creator Update). In this case SetProcessDpiAwarenessContext returns ERROR_INVALID_PARAMETER. Fallback to DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE using old API SetProcessDpiAwareness in such cases as the most suitable. Fixes: QTBUG-103733 Pick-to: 6.3 6.4 Change-Id: I39216e63ecfcae96aaa159237a52b0a76bc5d956 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-161-39/+3
| | | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* Windows QPA: Fix crash in some rare casesYuhang Zhao2022-05-101-1/+2
| | | | | | | | | | | | | | For the WM_SETTINGCHANGE message, lParam sometimes may be NULL [1] and that will lead to crash without extra safe guard. Amends commit qtbase/1ed449e168af133184633d174fd7339a13d1d595 [1] https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-settingchange Change-Id: Ibd1e94b4c1d7882db0719c31a66a5fcc9299c3bd Reviewed-by: Nodir Temirkhodjaev <nodir.temir@gmail.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Revert "Windows QPA: Remove dependency on swprintf_s() pulled in via ↵Kai Köhne2022-05-061-20/+1
| | | | | | | | | | | | | | | | | _com_error::ErrorMessage()." This reverts commit 043529c9dc609f3dc4bc6c79b7bc4d33ca3a3ba3, that was introduced to keep compatibility with Windows XP. This is not necessary anymore, as support for Windows XP got dropped. The now removed code also had an issue in the format of the fifth argument of FormatMessage, that is supposed to be a pointer to a pointer for FORMAT_MESSAGE_ALLOCATE_BUFFER. Pick-to: 6.2 6.3 Change-Id: Ib75b6a53a778801388d71388701340d3b79dacce Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Ihor Dutchak <ihor.youw@gmail.com>
* Plugins: use _L1 for for creating Latin-1 string literalsSona Kurazyan2022-05-041-8/+10
| | | | | | | | | As a drive-by, fix qsizetype -> int narrowing conversion warnings for the touched lines. Task-number: QTBUG-98434 Change-Id: I7fadd3cf27ad099028d70f05956303e3af62c0f5 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Windows QPA: Only refresh the window theme if it really changesYuhang Zhao2022-04-261-11/+14
| | | | | | | | | | | | | | | WM_SETTINGCHANGE may be triggered in many different reasons, we don't have to verify whether the system changes the global theme or not in all cases. Although not officially documented, there's a widely known and used technique to detect whether the user actually changes the personalize settings or not, that is when wParam is 0 and lParam is "ImmersiveColorSet", this combination indicates system's personalize settings has been changed. We can get rid of most unneeded verify of system theme by only execute the logic in this specific case. Change-Id: Iaf934c29975b3b2090fd692776f80b1125d3ddb3 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Send ThemeChange event to all windows when system theme changesTor Arne Vestbø2022-04-221-2/+1
| | | | | | | | | | | | | | | | | | | The QWSI event for theme change has an optional window parameter to specify the window affected, but most platform react to global theme changes, and end up passing nullptr into the event. The reasonable thing to do in QGuiApplication in that case is send a theme change event to every QWindow, so that they are all notified about the situation. This approach is what the Windows platform plugin was doing already, but did so by iterating manually over the windows, resulting in multiple calls to QGuiApplicationPrivate::handleThemeChanged -- one for each QWSI event. Change-Id: Ifb27b6c31231377c0df389a592cafd0075d3d8bb Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Windows QPA: Correctly respond to WM_ERASEBKGNDYuhang Zhao2021-12-151-1/+1
| | | | | | | | | | | | | | | | According to Microsoft Docs [1], applications should return non-zero in response to WM_ERASEBKGND if it processes the message and erases the background and that's indeed the case for Qt. Although I can't see any visual difference, this patch obeys the official documentation at least. [1] https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd Pick-to: 6.3 6.2 Change-Id: I8aa0bfb25259013bfc2ca4074f05a97c7865159c Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Windows QPA: Remove extra class name from the function nameYuhang Zhao2021-12-151-1/+1
| | | | | Change-Id: Iabe7c0093acc9b892182aa7e69e5af50abf61275 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Windows QPA: Fix cursors getting out of sync after restoring override ↵Friedemann Kleint2021-12-081-3/+6
| | | | | | | | | | | | | | cursors on native windows Introduce a flag to QWindowsWindow which forces the cursor to be applied after restoring override cursors. Fixes: QTBUG-98856 Pick-to: 6.2 5.15 Change-Id: Id62cdc2dd01f45324503a542446b1c11a1fe6f44 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Keith Kyzivat <keith.kyzivat@qt.io> Reviewed-by: André de la Rocha <andre.rocha@qt.io>
* QPA: Set focus reason when window activation changes focusVolker Hilsheimer2021-12-031-1/+1
| | | | | | | | | | | | | | | QApplication hides the fact that the reason is never set by several QPA plugins, but Quick items don't receive the correct reason on Windows, Android, the offscreen plugin, and other platforms. Add relevant scenario to the QFocusEvent test case, and fix the plugins to always set the focus reason when handling window activation changes. Exclude the minimal plugin from the test, it seems largely unmaintained anyway. Task-number: QTBUG-75862 Change-Id: I5404a225b387fc9a3851b6968d0777c687127ed1 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Windows QPA: Further cleanup of pre-Win10 codeYuhang Zhao2021-11-241-103/+18
| | | | | | | | | | | | | | | | | Mostly a removal of dynamically loaded Win32 APIs. Since Qt 6's minimum supported platform is Win10 1809 (10.0.17763, code name RS5), all these functions will be available and no need to resolve them at run-time. Things not remove: WinTab functions in "qwindowstabletsupport.cpp". Not my familiar area, so not touch it. Pick-to: 6.2 Task-number: QTBUG-84432 Change-Id: I7ad6c3bc8376f6c0e3ac90f34e22f7628efeb694 Reviewed-by: André de la Rocha <andre.rocha@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Handle WM_GETDPISCALEDSIZEMorten Johan Sørvig2021-10-071-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | By handling WM_GETDPISCALEDSIZE we can keep QWindow’s device independent size constant across DPI changes. This is done by scaling QPlatformWindow’s native size such that the change of scale factor and change of QPlatformWindow size cancels out. Qt now handles DPI change using two events: WM_GETDPISCALEDSIZE: Compute the new size for the window. WM_DPICHANGED: Apply the new DPI and window geometry. The reason for this complication is that Windows retains control over the window position during the DPI change, in order to e.g. accurately track the cursor position during a screen change. The default WM_GETDPISCALEDSIZE implementation (provided by Windows) scales the win32 window size linearly with the DPI change. We want to use linear scaling as well, however the win32 window size includes the margins, which do not change linearly as the DPI changes. Instead, scale the QPlatformWindow size, and then add the new margins. Pick-to: 6.2 Change-Id: I4f225be8fad56b1fa77e9e3cfd6538a206589d73 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Move VM_DPICHANGE handling to QWindowsWindowMorten Johan Sørvig2021-10-071-29/+2
| | | | | | | | | We want to have as little code in the QWindowsContext event switch as possible. Pick-to: 6.2 Change-Id: I04d578aae81c4ee804310a70bd87ee60b2890b6a Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* windows qpa: Handle invisible child windows gracefully on dpi changesOliver Wolff2021-09-301-0/+2
| | | | | | | Fixes: QTBUG-96466 Pick-to: 6.2 Change-Id: I58d90e85b4bb837df2dc5fd89abe984dadcd468d Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* Check for correct "Access Denied" errorMorten Sørvig2021-08-201-2/+2
| | | | | | | | | | | SetProcessDpiAwarenessContext() returns ERROR_ACCESS_DENIED if the DPI awareness has already been set, and not E_ACCESSDENIED like SetProcessDpiAwareness() does. Pick-to: 6.2 Change-Id: I6b29214773776f31c0622a35494d98c5c9637b0b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Improve WM_DPICHANGED handlingMorten Johan Sørvig2021-08-061-38/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Resize QPlatformWindow on DPI change, so that QWindow size can stay approximately constant. For example, a 100x100 QWindow at 100% scaling will have a 100x100 QPlatformWindow. If the scaling is changed to 200% then the QPlatformWindow is resized to 200x200, while the size of the QWindow stays at at 100x100. In practice the QWindow size will also change slightly, due to inaccuracies in how we adjust for the size of the non-client window area. This will be addressed in a later commit. We can get DPI change independently of screen change, so no resizing should happen in screen change events. Disable the resize code in QGuiApplication for Q_OS_WIN, and remove the WithinDpiChanged flag. The new flow for handling DPI change is: 1) Send screen change (if any), so that the correct screen will be used when calculating scale factors during the following resize. 2) Resize the native window, which will trigger geometry change events, possibly also for the QWindow. 3) Resize child windows; WM_DPICHANGED is sent to top-level windows only. Fixes: QTBUG-89294 Pick-to: 6.2 Change-Id: I0e2d44bae72d20ebdafc3d410db7be9964ad851b Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
* Track current window DPIMorten Johan Sørvig2021-08-061-0/+5
| | | | | | | | | | The WM_DPICHANGED event gives us the new DPI, but we also need the current DPI in order to determine the scale factor corresponding to the DPI change. Pick-to: 6.2 Change-Id: Ia61388415f57aa739397d3125b8751952e8fd392 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>