Bug 466337 - Plasma crashed in Positioner::sourceRowsAboutToBeRemoved() when moving files from Desktop to Pictures folder in Dolphin
Summary: Plasma crashed in Positioner::sourceRowsAboutToBeRemoved() when moving files ...
Status: RESOLVED FIXED
Alias: None
Product: plasmashell
Classification: Plasma
Component: Folder (show other bugs)
Version: 5.26.5
Platform: Compiled Sources Linux
: NOR crash
Target Milestone: 1.0
Assignee: Plasma Bugs List
URL:
Keywords: drkonqi
: 481850 (view as bug list)
Depends on:
Blocks:
 
Reported: 2023-02-24 08:37 UTC by Jaak Ristioja
Modified: 2024-03-02 21:40 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed In: 6.0.1


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jaak Ristioja 2023-02-24 08:37:17 UTC
Application: plasmashell (5.26.5)
 (Compiled from sources)
Qt Version: 5.15.8
Frameworks Version: 5.103.0
Operating System: Linux 6.2.0-gentoo x86_64
Windowing System: Wayland
Distribution: "Gentoo Linux"
DrKonqi: 5.27.1 [KCrashBackend]

-- Information about the crash:
Using two click-drag selections, I selected a number of picture files on the desktop and click-drag-moved them to the Pictures folder open in a Dolphin window, and selected the move option from the popup menu. After this plasma crashed.

As a somewhat unrelated issue but perhaps still noteworthy is that one of the pictures I moved was also used as the desktop wallpaper. This also caused the wallpaper to reset after restarting plasmashell.

The reporter is unsure if this crash is reproducible.

