Bug 476950 - KSortFilterProxyModel::filterRole & filterRoleName properties are buggy
Summary: KSortFilterProxyModel::filterRole & filterRoleName properties are buggy
Status: RESOLVED FIXED
Alias: None
Product: frameworks-kitemmodels
Classification: Frameworks and Libraries
Component: general (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: kdelibs bugs
URL:
Keywords: qt6
: 464116 (view as bug list)
Depends on:
Blocks:
 
Reported: 2023-11-13 15:57 UTC by ratijas
Modified: 2024-05-18 17:02 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
ksortfilter-bug.qml (4.59 KB, text/x-qml)
2023-11-13 15:57 UTC, ratijas
Details
automated and animated version (5.63 KB, text/x-qml)
2023-11-13 16:26 UTC, ratijas
Details

Note You need to log in before you can comment on or make changes to this bug.
Description ratijas 2023-11-13 15:57:52 UTC
Created attachment 163125 [details]
ksortfilter-bug.qml

SUMMARY

KSortFilterProxyModel exhibits "race condition" bug: depending on order of property initialization (which isn't quite defined in QML, except that more "complex" expressions are known to evaluate later than the simple literals and enums), it may end up with filterRole reset to 0 (thus the whole filtering not working, as currently in Flatpak KCM -> application list), or a model emits inappropriate rowsAdded signal which causes a view (e.g. ListView) to create a phantom and empty delegate which won't even ever be deleted.

STEPS TO REPRODUCE
1. Run the attached file with qml or kqml tool. It uses plasma-pa/SinkModel as an example, so make sure you have some functional speakers/headphones or replace it with some other model.
2. Type in anything in the search field.
3. Toggle ON the "Set model" check box.
4. Click the "Set filter role" button.
5. Clear the search field.

OBSERVED RESULT
After step 4, an empty delegate appears in the ListView.
After step 5, an empty delegate remains alive at the bottom of the list of your audio devices.

EXPECTED RESULT
No empty glitched delegates. No races between filterRole and model properties.

SOFTWARE/OS VERSIONS
Operating System: Arch Linux 
KDE Plasma Version: 5.81.0
KDE Frameworks Version: 5.245.0
Qt Version: 6.6.0
Kernel Version: 6.6.1-arch1-1 (64-bit)
Graphics Platform: X11
Comment 1 ratijas 2023-11-13 16:26:44 UTC
Created attachment 163127 [details]
automated and animated version

A more interactive demo with a button to run the whole sequence. Uncomment `Component.onCompleted` handler to run on start.

Note that with small timer delays on start the bug sometimes does not happen, probably because timer triggers or animation finishes before the component is completed which masks the issue.
Comment 2 Bug Janitor Service 2023-11-14 22:26:43 UTC
A possibly relevant merge request was started @ https://invent.kde.org/frameworks/kitemmodels/-/merge_requests/85
Comment 3 ratijas 2023-11-15 21:20:04 UTC
Git commit 4a9df06bc89e7c23a16832f7300e2efc7e9a1ee8 by ivan tkachenko.
Committed on 14/11/2023 at 22:14.
Pushed by ratijas into branch 'master'.

KSortFilterProxyModel: Fix multiple sources of truth confusion

Sort and filter roles may come from upstream model's properties (by ID)
or from our class (by role name), and it is important to keep track
which one was set explicitly and thus should be considered the source
of truth at any given moment in time -- especially if/when source model
is set afterwards such that these pairs of properties can not sync
immediately and have to be delayed instead.

To solve this problem, the an object now stores a flag which determined
the source of truth per each pair, and another flag to prevent
recursion and switch to "Role ID" source when *RoleChanged signals are
emitted NOT as a side-effect of us updating a corresponding *RoleName.

M  +93   -3    autotests/ksortfilterproxymodel_qml.cpp
M  +96   -39   src/qml/ksortfilterproxymodel.cpp
M  +24   -3    src/qml/ksortfilterproxymodel.h

https://invent.kde.org/frameworks/kitemmodels/-/commit/4a9df06bc89e7c23a16832f7300e2efc7e9a1ee8
Comment 4 ratijas 2023-11-15 21:20:12 UTC
Git commit 077f49e294e999e8e927bc745576aa472beee2e5 by ivan tkachenko.
Committed on 14/11/2023 at 22:14.
Pushed by ratijas into branch 'master'.

KSortFilterProxyModel: Don't recurse into syncRoleNames

Row count of a proxy model changes as it filters its source model, but
that's not a good reason to refresh role names every time. Instead we
are only interested in source model's changes.

This reduces amount of insert/remove back and forth signals during
filtering, and fixes the permanent "ghost delegate" at the end of a
ListView.

M  +18   -3    src/qml/ksortfilterproxymodel.cpp
M  +3    -0    src/qml/ksortfilterproxymodel.h

https://invent.kde.org/frameworks/kitemmodels/-/commit/077f49e294e999e8e927bc745576aa472beee2e5
Comment 5 Ismael Asensio 2024-05-18 17:02:12 UTC
*** Bug 464116 has been marked as a duplicate of this bug. ***