Fix scrolling during inline renaming causes rename of wrong file
ClosedPublic

Authored by akrutzler on Nov 14 2017, 7:19 PM.

Details

Summary

Scrolling during inline renaming accepts the renaming now, like if one would hit Return for example. I chose this approach because it seems the easiest way to fix this.
This also fixes the “possible” Ui glitch where the renaming KTextField doesn’t move along with the list item. Possible glitch, because I don’t know if this is intentional, but for me it looks broken.

BUG: 378786
Fixes T7443

Test Plan
  • Enable "Rename inline" in dolphin settings
  • Go to a folder where you have to scroll through items (many files, big zoom,…)
  • Start to rename a file (context menu, F2, …)
  • Scroll with mouse wheel
  • Rename accepted -> file is renamed

Diff Detail

Repository
R318 Dolphin
Branch
master
Lint
No Linters Available
Unit
No Unit Test Coverage
akrutzler created this revision.Nov 14 2017, 7:19 PM
Restricted Application added a subscriber: Dolphin. · View Herald TranscriptNov 14 2017, 7:19 PM
ngraham added inline comments.Nov 14 2017, 11:46 PM
src/kitemviews/private/kitemlistroleeditor.cpp
61

Why is this new function necessary?

akrutzler added inline comments.Nov 15 2017, 5:32 PM
src/kitemviews/private/kitemlistroleeditor.cpp
61

Actually it's not necessary. Just my personal preference since KIO::encodeFileName(toPlainText() is used 3 times (2 in kitemlistroleeditor.cpp and 1 in kstandarditemlistwidget.cpp). But I can also remove this function.

rkflx added a comment.Nov 15 2017, 6:44 PM

Wow, can't wait to test this! (Busy currently, give me a day or two).

src/kitemviews/private/kitemlistroleeditor.cpp
61

In general I'd just follow the same style as the surrounding code. I don't think there is a rule specifying a point at which you are supposed to refactor into a function.

I'd probably just keep what you have done right now and wait whether Dolphin's maintainers like it or not (they should give the final green light anyway).

I've tested this and it works great. As soon as the unnecessary new function is removed, I'll approve it and will wait for @rkflx to review as well.

akrutzler updated this revision to Diff 22411.Nov 15 2017, 7:13 PM

Removed KItemListRoleEditor::encodedFileName() function.

ngraham accepted this revision.Nov 15 2017, 7:39 PM
ngraham added a reviewer: Dolphin.
This revision is now accepted and ready to land.Nov 15 2017, 7:39 PM
rkflx accepted this revision.Nov 16 2017, 6:30 AM
rkflx added a subscriber: elvisangelaccio.

Had a look, works great, solves the bug and I cannot break it. Code seems fine. I still don't understand what is the actual problem in the bug, but at least it is not triggered anymore and the floating text input field is gone. Now shows same behaviour as in Windows Explorer, which is fine.

@akrutzler Please add Fixes T7443 to the summary :) Also, the title should not sound like a bug, instead reword to either describe the new behaviour, or add "Fix <the problem>".

@elvisangelaccio Is this approvable from Dolphin's perspective?

Note for the committer: This is currently branched from master, but should probably go to Applications/17.12.

Thanks for working on this.
Can you try to use the event filter in KItemListRoleEditor instead? It should be enough to also check for the QEvent::Wheel event.
It seems to work for me and the patch becomes much simpler.

In D8822#168268, @rkflx wrote:

I still don't understand what is the actual problem in the bug, but at least it is not triggered anymore and the floating text input field is gone.

The actual problem behind this is an "miscommunication" between View and Model. If you want to rename something, you tell the KItemListView to change the text-role of one of its items by calling KItemListView::editRole(int index, const QByteArray& role). index defines which item to change. But this index is not persistent! Once you scroll through the list, that index may change (because of some performance optimizations in KItemListView::doLayout()i guess). Because of this, the index of an Item in the View differs from the index in the Model(where necessary data like the URL is stored). But by design they must stay the same!

