Bug 167788 - device notifier list gets corrupted when removing a device while hovering over one
Summary: device notifier list gets corrupted when removing a device while hovering ove...
Status: RESOLVED WORKSFORME
Alias: None
Product: plasma4
Classification: Plasma
Component: general (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-30 23:03 UTC by Ambroz Bizjak
Modified: 2008-08-02 01:14 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
workaround/fix (1.53 KB, patch)
2008-07-30 23:25 UTC, Ambroz Bizjak
Details
fix corruption, recheck cursor (2.70 KB, patch)
2008-07-31 02:39 UTC, Ambroz Bizjak
Details
fix corruption, recheck cursor (2.60 KB, patch)
2008-07-31 02:50 UTC, Ambroz Bizjak
Details
fix (2.21 KB, patch)
2008-07-31 10:53 UTC, Ambroz Bizjak
Details
fix (5.22 KB, patch)
2008-07-31 20:54 UTC, Ambroz Bizjak
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ambroz Bizjak 2008-07-30 23:07:23 UTC
Version:            (using Devel)
Installed from:    Compiled sources
OS:                Linux

If I click on the Device Notifier, leave the cursor to hover on one of the devices, and then (physically) unplug one of the removable devices, the list of devices will get corrupt.
In particular, the first column on the list (device name, image and action name) completly disappears, and the second column (that may contain the Eject button) takes all the space.
The list gets normal once another device is plugged in.
Comment 1 Ambroz Bizjak 2008-07-30 23:25:52 UTC
Created attachment 26512 [details]
workaround/fix

The corruptions seems to occur whenever a row is removed from the table
(QStandardItemModel) while one of the items in the table is set as current
(setCurrentIndex). Looks like a bug in Qt to me. This patch deselects any item
prior to removing a device to prevent corruption from occuring, and also
deselects it after inserting a new device, which removes a minor painting
inconsistency in the same situation.
Comment 2 Aaron J. Seigo 2008-07-31 00:16:14 UTC
looks about right for row removal; but perhaps it makes sense to check if m_hoveredIndex is still valid before reseting it?

for rowInsertion, it would be good to reset it to whatever the mouse is over?
Comment 3 Ambroz Bizjak 2008-07-31 02:39:29 UTC
Created attachment 26515 [details]
fix corruption, recheck cursor

Well yes, concerning removal, it doesn't need to be updated if there is nothing
selected. I added a check.

And yes, also it would be good to recheck the mouse position and update the
highlight. I did that by calling the mouse event handler when something
changes, but first deselecting the current selection (otherwise it wouldn't get
updated as the row/column is the same but everything is shifted).
I've used the rowsInserted method to do that when adding devices, but I had to
use a signal from the data source to handle the "rowsRemoved" event (as there
is no method to overload).

So now it's all working properly - both the corruption is gone, and also the
highlight is properly updated even if the cursor doesn't move.
Comment 4 Ambroz Bizjak 2008-07-31 02:50:46 UTC
Created attachment 26516 [details]
fix corruption, recheck cursor

forgot to shrink some lines into one...
Comment 5 Aaron J. Seigo 2008-07-31 06:58:09 UTC
SVN commit 839907 by aseigo:

fix corruption on device plug/unplug while mouse hovered; based on patch by ambro
BUG:167788


 M  +35 -1     notifierview.cpp  
 M  +6 -0      notifierview.h  


WebSVN link: http://websvn.kde.org/?view=rev&revision=839907
Comment 6 Ambroz Bizjak 2008-07-31 10:53:42 UTC
Created attachment 26528 [details]
fix

I think what you did there was not correct.

Why did you remove the rowsAboutToBeRemoved? It is what fixes the corruption
this bug is all about. This method is called before the actual removal, so this
is the place where items have to be delesected (I tested it, bug not fixed).

The modelRowsRemoved and rowsInserted methods I added are used only after the
change, and all they do is refresh the highlight.
Also, the disconnect statement should be removed from modelRowsRemoved,
otherwise it would refresh properly on the first removal.

This patch (diff of current svn):
- adds rowsAboutToBeRemoved
- changes rowsInserted to only invalidate the selection if there is one
- changes modelRowsRemoved to never invalidate the selection (it is always
already invalidated in rowsAboutToBeRemoved), and removes the disconnect.
And I tested it, works in all aspects.
Comment 7 Ambroz Bizjak 2008-07-31 10:59:01 UTC
not fixed in svn see comment
Comment 8 Ambroz Bizjak 2008-07-31 16:07:10 UTC
It's still pretty much broken if used standalone on the desktop instead of the panel... I suggest you wait a little for me to rework things before changing anything.
Comment 9 Ambroz Bizjak 2008-07-31 20:54:44 UTC
Created attachment 26535 [details]
fix

This patch fixes all hover-related problems, both in panel and desktop mode.

Correct ordering of operations is crucial; the principle is not to interfere
with QTreeView's internal processing, in practice:
- invalidate the selection even before QTreeView handles rowsAboutToBeRemoved,
and before rows are inserted (it doesn't already have a slot for
rowsAboutToBeInserted)
- post (not invoke handler) a mouse move message after QTreeView handles
rowsInserted/rowsRemoved

I achieved the correct ordering of operations by overloading as many event
handlers as possible; only rowsAboutToBeInserted did not exist, so I created a
normal slot.

Also, to correctly refresh the selection I had to cache the cursor position.
That's becouse if the applet is on the desktop, the "global cursor position" is
actually relative to the black box arround the applet (why??) so I can't just
use QCursor::pos() which gives a true global position.

Please, do not commit something you haven't tested thoroughly; it only causes
confusion. If you think it can be done better, post your suggestions, so I can
at least test it.
Comment 10 Aaron J. Seigo 2008-07-31 21:18:20 UTC
i did test it (obviously), including on the desktop, and there was no corruption visible while testing when plugging and unplugging devices.

the reason i changed your patch was quite simple: connect/disconnect of the signal was done in the wrong place, testing seemed to indicate that the rowsAboutToBeRemoved implementation wasn't necessary (rowsAboutToBeRemoved was called, processing happened, then the rowsRemoved slot was called all before getting back to painting).

the new patch is really ugly, but that's the fault of the view, not you. i'm actually surprised that there is painting happening here between rowsAboutToBeRemoved and actual row removal =/


> the "global cursor position" is 
> actually relative to the black box arround the applet

yes, so that all operations in a widget can be done relative to the widget. this makes the common cases much easier; as for using QCursor::pos(), that will fail anyways unless you go through the view which you really don't want to do if at all possible since "the view" is not well defined enough for these kinds of cases due to multiple views being possible.

p.s. plasma-devel is really a better place for these discussions
Comment 11 Ambroz Bizjak 2008-08-02 01:14:01 UTC
I cannot reproduce the weird corruption I was seeing anymore; you probably just noticed the highlight-not-refreshed problem. Anyway works perfectly with current svn.