-- Backtrace:
Application: Plasma (plasmashell), signal: Aborted
Content of s_kcrashErrorMessage: std::unique_ptr<char []> = {get() = 0x0}
[KCrash Handler]
#6  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
#7  0x00007f03f78b1783 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
#8  0x00007f03f7864516 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#9  0x00007f03f784e7fb in __GI_abort () at abort.c:79
#10 0x00007f03f7e929cf in qt_message_fatal (message=<synthetic pointer>..., context=...) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/global/qlogging.cpp:1914
#11 QMessageLogger::fatal(char const*, ...) const (this=this@entry=0x7ffd19b65468, msg=msg@entry=0x7f03f818b968 "ASSERT: \"%s\" in file %s, line %d") at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/global/qlogging.cpp:893
#12 0x00007f03f7e917d2 in qt_assert(char const*, char const*, int) (assertion=assertion@entry=0x7f03f8270fea "last < rowCount(parent)", file=file@entry=0x7f03f8270a28 "/var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/itemmodels/qabstractitemmodel.cpp", line=line@entry=2815) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/global/qglobal.cpp:3391
#13 0x00007f03f7ead64e in QAbstractItemModel::beginRemoveRows(QModelIndex const&, int, int) (this=0x55b2f00f4500, parent=<optimized out>, first=120, last=120) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/itemmodels/qabstractitemmodel.cpp:2815
#14 0x00007f03bd7d7f8b in Positioner::sourceRowsAboutToBeRemoved(QModelIndex const&, int, int) (parent=<optimized out>, last=14, first=<optimized out>, this=0x55b2f00f4500) at /var/tmp/portage/kde-plasma/plasma-desktop-5.26.5-r2/work/plasma-desktop-5.26.5/containments/desktop/plugins/folder/positioner.cpp:626
#15 Positioner::sourceRowsAboutToBeRemoved(QModelIndex const&, int, int) (this=0x55b2f00f4500, parent=<optimized out>, first=<optimized out>, last=14) at /var/tmp/portage/kde-plasma/plasma-desktop-5.26.5-r2/work/plasma-desktop-5.26.5/containments/desktop/plugins/folder/positioner.cpp:591
#16 0x00007f03f80e73ae in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffd19b656c0, r=0x55b2f00f4500, this=0x55b2f00c0750) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#17 doActivate<false>(QObject*, int, void**) (sender=0x55b2f025a360, signal_index=14, argv=0x7ffd19b656c0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3923
#18 0x00007f03f80e0717 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x55b2f025a360, m=m@entry=0x7f03f83bfcc0 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=11, argv=argv@entry=0x7ffd19b656c0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3983
#19 0x00007f03f805c8a2 in QAbstractItemModel::rowsAboutToBeRemoved(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) (this=this@entry=0x55b2f025a360, _t1=..., _t2=<optimized out>, _t2@entry=5, _t3=<optimized out>, _t3@entry=14, _t4=...) at .moc/moc_qabstractitemmodel.cpp:600
#20 0x00007f03f8064c32 in QAbstractItemModel::beginRemoveRows(QModelIndex const&, int, int) (this=0x55b2f025a360, parent=..., first=5, last=14) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/itemmodels/qabstractitemmodel.cpp:2818
#21 0x00007f03f8086ded in QSortFilterProxyModelPrivate::remove_proxy_interval(QVector<int>&, QVector<int>&, int, int, QModelIndex const&, Qt::Orientation, bool) (this=0x55b2f0051ec0, source_to_proxy=..., proxy_to_source=..., proxy_start=<optimized out>, proxy_end=14, proxy_parent=<optimized out>, orient=Qt::Vertical, emit_signal=true) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/itemmodels/qsortfilterproxymodel.cpp:811
#22 0x00007f03f808a9b7 in QSortFilterProxyModelPrivate::remove_source_items(QVector<int>&, QVector<int>&, QVector<int> const&, QModelIndex const&, Qt::Orientation, bool) (this=0x55b2f0051ec0, source_to_proxy=..., proxy_to_source=..., source_items=<optimized out>, source_parent=<optimized out>, orient=Qt::Vertical, emit_signal=true) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/itemmodels/qsortfilterproxymodel.cpp:792
#23 0x00007f03f808acf8 in QSortFilterProxyModelPrivate::source_items_about_to_be_removed(QModelIndex const&, int, int, Qt::Orientation) (this=0x55b2f0051ec0, source_parent=..., start=5, end=14, orient=Qt::Vertical) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/itemmodels/qsortfilterproxymodel.cpp:1094
#24 0x00007f03f80e73f4 in doActivate<false>(QObject*, int, void**) (sender=0x55b2f00906b0, signal_index=14, argv=0x7ffd19b659d0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3935
#25 0x00007f03f80e0717 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x55b2f00906b0, m=m@entry=0x7f03f83bfcc0 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=11, argv=argv@entry=0x7ffd19b659d0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3983
#26 0x00007f03f805c8a2 in QAbstractItemModel::rowsAboutToBeRemoved(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) (this=this@entry=0x55b2f00906b0, _t1=..., _t2=<optimized out>, _t2@entry=5, _t3=<optimized out>, _t3@entry=14, _t4=...) at .moc/moc_qabstractitemmodel.cpp:600
#27 0x00007f03f8064c32 in QAbstractItemModel::beginRemoveRows(QModelIndex const&, int, int) (this=0x55b2f00906b0, parent=..., first=5, last=14) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/itemmodels/qabstractitemmodel.cpp:2818
#28 0x00007f03f724d568 in KDirModelPrivate::_k_slotDeleteItems(KFileItemList const&) (this=0x55b2f01cdab0, items=<optimized out>) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/widgets/kdirmodel.cpp:653
#29 0x00007f03f80e73ae in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffd19b65c30, r=0x55b2f00906b0, this=0x55b2f01265a0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#30 doActivate<false>(QObject*, int, void**) (sender=0x55b2f008db70, signal_index=18, argv=0x7ffd19b65c30) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3923
#31 0x00007f03f80e0717 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=<optimized out>, m=m@entry=0x7f03f76d1880 <KCoreDirLister::staticMetaObject>, local_signal_index=local_signal_index@entry=15, argv=argv@entry=0x7ffd19b65c30) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3983
#32 0x00007f03f7638c69 in KCoreDirLister::itemsDeleted(KFileItemList const&) (this=<optimized out>, _t1=...) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0_build/src/core/KF5KIOCore_autogen/include/moc_kcoredirlister.cpp:583
#33 0x00007f03f763d398 in KCoreDirListerPrivate::emitItemsDeleted(KFileItemList const&) (this=0x55b2f00f2f60, itemsList=...) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/core/kcoredirlister.cpp:2611
#34 0x00007f03f764c873 in KCoreDirListerCache::itemsDeleted(QList<KCoreDirLister*> const&, KFileItemList const&) (this=this@entry=0x7f03f76d55c0 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, listers=..., deletedItems=...) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/core/kcoredirlister.cpp:1924
#35 0x00007f03f764cf9e in KCoreDirListerCache::deleteUnmarkedItems(QList<KCoreDirLister*> const&, QList<KFileItem>&, QHash<QString, KFileItem> const&) (this=this@entry=0x7f03f76d55c0 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, listers=..., lstItems=..., itemsToDelete=...) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/core/kcoredirlister.cpp:1918
#36 0x00007f03f76532e8 in KCoreDirListerCache::slotUpdateResult(KJob*) (this=0x7f03f76d55c0 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, j=<optimized out>) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/core/kcoredirlister.cpp:1842
#37 0x00007f03f80e73ae in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffd19b65fe0, r=0x7f03f76d55c0 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, this=0x55b2efda2ef0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#38 doActivate<false>(QObject*, int, void**) (sender=0x55b2f1e1d190, signal_index=6, argv=0x7ffd19b65fe0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3923
#39 0x00007f03f80e0717 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x55b2f1e1d190, m=m@entry=0x7f03f93a8160 <KJob::staticMetaObject>, local_signal_index=local_signal_index@entry=3, argv=argv@entry=0x7ffd19b65fe0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3983
#40 0x00007f03f9349987 in KJob::result(KJob*, KJob::QPrivateSignal) (this=this@entry=0x55b2f1e1d190, _t1=<optimized out>, _t1@entry=0x55b2f1e1d190, _t2=...) at /var/tmp/portage/kde-frameworks/kcoreaddons-5.103.0/work/kcoreaddons-5.103.0_build/src/lib/KF5CoreAddons_autogen/include/moc_kjob.cpp:635
#41 0x00007f03f934afab in KJob::finishJob(bool) (this=0x55b2f1e1d190, emitResult=<optimized out>) at /var/tmp/portage/kde-frameworks/kcoreaddons-5.103.0/work/kcoreaddons-5.103.0/src/lib/jobs/kjob.cpp:98
#42 0x00007f03f80e73ae in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffd19b660b0, r=0x55b2f1e1d190, this=0x55b2f1fb3cc0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#43 doActivate<false>(QObject*, int, void**) (sender=0x55b2f01f61a0, signal_index=7, argv=0x7ffd19b660b0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3923
#44 0x00007f03f80e0717 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x55b2f01f61a0, m=m@entry=0x7f03f76cf820 <KIO::SlaveInterface::staticMetaObject>, local_signal_index=local_signal_index@entry=4, argv=argv@entry=0x0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3983
#45 0x00007f03f75dd5e7 in KIO::SlaveInterface::finished() (this=this@entry=0x55b2f01f61a0) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0_build/src/core/KF5KIOCore_autogen/include/moc_slaveinterface.cpp:465
#46 0x00007f03f75df802 in KIO::SlaveInterface::dispatch(int, QByteArray const&) (this=0x55b2f01f61a0, _cmd=<optimized out>, rawdata=...) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/core/slaveinterface.cpp:149
#47 0x00007f03f75dde4a in KIO::SlaveInterface::dispatch() (this=0x55b2f01f61a0) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/core/slaveinterface.cpp:78
#48 0x00007f03f75e2ba1 in KIO::Slave::gotInput() (this=0x55b2f01f61a0) at /var/tmp/portage/kde-frameworks/kio-5.103.0/work/kio-5.103.0/src/core/slave.cpp:354
#49 0x00007f03f80e73ae in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffd19b66310, r=0x55b2f01f61a0, this=0x55b2f022e940) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#50 doActivate<false>(QObject*, int, void**) (sender=0x55b2f03612b0, signal_index=3, argv=0x7ffd19b66310) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:3923
#51 0x00007f03f80de50c in QObject::event(QEvent*) (this=0x55b2f03612b0, e=0x7f03a824cae0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qobject.cpp:1347
#52 0x00007f03f8d6c6b3 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x55b2f03612b0, e=0x7f03a824cae0) at /var/tmp/portage/dev-qt/qtwidgets-5.15.8-r2/work/qtbase-everywhere-src-5.15.8/src/widgets/kernel/qapplication.cpp:3640
#53 0x00007f03f80af4a8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55b2f03612b0, event=0x7f03a824cae0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qcoreapplication.cpp:1064
#54 0x00007f03f80b2b2e in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x55b2ef9923b0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qcoreapplication.cpp:1821
#55 0x00007f03f8108737 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x55b2ef9b3dd0) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qeventdispatcher_glib.cpp:277
#56 0x00007f03f651a458 in g_main_dispatch (context=0x55b2ef9b7ee0) at ../glib-2.74.5/glib/gmain.c:3454
#57 g_main_context_dispatch (context=0x55b2ef9b7ee0) at ../glib-2.74.5/glib/gmain.c:4172
#58 0x00007f03f651a6e8 in g_main_context_iterate (context=context@entry=0x55b2ef9b7ee0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib-2.74.5/glib/gmain.c:4248
#59 0x00007f03f651a780 in g_main_context_iteration (context=0x55b2ef9b7ee0, may_block=1) at ../glib-2.74.5/glib/gmain.c:4313
#60 0x00007f03f8107d9a in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55b2ef9b87e0, flags=...) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/corelib/kernel/qeventdispatcher_glib.cpp:423
#61 0x00007f03f80ad8fb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7ffd19b666f0, flags=..., flags@entry=...) at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/include/QtCore/../../src/corelib/global/qflags.h:69
#62 0x00007f03f80b6924 in QCoreApplication::exec() () at /var/tmp/portage/dev-qt/qtcore-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/include/QtCore/../../src/corelib/global/qflags.h:121
#63 0x00007f03f8530c50 in QGuiApplication::exec() () at /var/tmp/portage/dev-qt/qtgui-5.15.8-r3/work/qtbase-everywhere-src-5.15.8/src/gui/kernel/qguiapplication.cpp:1870
#64 0x00007f03f8d6c629 in QApplication::exec() () at /var/tmp/portage/dev-qt/qtwidgets-5.15.8-r2/work/qtbase-everywhere-src-5.15.8/src/widgets/kernel/qapplication.cpp:2832
#65 0x000055b2ef0af29b in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at /var/tmp/portage/kde-plasma/plasma-workspace-5.26.5-r1/work/plasma-workspace-5.26.5/shell/main.cpp:233
[Inferior 1 (process 3525) detached]

