Bug 464196 - Drag and drop in GTK apps: 'drag-motion' is triggered when GTK window regains focus
Summary: Drag and drop in GTK apps: 'drag-motion' is triggered when GTK window regains...
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: wayland-generic (show other bugs)
Version: 5.27.8
Platform: openSUSE Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL: https://gitlab.gnome.org/GNOME/gtk/-/...
Keywords: wayland
Depends on:
Blocks:
 
Reported: 2023-01-12 15:18 UTC by postix
Modified: 2024-04-11 13:50 UTC (History)
15 users (show)

See Also:
Latest Commit:
Version Fixed In: 6.0.4


Attachments
Screenrecording (609.96 KB, video/x-matroska)
2023-01-12 15:29 UTC, postix
Details

Note You need to log in before you can comment on or make changes to this bug.
Description postix 2023-01-12 15:18:08 UTC
## Steps to reproduce

1. Run the demo code below
2. Drag and drop a file into the window
- When dragging the filer over the window, a label saying '…drop it here' appears.
- After dropping, the label vanishes.
3. Click on any KDE Plasma widget (e.g. clipboard, network, ...) in the panel to open it.

## Current behavior
When clicking on the the Plasma widget to open it, the 'drag motion' event is triggered and the overlay becomes permanently displayed.
```
...
Drag Motion: time: 8271120 x: 770 y: 39
Drag Motion: time: 8271136 x: 769 y: 39
Drag Motion: time: 8271163 x: 769 y: 39
Drag Motion: time: 0 x: 769 y: 39
Drag Motion: time: 0 x: 769 y: 39
```
Interestingly the drop time is in this case always zero and drop position is the same as in step 2 from "Steps to reproduce".

## Expected outcome
When clicking on the the Plasma widget to open it, the 'drag motion' event is not triggered.

## Version information
GTK Version: 3.24.35
GLib Version: 2.74.0
Operating System: openSUSE Tumbleweed 20230110
KDE Plasma Version: 5.26.5
KDE Frameworks Version: 5.101.0
Qt Version: 5.15.7
Graphics Platform: Wayland

## Additional information
```
import gi
gi.require_version("Gtk", "3.0")
gi.require_version('Gdk', '3.0')
from gi.repository import Gdk
from gi.repository import Gtk

TARGET_TYPE_URI_LIST = 80


class MyWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="Hello World")
        self.set_default_size(800, 600)

        self._drop_area = Gtk.Box(
        orientation=Gtk.Orientation.VERTICAL, spacing=18)
        self._drop_area.set_no_show_all(True)
        self._drop_area.add(Gtk.Label(label='…drop it here'))

        overlay = Gtk.Overlay()
        overlay.add_overlay(self._drop_area)
        overlay.connect('drag-data-received', self._on_drag_data_received)
        overlay.connect('drag-motion', self._on_drag_motion)
        overlay.connect('drag-leave', self._on_drag_leave)

        uri_entry = Gtk.TargetEntry.new(
            'text/uri-list',
            Gtk.TargetFlags.OTHER_APP,
            TARGET_TYPE_URI_LIST)

        dnd_list = [uri_entry,
                    Gtk.TargetEntry.new(
                        'OBJECT_DROP',
                        Gtk.TargetFlags.SAME_APP,
                        0)]

        dst_targets = Gtk.TargetList.new([uri_entry])
        dst_targets.add_text_targets(0)

        overlay.drag_dest_set(
            Gtk.DestDefaults.ALL,
            dnd_list,
            Gdk.DragAction.COPY | Gdk.DragAction.MOVE)
        overlay.drag_dest_set_target_list(dst_targets)

        self.add(overlay)
        self.show_all()


    def _on_drag_data_received(self,
                               _widget: Gtk.Widget,
                               _context: Gdk.DragContext,
                               _x_coord: int,
                               _y_coord: int,
                               selection: Gtk.SelectionData,
                               target_type: int,
                               _timestamp: int
                               ) -> None:
        pass


    def _on_drag_leave(self,
                       _widget: Gtk.Widget,
                       _context: Gdk.DragContext,
                       _time: int
                       ) -> None:
        self._drop_area.set_no_show_all(True)
        self._drop_area.hide()


    def _on_drag_motion(self,
                        _widget: Gtk.Widget,
                        _context: Gdk.DragContext,
                        _x_coord: int,
                        _y_coord: int,
                        _time: int
                        ) -> bool:
        self._drop_area.set_no_show_all(False)
        self._drop_area.show_all()
        print(f"Drag Motion: time: {_time} x: {_x_coord} y: {_y_coord}")
        return True

win = MyWindow()
Gtk.main()
```
Comment 1 postix 2023-01-12 15:29:53 UTC
Created attachment 155237 [details]
Screenrecording

Here's a screenrecording.

