[RFC] Implement drag from free space also for QtQuickControls
ClosedPublic

Authored by drosca on Dec 3 2016, 2:42 PM.

Details

Summary

Use window manager to handle window move when dragging from free space
also with QtQuickControls.

Registering the QQuickItems is hacky, because there is no Style::polish
for QtQuickControls, so those items are now registered from ::isQtQuickControl.

Test Plan

Works on both X11 and Wayland. Tested with discover and plasma config dialogs
(there it needs to remove the MouseEventListener that also implements window moving).
Also works fine with QQuickWidget in KCM.

Diff Detail

Repository
R31 Breeze
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
drosca updated this revision to Diff 8721.Dec 3 2016, 2:42 PM
drosca retitled this revision from to [RFC] Implement drag from free space also for QtQuickControls.
drosca updated this object.
drosca edited the test plan for this revision. (Show Details)
drosca added reviewers: Plasma, hpereiradacosta.
Restricted Application added a project: Plasma. · View Herald TranscriptDec 3 2016, 2:42 PM
Restricted Application added a subscriber: plasma-devel. · View Herald Transcript

apart from being hacky: very nice! I would not have thought that this is possible at all.

hpereiradacosta edited edge metadata.EditedDec 4 2016, 10:04 AM

in principle, no objection to the patch, but (big but): breeze style is supposed to compiled and be used against both qt4/kde4 and kf5, this as long as we still have kde4 applications around

There is an option (-DUSE_KDE4=true) in the CMakeLists to test that. (and quite some #if BREEZE_USE_KDE4 in the code)

This patch completely breaks kde4 compilation: there is no QQuickItem in Qt4, nor QWindow (so that all changes QWidget -> QWindow are not allowed)

in the end, I think you're better off forking BreezeWindowManager for QQuickItems, an use it only if not under kde4, possibly moving the widget move technology (wayland and stuff) to a common baseclass.

  • Also note that you have no guarantee that all QtQuickItems pass through IsQtQuick
  • This guy is called only in cases when you need slightly different render path between widgets and quick. Everywhere else, quicks are not checked and thus cannot be registered to the window manager.
  • Also note that you have no guarantee that all QtQuickItems pass through IsQtQuick
  • This guy is called only in cases when you need slightly different render path between widgets and quick. Everywhere else, quicks are not checked and thus cannot be registered to the window manager.

I am aware of this. Other option is to filter QEvent::Expose of QQuickWindows and then for contentItem of those windows filter QEvent::ChildAdded to find QQuickStyleItem.
Not sure what is better, the current solution appears to *work* even if there (probably?) is a case where isQtQuickItem would not pick the window.

mart added a subscriber: mart.Dec 5 2016, 9:38 AM

big +1 on this.
to make it build on kde4, even if it's not pretty, could the method declarations be ifdeffed? implementations are mostly the same

drosca updated this revision to Diff 8804.Dec 6 2016, 11:40 AM
drosca edited edge metadata.

Attempt to make it build with KDE4, untested. I don't have KDE4 anymore.

Thanks for the updated patch !
I tested it compiles on kde4
Made a few suggestions above, then it can go.

kstyle/breezewindowmanager.cpp
467

should be "return false"
Comments few lines below says we never eat events.

kstyle/breezewindowmanager.h
176

I'd rather use typedef, or even better

"using Window = QWindow;"
and "using Window = QWidget;"

instead of preprocessors

drosca added inline comments.Dec 6 2016, 2:27 PM
kstyle/breezewindowmanager.cpp
467

It needs to be return true. If we return false here, then we won't get following move and release events. We can eat events for QQuickItems, because we only get events that were not handled by any Item.

hpereiradacosta added inline comments.Dec 6 2016, 2:42 PM
kstyle/breezewindowmanager.cpp
467

Guess I'll trust you on that, though I am a bit surprised.
Event filter should guaranty that you receive mouseMove and mouseRelease disregarding the return value of here ... maybe I miss something

drosca updated this revision to Diff 8808.Dec 6 2016, 3:06 PM

"using" instead of defines

hpereiradacosta accepted this revision.Dec 6 2016, 3:07 PM
hpereiradacosta edited edge metadata.
This revision is now accepted and ready to land.Dec 6 2016, 3:07 PM
This revision was automatically updated to reflect the committed changes.

This patch has a disavantage (i'm not pretty sure it's this or Martin's) drag from empty area is ignored every even time e.g.

  1. drag from empty area -> OK
  2. drag again -> ignored
  3. drag again -> OK
  4. drag agina -> ignored

and so on...

drosca added a comment.Feb 7 2017, 7:50 AM

This patch has a disavantage (i'm not pretty sure it's this or Martin's) drag from empty area is ignored every even time e.g.

Did you actually try to revert it and see if anything changes?

The problem is reproducible only with Qt 5.8, and it doesn't just block second drag - it breaks all mouse events until you click in the window to "reset" it. Because the wm move is started in between mouse click sequence (right after mouse press), Breeze is sending fake mouse release right after the wm move is started to make it look as normal mouse press + release to Qt. Unfortunately, this trick no longer works with Qt 5.8 and I have no idea how to fix it.

This would probably help us https://codereview.qt-project.org/#/c/150399/

Ah, the bug stays over an year opened. Ok i will investigate to re-simulate move start.

Did you actually try to revert it and see if anything changes?

The problem is reproducible only with Qt 5.8, and it doesn't just block second drag - it breaks all mouse events until you click in the window to "reset" it. Because the wm move is started in between mouse click sequence (right after mouse press), Breeze is sending fake mouse release right after the wm move is started to make it look as normal mouse press + release to Qt. Unfortunately, this trick no longer works with Qt 5.8 and I have no idea how to fix it.

This would probably help us https://codereview.qt-project.org/#/c/150399/

To David: this happend both with QtQuickControls and QWidgets ?
i'll need to upgrade to Qt5.8 to investigate.
(indeed I cannot reproduce with Qt5.7 and QWidget at least)

drosca added a comment.Feb 7 2017, 8:58 AM

@hpereiradacosta Yes, happens with both QQC and QWidgets.

Workaround cannot be made, Qt 5.8 counts internal messages e.g. MouseEventPress internal wants MouseEventRelease intenal, our message can't mess counting. Will be good when Qt bug is closed :)