Reported using DrKonqi
Comment 1 Bug Janitor Service 2024-02-26 16:19:22 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/plasma-desktop/-/merge_requests/2069
Comment 2 Nate Graham 2024-02-26 22:15:37 UTC
*** Bug 481850 has been marked as a duplicate of this bug. ***
Comment 3 Marco Martin 2024-02-28 08:49:41 UTC
Git commit f0ede2d83731952012be0d43c77916d18617edb2 by Marco Martin.
Committed on 28/02/2024 at 08:49.
Pushed by mart into branch 'master'.

FolderView Positioner: fix rows insert and remove

The positioner "proxy" model had problems both in rows insertion and
removal.

when an icon is dropped in an empty desktop area as the new "last"
position, the positioner model creates new empty items for the GridView
until it reaches the cell of the drop position.

This broke because of connection slot invocation order: the connection
to QAbstractItemModel::rowsInserted in FolderModel constructor was
executed before the connection in positioner.
In turn that connection emitted move, which invoked move on Positioner,
which at this point thinks its still in the first rows insertion
transaction, because its slot has not been executed yet,
and m_beginInsertRowsCalled is still true, so there won't be a "correct"
new beginInsertRows called.
Make it a Queued connection to push it back.

In the same way, when dragging from a "last" position, the Positioner model
will remove all the trailing empty items. But it modified m_proxyToSource
(from which rowCount() depends) before calling beginRemoveRows, sending
the model into an inconsitent state and causing an assert. Make sure
that m_proxyToSource is touched only after beginRemoveRows.
Related: bug 481254

