Bug 480594

Summary: Overlapping text/delegates after searching/filtering and then deleting search/filter text
Product: [Plasma] Breeze Reporter: Victor Rijnoveanu <hackandgo3>
Component: generalAssignee: Plasma Bugs List <plasma-bugs>
Status: RESOLVED FIXED    
Severity: normal CC: adam.m.fontenot+kde, agurenko, akselmo, brandowlucas, dominik.klementowski, dougshaw77, duha.bugs, eruditezenith, fanzhuyifan, fin-w, hackandgo3, isma.af, justin, kde, me, nate, nicolas.fella, semlraug, uhhadd
Priority: VHI Keywords: qt6
Version: 5.93.0   
Target Milestone: ---   
Platform: Arch Linux   
OS: Linux   
See Also: https://bugs.kde.org/show_bug.cgi?id=480631
https://bugreports.qt.io/browse/QTBUG-115717
https://bugs.kde.org/show_bug.cgi?id=480707
https://bugs.kde.org/show_bug.cgi?id=448833
Latest Commit: Version Fixed In: 6.0
Attachments: A screenshot of the glitched text in the shortcuts menu of systemsettings
settings search

Description Victor Rijnoveanu 2024-01-31 10:57:32 UTC
Created attachment 165391 [details]
A screenshot of the glitched text in the shortcuts menu of systemsettings

SUMMARY
***
NOTE: If you are reporting a crash, please try to attach a backtrace with debug symbols.
See https://community.kde.org/Guidelines_and_HOWTOs/Debugging/How_to_create_useful_crash_reports
***


STEPS TO REPRODUCE
1. Open systemsettings
2. go to keyboard > shortcuts
3. open the shortcuts of an app that has a lot of shortcuts, e.g. kwin
4. scroll a bit
5. start searching for a shortcut that may exist in that tab, make sure it is not in the view at that point
6. may need to CTRL-A and delete the text

OBSERVED RESULT

screenshot provided

EXPECTED RESULT

normal text


SOFTWARE/OS VERSIONS
Linux/KDE Plasma:  6.7.2-x64v3-xanmod1
(available in About System)
KDE Plasma Version:  5.92.0
KDE Frameworks Version: 5.248.0
Qt Version: 6.7.0

ADDITIONAL INFORMATION
Comment 1 Victor Rijnoveanu 2024-01-31 11:06:58 UTC
After running systemsettings from the terminal and looking at its output, it returns

Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.
Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.
qrc:/kcm/kcm_keys/ShortcutActionDelegate.qml:101:30: QML RowLayout: Layout polish loop detected for QQuickRowLayout_QML_373(0x5ede0951ad30, parent=0x5ede08173250, geometry=0,0 328x66). Aborting after two iterations.
Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.
qrc:/kcm/kcm_keys/ShortcutActionDelegate.qml:101:30: QML RowLayout: Layout polish loop detected for QQuickRowLayout_QML_373(0x5ede0951ad30, parent=0x5ede08173250, geometry=0,0 328x66). Aborting after two iterations.
Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.
Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.
qrc:/kcm/kcm_keys/ShortcutActionDelegate.qml:101:30: QML RowLayout: Layout polish loop detected for QQuickRowLayout_QML_373(0x5ede0951ad30, parent=0x5ede08173250, geometry=0,0 328x66). Aborting after two iterations.
Qt Quick Layouts: Detected recursive rearrange. Aborting after two iterations.
qrc:/kcm/kcm_keys/ShortcutActionDelegate.qml:101:30: QML RowLayout: Layout polish loop detected for QQuickRowLayout_QML_373(0x5ede0951ad30, parent=0x5ede08173250, geometry=0,0 328x66). Aborting after two iterations.

and it similarly spans over several hundred lines
Comment 2 Victor Rijnoveanu 2024-01-31 14:20:10 UTC
Update: It crashes if I do it enough times. I sent the crash report via the automatic crash reporter.
Comment 3 Gurenko Alex 2024-01-31 17:39:09 UTC
Created attachment 165403 [details]
settings search

Seems like what I have just by searching the settings itself, I was going through several settings item, by searching them and ~on a 3rd search whole left panel got scrambled.
Comment 4 Doug 2024-02-01 04:51:33 UTC
Can confirm. Neon Testing, Plasma 5.92.90, Frameworks 5.249.0, Qt 6.6.1
Comment 5 fanzhuyifan 2024-02-01 23:48:08 UTC
*** Bug 480712 has been marked as a duplicate of this bug. ***
Comment 6 fanzhuyifan 2024-02-02 04:18:39 UTC
*** Bug 480715 has been marked as a duplicate of this bug. ***
Comment 7 Nate Graham 2024-02-02 17:38:31 UTC
It's Qt issue: https://bugreports.qt.io/browse/QTBUG-115717
Comment 8 Nate Graham 2024-02-02 17:38:39 UTC
*** Bug 480631 has been marked as a duplicate of this bug. ***
Comment 9 Nate Graham 2024-02-02 17:40:47 UTC
*** Bug 479744 has been marked as a duplicate of this bug. ***
Comment 10 fanzhuyifan 2024-02-03 08:14:56 UTC
*** Bug 480707 has been marked as a duplicate of this bug. ***
Comment 11 fanzhuyifan 2024-02-07 01:16:51 UTC
I am not fully convinced that this is an upstream issue -- when I trigger the faulty behavior, I see a lot of binding loops/layout polish loops in my logs. Also, for 480707, when I added debugging print statements, I saw that the contentItem of the QQC2.CheckDelegate (in configTimeZones.qml) had zero implicit height, which doesn't seem correct.
Comment 12 fanzhuyifan 2024-02-07 04:56:49 UTC
Reopening since this doesn't seem like https://bugreports.qt.io/browse/QTBUG-115717 -- the problem persists if I remove the custom filterAcceptsRow, and instead use the regex filtering provided by QSortFilterProxyModel. This indicates that QTBUG-115717 is probably not the root cause.

