From 5e35194b00d84db6aea3370ee8bb0ad560428c62 Mon Sep 17 00:00:00 2001 From: Pan Zhang Date: Mon, 23 Mar 2026 10:12:10 +0800 Subject: kitemviews: Preserve inline rename when item scrolls out of view Inline rename was canceled when the edited item scrolled out of view. Scrolling could both finish the edit and recycle the item widget, causing the typed name to be lost. Keep the inline rename editor alive while the item is temporarily offscreen. Update the editor geometry on scroll, avoid recycling the widget while it is being edited, and suppress the temporary FocusOut triggered by hiding the editor. If the user interacts with another item while the edited one is offscreen, finish the hidden edit first so normal selection behavior is preserved. BUG: 506884 --- src/kitemviews/kitemlistview.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/kitemviews/kitemlistview.cpp') diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 1d02ee5c0..452567f05 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -771,7 +771,7 @@ void KItemListView::editRole(int index, const QByteArray &role) connect(widget, &KItemListWidget::roleEditingCanceled, this, &KItemListView::slotRoleEditingCanceled); connect(widget, &KItemListWidget::roleEditingFinished, this, &KItemListView::slotRoleEditingFinished); - connect(this, &KItemListView::scrollOffsetChanged, widget, &KStandardItemListWidget::finishRoleEditing); + connect(this, &KItemListView::scrollOffsetChanged, widget, &KStandardItemListWidget::updateRoleEditorGeometry); } void KItemListView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -1092,6 +1092,20 @@ bool KItemListView::event(QEvent *event) return true; break; + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneMouseDoubleClick: + case QEvent::GraphicsSceneContextMenu: + if (m_editingRole) { + for (KItemListWidget *widget : std::as_const(m_visibleItems)) { + auto *standardWidget = qobject_cast(widget); + if (standardWidget && !standardWidget->isVisible() && !standardWidget->editedRole().isEmpty()) { + standardWidget->finishRoleEditing(); + break; + } + } + } + [[fallthrough]]; + default: // Forward all other events to the controller and handle them there if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) { @@ -2026,6 +2040,10 @@ QList KItemListView::recycleInvisibleItems(int firstVisibleIndex, int lastV const bool invisible = (index < firstVisibleIndex) || (index > lastVisibleIndex); if (invisible) { + if (!widget->editedRole().isEmpty()) { + widget->setVisible(false); + continue; + } if (m_animation->isStarted(widget)) { if (hint == NoAnimation) { // Stopping the animation will call KItemListView::slotAnimationFinished() -- cgit v1.3