I just noticed that the bug is triggered, when the GTK window regains focus, i.e. when it was selected before and the Plasma Widget is closed (by a second click), the GTK window is focused again and a 'drag-motion' event is triggered.
Comment 2 postix 2023-01-13 11:17:43 UTC
I wanted to add that this issue could not be observed on other DE such as Gnome Wayland. Therefore the guess that it's a Plasma Wayland issue.
Comment 3 Alex Dewar 2023-02-02 20:42:38 UTC
Is anyone else seeing this issue? I notice it all the time when running Evolution under Plasma.
Comment 4 15c730840a66 2023-03-21 10:41:02 UTC
This is still a constant issue for me on Plasma 5.27.3, especially in Firefox
Comment 5 sedrubal 2023-07-23 18:25:54 UTC
Same for me. This one is really annoying. The only solution I found is to close and reopen the application that gets those spurious DnD events, which is most of the time Firefox.

Plasma Version: 5.27.6
KDE Frameworks Version: 5.108.0
Qt Version: 5.15.10
Graphics Platform: Wayland
Gtk: 3.24.38
Comment 6 nyikoszoltan0 2023-08-05 15:19:01 UTC
Interestingly I'm not able to reproduce this unless plasmashell is running. Just kwin_wayland by itself (nested or from a tty) doesn't cause the bug to trigger.
Comment 7 nyikoszoltan0 2023-08-06 18:42:23 UTC
I was able to debug a bit further but I don't think I'm any closer to the root cause.
The trigger seems to be KSystemClipboard::setMimeData. Once it is called then every time a gtk window is activated it will receive the repeat of any last drag move event. Looking into KSystemClipboard it does send the clipboard data every time a window is activated (through wl_data_device/wl_data_offer/etc), but as to where this event is mistaken as a drag motion event I'm not sure.

I created a simple reproduction setup: https://github.com/nyz93/kde-drag-repro if someone more familiar with the internals of kwin and/or wayland would like to try.
Comment 8 Dragoon Aethis 2023-09-30 20:46:05 UTC
One more +1, with more notes in this Gtk bug: https://gitlab.gnome.org/GNOME/gtk/-/issues/5519 - I can reproduce this behavior with Zoltan's code too.
Comment 9 Ilya Bizyaev 2023-10-01 11:03:17 UTC
Marking this bug as confirmed because it affects many users (me included)
Comment 10 Jessica M 2023-12-20 22:16:33 UTC
This happens to me in Firefox all the time, very annoying bug. Still happens in KDE 6
Comment 11 postix 2023-12-20 22:34:30 UTC
The comment [1] got some interesting hint
> The problem is that plasma(klipper(ksystemclipboard)) is sending 
> "selection" and "primary selection" every time a window is activated,
> which gtk detects as drag move events.

[1] https://gitlab.gnome.org/GNOME/gtk/-/issues/5519#note_1811179

I also updated the URL, as the former one was marked as a dup.
Comment 12 postix 2023-12-20 22:36:34 UTC
Oh, the hint was already mentioned in comment 7 from the very same user. :)
Comment 13 Albert Eureka 2024-04-04 11:57:11 UTC
firefox, chromium and many gtk apps are influenced by this bug, https://bugzilla.mozilla.org/show_bug.cgi?id=1875031
Comment 15 Dragoon Aethis 2024-04-09 15:00:05 UTC
It appears that Sublime Text is also affected by odd drag-drop issues, only on KDE + Wayland: https://github.com/sublimehq/sublime_text/issues/4077
Comment 16 Vlad Zahorodnii 2024-04-11 08:31:48 UTC
Git commit ab1350b6a67cc518f47ea71c33866041abee7bcd by Vlad Zahorodnii.
Committed on 11/04/2024 at 08:21.
Pushed by vladz into branch 'master'.

wayland: Send data offer source actions only for dnd

It makes sense only with dnd and sending the source_actions events for
selections and primary selections tricks gtk into thinking that there
are drag motion events.

M  +2    -1    src/wayland/datadevice.cpp

https://invent.kde.org/plasma/kwin/-/commit/ab1350b6a67cc518f47ea71c33866041abee7bcd
Comment 17 Vlad Zahorodnii 2024-04-11 08:41:08 UTC
Git commit f76b1947b1d74f2fc68198da37bca11724c0eb5f by Vlad Zahorodnii.
Committed on 11/04/2024 at 08:34.
Pushed by vladz into branch 'Plasma/6.0'.

wayland: Send data offer source actions only for dnd

It makes sense only with dnd and sending the source_actions events for
selections and primary selections tricks gtk into thinking that there
are drag motion events.


(cherry picked from commit ab1350b6a67cc518f47ea71c33866041abee7bcd)

M  +2    -1    src/wayland/datadevice.cpp

https://invent.kde.org/plasma/kwin/-/commit/f76b1947b1d74f2fc68198da37bca11724c0eb5f