Can you try to use the event filter in KItemListRoleEditor instead? It should be enough to also check for the QEvent::Wheel event.
It seems to work for me and the patch becomes much simpler.

I tried to catch the QEvent::Wheel event in KStandardItemListWidget but of course that doesn't work because KItemListRoleEditor has focus. If that works, this patch should be very simple thanks :) Maybe I'll make it until tonight.

akrutzler retitled this revision from Rename inline: scrolling causes rename of wrong file to Fix scrolling during inline renaming causes rename of wrong file.Nov 16 2017, 1:33 PM
akrutzler edited the summary of this revision. (Show Details)
rkflx added a comment.Nov 16 2017, 1:45 PM

The actual problem behind this is an "miscommunication" between View and Model. If you want to rename something, you tell the KItemListView to change the text-role of one of its items by calling KItemListView::editRole(int index, const QByteArray& role). index defines which item to change. But this index is not persistent! Once you scroll through the list, that index may change (because of some performance optimizations in KItemListView::doLayout()i guess). Because of this, the index of an Item in the View differs from the index in the Model(where necessary data like the URL is stored). But by design they must stay the same!

@akrutzler Thanks for the analysis, sounds like you are onto another fix :) If you are interested (if not, I can also recommend a few Gwenview bugs): https://bugs.kde.org/show_bug.cgi?id=334533#c7

akrutzler updated this revision to Diff 22540.Nov 17 2017, 6:41 PM

This patch is pretty simple now. The behaviour is slightly different. Now the renaming gets accepted once you turn the mouse wheel, even if
there is actually nothing to scroll. But i like it that way too :)

ngraham added inline comments.Nov 17 2017, 6:44 PM
src/kitemviews/private/kitemlistroleeditor.cpp
64

Not all users will be using a mouse with a wheel. Can we use QEvent::Scroll instead, so this continues to work with a laptop touchpad or touchscreen?

In D8822#168505, @rkflx wrote:

@akrutzler Thanks for the analysis, sounds like you are onto another fix :) If you are interested (if not, I can also recommend a few Gwenview bugs): https://bugs.kde.org/show_bug.cgi?id=334533#c7

334533 seems to be a tricky one, but definitely related to this Model/View bug, lets see what i can do. I am not very familiar with gwenview as a user, but yes i can have a look at it :)

src/kitemviews/private/kitemlistroleeditor.cpp
64

I tested this with my touchpad too and it works pretty well. But since i have no touchscreen available right now i cannot test this case. But then i have to catch QEvent::Wheel and QEvent::Scroll right? Because i don't get any scroll events when using mouse/touchpad.

ngraham added inline comments.Nov 17 2017, 7:09 PM
src/kitemviews/private/kitemlistroleeditor.cpp
64

If what you have works with a touchpad already, then that's fine. It's not like Dolphin is very well optimized for touchscreen use anyway.

ngraham accepted this revision.Nov 17 2017, 7:09 PM

@rkflx, any remaining concerns, or should we land this?

elvisangelaccio accepted this revision.Nov 18 2017, 8:46 AM
rkflx requested changes to this revision.EditedNov 18 2017, 10:07 AM

Sorry to say, but now it breaks for me: Try scrolling with the mouse wheel over the scrollbar (can easily happen if you are trying to move the mouse "out of the way" or when using the context menu for Rename). We do not get the scroll event anymore, the line edit is floating again and the rename target becomes unpredictable.

I tried qDebug() << event, but at this point there's no event at all to observe. Either we go back to the previous version of the patch, or we find another elegant solution…

src/kitemviews/private/kitemlistroleeditor.cpp
64

Touchpad support was the first thing I looked up after Elvis mentioned this :). Apparently "Wheel events are generated for both mouse wheels and trackpad scroll gestures." Source

As for testing touchscreen support, maybe there's some trickery you can setup in X11 to emulate touch events with a regular mouse?

This revision now requires changes to proceed.Nov 18 2017, 10:07 AM
This comment was removed by rkflx.
anthonyfieroni added inline comments.
src/kitemviews/private/kitemlistroleeditor.cpp
64

