summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
Commit message (Collapse)AuthorAgeFilesLines
* test: Don't crash when focusWidget() is nullEskil Abrahamsen Blomfeldt7 days1-14/+21
| | | | | | | | | | | | | If QApplication::focusWidget() returns null, which was the case on Wayland under some circumstances, then the code collecting the error output would crash when dereferencing the null pointer. This fixes that crash and gets proper test failure output instead. Pick-to: 6.5 6.7 Fixes: QTBUG-124475 Change-Id: Ic34228be953cf42dfe2ebf75957cd48791e6de7d Reviewed-by: Liang Qi <liang.qi@qt.io>
* Widgets focus abstraction: Skip isFocusChainConsistent w/o logging catAxel Spoerl11 days1-0/+1
| | | | | | | | | | | | | | | | | | 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>
* tst_QWidget::grabKeyboard remove QApplicationPrivate::setActiveWindow()Frédéric Lefebvre2024-04-231-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: Iea870711410dee1347f1020a6f7afc037e520825 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::grabMouse() remove QApplicationPrivate::setActiveWindow()Frédéric Lefebvre2024-04-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I7fd9005ef66c11f640a50f0db468cdcb07eb621f Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::imEnabledNotImplemented() remove setActiveWindow()Frédéric Lefebvre2024-04-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I432e7ced3e49b570cf9e4057fe98411271693750 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::enterLeaveOnWindowShowHide() remove setActiveWindow()Frédéric Lefebvre2024-04-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: Ic189b1c55b6bdf0397636b3ae9555cc38b60fc48 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::dumpObjectTree remove QApplicationPrivate::setActiveWindowFrédéric Lefebvre2024-04-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I1cd2d45c54fbeb2b89accc257f2ec5b57f20c013 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::clean_qt_x11_enforce_cursor() remove setActiveWindow()Frédéric Lefebvre2024-04-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I2a3f400e58f86cbc339c355977da784ef5c24800 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::showAndMoveChild() remove setActiveWindow()Frédéric Lefebvre2024-04-191-1/+0
| | | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I7bd841574c07d73416f9f63d564fe31a8475fa9e Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* tst_QWidget::showMinimizedKeepsFocus() remove setActiveWindow()Frédéric Lefebvre2024-04-191-5/+0
| | | | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls from testing deletion of the focusWidget, testing reparenting of the focus widget, testing setEnabled(false) and testing clearFocus sections. Task-number: QTBUG-121488 Change-Id: I7e46ddb31bd7dbc0492d057d8d84846db8c873aa Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::explicitTabOrderWithSpinBox_QTBUG81097 remove setActiveWinFrédéric Lefebvre2024-04-191-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I5d6871b192b5c4dda00ef912a806e62a529b629e Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::appFocusWidgetWhenLosingFocusProxy remove setActiveWindowFrédéric Lefebvre2024-04-191-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I2841522f533c7679cc9c254c5fe7c37f5632fd30 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::appFocusWidgetWithFocusProxyLater remove setActiveWindow()Frédéric Lefebvre2024-04-191-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I4a0d026fbe5da014723254bb9eb8d614cf50232f Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::focusChainOnHide remove QApplicationPrivate::setActiveWindFrédéric Lefebvre2024-04-181-2/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I5b429dcaa47cd179785345f9f7a80648574670dd Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Abstract QWidget focus chain managementAxel Spoerl2024-04-041-0/+87
| | | | | | | | | | | | | | | | | | | 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>
* Tests: check the output of QFile::openGiuseppe D'Angelo2024-03-271-2/+1
| | | | | | | | | | Wrap the call in QVERIFY. tst_QTextStream::read0d0d0a was also faulty as it *never* opened the file because of a broken path. Fix it with QFINDTESTDATA. Change-Id: I61a8f83beddf098d37fda13cb3bfb4aaa4913fc5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* tst_QWidget::reverseTabOrder remove QApplicationPrivate::setActiveWindoFrédéric Lefebvre2024-03-251-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: Ifd2c5dcd1cc3d13f689ffd6400ffec0fcc3a6b93 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget: use focus abstraction instead of focus_next/prevAxel Spoerl2024-03-221-14/+20
| | | | | | | | | | | | Focus abstraction in QWidgetPrivate makes direct access to QWidget::focus_next and focus_prev an antipattern. Remove usage. Add object names for better diagnostics when debugging focus issues. Task-number: QTBUG-121478 Change-Id: Iecd3bdc824bf77c519951f8f7801eb50b29a6e00 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* tst_QWidget::tabOrderWithProxy remove QApplicationPrivate::setActiveWindFrédéric Lefebvre2024-03-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: Id3b9967ddaa7dbb87eef9faaf4681d7cb014ba8c Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::tabOrderWithProxyDisabled() remove setActiveWindow()Frédéric Lefebvre2024-03-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I88d39def0e85e147b3621d98d150ee65463be94f Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::tabOrderWithCompoundWidgets() remove setActiveWindow()Frédéric Lefebvre2024-03-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: If805bc0e021625b94edc83d7abccc435c1880bea Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::tabOrderWithProxyOutOfOrder() remove setActiveWindow()Frédéric Lefebvre2024-03-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I7a4b21018216c2b7cced8d4aa5084c527b694f4a Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::tabOrderWithCompoundWidgetsNoFocusPolicy remove setActiveWFrédéric Lefebvre2024-03-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: Ieb516cc4fd02230c0ec6bb189da049c3741358dd Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget::defaultTabOrder() remove setActiveWindow()Frédéric Lefebvre2024-03-221-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I2faaf575a04652a395956c7d790ac18d9f3ec9e6 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* tst_QWidget::explicitTabOrderWithComplexWidget remove setActiveWindow()Frédéric Lefebvre2024-03-221-1/+0
| | | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I0271f3baf718ca5ae03464bbd415cd0feaa9087d Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Reparent QWindow children when reparenting QWidgetTor Arne Vestbø2024-03-141-0/+152
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Implement Qt::ImEnabled by isEnabled() and isReadOnly()Yansheng Zhu2024-03-011-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | Previously, querying Qt::ImEnabled only returned the value of isEnabling(), which is incorrect for edit widgets with read-only properties set, as Qt::ImEnabled indicates whether text can be *input* through the input method, which results in the IM being able to insert text into read-only edit widgets. The fixed version uses both isEnabling() and isReadOnly() values to determine whether input methods need to be enabled. For some platforms (like iOS and Android) that rely on IM to select text, a check for ImReadOnly has been added to their QPA plugins to enable handles on read-only input boxes. At the same time, the imEnabledNotImplemented function in the test file tst_qwidget was modified, since ImEnabling should give a _false_ value when a lineedit is read-only. Task-number: QTBUG-105009 Task-number: QTBUG-110838 Task-number: QTBUG-119182 Pick-to: 6.7 6.6 6.5 Change-Id: Ia2abcdb3200826d567f90447d4f8b71d0ef1fbf0 Reviewed-by: Yansheng Zhu <670429759@qq.com> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* tst_QWidget::realFocusChain: don't remove from iterated QListChris Lerner2024-02-241-5/+6
| | | | | | | | | | | | | | The method removed from QWidgetList widgets in a ranged for loop. That caused items being skipped. Create a new list by adding positives, instead of removing negatives from the original. This amends b1802a164b8682ed9e8956a5a19a90ade65c25d0. Pick-to: 6.7 6.6 Change-Id: I3f329290187ddc76169ababe8ffa6059d953212d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidgetWindow: Don't meddle with WA_WState_{Hidden/ExplicitShowHide}Tor Arne Vestbø2024-02-121-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In ccd3bf0871b81dfc09bb469b161f32dfb47ee53e we introduced code that would ensure that our call to QWidgetPrivate::setVisible() from QWidgetWindow would not result in WA_WState_Hidden being set. This code was later modified in 51300566ffe2ece2455e1d0479a556c5dbb3bb8e to apply to widgets that were explicitly shown/hidden. Unfortunately, the reset of the Hidden and ExplicitShowHide attributes would in some cases result in the widget having only ExplicitShowHide after being hidden, which is an invalid state. It also resulted in the widget having both Visible, Hidden, and ExplicitShowHide, if first being hidden via QWidget, and then shown via QWindow, which in turn prevented the widget from being hidden via QWidget::hide(). As we no longer rely on the adjustments to Hidden/ExplicitShowHide to fix QTBUG-73021, we can remove the entire logic. Any setVisible call to QWidgetWindow will either come from outside, in which case we should respect that and set Visible/Hidden via QWidgetPrivate, or the setVisible call is a result of QWidget itself (or its parent) showing the QWidgetWindow, in which case the QWidget visible state is already up to date and we skip the QWidgetPrivate::setVisible call. Task-number: QTBUG-121398 Task-number: QTBUG-73021 Fixes: QTBUG-120316 Pick-to: 6.7 Change-Id: I3174ad66b7e10c55aa99b7cb433267632169ca8f Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Ensure QWidget::destroy() events and attributes match hiding the widgetTor Arne Vestbø2024-02-121-28/+107
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Un-blacklist tst_QWidget::optimizedResizeMove on macOSTor Arne Vestbø2024-02-121-1/+1
| | | | | | | | | | | It has been passing consistently in dev, 6.7, 6.6, and 6.5 for the past 6 months: http://testresults.qt.io/grafana/goto/S35hM52IR As a drive-by, fix comment that claims the test is only run on macOS. Pick-to: 6.7 6.6 6.5 Change-Id: I6502c40e0c39afb68a461bd530df1bacb5211dec Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Change license for tests filesLucie Gérard2024-02-041-1/+1
| | | | | | | | | | | | According to QUIP-18 [1], all tests file should be LicenseRef-Qt-Commercial OR GPL-3.0-only [1]: https://contribute.qt-project.org/quips/18 Pick-to: 6.7 Task-number: QTBUG-121787 Change-Id: I9657df5d660820e56c96d511ea49d321c54682e8 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
* tst_QWidget::scroll() remove QApplicationPrivate::setActiveWindow()Frédéric Lefebvre2024-02-021-1/+0
| | | | | | | | | | | 2f6fe3a26843ff68c5d3f9af0a2fc3cce6caac22 has made calls to QApplicationPrivate::setActiveWindow() redundant. Remove redundant calls. Task-number: QTBUG-121488 Change-Id: I13ea8c0994eaeb764462af23ef66ea1a37659b77 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Don't set ExplicitShowHide on children when showing parent widgetTor Arne Vestbø2024-02-011-2/+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>
* Simplify tst_QWidget::closeAndShowWithNativeChildTor Arne Vestbø2024-02-011-5/+10
| | | | | | | | | | | | | | | | | The nativeHiddenChild is not used for anything, and shouldn't be needed to trigger the failure condition. That said, I was not able to reproduce the test failure on macOS 14 with the test neither pre or post patch, nor with any of the test cases mentioned in 51300566ffe2ece2455e1d0479a556c5dbb3bb8e, nor with 51300566ffe2ece2455e1d0479a556c5dbb3bb8e itself, so this has seemingly been fixed or worked around some other way in the meantime. Task-number: QTBUG-121398 Pick-to: 6.7 Change-Id: I299e7f4b71ebdb17870348a3d5b0c49a93228c8b Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add logging, clarifications, and tests for QWidget show/hide behaviorTor Arne Vestbø2024-02-011-0/+114
| | | | | | | Task-number: QTBUG-121398 Pick-to: 6.7 Change-Id: I94b4c90c3bd515279417c88497d7b9bd5a362eae Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* tst_QWidget: Add test that WA_NativeWindow results in window handleTor Arne Vestbø2024-01-201-0/+20
| | | | | | | Pick-to: 6.7 Change-Id: I63a653a552be2a6435e0c068e47c2442e53642cb Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
* tst_QWidget::renderInvisible: Use QImage::Format_ARGB32_PremultipliedTor Arne Vestbø2024-01-201-17/+14
| | | | | | | | | | | | | | | The test renders QCalendarWidget, which ends up in the QStyle code eventually. On macOS we use a CGContext to draw the native style, into the test's image/paint device, but CGBitmapContextCreate does not support QImage::Format_ARGB32. It needs either a premultiplied alpha, or no alpha at all. The unification of the palette for the calendar, as is done for Windows, is also needed on macOS. Pick-to: 6.7 Change-Id: I5b26e5434b84e4b14eb8784875b76810e0a14230 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QWidget: deliver DragLeave events symmetricallyVolker Hilsheimer2023-12-201-0/+96
| | | | | | | | | | | | | | | | | | | | | | | | | | If a widget received a DragEnter event that it didn't accept, then the UnderMouse widget attribute gets set. But the drag manager never got a drag target, so the DragLeave event was never delivered, leaving the UnderMouse attribute set incorrectly. We always need to send DragLeave events to the receiver, even if the DragEnter or DragMove was not accepted. Otherwise we are not in balance, and the UnderMouse attribute will remain set. This is a change of behavior and a very old bug, so only fixing this in unreleased branches. Test case added to verify that explicitly generated drag events result in the correct enter/leave events. [ChangeLog][QtWidgets][QWidget] DragLeave events are now always sent to the widget the mouse is leaving, even if it didn't accept the DragEnter event. Fixes: QTBUG-50403 Pick-to: 6.7 Change-Id: I5eae49da000fb4fea81f1767f0e73a06a6b78975 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Sync QWindow visible state during QWidget destructionTor Arne Vestbø2023-12-201-0/+28
| | | | | | | | | | | | | | | | | | | | | | | | A call to QWidget::destroy() will end up in QWindow::destroy(), which calls QWindow::setVisible(false). A call to QWindow::setVisible(false) on a widget's window will under normal circumstances end up in QWidgetPrivate::setVisible(), which in turn recurses back into QWindowPrivate::setVisible(), via QWidgetPrivate::hide_helper(), ensuring that the QWindow internal state is updated, visibleChanged emitted, and show/hide events sent. Durin QWidget::destroy() we end up in QWindow::destroy(), which calls QWindow::setVisible(false), but in this case the widget no longer has Qt::WA_WState_Created, so the hide_helper() call is skipped, and the corresponding QWindow is not kept in the loop. To work around this we could have checked for windowHandle() instead of Qt::WA_WState_Created before calling hide_helper(), but that had many other side effects, so we opt for a more targeted fix. Pick-to: 6.7 6.6 6.5 Change-Id: I68f80e5f7df9ee811afcd274a7ee4de31a110da5 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Android: Skip showAndMoveChild() test case temporarilyTinja Paavoseppä2023-12-071-0/+3
| | | | | | | | | | | | grabWindow() currently returns a null QPixmap on Android due to even raster windows being backed up by OpenGL/QRhi. The test case uses grabWindow() internally to grab contents to a pixmap and comparing whether the pixmap contents are as expected, leading now to failures due to null QPixmap being returned. Task-number: QTBUG-118849 Change-Id: I51cda2d43fe482252d5604f6b18281d810aa4d2f Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Android: skip tst_qwidget::render()Assam Boudjelthia2023-11-161-0/+3
| | | | | | | Task-number: QTBUG-118984 Change-Id: Ie9f30608ae96dd53900501d7b5f90c38ca6bc40f Reviewed-by: Dimitrios Apostolou <jimis@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Android: temporarily skip tst_qprinterinfo, tst_qwidget and tst_qwindowAssam Boudjelthia2023-07-261-0/+4
| | | | | | | | | | | Those tests often fail on Android 13 on RHEL 8.6 and 8.8. This patch skips them to unblock CI while the underlying reasons are investigated and fixed. Task-number: QTQAINFRA-5606 Change-Id: If088d69c2160470ef50b2e74cd9b9399451c526d Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
* Add missing nullptr check in QWidget::setFocusProxyAxel Spoerl2023-04-251-0/+26
| | | | | | | | | | | | | | 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/+99
| | | | | | | | | | | | | | | | | 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-20/+32
| | | | | | | | | | | | | 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>
* Handle tab order inceptionVolker Hilsheimer2023-03-091-0/+125
| | | | | | | | | | | | | | | | | 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>
* Skip tst_QWidget::optimizedResizeMove and ..._topLevel on waylandAxel Spoerl2023-01-031-2/+16
| | | | | | | | | | | | | | | | Wayland omits optimizations tested in tst_QWidget::optimizedResizeMove() and optimizedResize_topLevel() under certain circumstances, e.g. on Ubuntu 22.04 / Gnome. This makes the test functions fail. This patch skips the test functions on wayland platforms, if an omission is detected. This amends 2ec7a6322f465ad7cce3c48096d8912903196ab2. Fixes: QTBUG-109746 Pick-to: 6.5 6.4 Change-Id: If0df6b1cf451a7f0dccfc1bb7411e895d7ae29a3 Reviewed-by: Liang Qi <liang.qi@qt.io>
* Fix QWidget::restoreGeometry when restored geometry is off screenAxel Spoerl2022-12-161-0/+73
| | | | | | | | | | | | | | | | | | | | | | | If a widget's geometry is restored to a screen, which is smaller than the one it was saved from, - the widget could appear (partly) off screen - the widget's title bar and resize handles could be inaccessible This patch refactors and documents checkRestoredGeometry. In a first step, the restored geometry's size is checked against a given screen size. It is corrected if necessary. In a second step, the restored geometry is moved inside the screen, if necessary. It makes the function a static member of QWidgetPrivate in order to expose it for auto testing and adds a respective test function to tst_QWidget. Fixes: QTBUG-77385 Fixes: QTBUG-4397 Task-number: QTBUG-69104 Pick-to: 6.5 6.4 Change-Id: I7172e27bfef86d82cd51de70b40de42e8895bae6 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Deliver tablet events to the toplevel widget if there is no childVolker Hilsheimer2022-12-021-44/+38
| | | | | | | | | | | | | | | | | | | | | QWidgetWindow dispatched only tablet presses to the toplevel widget if no child was found at the position; other events, such as hover events, were discarded. The tabletTracking test case even documented that shortcoming in a comment. Fix that by falling back to the toplevel widget for any event. As before, only press events initialize the tablet grabbing target widget. Remove the now unneeded parent widget from the test case, and move the test class into the only test function that uses it. Amends ea615b421b76668332a3029ad31fa725b5bb9e58 and 8fd6cef3724b2d676c5f6ae235956192d85eac39. Pick-to: 6.4 Fixes: QTBUG-108747 Change-Id: I79050f1e063931e439945f64b50712dcc1ecb18c Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>