summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel/qwidget.cpp
Commit message (Collapse)AuthorAgeFilesLines
...
* Widgets: Don't assume layout handles safe area margins if widget opts outTor Arne Vestbø2024-05-161-2/+6
| | | | | | | | | | | | | | | | As an optimization when calculating the safe area margins for child widgets we look at the parent hierarchy, and if we find a widget that is in a layout, and that layout respects the widget's contents rect, we assume the safe area margins are accounted for already. But this relies on the widget the layout is operating on to not opt out of the safe area margins affecting the contents rect. If it does, the layout can't help us, and we need to fall back to computing the child widget's safe area margins. Task-number: QTBUG-125345 Change-Id: I2e2f7d292d2b2c3ecd2e2e95316c4d72b92db5d6 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* QWidget: fix render() in RTL modeChristian Ehrlicher2024-05-081-0/+3
| | | | | | | | | | | | | | | Rendering a widget to a paintdevice via QWidget::render() did not pass the LayoutDirection mode of the widget to the paintdevice which lead to wrong rendering of text. This is especially visible with the windows 11 style which does not draw some widgets directly on the screen but through a QGraphicsEffect on a QImage. Pick-to: 6.7 6.5 6.2 Fixes: QTBUG-124931 Change-Id: If2cfa326d2ca45c42e203a4ae91fd857afa5c69c Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
* Widgets focus abstraction: Skip isFocusChainConsistent w/o logging catAxel Spoerl2024-04-261-1/+6
| | | | | | | | | | | | | | | | | | QWidgetPrivate::isFocusChainConsistent() iterates over QApplication::allWidgets() to identify and log inconsistencies. In applications with many widgets, this has a major performance impact. Disable the check and return true, unless the logging category qt.widgets.focus is enabled. Adapt tst_QWidget::focusAbstraction() to enable the logging category. This amends 58d5d4b7c2faaeaa2c2ccdabb3da6d37f9db880a. Fixes: QTBUG-124666 Change-Id: Ia487b381ab45b052638b189bf56acaf4353b1a37 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Set focus to the window container when contained window gains focusDoris Verria2024-04-221-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As it is, when a QWindowContainer's embedded window gains focus, the container doesn't report having focus and QApplication::focusWidget() will be nullptr. This is because when the embedded window gets focus, the container will clearFocus() on the old focus widget. To be able to set focus to the next focus widget (eg: as a result of a key tab event sent to the container's parent window), the container checks if its embedded window is already focused, and if so, forwards focus to its nextInFocusChain(). That is why it keeps track of the (old) focusWindow. The problem with the current behavior is that if we want to make focus navigation via key tabbing work and return focus *from within the window* back to the normal widget focus chain, the encapsulating widget needs to remember its focusWidget(), in this case the window container, in order to be able to set focus to the next/PrevInFocusChain(). That is why we now set the focus to the window container whenever its contained window gains focus. This means that QApplication::focusWidget() will be the window container if the contained window has focus. In this way, we don't have to call clearFocus() on the old focus widget, or keep track of focus windows, because calling setFocus() on the container will handle that. It is worth noting and probably documenting the following caveats: - even though the window container will be the qApp's focusWidget(), it won't directly handle keyboard events, but the contained window will - we won't be able to respect the window container's focusPolicy in this case, since the contained window will be activated from interactions inside it, no matter the container's focusPolicy [ChangeLog][QtWidgets][QWindowContainer] The window container will become focused if the contained window becomes focused. This implies that the QApplication::focusWidget() will be the window container if the contained window is the focus window. Task-number: QTBUG-121789 Change-Id: I1050afc59780f7189a0d8e8c95bff27f96f38dbc Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add preliminary support for Qt for visionOSTor Arne Vestbø2024-04-181-1/+1
| | | | | | | | | | | | | | | | | | | | | | Qt already runs on Vision Pro as "Designed for iPad", using Qt for iOS. This change enables building Qt for visionOS directly, which opens the door to visionOS specific APIs and use-cases such as volumes and immersive spaces. The platform removes some APIs we depend on, notably UIScreen, so some code paths have been disabled or mocked to get something up and running. As our current window management approach on UIKit platforms depends on UIWindow and UIScreen there is currently no way to bring up QWindows. This will improve once we refactor our window management to use window scenes. To configure for visionOS, pass -platform macx-visionos-clang, and optionally add -sdk xrsimulator to build for the simulator. Change-Id: I4eda55fc3fd06e12d30a188928487cf68940ee07 Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
* QWidget: Remove un-needed nullptr check for oldtlwTor Arne Vestbø2024-04-171-2/+3
| | | | | | | | | | | | | | | | | | Added in 1bd755465efa27294362925f55306f88f1800936 We already access oldtlw and oldtlw->d_func() in other places, and the source of oldtlw is a call to QWidget::window(), which returns the widget itself if it doesn't have a parent. This should also fix a CodeChecker issue where it thinks that the other unchecked accesses to oldtlw are suspicious. Add assert just in case, so we catch it explicitly if for some reason this assumption doesn't hold in the future. Pick-to: 6.7 6.5 Change-Id: Iefa9b2df6b25a993afe87e4ee90fe9d2075ebbd0 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* QWidget: fix link error in static buildZhao Yuhang2024-04-061-19/+19
| | | | | | | | | | | | QtQuick also uses "lcFocus" as a category name, which causes link errors in static builds when both QWidget and QtQuick are linked in one executable. Making it static is also a good solution, but here adding a "Widget" prefix seems more consistent. Change-Id: I0a6a02750bd347f62b67544b4044789612f0fa4d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* widgets: Invalidate RHI swapchain when window moves to new top levelTor Arne Vestbø2024-04-041-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a QWidget with an associated RHI swapchain (via its QWindow) is moved to a different top level window, that top level window has its own backing store, and QBackingStoreRhiSupport, which doesn't know anything about the fact that the window already has an associated swap chain in the original top level window's QBackingStoreRhiSupport. As having multiple swap chains for the same window is not supported on all RHI backends (Vulkan and DX in particular), we need to throw away the swap chain when detecting that the window is moved to a new top level. We do this by hooking into the existing WindowAboutToChangeInternal event delivery to renderToTexture children, which now delivers the event both to renderToTexture QWidget children as well as QWindows in the hierarchy. The condition of when to deliver the event has been updated to reflect whether the top level uses RHI for flushing, instead of only including renderToTexture children, as the former also includes setting QT_WIDGETS_RHI=1 explicitly. The event is then caught by QBackingStoreRhiSupportWindowWatcher, and handled the same way as for SurfaceAboutToBeDestroyed. Renaming qSendWindowChangeToTextureChildrenRecursively would make sense at this point, but to make cherry-picks easier we keep the current name for now. Fixes: QTBUG-120276 Pick-to: 6.7 6.5 Change-Id: Ic4c60e89be985f12a84e9f893c299e602b70851a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* Abstract QWidget focus chain managementAxel Spoerl2024-04-041-136/+420
| | | | | | | | | | | | | | | | | | | The focus chain in widgets is implemented as a double-linked list, using QWidgetPrivate::focus_next and focus_prev as pointers to the next/previous widget in the focus chain. These pointers are manipulated directly at many places, which is error prone and difficult to read. Build an abstraction layer and remove direct usage of focus_next and focus_prev. Provide functions to insert and remove widgets to/from the focus chain. Add a test function to tst_QWidget. Task-number: QTBUG-121478 Change-Id: Ide6379c0197137e420352a2976912f2de8a8b338 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Reparent QWindow children when reparenting QWidgetTor Arne Vestbø2024-03-141-39/+91
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a QWidget was reparented, we would take care to reparent its backing QWidgetWindow as well, into the nearest QWindow of the new QWidget parent. However we would only do this for the reparented widget itself, and not any of its child widgets. In the case where the widget has native children with their own QWindows, the widget itself may not (yet) be native, e.g. if it hasn't been shown yet, or if the user has set Qt::WA_DontCreateNativeAncestors. In these scenarios, we would be left with dangling QWindows, still hanging off their original QWindow parents, which would eventually lead to crashes. We now reparent both the QWindow of the reparented widget (as long as it's not about to be destroyed), and any QQWindow children we can reach. For each child hierarchy we can stop once we reach a QWindow, as the QWindow children of that window will follow along once we reparent the QWindow. QWindowContainer widgets don't usually have their own windowHandle(), but still manage a QWindow inside their parent widget hierarchy. These will not be reparented during QWidgetPrivate::setParent_sys(), but instead do their own reparenting later in QWidget::setParent via QWindowContainer::parentWasChanged(). The only exception to this is when the top level is about to be destroyed, in which case we let the window container know during QWidgetPrivate::setParent_sys(). Finally, although there should not be any leftover QWindows in the reparented widget once we have done the QWidgetWindow and QWindowContainer reparenting, we still do a pass over any remaining QWindows and reparent those too, since the original code included this as a possibility. We could make further improvements in this areas, such as moving the QWindowContainer::parentWasChanged() call, but the goal was to keep this change as minimal as possible so we can back-port it. Fixes: QTBUG-122747 Pick-to: 6.7.0 6.7 6.6 6.5 Change-Id: I4d1217fce4c3c48cf5f7bfbe9d561ab408ceebb2 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QDialogButtonBox: Don't set focus in a dialog with StrongFocus childrenAxel Spoerl2024-03-071-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A QDialogButtonBox with the first accept button becoming default, didn't explicitly set focus on such a button in a QDialog. d44413d526ec12ed83acd7343c2005782178c7ad implemented this missing functionality. It set focus to the automatic default button, unless the QDialog had a focusWidget() set. That has caused a regression, in cases where - the QDialog has a QWidget child with a Qt::StrongFocus policy, and - the QDialog is not yet visible, so focusWidget() returns nullptr. Amend d44413d526ec12ed83acd7343c2005782178c7ad: Implement a helper in QWidgetPrivate, that returns true, if a child with a given focus policy is found. Do not set focus to a QDialogButtonBox's automatic default button, when - not located inside a QDialog, or - a focusWidget() exists, or - the dialog has QWidget child with Qt::StrongFocus, that is not a child of the QDialogButtonBox. Add an autotest function. Pick-to: 6.7 6.6 6.5 Fixes: QTBUG-121514 Fixes: QTBUG-120049 Change-Id: I3c65ae36b56657f9af4a3a4b42f9b66e8bc5c534 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Add QWidgetPrivate::rhi() helper methodTor Arne Vestbø2024-03-011-0/+8
| | | | | | | | For accessing the RHI managed by the widget compositing machinery. Pick-to: 6.7 6.6 6.5 Change-Id: Ia3c1227cc2d9cfebe95611cad3dbcd7aa6f6f8c7 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add QWidgetPrivate::closestParentWidgetWithWindowHandle helper methodTor Arne Vestbø2024-03-011-0/+18
| | | | | | | | | In contrast to nativeParentWidget(), we return the closest widget with a QWindow, even if this window has not been created yet. Pick-to: 6.7 6.6 6.5 Change-Id: Icac46297a6052a7a5698d752d4aa871bd5c2bdd8 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Ensure QWidget::destroy() events and attributes match hiding the widgetTor Arne Vestbø2024-02-121-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When destroying a widget via QWidget::destroy(), we clear WA_WState_Created, and then delete the QWidgetWindow, which in turn hides the widget. But QWidgetPrivate::setVisible(false) skips hide_helper() if the widget has not been created, which leaves out important events such as the hide event, and even more important, fails to clear WA_WState_Visible. As a result, the widget is left visible (and mapped), even if it has been destroyed. This is normally not a big issue for the main use of destroy(), namely destructing the widget, but for cases where destroy() and create() is used to recreate the widget this is important. We now unconditionally call hide_helper() if the widget is not already hidden. As a result, the widget will correctly be visible=false after a destroy(). This in turn means we need to re-apply the visible state after recreating the widget when we detect a mismatch in RHI configuration. Due to our meddling of the Hidden and ExplicitShowHide attributes in QWidgetWindow private, a QWidet::show() will not have any effect after being destroy(). This is okey for now, as destroy() is internal to a widget, and we make sure to either update WA_WState_Visible and WA_WState_Hidden (in QWidgetPrivate::setParent_sys), or use the QWidgetPrivate::setVisible() code path directly, which doesn't have that issue. The root problem will be fixed in a follow up. Pick-to: 6.7 Change-Id: I77cb88d75e57f0d9a31741161fb14d618a653291 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Restore window state of recreated top level widget, not closest QWindowTor Arne Vestbø2024-02-121-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When we recreate a top level QWidget due to the RHI config not matching, we need to re-apply the window state, as the state is lost on destroy(). But we should do this on the QWidget we are recreating, not on its closest QWindow. These are usually the same, so it didn't matter in practice for most cases (besides the more convoluted way of getting to the QWidget's window). But if the top level widget does not have a winId yet, the call to find the closest QWindow via QWidgetPrivate::windowHandle() will traverse from the top level widget to its transient parent widget, via nativeParentWidget, which is strange and likely a bug. As a result of that, we would store the window state of the transient parent widget, and then, once we had created() the new top level, we would apply the window state to the top level, which now had a winId. We can simplify all of this by just storing and applying the window state on the widget we are re-creating. There's no need to go via the closest QWindow for this. We do however need to set the window state on the widget's window, as going via QWidget will just bail out since the window state hasn't changed. Amends c88211d1e4ac12eb2ae4990703a4f73c7085d624 Fixes: QTBUG-119795 Pick-to: 6.7 6.6 6.5 Change-Id: I0ad6e7bbac5f29d095cc643e9a7094784e9a2122 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Harden WidgetAttributes debug stream operatorTor Arne Vestbø2024-02-021-9/+10
| | | | | | | | The call site may pass in a null-widget, so guard for that. Pick-to: 6.7 Change-Id: I631cb2fc105bad69faf3daaeac4b893457d27cc1 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Don't set ExplicitShowHide on children when showing parent widgetTor Arne Vestbø2024-02-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | As a result of using QWidget::setVisible to show the child widgets we would end up also setting ExplicitShowHide. This is not in line with the intent of ExplicitShowHide, which is to flag a widget as explicitly shown/hidden by the developer, which in turn prevents Qt Widgets from toggling WState_Hidden when the widget is reparented. By using QWidgetPrivate::setVisible instead, we can show the child without setting ExplicitShowHide. As side effect of this is that we no longer reset WA_WState_Hidden from QWidgetWindowPrivate::setVisible(). This is an issue when the setVisible call comes as a result of destroying the QWidgetWindow, as that is an implicit hide, and should not result in the widget having WA_WState_Hidden. QWidget handles this case in hideChildren by not calling QWidgetPrivate::setVisible -- instead doing its own reset of WA_WState_Visible. We don't want to untangle this just yet, so as a workaround we detect that the widget is already !isVisible(), thanks to hideChildren having hidden it, and then skip the call to QWidgetPrivate::setVisible that results from QWindow::destroy(). Task-number: QTBUG-121398 Pick-to: 6.7 Change-Id: Ib5b4d9c84f0569124c5f3ca2169cabff18934e2d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add logging, clarifications, and tests for QWidget show/hide behaviorTor Arne Vestbø2024-02-011-10/+60
| | | | | | | Task-number: QTBUG-121398 Pick-to: 6.7 Change-Id: I94b4c90c3bd515279417c88497d7b9bd5a362eae Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add QWidgetPrivate::isExplicitlyHidden() helper functionTor Arne Vestbø2024-01-311-2/+8
| | | | | | | | | To aid readability. Task-number: QTBUG-121398 Pick-to: 6.7 Change-Id: I3cb231584c2b7aee72e9f01c669fed1e01fbe475 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* QWidget: Clean up state that depends on QWindow from ~QWidgetWindow()Tor Arne Vestbø2024-01-231-27/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We were assuming that QWidget was in full control of QWidgetWindow destruction, via deleteTLSysExtra(), and that we could limit any cleanups to that function. But in some situations QWidgetWindow is destructed from other code paths, in which case we were left with dangling pointers to the QWidgetWindow in both QTLWExtra, as well as the backingstore. This can happen if there's a child widget hierarchy where there is not a 1:1 mapping between QWidgets and QWindows, for example if the window attribute WA_DontCreateNativeAncestors has been set. In this situation our normal recursion into children in QWidget::destroy() stops at the first widget without a window handle. When we then delete the top level QWindow, the QWindow destructor will delete any child QWindows, which includes our leaf QWidgetWindow. We should probably fix up QWidget::destroy to continue looking for children, even if we don't destroy the current child. But independently of that we should make sure the QWidgetWindow cleans up when it's being deleted, regardless of how it ended up there. There's further room to clean up the deleteTLSysExtra() function and friends, but that's been left for a later time. Fixes: QTBUG-120509 Pick-to: 6.7 6.6 6.6.2 6.5 Change-Id: Ib691df164d7c9c83cb464c0a6bf3bc2116e8ca43 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Widgets: pass widget to QStyle::pixelMetric()Christian Ehrlicher2024-01-161-1/+1
| | | | | | | | | | | | Make sure to pass the widget to QStyle::pixelMetric() as some styles might use this (e.g. the new windows styles) to determine the correct pixel metric. Pick-to: 6.7 6.6 6.5 6.2 Task-number: QTBUG-1857 Change-Id: I5c32f5af8b284749732b610e56b4e3d8c8ed1946 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
* Use Qt::WindowNoState for child windows/widgets shown via show()Tor Arne Vestbø2023-12-131-10/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Qt::WindowState enum is documented to specify the current state of top-level windows, and does not make sense for child windows. It's up to the client code to ensure any sizing of child windows/widgets, e.g. via layouts. Many of our QPA backends bail out on QPlatformWindow::setWindowState() for a child window. Ideally we would do this at a higher level, in QWindow, but that's a bigger task, and the semantics of what happens when a window is moved from being top level to child or back are not fully clear. As a first step, we ensure that the default window state when showing the window via show() is Qt::WindowNoState. Unfortunately, the QPlatformIntegration::defaultWindowState() API only takes into account the window flags, which sadly do not have a way to reflect whether the window is a child window or not (Qt::SubWindow is not a child window, see QTBUG-115729). We don't want to pass a QWindow to this API, as it would mean QWidget would need to create a window when requesting the default window state. Instead we hard-code the opt-out for child windows/widgets. [ChangeLog][Gui/Widgets] Child windows and widgets are now always shown in their normal state by show(). Pick-to: 6.7 Change-Id: Ie8caf2df2d854194b9985c9427a9eac1312aba65 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
* Don't clear Qt::Window/ForeignWindow of QWidget if window is not top levelTor Arne Vestbø2023-12-061-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The logic was needed for the old QMacCocoaViewContainer, which was a QWidget, that set Qt::ForeignWindow, and hence Qt::Window, on its windowHandle(). The modern way of embedding a foreign window into a widget hierarchy is via QWindow::fromWinId() and QWidget::createWindowContainer(), which manages the foreign window as a child QWindow of the window container's window handle, instead of replacing or modifying the window container's own window handle. The opposite case is a QWidget embedded into a foreign/non-widget window hierarchy. Ideally, in this case, we should return false for isWindow(), as the function is documented to only return true for "if the widget is an independent window", and "a window is a widget that isn't visually the child of any other widget and that usually has a frame and a window title". This notion is used in many places, including in QApplication::topLevelWidgets(), which in turn affects the quit logic of QApplication to prevent quitting the application as long as the child/embedded widget is visible. Unfortunately, embedding the widget as a non-Qt::Window is not an option at this point, as we have a lot of code paths that assume isWindow() || parentWidget(), and these code paths break down in flames when we end up dereferencing the (non existing) parent widget. As a result of removing the logic, we can now embed a QWidget into a non-widget window hierarchy as a Qt::Window, without the removed logic resetting the widget back to a Qt::Widget on create(), which would send us into into the broken code paths described above. Removing this logic should not cause issues for child widgets backed by a native window, as those are created with Qt::Widget window flags, not Qt::Window, so we never relied on the removed logic to sanitize those window flags. Task-number: QTBUG-119652 Change-Id: Id6b8e5c67bf8f83af8c2f1594806f3419303b1a1 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Make QApplicationPrivate::active_window privateTor Arne Vestbø2023-11-201-1/+1
| | | | | | | | | | The active window of QApplication overlaps largely with the focus window of QGuiApplication. As a first step towards potentially removing the active_window member, make it private so we control access to it. Task-number: QTBUG-119287 Change-Id: I95785fea3ba4444db64063f4e4d3d3004465ef64 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Doc: Fix \fn template arguments for Qt WidgetsTopi Reinio2023-11-181-4/+4
| | | | | | | | | Upcoming changes to QDoc require accurate definition for template arguments in \fn commands. Task-number: QTBUG-118080 Change-Id: I3a193ca69a911ee2f62e7663aaf4c032a35ee5dd Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* Restore WindowState when changing SurfaceTypeWladimir Leuschner2023-11-061-0/+2
| | | | | | | | | | Restore the WindowState, when a Window has to be recreated due to changed SurfaceType. Fixes: QTBUG-118194 Pick-to: 6.6 6.5 Change-Id: I40ba552cda9dfc8ab543611595c068f80b8fa1d6 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* Doc: Revise QWidget docsAndreas Eliasson2023-11-011-47/+42
| | | | | | | | | | | | | | Reviewing and improving the docs for QWidget is part of the objectives for the 2023 Q4 OKRs. Most of the work in this patch is fixing grammatical errors and typos. It is tempting to move much, if not all, of the Detailed Description content from the QWidget class reference page (qwidget.cpp) into its own overview/explanation page, which would be more in line with the diátaxis framework. But I think that should be a different patch. Fixes: QTBUG-117758 Pick-to: 6.6 6.5 6.2 5.15 Change-Id: Ibb3f367c4677f7e6615bc0cd39d0ffe921862cb9 Reviewed-by: Safiyyah Moosa <safiyyah.moosa@qt.io> Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* widget: set WA_X11NetWmWindowType* after xcb window was createdLiang Qi2023-09-061-1/+1
| | | | | | | | | | | This amends 17d68c4fc371c32bd58d0a94ac63f0170edaf29e. Fixes: QTBUG-116696 Task-number: QTBUG-39887 Pick-to: 6.6 6.5 6.2 5.15 Change-Id: Idf385bcbeb630ddfc51b39b2af35da3ab94b07c0 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Fix texture-based non-native child of a non-texture-based native childLaszlo Agocs2023-08-151-4/+12
| | | | | | | | | | | | | Another one in the series of problems around having texture-based and regular widgets in hierarchies where some widgets are native and some are not. Pick-to: 6.6 6.5 Fixes: QTBUG-115652 Task-number: QTBUG-108344 Task-number: QTBUG-113557 Change-Id: I34306503cb17ccb915b90168ec3f39e209f668e5 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* Add QRhiWidgetLaszlo Agocs2023-08-141-1/+2
| | | | | | Task-number: QTBUG-113331 Change-Id: I8baa697b4997b05f52acdee0e08d3c368fde5bc2 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* Pull QWidget::setTabOrder(std::initializer_list...) behind ABI boundaryAxel Spoerl2023-08-111-0/+14
| | | | | | | | | Found in API-review. Pick-to: 6.6 Change-Id: I261aa450d25288e7a3e8caa033ce5000e5dd77f2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Fix link to platform window in QAndroidPlatformBackingStore::flush()Axel Spoerl2023-08-041-5/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Android QPA implementation requires a 1:1 link between a platform window and a platform backing store, to correctly flush a backing store to the screen. QAndroidPlatformBackingStore has a bool member m_backingStoreSet, to remember if this link exists. It defaults to false and is set to true, when setBackingStore() is called in the constructor. It falsely remains true, when a platform window is deleted, e.g. because a QWindow has been hidden. When the QWindow is shown again, a new Android platform window is created. With m_backingStoreSet still being true, this new platform window will never be associated with a backing store. As a consequence, it will never be displayed on the screen. The 1:1 relationship of an Android platform window and an Android backing store is neither ideal, nor in line with other QPA layers (e.g. XCB). Changing the Android QPA implementation is complex and a short term fix is necessary. This patch removes the member m_backingStoreSet. Instead of it, QAndroidPlatformBackingStore::flush() directly checks, if the platform window corresponding to the QWindow argument is associated to a backing store. If that is not the case, setBackingStore() is called. QTBUG-97482 has been fixed with another approach, which this patch reverts. The following commits are effectively reverted by this patch: 9a39ad8dfb4e6d1a179bd0fa38026886f8f7cb8e f91588923b1e7b68f1bd79b38af44d024df85996 a4ca9e80658bca7dad1529f03c1b59173a6ecf62 dbb072eb2838a04e89e34dad686394a496d5de87 959a8b3967ac3b6315f5b458628ec5661dfc367e Fixes: QTBUG-97482 Pick-to: 6.6 6.5 6.2 Change-Id: Ic4344f8df2e954c057dd2705340f11dfd2d4c6fe Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Implement virtual void QPlatformWindow::setBackingStore()Axel Spoerl2023-07-141-6/+5
| | | | | | | | | | | | | | | | | | QWidget re-uses an existing backing store. Platform windows depend on being associated to a backing store, in case they become toplevel windows. If a platform window gets deleted and re-created each time it is shown or hidden, it has to be manually associated to the re-used backing store. This patch partly reverts fbf0aeea7d3b38ced7a16fcd5c3e2e9b45536292. It removes Android specific code from QWidgetPrivate::create(), which has been added to suppress re-using backing stores in the absence of the new API. Fixes: QTBUG-97482 Pick-to: 6.6 Change-Id: Iaa1b7652efa120ec1955914c0383e8ccd8a41429 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* QWidget: Don't re-use backing store on AndroidAxel Spoerl2023-07-141-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | QWidget re-uses backing stores created in QWidgetPrivate::create(). The Android platform plugin creates a new platform window, when a widget becomes a toplevel window. When it is hidden, the platform window is deleted. The link between QAndroidPlatformWindow and its backing store is made in the constructor of QAndroidPlatformBackingstore. When a new QAndroidPlatformWindow is constructed and the backing store is re-used, there is no more link between platform window and platform backing store. This has lead to screen assets not being painted, when shown more than once. This patch forces QWidgetPrivate::create() to construct a new backing store on Android. This way, toplevel windows always have a backing store associated with it. It adds an assertion to QAndroidPlatformScreen::addWindow(). That will make e.g. tst_QWidget::visible() crash without the fix. Fixes: QTBUG-97482 Pick-to: 6.6 6.5 6.2 Change-Id: Ib1b172068b03549df161ab93ac24a273221d5423 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* Correct typo in QWidget::backgroundRole()Keith Kyzivat2023-07-101-1/+1
| | | | | | | | | Correct the typo inherts to inherits in QWidget::backgroundRole() docs, as it is incorrect english. Fixes: QTBUG-115160 Change-Id: I03892753d6ec7d81c1f818fd9caa279ca11cc3ec Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Move textedit example to manual testTor Arne Vestbø2023-06-291-4/+0
| | | | | | Pick-to: 6.5 6.6 Change-Id: Ic3189044598be8e121c1f065e68e04a3547a87d0 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Move tetrix example to manual testTor Arne Vestbø2023-06-291-1/+1
| | | | | | Pick-to: 6.5 6.6 Change-Id: Ie73d9e35df8513d05d55ffbad1f02584359e3bd0 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Move MDI example to manual testTor Arne Vestbø2023-06-291-1/+1
| | | | | | Pick-to: 6.5 6.6 Change-Id: Ide698a171a4600cb4bac6574b6be74c17f779051 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Fix missing references to 'Qt Widgets - Application Example'Tor Arne Vestbø2023-06-271-2/+1
| | | | | | | | Amends eda71105ff9a516059c6dd6643ff446a82edac81 Pick-to: 6.5 6.6 Change-Id: I44fa9acef37667d635d5770ce5d50fc52d92aa88 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Implement QWidgetPrivate::focusObject()Axel Spoerl2023-06-211-0/+7
| | | | | | | | | | | | | | | | | | | | | | | QWidgetPrivate::focusObject() always returns nullptr. That has lead to mismatches between QGuiApplication::focusObject() and QApplication::focusWidget(), when a widget got focus by the window system (e.g. mouse click). This patch implements QWidgetPrivate::focusObject. It returns the current widget, if it doesn't have a focus proxy. If it has a focus proxy, it resolves the proxy chain and returns the deepest focus proxy. (Note: It does not return QWidget::focusWidget(), because the focus widget might not yet have been set, when the method is called). Fixes: QTBUG-92464 Fixes: QTBUG-108522 Pick-to: 6.6 6.5 6.2 Done-With: Liang Qi <liang.qi@qt.io> Change-Id: Icf01e8ac4fc5f722fbf8e0ca5a562617ae9ae8f2 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Liang Qi <liang.qi@qt.io>
* Doc: Fix documentation issuesTopi Reinio2023-06-091-4/+3
| | | | | | | | | | | | | | | | The Qt Widgets Application example was moved to manual tests, and no longer contains the snippet identifiers. Fix \snippet and \quotefile commands to quote similar code snippets from other examples or snippet files. Fix also the following documentation warnings: * No such parameter 'parsingMode' in QUrl::fromEncoded() * Missing image: rsslisting.cpp Pick-to: 6.6 6.5 Change-Id: Ibc989e83abc49837db08628facaf8e5f72b2f123 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Revamp the shapedclock exampleVolker Hilsheimer2023-05-161-4/+12
| | | | | | | | | | | | | | | | Rename it to "Translucent Background", as that's what the example shows how to do. And modern applications shouldn't use a (binary) mask to create shaped windows. Instead, set the TranslucentBackground attribute, don't paint pixels that should be fully transparent and use anti-aliased or semi-opaque painting for pixels that should be translucent. Adjust the example and documentation accordingly. Move the statment that widget masks create coarse visual clipping to the QWidget::setMask documentation. Pick-to: 6.5 Change-Id: Id49d854093f2cb471afb178d32723081c7543543 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Add missing nullptr check in QWidget::setFocusProxyAxel Spoerl2023-04-251-1/+1
| | | | | | | | | | | | | | b1802a164b8682ed9e8956a5a19a90ade65c25d0 added handling for a parent to become focus proxy of a child. The respective 'else if' branch didn't check whether setFocusProxy() was called with a nullptr argument. This patch adds the missing nullptr check. It also adds functionality to tst_QWidget::tabOrderComboBox() to test the removal of a focus proxy, as well as the complete removal of an element from the focus chain. Change-Id: I4cb865b9ac4497fc5e2595910738fb77694f5837 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Handle parent being a child's focus procy in QWidget::setFocusProxyAxel Spoerl2023-04-221-0/+24
| | | | | | | | | | | | | | | | | When a parent became a new child's focus proxy in an existing focus chain, the child was appended at the end of the chain. That leads to broken tab order, e.g. with a QComboBox which became editable after a focus chain has been set. This patch captures the case and insertes the new child after its parent in the focus chain. A corresponding test function is added in tst_QWidget. Fixes: QTBUG-111978 Pick-to: 6.5 Change-Id: I3a426c0560fa830b7b7ffead54f26dd0adef499f Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget: add overload to set tab order as a list of widgetsVolker Hilsheimer2023-04-111-0/+24
| | | | | | | | | | | | | The "two widgets at a time" API to set the tab order is awkward and easily misused (as the documentation explicitly explains). Add an inline overload that takes an initializer_list, and call the existing function for each consecutive pair of widgets in the list. Add documentation with snippet, and a test. Change-Id: I8e6f14a242866e3ee7cfb8ecade4697d6bdfb4d4 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* doc: Add note about platform support for window positionsEskil Abrahamsen Blomfeldt2023-03-171-0/+4
| | | | | | | | | | | On some platforms, such as Wayland (and also eglfs), manual window positioning is not supported. Since this has caused confusion in the past, we add a note to the documentation. Pick-to: 6.2 6.5 Fixes: QTBUG-86780 Change-Id: Idf8dcdfad8ccfb9eb0f704fce05216562e433e20 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Handle device loss for texture widgetsDavid Redondo2023-03-171-4/+4
| | | | | | | | | | | | Previously the widget stayed black and we printed "QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen". To make it work the compositor is recreated in addition to the rhi and the widgets are informed with the internal events. Change-Id: I982d08bd3530478fe0f827080154c008a92a812e Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Handle tab order inceptionVolker Hilsheimer2023-03-091-21/+24
| | | | | | | | | | | | | | | | | If a composite widget is put behind one of it's contained children via QWidget::setTabOrder, then our logic might replace the composite widget with the contained child. In that case, we'd end up with a broken tab chain, possibly resulting in incomplete clean-ups and triggering asserts when shutting down the UI. Handle this by stopping the last-child searching logic at the respective other widget, and by not allowing both widgets to be the same. Augment test case, and apply some minor refactoring to the code. Pick-to: 6.5 6.2 Change-Id: I7d97dfa85315b6c01daa283253025d94a1727048 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Remove the 'sdi' exampleVolker Hilsheimer2023-03-021-1/+1
| | | | | | | | | | | It is essentially the same as the other mainwindow examples, showing how to create a text editor. The only special code here is the tiling of the different main windows, which - without any documentation or explanation - is neither very helpful, nor relevant in 2023. Pick-to: 6.5 Change-Id: I48b92b1cf057f586e0d2842d1c0a3312154e9a13 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Doc: fix link to Widgets TutorialVolker Hilsheimer2023-03-011-1/+1
| | | | | | | | It's been a while since we had a single Tutorial for all of Qt. Pick-to: 6.5 Change-Id: I7317291c445c09b0bf728513670b6a575dd536bc Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>