Can you try event->type() == QEvent::Expose

akrutzler added inline comments.Nov 18 2017, 1:01 PM
src/kitemviews/private/kitemlistroleeditor.cpp
64

In my former approach, the renaming was accepted once the View "scrolls" its content. It was completely independent of what the scrolling actually triggered since i was not catching any event. This could be either by mouse/touchpad or even programmatically by calling KItemListView::scrollToItem for example. IMO that should work for touchscreens too.

I tried to catch QEvent::Expose in KItemListRoleEditor::eventFilter and KItemListRoleEditor::event but i don't even get this event. :\

rkflx added a comment.Nov 18 2017, 1:14 PM

Let's not get too sidetracked on the touchscreen topic. I'm not even sure Dolphin supports scrolling the view on a touchscreen without resorting to the scrollbar.

Also not sure if fiddling with the painting code/visibility (i.e. what is related to expose events) helps us here.

As I said, there are two approaches:

  • React to the scrolling after it happened (original patch, which is not pretty but works).
  • Catch the scrolling before it propagates (current patch, but maybe needs to be caught in a different place, i.e. you could try to investigate where scrollOffsetChanged is triggered from).
In D8822#169322, @rkflx wrote:

Catch the scrolling before it propagates (current patch, but maybe needs to be caught in a different place, i.e. you could try to investigate where scrollOffsetChanged is triggered from).

The problem with catching the wheel event in a different place is that i still need a "connection" between this new place and the KItemListRoleEditor (because the new name is stored in there). So i don't know if that makes it simpler. It would be easier/prettier if we cancle the renaming instead of accepting it, because in that case i don't care about KItemListRoleEditor. But accepting it is the right way to go :)
Unless I find a better solution for it, I'll just go back to my previous approach.

akrutzler updated this revision to Diff 22571.Nov 18 2017, 2:33 PM

Reverting to previous patch, beacause reacting to KItemListView::scrollOffsetChanged-signal is independent of what/who actual causes the
scrolling.

src/kitemviews/kstandarditemlistwidget.h
189

Maybe let's call it emitRoleEditingFinished() ? (which is what eventually happens)

finishRoleEditing() could also work...

akrutzler updated this revision to Diff 22574.Nov 18 2017, 4:43 PM

Rename forceRoleEditingFinished() to finishRoleEditing()
Rebase to latest master.

akrutzler marked an inline comment as done.Nov 18 2017, 4:44 PM
elvisangelaccio accepted this revision.Nov 18 2017, 4:45 PM
rkflx accepted this revision.Nov 18 2017, 11:49 PM
This revision is now accepted and ready to land.Nov 18 2017, 11:49 PM
ngraham accepted this revision.Nov 19 2017, 3:32 AM
This revision was automatically updated to reflect the committed changes.
rkflx added a comment.Nov 19 2017, 7:20 AM
In D8822#168268, @rkflx wrote:

Note for the committer: This is currently branched from master, but should probably go to Applications/17.12.

Any reason this has been committed to master only?

(Interestingly, I just noticed what Andreas fixed here was still working in a KDE4 based Dolphin…)

In D8822#169485, @rkflx wrote:

(Interestingly, I just noticed what Andreas fixed here was still working in a KDE4 based Dolphin…)

I think this bug was introduced in Dolphin 2.0(4.8), where he got his new view engine six years ago. Somewhere around f23e9496f303995557b744c03178f5dbd9b35016. Just a guess because i am not able to build this version.

rkflx added a comment.Nov 19 2017, 9:17 AM

On a stock Ubuntu 16.04 Dolphin (15.12.3, Qt 5.5.1, KF 5.18) it works, however when compiling 15.12.3 on a recent system, it does not work. Weird. So it is probably more complicated or somewhere outside of Dolphin.

However (just checked), 334533 is already broken in the old Ubuntu as well as KDE4 (post-2.0, i.e. 15.04), so probably not worth bisecting this further…

Cherry-picked on the stable branch.
@ngraham Next time please push bugfixes to the Applications/xx.yy branch, then merge on master.

My mistake, sorry.