M  +18   -11   containments/desktop/plugins/folder/foldermodel.cpp
M  +11   -6    containments/desktop/plugins/folder/positioner.cpp

https://invent.kde.org/plasma/plasma-desktop/-/commit/f0ede2d83731952012be0d43c77916d18617edb2
Comment 4 Marco Martin 2024-02-28 08:50:53 UTC
Git commit e306c63ddbeaccea72a03fbb2c3dbd8245addef5 by Marco Martin.
Committed on 28/02/2024 at 08:50.
Pushed by mart into branch 'Plasma/6.0'.

FolderView Positioner: fix rows insert and remove

The positioner "proxy" model had problems both in rows insertion and
removal.

when an icon is dropped in an empty desktop area as the new "last"
position, the positioner model creates new empty items for the GridView
until it reaches the cell of the drop position.

This broke because of connection slot invocation order: the connection
to QAbstractItemModel::rowsInserted in FolderModel constructor was
executed before the connection in positioner.
In turn that connection emitted move, which invoked move on Positioner,
which at this point thinks its still in the first rows insertion
transaction, because its slot has not been executed yet,
and m_beginInsertRowsCalled is still true, so there won't be a "correct"
new beginInsertRows called.
Make it a Queued connection to push it back.

In the same way, when dragging from a "last" position, the Positioner model
will remove all the trailing empty items. But it modified m_proxyToSource
(from which rowCount() depends) before calling beginRemoveRows, sending
the model into an inconsitent state and causing an assert. Make sure
that m_proxyToSource is touched only after beginRemoveRows.
Related: bug 481254

M  +18   -11   containments/desktop/plugins/folder/foldermodel.cpp
M  +11   -6    containments/desktop/plugins/folder/positioner.cpp

https://invent.kde.org/plasma/plasma-desktop/-/commit/e306c63ddbeaccea72a03fbb2c3dbd8245addef5