It still seems highly likely that all the bugs marked as duplicates of this one are actual duplicates, as the symptoms are almost exactly the same. However, I have not been able to uncover the root cause yet, and more investigation is needed.

This issue has been reported both against Qt 6.6 and Qt 6.7, so this doesn't seem like a regression in Qt 6.7.
Comment 13 fanzhuyifan 2024-02-08 02:44:11 UTC
Observation: 

In both 480707 and 480631, the problem disappears after setting the implicitHeight of the delegate item to a fixed value. In both cases, the content item is a RowLayout.
Comment 14 fanzhuyifan 2024-02-08 03:48:52 UTC
Git bisection shows that https://invent.kde.org/frameworks/qqc2-desktop-style/-/commit/552517c356d04e6e9eda9795e5bdbb9e6071f63a is the cause of both 480707 and 480631.

I haven't checked the others. I checked these two because for me these are the easiest to reproduce (I can always reproduce them).
Comment 15 fanzhuyifan 2024-02-08 04:13:38 UTC
The general problem seems to be that scrollviews cannot correctly handle items that dynamically resize based on their index...

Here is a more extreme example where the topPadding is a function of index: (type 123 into the search and you can see the problem)

```
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import mysearch

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    ListModel {
        id: listModel
    }
    Component.onCompleted: {
        for (var i = 0; i < 1000; i++) {
            listModel.append({display: "Item " + i})
        }
    }
    // Column layout
    ColumnLayout {
        anchors.fill: parent
        // search box
        TextField {
            id: searchBox
            Layout.fillWidth: true
            Layout.fillHeight: false
            placeholderText: "Search"
        }
        ScrollView {
            Layout.fillWidth: true
            Layout.fillHeight: true
            ListView {
                id: listView
                // Layout.fillWidth: true
                // Layout.fillHeight: true
                model: CustomProxyModel {
                    sourceModel: listModel
                    filter: searchBox.text
                }
                clip: true
                delegate: ItemDelegate {
                    id: controlRoot
                    text: model.display
                    width: listView.width
                    topPadding: (index % 10) * 10
                }
            }
        }
    }
}
```

and 
```
#pragma once

#include <QSortFilterProxyModel>
#include <QtQml/qqmlregistration.h>

class CustomProxyModel : public QSortFilterProxyModel {
    Q_OBJECT
    QML_ELEMENT
    Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
public:
    CustomProxyModel(QObject *parent = nullptr)
        : QSortFilterProxyModel(parent) {}

    QString filter() const { return m_matchString; }
    void setFilter(const QString &s) {
        if (m_matchString == s)
            return;

        m_matchString = s;
        invalidateFilter();
    }

    bool filterAcceptsRow(int sourceRow,
                          const QModelIndex &sourceParent) const override {
        const auto index = sourceModel()->index(sourceRow, 0, sourceParent);
        if (!index.isValid())
            return false;
        const auto &str = index.data().value<QString>();
        bool accepted = str.contains(m_matchString);
        return accepted;
    }

Q_SIGNALS:
    void filterChanged();

private:
    QString m_matchString;
};
```
Comment 16 Akseli Lahtinen 2024-02-08 09:22:52 UTC
Can confirm reverting that patch fixes both crashing and weird overlap issues for me
Comment 17 Bug Janitor Service 2024-02-08 09:43:16 UTC
A possibly relevant merge request was started @ https://invent.kde.org/frameworks/qqc2-desktop-style/-/merge_requests/365
Comment 18 fanzhuyifan 2024-02-08 15:52:36 UTC
*** Bug 481004 has been marked as a duplicate of this bug. ***
Comment 19 fanzhuyifan 2024-02-08 19:24:24 UTC
*** Bug 481075 has been marked as a duplicate of this bug. ***
Comment 20 fanzhuyifan 2024-02-09 16:22:01 UTC
*** Bug 481104 has been marked as a duplicate of this bug. ***
Comment 21 fanzhuyifan 2024-02-11 20:02:56 UTC
*** Bug 481236 has been marked as a duplicate of this bug. ***
Comment 22 fanzhuyifan 2024-02-11 20:03:32 UTC
*** Bug 481230 has been marked as a duplicate of this bug. ***
Comment 23 duha.bugs 2024-02-19 17:46:20 UTC
*** Bug 480012 has been marked as a duplicate of this bug. ***