summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel/qwidget.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QPainter: move painter dirty flag handling into QWidget::initPainterTim Blechmann2025-10-141-4/+15
| | | | | | | | | | | | | `QWidget::initPainter` modifies font, pen and brush of the painer. The dirty flags were set from within QPainterPrivate::initFrom. This sprinkles the semantics across the codebase. The code becomes much easier to reason about, when setting the flags immediately after updating the state. In a similar manner we handle QPaintEngineEx::penChanged. Change-Id: I2f1095df4b56276681c58af0fb8163854835d060 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Doc: Add alternate text for Qt Widgets imagesJerome Pasion2025-10-091-1/+7
| | | | | | | | | | Alternate text (alt text) improves the documentation experience for screen readers and for other accessibility tools. Pick-to: 6.9 6.10 Task-number: QTBUG-135124 Change-Id: Ic481c1468548d197a69c9e19703c5773226fbd39 Reviewed-by: Alexei Cazacov <alexei.cazacov@qt.io>
* QWidget: initPainter - remove unnecessary const_castTim Blechmann2025-10-091-1/+1
| | | | | | | | | const_cast tend to be evil and is not necessary when calling a function that takes a const pointer. Pick-to: 6.10 Change-Id: I0e10a5717c636e474a21cb710f1f9d213adeb6b7 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Fix scrolling of QTableWidget within QGraphicsViewFriedemann Kleint2025-10-091-0/+1
| | | | | | | | | | | In the QGraphicsView branch of QWidget::scroll, scroll the children, too. Task-number: QTBUG-138381 Pick-to: 6.10 Change-Id: I77cb9288d5b9630dca659d7ef987d11914ed1e43 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Mark Qt::WindowType::Desktop deprecatedAxel Spoerl2025-09-301-0/+4
| | | | | | | | | Qt::WindowType::Desktop is no longer a valid window type in Qt6. Mark it deprecated. Fixes: QTBUG-140514 Change-Id: Ic47da86bc44fb5eb510a07150de1d07941406177 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Remove Qt::WindowType::Desktop in QWidgetAxel Spoerl2025-09-301-74/+41
| | | | | | | | | Qt::WindowType::Desktop is no longer a valid window type in Qt6. Remove its occurence in QWidget. Task-number: QTBUG-140514 Change-Id: I4ed072b0d038d54bbc16d129d9525ccf3881a6e0 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
* QWidget: Ignore Qt::WindowType::DesktopAxel Spoerl2025-09-291-0/+9
| | | | | | | | | | | | | Qt::WindowType::Desktop has been reserved for desktop widgets, which do not exist in Qt 6. Ignore the flag in QWidgetPrivate::setWindowFlags(). Add a Q_ASSERT in QWidgetPrivate::init() and force it to false in release builds. Task-number: QTBUG-124559 Change-Id: I80a547089ff6d22314c5373e4e08bce0468dcc5f Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Add note to the setWindowFlag to reflect known effectMorteza Jamshidi2025-09-241-0/+4
| | | | | | | | | | After calling setWindowFlag, widget becomes hidden. This is mentioned in the windowFlags property but not for the setWindowFlag, so I added that. Fixes: QTBUG-138459 Change-Id: I280698a212fa7d4bccdc69088c68bbe457599cfd Pick-to: 6.10 6.8 6.5 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
* CRA review: src/widgets/kernel/qwidget.*MohammadHossein Qanbari2025-09-231-0/+1
| | | | | | | | | | | The security level for qwidget.* files are tagged as significant. QUIP: 23 Fixes: QTBUG-140351 Task-number: QTBUG-135741 Pick-to: 6.10 6.8 Change-Id: Ida69fed90caec4801a47f97d46b1133649b12a8f Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget: fix propagating style with descendant selectorsChristian Ehrlicher2025-09-221-1/+8
| | | | | | | | | | | | | | | The fix for QTBUG-133332 introduced a check to avoid an endless recursion within setStyle_helper() but it prevents the correct propagation of the style with a descendant selector. Therefore use another approach and make sure QWidgetPrivate::inheritStyle() is not called recursivly. This amends 3252e1808c12c21f27bb4844a1497d18587a64b5. Pick-to: 6.10 6.9 Task-number: QTBUG-133332 Fixes: QTBUG-139924 Change-Id: Ia0a1eec652380397f861364bbdc303dfd17b34f3 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Don't report/enable safe areas for graphics-view proxied widgetsTor Arne Vestbø2025-09-151-1/+13
| | | | | | | | | | We don't handle the safe area mapping for proxied widgets. Task-number: QTBUG-140133 Pick-to: 6.10 6.9 Change-Id: I87b666f5364b7ad89be77e84054eb2d653933b61 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
* wasm: a11y - Implement ParentChanged callbackEven Oscar Andersen2025-09-081-0/+8
| | | | | | | | | | | | | | | | Implement the QAccessible::ParentChanged callback. Probably not possible with a perfect implementation. What can reasonably be done is to issue ParentChanged on; QWidget::setParent, QWindow::setParent, QQuickItem::setParentItem. However calling these functions do not necessarily map 1:1 to QAccessibleInterface::parent(). Fixes: QTBUG-138802 Fixes: QTBUG-134923 Change-Id: Iac4ac7843ba904bf0b7aa9964ee68a94294ad979 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* Widgets: use safe margins from QWindow::safeAreaMargins()Assam Boudjelthia2025-07-281-5/+1
| | | | | | | | | | We don't need to go through the platform window and handle native pixels conversion because QWindow::safeAreaMargins() already does that. Pick-to: 6.10 6.9 Fixes: QTBUG-138157 Change-Id: I11ec493d1b3a55628a27632fa94b3d14e3f30a50 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* a11y - send ObjectDestroyed event on object destructionEven Oscar Andersen2025-07-211-0/+6
| | | | | | | | We send the event from the accessible cache. This is the only place we have access to both the interface and the object. Change-Id: I078d6e082b0c3205bfcb544e94b9736360fea4a3 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* wayland: Add xx-session-management-v1 supportDavid Edmundson2025-06-271-4/+17
| | | | | | | | | | | | | | | | | | This is powered by the xx-session-manager which is tagged as experiemntal. This is guarded by an env variable. Application level session IDs are exposed via QSessionManager. The public API for windows is exposed via the existing QSessionManager and QWidget::setWindowRole. As it's not widely supported the documentation in QWidget is left untouched for now. [ChangeLog][Third-Party Code] New protocol synced from wayland-protocols Change-Id: Ibfbef86c6e75f8b95433cbba69ca10a5abea9e21 Reviewed-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
* wasm: a11y - Implement support for disabled attributeEven Oscar Andersen2025-06-131-0/+17
| | | | | | Fixes: QTBUG-137449 Change-Id: I6aa07c7108b5ad14c12e6f24e71b8dda12fec483 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
* Doc: Fix auto-links to deprecated functionsDavid Boddie2025-05-311-2/+2
| | | | | Change-Id: Id4456eef3440734add2d804d186966e253335b7c Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* QWidget: don't re-polish when style did not changeChristian Ehrlicher2025-05-201-1/+1
| | | | | | | | | | | | Don't call style->unpolish()/polish() when the old and new style did not change which might happen when setting a style sheet as this might create an infinite loop and the style (re)sets some window attribute. Bailing out early is not an option here as newStyle might be a nullptr so q->style() will fall back to the application default style. Pick-to: 6.9 Fixes: QTBUG-133332 Change-Id: Ifa9ee4fdfa64b2768337e2d90b7bbaac5f3fcd70 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Widgets/Stylesheets: compile without FEATURE_style_stylesheetChristian Ehrlicher2025-05-011-0/+2
| | | | | | | | | | | Make sure to not compile the stylesheet sources when FEATURE_style_stylesheet is disabled, also don't include the relevant headers in this case. Pick-to: 6.9 Fixes: QTBUG-136341 Change-Id: I4fc2de2fcba004b93140809ef79374401209f14a Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Widgets/Stylesheets: Remove double negations for stylehseet featureChristian Ehrlicher2025-05-011-11/+11
| | | | | | | | | | Replace ifndef QT_NO_STYLE_STYLESHEET antipattern by if QT_CONFIG(style_stylesheet). Pick-to: 6.9 Task-number: QTBUG-136341 Change-Id: I8f5d5ff0b7b5cce010df167977214bc92a9443b7 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Only default top levels to Qt::WA_ContentsMarginsRespectsSafeAreaTor Arne Vestbø2025-03-181-2/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When safe area margins are in play, such as on iOS and Android, or on macOS in 6.8 and above when the NSWindowStyleMaskFullSizeContentView styleMask has been set (manually or via Qt::ExpandedClientAreaHint in 6.9), then widgets with a layout will by default try to avoid the non- safe areas. This worked well as a safe default, ensuring widget applications filled the entire window with its background color, while constraining the layout of children to the safe area. However, for those that explicitly want to put content in the non-safe areas, by setting Qt::WA_ContentsMarginsRespectsSafeArea to false, the story was a bit cumbersome, as we set the attribute to true by default for all widgets. Meaning, any child widget put into the non-safe areas that itself had a layout (such as a push button) would also need the Qt::WA_ContentsMarginsRespectsSafeArea = false override. We now default Qt::WA_ContentsMarginsRespectsSafeArea to true only for top level widgets on creation, and leave it up to the user to manage the attribute for the other use-cases, as they then need to be in full control. [ChangeLog][QtWidgets] The Qt::WA_ContentsMarginsRespectsSafeArea attribute is no longer set by default for non-top-level widgets. Top level widgets still default to Qt::WA_ContentsMarginsRespectsSafeArea=true, so children are laid out in the safe areas, but overriding the attribute for the top level now allows placing widgets in the non-safe areas without also setting the Qt::WA_ContentsMarginsRespectsSafeArea attribute to false for every descendant widget that overlaps the non-safe area. Task-number: QTBUG-133215 Pick-to: 6.9 6.8 Change-Id: I7b1d420d730ee896ec2fb61aadacd94473dc9681 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add QAccessible::LocationChanged to QWidgetEven Oscar Andersen2025-03-111-0/+6
| | | | | | | | | Issue the event when geometry has changed to match QML. Task-number: QTBUG-115926 Pick-to: 6.9 6.8 Change-Id: I31d87a2b07c1cbdb31063bdbf146f21310103798 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget: init `data` in ctor, not Private::init()Marc Mutz2025-03-041-2/+1
| | | | | | | | | | | | | | | This should fix Coverity's hallucination that QWidget::data is used uninitialized, or, after 58b9250aea0b1b41c8cbd1033149371a93a5b2c1, dereferenced while it's still nullptr. Coverity-Id: 475552 Coverity-Id: 475551 Coverity-Id: 475550 Coverity-Id: 475549 Coverity-Id: 396828 Pick-to: 6.9 6.8 6.5 Change-Id: I49705b8bc44082fc68a59c2c98c4e37a6d841b19 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget: Don't offset the clip region for windows using effectsChristian Ehrlicher2025-03-041-1/+1
| | | | | | | | | | | | | When a top-level widget has a graphic effect applied, QWidgetPrivate::clipToEffectiveMask() must not use the parent widget for the mask calculation as this prevents the loop below from bailing out in the first loop (w->isWindow()) and might mess up the clip region when there is a widget with a mask in the parent chain. Pick-to: 6.9 6.8 Fixes: QTBUG-131893 Change-Id: I5d5777e730bee309db21ad5eb65387d19321ee6c Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget: DRY the ctors, use ctor delegationMarc Mutz2025-03-031-7/+1
| | | | | | | | | | | | | | | | | | Don't repeat the body in the two QWidgets ctors, call one from the other instead. This will help fighting Coverity's hallucination that QWidget::data is used uninitialized, or, after 58b9250aea0b1b41c8cbd1033149371a93a5b2c1, dereferenced while it's still nullptr. Coverity-Id: 475552 Coverity-Id: 475551 Coverity-Id: 475550 Coverity-Id: 475549 Coverity-Id: 396828 Pick-to: 6.9 6.8 6.5 Change-Id: I1f9a8b93871143b420b9c8f247e49d57510a2379 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Use QThread::isMainThread() in a few placesThiago Macieira2025-02-261-1/+1
| | | | | | | | | | | | | | | It's thread-safe, whereas trying to load qApp isn't in Qt 6.x (will be in 7.0) and dereferencing it to call QObject::thread() will probably never be. It's also faster, being a single function call instead of two or three. This is not an exhaustive search, it's just a few places I found while searching for QThread::instance(). Pick-to: 6.9 6.8 Change-Id: I3b4e1c75bb3966e2cd2dfffd79bfc8a40f6cf40b Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QObjectPrivate: encode the version number in the constructor parametersThiago Macieira2025-01-271-11/+1
| | | | | | | | | | | | | | | | Instead of allowing the code to start and then possibly fail at runtime. This isn't a 100% sure solution because it's a function call. With lazy symbol binding on some OSes, the mistake won't be noticed until the function call is attempted. However, most OSes now resolve *all* calls at load time so they can mark the GOT (or equivalent) pages read-only, meaning the loading of the library will fail. qversiontagging_p.h is a more sure way in OSes / executable formats it works on. Change-Id: If7867a37256b7141001dfffd9bd299bb1bbd7c63 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Use old position to set window position after recreationMorteza Jamshidi2025-01-221-0/+2
| | | | | | | | | Like window state and visibility, the window position should also remain the same after the window is recreated. Fixes: QTBUG-128790 Change-Id: Iad8599da7ef83eff6a93f7f071e6b452491a0d87 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* widget: clear WA_OutsideWSRange when needed in QWidgetPrivate::create()Liang Qi2025-01-161-3/+6
| | | | | | | | | which follows the behavior in QWidgetPrivate::setGeometry_sys(). Pick-to: 6.9 6.8 Fixes: QTBUG-129698 Change-Id: Ia85e9470111eea9e3392cdf38c3da2db232ef065 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* QWidget::mapTo()/mapFrom(): Do not crash if parent argument is invalidEirik Aavitsland2024-12-121-5/+8
| | | | | | | | | | | | | | | These functions iterate through the parent hierarchy until the widget given as argument is found. If never found, the code would assert (in debug mode) or just silently crash (in release mode). No need to bring down the entire application just because some widget coordinate calculation is off. Instead, just emit a qWarning and return cleanly. Task-number: QTBUG-132072 Pick-to: 6.9 6.8 Change-Id: I4d13f46037cdcf855f76e040f941a8a7050ab12b Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Introduce Qt::ExpandedClientAreaHintTor Arne Vestbø2024-11-251-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The hint requests that the window's client area is expanded to fill parts of the window that might be (partially) covered by, or conflicting with, other (system) UI elements, such as the window's title bar, resize controls, or a status bar. The safe area margins of the window will reflect any areas that may have conflicting UI elements. If the client area is expanded into the area previously covered by the frame margins, the frame margins are reduced accordingly, as the frame margins represent the non-client-area parts of the window. This new flag replaces, and overlaps in value, with the existing Qt::MaximizeUsingFullscreenGeometryHint, as the latter was added to cover this exact use-case for mobile platforms. Now that we have the use-case on desktop platforms as well we want to use a more generic flag, so the old flag has been deprecated. Semantically, on iOS and Android, without the flags set, the window can be seen as being maximized to take up the entire screen, but with a frameMargin() that reflects the system status bar and resize controls. That's not technically how we implement things right now, but this is an implementation detail that will be changed in a follow-up. On macOS the flag maps to NSWindowStyleMaskFullSizeContentView, and on Windows we have an implementation cooking that uses the DwmExtendFrameIntoClientArea function. Task-number: QTBUG-127634 Change-Id: I9b6863b1550ccc056c16bce235d87b26a7d239b9 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
* QWidget: delete 'extra' in dtorChristian Ehrlicher2024-11-111-0/+1
| | | | | | | | | | | | | | | Call d->deleteExtra() in dtor of QWidget to make sure it's cleaned up before QWidgetPrivate calls it which might access the already deleted QWidget through deleteTLSysExtra() / QWindowContainer::toplevelAboutToBeDestroyed(q). Amends 006cbf658ea1f5986bbe1baafa7c146780320661. Pick-to: 6.8 6.8.1 Task-number: QTBUG-130932 Change-Id: I9109072a457cc01abd5d1b4e844a3ed3309d942b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget::mapTo/FromGlobal(): Fix transformation in case of ↵Friedemann Kleint2024-11-011-2/+3
| | | | | | | | | | | | QGraphicsItem::ItemIgnoresTransformations Extract a helper returning the transform from QGraphicsViewPrivate::mapToViewRect() and use that. Fixes: QTBUG-128913 Pick-to: 6.8 Change-Id: Idc31f653c23cd7d0e5bbb8af560f010f01ac4d4b Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* QWidget::mapTo/FromGlobal(): Fix transformation for QGraphicsView with offsetsFriedemann Kleint2024-11-011-2/+2
| | | | | | | | | | | | | Amends 474af0a61d6154006966a775d186687aa8881708. The code had an error showing when the QGraphicsView was not at 0,0 in the window. Pick-to: 6.8 Task-number: QTBUG-128913 Task-number: QTBUG-52507 Change-Id: Ic228cc7e71ef54dd23c946b9d90f9c45aac793d9 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* widgets: Send Window{AboutToChange}Internal when top level used RHIInho Lee2024-10-021-3/+4
| | | | | | | | | | | | | | | | When calling setParent for a top-level widget that used RHI it's not enough to check if the widget's parent used RHI, as that's always going to be false. Missing this results in not sending textureChildren events for the reparented widget. Amends eb4cb719257d3b57cd801273d4011579d8c81714 Fixes: QTBUG-129299 Pick-to: 6.8 6.8.0 Change-Id: I632d8d63ec56243cd6da2b196ad9651c28128f0b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* QWidgetWindow: fix enter/leave events not sent due to fractional scalingDavid Faure2024-08-301-3/+16
| | | | | | | | | | | | | | | | If widget A starts at y=0 and widget B starts at y=19, when the mouse moves from y=15 to y=18.6667, the code was doing childAt(p) with a rounded QPoint y=19 and finding B, but then the relative coord for B was set to -0.33333 so B wasn't under the mouse and didn't get an enter event (and since it's now the "last receiver", it doesn't get one later either when y is bigger). Add QWidget::childAt(QPointF) to fix this. Fixes: QTBUG-128391 Pick-to: 6.8 Change-Id: I76d4b711a8297648780bdd079eb67405ab12be14 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* a11y: Notify of implicit window title changeMichael Weghorn2024-08-231-14/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 25ab8ada1019adf9e88addd47acb0924831edc5a implemented sending a QAccessible::NameChanged event when the window name is used as accessible name and is changed by calling QWidget::setWindowTitle. Besides explicitly setting a new window title that way, the title can also be changed less explicitly: If the window title contains a corresponding "[*]" placeholder, changing the QWidget::windowModified property also results in a changed window title, with no QAccessible::NameChanged being sent so far. Move the logic introduced in 25ab8ada1019adf9e88addd47acb0924831edc5a further down into QWidgetPrivate::setWindowTitle_sys so it covers that case as well. While at it, also adjust this to skip retrieving the accessible here after all if accessibility is not enabled. This also needs 5178606a98be57f6dc5f3dddc1fa0f1e16c933e5 (for xcb; corresponding qtwayland still pending in Gerrit) for the event to actually be sent for the QWidget::setWindowModified case, because oldAccessibleName in QWidgetPrivate::setWindowTitle_sys would previously already be evaluated to the new accessible name by qt_setWindowTitle_helperHelper instead of using the old window title still set on the window before the actual title gets updated. Fixes: QTBUG-128296 Change-Id: Iaf80cd4019b6bc7383f425b45ece51f322a9e1c4 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* widgets: Persist window Qt::Popup state when reparenting parent widgetTor Arne Vestbø2024-08-031-10/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | As a result of c956eb8eddb1b3608d7e3d332fbe55df5ec41578 we are now reparenting QWindows managed by QWidgets when the widget itself or any of its parent widgets are reparented. When reparenting a child widget from being a child to a top level, or top level to child, we need to know the new top level state to determine if the QWindow should have a QWindow parent or not. As the window flags of the widget are in flux during the reparenting, we were using the new window flags of the reparented widget to determine this. However, for QWidget children of the widget that's being reparented we can't use the window flags of the reparented widget. We must use the flags of the child itself. These flags are not in flux, so we can use QWidget::windowFlags() directly. Failing to propagate the child widget window flags was causing us to lose the transient parent relationship to its parent QWindow for popup windows. Fixes: QTBUG-127641 Fixes: QTBUG-125149 Task-number: QTBUG-122747 Pick-to: 6.8 6.7 6.5 Change-Id: I6dbc5ff5ad019b0f9188516ff3d645e860a9627b Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Volodymyr Zibarov <gogan419@gmail.com>
* a11y: Don't notify about name/desc/id change if there was noneMichael Weghorn2024-07-191-0/+9
| | | | | | | | | | | | | | | | | | | | Return early if the setters are called with the same string as is already set for the accessible name, description or identifier. This avoids sending an event wrongly notifying about a change when there was actually none. Extend the `tst_QAccessibility::accessibleIdentifier` autotest accordingly to test that no event is triggered when setting the same ID again. Thanks to Jan Arve Sæther for suggesting that in the previous change introducing the accessibleIdentifier property. (Implemented in a separate commit as it is a preexisting issue for accessible name and description.) Change-Id: Id3af3f0c4769e93e4970be9db87734df9ef84212 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
* a11y: Add property for QWidget's accessible IDMichael Weghorn2024-07-191-0/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 9ec1de2528b871099d416d15592fcc5ef9242a64 added an Identifier role to QAccessible that can be used to provide an identfier for reliable identification by assistive technologies, e.g. in automated tests. As discussed in that commit's Gerrit change, add a corresponding accessibleIdentifier property to QWidget to allow easily setting a specific identifier for widgets, in the same way that an accessible name or description can be set. This provides more flexibility than the default logic that generates an identifier to be used in platform bridges that is based on the object or class names of the objects in the widget's subtree. (The only alternative so far to set a particular ID not including the "object path" would have been to provide a custom QAccessibleInterface implementation with a corresponding QAccessibleInterface::text implementation.) Add an autotest testing both, the default platform bridge logic and that the the newly added property overrides that. [ChangeLog][QtWidgets][QWidget] Add an accessibleId property that allows to easily set a particular accessible identifier for QWidgets that can be used by assistive technologies to identify the widget. Change-Id: If24e138c7d8fe4c78f25d3f0629a9520c352bacc Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Call QWidget::setVisible, not QWidgetPrivate, when showing childrenTor Arne Vestbø2024-07-041-5/+17
| | | | | | | | | | | | | | | | | | | | | | | | As part of 5ba0982b2879a1a4c13bf97467b8e5ad296e57a2 we started calling QWidgetPrivate::setVisible instead of QWidget::setVisible when showing children, to avoid setting ExplicitShowHide. Unfortunately some widget subclasses wrongly override setVisible to do initialization, which resulted in these widgets not running their init code. The documentation clearly specifies to use showEvent or Polish for this use case, but to avoid a regression we temporarily set a flag that prevents QWidget::setVisible from setting the ExplicitShowHide attribute. We can not rely on simply unsetting ExplicitShowHide after our call to QWidget::setVisible, as the call might recurse into logic that checks ExplicitShowHide and wrongly determines that the show is explicit. Fixes: QTBUG-126721 Fixes: QTBUG-126218 Pick-to: 6.7 6.8 Change-Id: Ibf88340b68cb4fcb20ce3d8ec5b76de0fd2d2551 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Remove unused qt_pressGrab in qwidget.cppShawn Rutledge2024-07-011-5/+1
| | | | | | | | I can't find evidence that it has been anything other than nullptr since the 2011 "Qt by Nokia" commit at least. Change-Id: I191f35b1fc8ca06c5c28696fed5c44f1e8c30f59 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Straighten out various logging categoriesUlf Hermann2024-06-191-2/+2
| | | | | | | | | | | | Either make them static or declare them in a header. We want them to be static wherever possible, in order to reduce the number of visible symbols. If they can't be static, however, they should at least be declared in only one place. Task-number: QTBUG-67692 Change-Id: I6f3b596ed4f0adc9873dd0a5f54f055a991a6207 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Let QWindowContainer know when its top level is about to be destroyedTor Arne Vestbø2024-06-181-0/+4
| | | | | | | | | | | | | | | | | | | | | | | When the top level window that a QWindowContainer is in is about to be destroyed the QWindowContainer must reparent the contained window into a dummy window, as otherwise the destruction of the top level will bring down the contained window as well. We were notifying the window container about this situation when the window container was moved from being a top level itself, to being a child widget, but did not have any logic for other ways the window container could lose its parent QWindow. An example of this was when RHI-needs would result in recreating the top revel with a different RHI backend. We now have a last minute call to toplevelAboutToBeDestroyed in QWidgetPrivate::deleteTLSysExtra(). Fixes: QTBUG-126303 Pick-to: 6.8 6.7 6.5 Change-Id: I5b14e156956ae76a8f53cac31904eaadee9e791f Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget: do not send hide events to hidden childrenGiuseppe D'Angelo2024-06-111-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The logic in QWidgetPrivate::hideChildren sends hide events to all of its children, including the ones that are already hidden (and thus have received already a hide event). This breaks some "event counting" logic in QGraphicsScene, which (since it can be displayed in multiple views) keeps track of how many hide/show events it has received. It is possible to break this counter by having it receive several hide events in a row, which won't be matched by the same number of show events. These extra hide events may be generated by adding a QGraphicsView into a QTabWidget (or QStackedWidget), hiding *that*, and then changing the current index -- which shows/hides the children. This makes the counter go negative and break. Furthermore, a hide event is received after the widget has been made invisible, therefore one can't check for "was I visible when I received this hide event?" This commit changes the logic in QWidgetPrivate::hideChildren so that we don't do anything if the a child was already not visible. [ChangeLog][QtWidgets][QWidget] Widgets which are already hidden no longer receive hide events if they're made hidden again (for instance because an ancestor gets hidden). Change-Id: I73061b9d8bf33911778c9c30df33dbe43e9deaa3 Fixes: QTBUG-53974 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
* QStyleSheet/QProxyStyle: Avoid deref after setWindowFlags in polishWladimir Leuschner2024-06-051-1/+3
| | | | | | | | | | | | | | When invoking setWindowFlags with a QStyleSheet and QProxyStyle set, a repolish is recursivly done creating a second QStyleSheetStyle in QWidgetPrivate::inheritStyle due to not cleared WA_SetStyle window flag. This leads to a use-after-free in the then following recursive call to QStyle::polish. This patch uses the previously create QStyleSheetStyle in the case that there is already a QStyleSheetStyle for the proxy. Fixes: QTBUG-125513 Pick-to: 6.8 6.7 Change-Id: I841bf68143e893d74ab7373b7a3d3d4ee2bce514 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* widgets: Use per-surface-format RHI support and compositorTor Arne Vestbø2024-06-011-45/+73
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The RHI support and compositor in QPlatformBackingStore were tied to the surface format of the top level window owning the backing store. This meant that inserting an RHI-enabled widget (QRhiWidget, QOpenGLWidget, QQuickWidget, QWebEngineView) into the widget hierarchy required recreating the top level window with a matching surface format that could support the RHI composition. It also meant that we could not have two RHI enabled widgets with different surface format requirements (Metal and OpenGL for example) in the same top level widget hierarchy. The recreation of the window had various visual side effects, such as temporarily switching out of full screen state, or the widget rendering a frame of black, as well as more serious problems such as not correctly restoring the window geometry. In addition, if client code had pulled out the winId() of the window, and did not invalidate these references on window destruction via QEvent::WinIdChange or QEvent::PlatformSurface, the client would reference stale window handles. Although this is a programming error (QWidget::winId() specifically mentions this requirement), we should avoid recreation if we can. We were already supporting flushing the backingstore to individual native child widgets, but always did so via a single RHI managed by the platform backingstore. By expanding QPlatformBackingStore to keep one set of RHI support and compositor per surface format, we can refine the logic in QWidget and QWidgetRepaintManager to not require recreating the top level. Native child widgets are then flushed independently, including any RHI textures and raster content that overlaps with the widget. We still assume that a single RHI support and compositor can be be used for multiple windows, as long as those windows have the same surface format. In the future, if needed, we can refine this to use one set per surface format e.g. Fixes: QTBUG-119221 Fixes: QTBUG-121181 Fixes: QTBUG-120096 Task-number: QTBUG-115652 Task-number: QTBUG-108344 Task-number: QTBUG-113557 Task-number: QTBUG-119309 Change-Id: I2635ed3d20c2fb76eab3b8130007dd656a0b93e5 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* Add QPaintDevice metric query to get precise fractional DPR valueEirik Aavitsland2024-05-301-0/+4
| | | | | | | | | | | | | | | | | | | | | For compatibility reasons, QPaintDevice needs to query subclasses for device metrics as int values. To report fractional DPR values, they have been multiplied with a large constant and divided back afterwards. However, the loss of accuracy introduced by this, though tiny, could still lead to rounding errors and painting artefacts when the values where multiplied up for large coordinates. Avoid this issue by adding a metric query that transports the full floating point value encoded as two ints. [ChangeLog][QtGui] Added new QPaintDevice metrics for querying fractional device pixel ratios with high precision. Custom paintdevice classes that support fractional DPRs are recommended to implement support for these queries in metric(). Others can ignore them. Fixes: QTBUG-124342 Change-Id: Ia6fa46e68e9fe981bdcbafb41daf080b4d1fb6d7 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Widgets focus abstraction: Fix re-parentingAxel Spoerl2024-05-231-26/+54
| | | | | | | | | | | | | | | | | | | | | | | | | Focus abstraction in 58d5d4b7c2faaeaa2c2ccdabb3da6d37f9db880a was supposed to be behavior-neutral. QWidgetPrivate::reparentFocusChildren used QObject::findChildren() to find children inside and outside the current focus chain. If the re-parented widget had only direct children and the focus chain was equal to creation-order, the result was identical to previous behavior. When the re-parented widget had grandchildren, the behavior differred. While not being detected by existing tests, it caused a regression. Re-implement the previous logic: Iterate through the focus chain, instead of relying on QObject::findChildren() returning a complete and well-ordered list. Modify tst_QWidget::focusChainOnReparent() in order to cover the regression. This amends 58d5d4b7c2faaeaa2c2ccdabb3da6d37f9db880a. Fixes: QTBUG-125257 Change-Id: Iff4f1d0d9b6117c50c8980dfb6eebfc6f6d4a710 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* a11y: Notify of name change when setting window title used as a11y nameMichael Weghorn2024-05-221-0/+14
| | | | | | | | | | | | | | | | | | | When no explicit accessible name is set for a window, QAccessibleWidget::text uses the window title instead for a non-minimized window. Send a QAccessible::NameChanged event when changing the window title results in a change of the accessible name, to ensure that the AT-SPI cache on Linux gets updated. Extend tst_QAccessibility::mainWindowTest() to cover the scenario as well. Note: The entire test function is skipped on platforms not supporting window activation, e.g. Wayland. Fixes: QTBUG-124192 Change-Id: I0fa7f683fb5969d6ba9878f6a506c4f192069799 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>