flipperdevices / qFlipper

qFlipper — desktop application for updating Flipper Zero firmware via PC
https://update.flipperzero.one
GNU General Public License v3.0
1.14k stars 152 forks source link

Dragging the window by its top bar is unreliable with Qt6 #157

Open sur5r opened 1 year ago

sur5r commented 1 year ago

While trying to switch the Debian package to Qt6, I noticed that moving the window by it's top bar is unreliable. It feels like the release event gets lost/ignored somewhere.

To Reproduce

  1. Build qFlipper against Qt6. (6.4.2 at the time of this writing)
  2. Drag the window by its top bar.
  3. Notice how the release events seems to get lost and the window is "stuck" to the mouse pointer.
  4. Click several times to eventually release the window

Expected behavior Window can be moved/dragged as expected.

Actual behavior Window is stuck to the mouse pointer.

Additional troubleshooting This can be reproduced easily and has been reproduced on two machines.

I also noticed the following detail: When releasing the mouse button for the first time, the cursor shape briefly turns back to the normal pointer and immediately switches back to the "movement cross".

https://user-images.githubusercontent.com/1111369/211906859-4b11b03b-9b32-4fa7-b129-f7bfc158c959.mp4

Additional context A build against Qt5 (5.15.7) does not show this problem.

Log

158 [APP] qFlipper version 1.2.2 commit fdf5997b 2023-01-05T19:06:04
158 [APP] OS info: Debian GNU/Linux bookworm/sid unknown 6.0.0-6-amd64 Qt 6.4.2
216 [UPD] Fetched update information from https://update.flipperzero.one/qFlipper/directory.json
286 [UPD] Fetched update information from https://update.flipperzero.one/firmware/directory.json
5423 [default] QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-sur5r'
5423 [default] Unable to detect a launcher for 'file:///home/sur5r/.local/share/qFlipper/qFlipper-20230111-192754.txt'
328608 [APP] qFlipper exited
328654 [default] "There are still \"1\" items in the process of being created at engine destruction."
gsurkov commented 1 year ago

What desktop environment (KDE/GNOME/XFCE/some window manager) and graphical system (Xorg/Wayland) are you using?

sur5r commented 1 year ago

This was using i3 and Xorg.

gsurkov commented 1 year ago

I was able to reproduce this under i3 (but not under more common window managers like KDE's kwin). The window gets stuck to the mouse and pressing escape returns it to the initial position. I'll see what I can do but can't promise much.

The dragging action is implemented via Qt's startSystemMove() method which forwards input events directly to the underlying window manager. The fact that it worked with Qt5 suggests some weird edge case bug either in Qt6, i3 or their combination.

Dragging using the floating modifier key, however, worked just fine. There's also no difference whether a compositing manager (like picom) is running or not. I also had my suspicions about the focus_follows_mouse option but disabling it also did nothing.

sur5r commented 1 year ago

Thanks for looking into this.

I just tried it on another machine using XFCE and the bug shows there as well.

I will try and find some time to build a minimal QML app to reproduce this so it can be reported to Qt.

gsurkov commented 1 year ago

WindowDragExample.zip Here is the minimal app that reproduces this bug.

sur5r commented 1 year ago

Thank you very much!

sur5r commented 1 year ago

Reported to QT: https://bugreports.qt.io/browse/QTBUG-110145

Noteworthy: https://bugreports.qt.io/browse/QTBUG-102488 seems related but is C++ only, no QML and does work fine for me.

gsurkov commented 1 year ago

Thanks for your effort. I don't have high hopes for them fixing it, but it's certainly worth a try. I'll try to come up with some workaround in the meantime, as this affects a bigger number of window managers than it seemed initially.

sur5r commented 1 year ago
diff --git a/main.qml b/main.qml
index 11bb590..7020c93 100644
--- a/main.qml
+++ b/main.qml
@@ -17,9 +17,20 @@ Window {
     visible: true
     title: qsTr("Window Drag Example")

+    Timer {
+        id: dragTimer
+    }
+
+    function delayDrag(delayTime, cb) {
+        dragTimer.interval = delayTime;
+       dragTimer.repeat = false;
+       dragTimer.triggered.connect(cb);
+       dragTimer.start();
+    }
+
     DragHandler {
         target: null
-        onActiveChanged: if(active) window.startSystemMove();
+        onActiveChanged: delayDrag(10, function() { if(active) window.startSystemMove(); });
     }

     Text {

I tried this as it seems like a race condition to me. It indeed improves the situation in the sense that releasing the window works reliably, but sometimes the window jumps around long after I released it, so it's more complex...