Don't update the focused pointer Surface if a button is pressed
ClosedPublic

Authored by graesslin on Apr 15 2017, 9:42 AM.

Details

Summary

During pointer motion we already had the condition that an update of
focused pointer surface can only happen when no button is pressed. But
there are more conditions where we try to update the focused pointer even
if a button is pressed. E.g. if the stacking order changes.

This happens when trying to move one of Qt's dock widgets:

  1. Press inside a dock widget
  2. Qt opens another window, which is underneath the cursor
  3. KWin sends pointer leave to parent window
  4. dock widget movement breaks

This change ensures that also this sequence works as expected and the
pointer gets only updated when there are no buttons pressed, no matter
from where we go into the update code path.

BUG: 372876

Test Plan

Dock widgets in Dolphin can be moved now.

Diff Detail

Repository
R108 KWin
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
graesslin created this revision.Apr 15 2017, 9:42 AM
Restricted Application added a project: KWin. · View Herald TranscriptApr 15 2017, 9:42 AM
Restricted Application added subscribers: kwin, plasma-devel. · View Herald Transcript
markg added a subscriber: markg.Apr 15 2017, 10:01 AM
markg added inline comments.
pointer_input.cpp
440

Just curious, why do you define end as opposed tho this:
for (auto it = m_buttons.constBegin(); it != m_buttons.constEnd(); it++) {

}

Another route you can go which looks much cleaner imho (requires Qt 5.7 because of qAsConst):
for (auto entry, qAsConst(m_buttons)) {

}

Just my 2 cents.

graesslin added inline comments.
pointer_input.cpp
440

Just curious, why do you define end as opposed tho this:

Because @broulik tends to point out that it is not cached.

Another route you can go which looks much cleaner imho (requires Qt 5.7 because of qAsConst):

does that work in a sensible way for a QHash? The most lean way would have been:

if (std::any_of(m_buttons.constBegin(), m_buttons.constEnd(), [] ...))

But that doesn't work with QHash. So I kind of doubt QHash and qAsConst do something sensible.

markg added inline comments.Apr 15 2017, 3:59 PM
pointer_input.cpp
440

This is where STL and Qt apparently diverge a bit.

for (auto value : qAsConst(m_buttons)) {
// ...
}

Gives you the values in the map. Not the keys. And that is because it's a QHash container which apparently behaves like that.
If it were an std::unordered_map it would have given you a std::pair where first would be the key, second would be the value.

However, in *this* case you are only using the value thus you are fine when using:
for (auto value : qAsConst(m_buttons)) {
// ...
}

Since you seem to mention optimization (you shouldn't have done that ;)), this is the most efficient version, and i looked it up [1], hehe:
for (cont auto &value : qAsConst(m_buttons)) {
// ...
}

In fact. You likely always want this version of the range-based-for loop. And "for (auto&& value: ...)" if you want to modify them in place. You nearly never want a plain range-based-for without a reference symbol in there because that makes a copy.

Hope that helps :)

[1] Read https://blog.petrzemek.net/2016/08/17/auto-type-deduction-in-range-based-for-loops/ for the details

graesslin updated this revision to Diff 13474.Apr 15 2017, 4:08 PM

Use range-based for loop with qAsConst

Restricted Application edited projects, added Plasma; removed KWin. · View Herald TranscriptApr 15 2017, 4:08 PM
markg accepted this revision.Apr 16 2017, 1:41 PM

Fine by me :)

You did forgot an "&" (making it by reference). On the other hand, this is a POD type where performance wise this wouldn't matter at all.

This revision is now accepted and ready to land.Apr 16 2017, 1:41 PM
This revision was automatically updated to reflect the committed changes.