Wayland input events flow during drag-and-drop sessions
---
>[!info]-
> Author:
[email protected]
> Publish date: 2024/03/12
> Last update: 2024/05/16
> Status: Draft
> Revision: 1
> Visibility: Public
This document contains observations and findings related to [Wayland](https://wayland.freedesktop.org/) input events flow during drag-and-drop sessions. Primary focus is [Chromium](https://www.chromium.org/)'s tab dragging use case and issues listed below, though they mostly apply to general DnD, especially the divergences of its implementation across different compositors, as analyzed in details on the [[#Appendix Inspecting major compositors behavior|Appendix]] section.
### Symptoms:
- [lacros: canceling tab drag sometimes causes browser to become unresponsive](https://issuetracker.google.com/41497106)
- [[Lacros]: Successive Lacros drag cancellations with ESC key pressed results in browser window unresponsiveness](https://issues.chromium.org/issues/326724593)
- [wl_pointer.enter must never be ignored](https://issues.chromium.org/325309572)
- [Browser Wayland UI sometimes becomes unresponsive to mouse clicks after dragging event](https://issues.chromium.org/issues/327643790)
- [Under wayland, the last enter serial is not updated if it's received during a DnD operation](https://issues.chromium.org/324280587)
- [Chrome/Wayland window freezing when a tab is moved out of a window](https://issues.chromium.org/issues/40944743)
# Changelog
Related changes have been incrementally landing as bugs were being reported. Mostly were due to compositor side bugs and/or deviations among compositor impls. **But**, it's also a possible misuse (from our side) of wl_data_source events, such as, `dnd_finished` and `cancelled`.
First, let's collect the related changes, and the supposed motivation for each of them:
- 2020/07/04: [ozone/wayland: tabdrag: Reliably deliver drop event](https://chromium-review.googlesource.com/c/chromium/src/+/2281112)
- pointer.leave received before dnd_finished when processing drop
- addressed by introducing the pointer_grab_owner_ class var in drag controller
- Afftected tests: WaylandWindowDragControllerTest.DragToOtherWindowSnapDragDrop
- 2020/11/12: [ozone/wayland: tabdrag: Ignore wl_pointer events until session finishes](https://chromium-review.googlesource.com/c/chromium/src/+/2533693)
- Handled within WindowDragController by adding the should_process_drag_event_ flag (possible only because it used to override event dispatcher?)
- Affected tests: WaylandWindowDragControllerTest.IgnorePointerEventsUntilDrop
- 2023/01/06: [ozone/wayland: Guard against spurious wl_pointer.enter|leave events](https://chromium-review.googlesource.com/c/chromium/src/+/4123067) + its [fixup](https://chromium-review.googlesource.com/c/chromium/src/+/4177994) which restricts it to window drag sessions
- pointer enter/leaves received before wl_data_source.dnd_finished
- 2023/01/26: tentative [fix](https://chromium-review.googlesource.com/c/chromium/src/+/4191399) for the compositor-side issue landed by oshima.and is shipping since 112.0.5615.47 stable.
- Affected tests: WaylandWindowDragControllerTest.DragToOtherWindowSnapDragDrop and WaylandWindowDragControllerTest.DragToOtherWindowIgnoringSpuriousPointerEnterEvent (added)
- 2023/01/30: [ozone/wayland: Relax ShouldSuppressPointerEnterOrLeaveEvents()](https://chromium-review.googlesource.com/c/chromium/src/+/4201767)
- Relaxes previous tonikitoo's fix such that it no-ops when Lacros already contains oshima's fix mentioned above
- Affected tests: None
- 2023/11/02: [wayland: skip pointer events when there is a dnd session in progress](https://chromium-review.googlesource.com/c/chromium/src/+/4996004)
- Expands pointer events skipping to: (1) all drag sessions, and (2) for lacros, even if the exo fix is in place.
- Written under the assumption that, even though pointer events during drag sessions are possible/legit spec-wise, skipping them could enforce/protect the synchronous chrome UI APIs. Though, it's proven that it can cause subtle issues and likely must be rolled back and handled case-by-case instead.
- Affected tests: WaylandWindowDragControllerTest.IgnorePointerEventsUntilDrop
# Analysis
This section outlines the consolidated list of observations resulting from the in-depth analysis detailed in [[#Appendix Inspecting major compositors behavior]].
### Pointer focus
- **Exo:**
- Origin surface lose pointer focus before any data_device event
- After successful drops, the surface under pointer regain focus only after `data_source.dnd_finished`
- On cancelled sessions, the surface under pointer regain focus only when the mouse button is released.
- **Gnome Shell:**
- Origin surface loses focus before any other data_device event (just like in Exo)
- Pointer focus is regained after `data_device.leave`, which may happen before `data_source.dnd_finished`, but not before `data_source.dnd_drop_performed`.
- On cancelled sessions, focus is regained (if applicable) after `data_device.leave`, which happens after `data_source.cancelled`
- **KWin:**
- No `pointer.leave` is sent before `data_device.enter` when the session starts, though no `pointer.motion` is sent until drop/cancel.
- On successful sessions, a `pointer.leave` + `pointer.enter` (if applicable) are received just after `data_source.dnd_drop_performed`.
> [!attention]- Possible KWin bugs
> Even though the specs do not explicitly set expectations about `wl_pointer` events during dnd sessions, as can be seen in the [[#KWin|Appendix]], the overall behavior in KWin is (at least) inconsistent, and may indicate compositor bugs and other undesirable side effects, such as the `wl_pointer.button` issue described below.
>
> Update(2024/05/16): Related upstream issue [Cursor updates during drag and drop (#444) · Issues · wayland / wayland · GitLab](https://gitlab.freedesktop.org/wayland/wayland/-/issues/444)
- **Sway:**
- Origin surface loses focus before any other data_device event (just like in Exo)
- ESC-triggered cancellation unsupported.
- After successful drops, the surface under pointer regain focus only after `data_source.dnd_finished` (just like Exo). It's worth noting that the subsequent `pointer.enter` is sent only upon the next mouse interaction, eg: move or button press.
> [!bug] Bug: Report both to wlroots/sway team.
### Pointer motion, button, frame
- **Exo**:
- No other pointer event in between `pointer.leave`/`enter` which mark the drag session begin and end.
- **Gnome Shell:**
- No other pointer event in between `pointer.leave`/`enter` which mark the drag session begin and end.
- **KWin:**
- `pointer.frame` keep being sent after `data_device.enter` and even while the user is dragging outside of any top-level surface, e.g: over the desktop shell.
- `pointer.button` release is sent when drop happens, more specifically before `data_source.dnd_drop_performed`. More details on section [[#KWin#1. Drag attached and drop|1]], for example.
> [!bug]- Compositor Bug [Fixed]
>
> Update(2024/05/16): Fixed by [wayland: Only send artificial mouse up events for xwayland drags (!5392) · Merge requests · Plasma / KWin · GitLab](https://invent.kde.org/plasma/kwin/-/merge_requests/5392)
> [!todo]- To-do: Needs special handling in Chromium. **[Done]**
>
> Update(2024/05/16): Reported and fixed at [crbug/329703410](https://issues.chromium.org/issues/329703410)
- **Sway:**
- No other pointer event in between `pointer.leave`/`enter` which mark the drag session begin and end.
### Drop detection
- **Exo:**
- `data_source.dnd_drop_performed` always sent unless cancelled. This happens only because extended-drag is in place.
- Currently `data_device.leave` is sent before `dnd_drop_performed`, though likely because the offer is destroyed upon `data_device.drop`, which probably can be moved to `dnd_drop_performed` handler instead.
- **Gnome Shell:**
- `data_source.dnd_drop_performed` always sent when drop happens "successfully" within a surface. Success requires the entered surface to accept the drag, which does not happen in [[#Gnome Shell 45#2b. Drag, detach and drop *outside* the detached window|2b]] and [[#Gnome Shell 45#2c. Drag, detach and drop *inside* a (non-chromium) window|2c]], for example. In those cases, `data_source.cancelled` should be used to detect drop.
- `data_device.leave` sent only after `data_source.dnd_drop_performed`
- **KWin:**
- `data_source.dnd_drop_performed` is sent always, **even** when the drop happens on desktop shell or other within client's surface (unlike in other compositors), for example , see [[#KWin#2b. Drag, detach and drop *outside* the detached window|2b]] and [[#KWin#2c. Drag, detach and drop *inside* a (non-chromium) window|2c]].
- `data_device.leave` sent before `data_source.dnd_finished` but always after `data_source.dnd_drop_performed`.
- **Sway:**
- `data_source.dnd_drop_performed` always sent when drop happens "successfully" within a surface, it is sent just after `data_device.drop`. Success requires the entered surface to accept the drag, similar to Gnome's behavior.
- `data_device.leave` sent only after `data_source.dnd_drop_performed`
### Keyboard events and cancellation
- **Exo:**
- No keyboard focus events when drag starts
- ESC cancels the drag session.
- When cancelling, focus change sometimes and `keyboard.key` release is sent for ESC, which triggered the cancellation. Eg: [[#Exosphere#6a. Drag, detach and cancel inside the detached window|6a]]. Not consistent across all cancellation scenarios, bug?
- `data_device.leave` preceding `data_source.cancelled` makes it difficult for clients to properly handle cancellation. How to differentiate a regular leave from a actual cancellation event sequence?
> [!bug]- Bug: Report to Exo [Reported]
>
> https://issues.chromium.org/329781395
- **Gnome Shell:**
- `keyboard.leave` is sent when starting the session, before `data_device.enter`
- ESC cancels the drag session.
- when dropping, `keyboard.enter` sent after `pointer.enter` for the same surface (when applicable). PS: Doesn't seem consistent, eg: happens in [[#Gnome Shell 45#1. Drag attached and drop|1]], [[#Gnome Shell 45#2c. Drag, detach and drop *inside* a (non-chromium) window|2c]], [[#Gnome Shell 45#3a. Drag single-tab window (without leaving it) and drop|3a]], for example, but not in other cases. When tabs are detached, its surface gains focus.
- `keyboard.key` release is sent for ESC, which triggered the cancellation. Similar to Exo, but differently it happens consistently in all cancellation scenarios.
- **KWin:**
- No keyboard focus change event when starting nor on drop for non-cancelled sessions.
- ESC cancels the drag session.
- Only in the specific case [[#KWin#5. Drag attached and cancel|5]], upon cancellation some keyboard focus/modifiers events get sent. Maybe a bug/edge case?
- `data_device.leave` preceding `data_source.cancelled` makes it difficult for clients to properly handle cancellation. How to differentiate a regular leave from a actual cancellation event sequence?
> [!bug]- Bug: Report to KWin [Fixed]
>
> Fixed at https://invent.kde.org/plasma/kwin/-/merge_requests/5738
- **Sway:**
- No keyboard focus events when drag starts
- ESC-triggered cancellation is not supported.
- when dropping, keyboard focus (+ `modifiers` event, if applicable) is updated just before pointer focus.
# Action Points
## Short-term fixes
1. Lacros is approaching an important milestone in ~1w, so we must be careful with changes which may cause more regressions. That said, in the short-term we will: ^436511
- Roll back the change that expanded the pointer events skipping, which is known to be the culprit for [lacros: canceling tab drag sometimes causes browser to become unresponsive](https://issuetracker.google.com/41497106). In practice, it implies in (partially) reverting [crrev.com/c/4996004](https://crrev.com/c/4996004)
- Status: Done
- Landed [crrev.com/1272780](https://chromium-review.googlesource.com/c/chromium/src/+/5370834)
2. Report and look into the [[#^3c20f2|drag cancellation bug]], where `data_device.leave` comes first, causing a quick "detach", which is probably causing races leading to the "unresponsiveness" observed, which actually is a `pointer.enter` skipping that keeps the drag session alive forever. This will already be mitigated by the change [[#^436511|above]].
- Status: WIP
- Filed https://issues.chromium.org/issues/329781395
## Follow-ups
Tracked under https://issues.chromium.org/issues/329479345
3. Move drop handling from `data_source.dnd_finished` to `data_source.dnd_drop_performed`
- When ext-drag is available, `dnd_drop_performed` is always sent for non-cancelled sessions. For cancelled sessions, logic must be in `data_source.cancelled` handler callback
- If not, `dnd_drop_performed` is sent when dropped within a chromium surface, otherwise there must be a code branch in `OnDragSourceFinish` handling drop as always successful, as it's impossible to detect real cancellation in this case (best-effort for Linux Desktop).
4. Stop ignoring pointer events during for window drag sessions (at least when ext-drag is available)
5. Remove focus assumptions from window drag controller. E.g: in [HandleDropAndResetState()](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc;l=595-597;drc=70e628cc669ddafe7f881f3e61dbc1edd67a4ee0)
- Currently, pointer/touch focus is 'temporarily' set the latest drag-entered window
- Original motivation for that was: make sure the MOUSE_RELEASED event is delivered to the target window
- At that point, a `pointer.enter` may have already been ignored, and we're basically assuming that the latest drag-entered window would be the one to gain focus after the drag session end.
6. If in the end, ignore drag events is still needed in any case, consider moving it to window drag controller, which already overrides event dispatcher in detached mode. These steps would be required to achieve it:
- Override dispatcher for the whole session and move its current implementation to a `if (state_ == kDetached)` branch block
- Make sure pointer/touch events contain a [source_device_id](https://source.chromium.org/chromium/chromium/src/+/main:ui/events/event.h;l=101-102;drc=f4a00cc248dd2dc8ec8759fb51620d47b5114090) and use it to distinguish them from those inject by itself when determining if it should be ignored or not. i.e: a real pointer/touch event would have `event->source_device_id() != ED_UNKNOWN_DEVICE)`;
7. Most of those edge cases and special conditions are there to ensure minimally functional UX on envs where ext-drag is not available. For example: assuming `data_source.dnd_finished|cancelled` is the only reliable way of detecting drag end (either drop or cancel), which leads to (1) being necessary as well as ignoring pointer events until it happens;
- So, probably it's time to factor out such code pieces into a specialized win drag controller class, so the current one can safely assume ext-drag, etc.
# Appendix: Inspecting major compositors behavior
Manually checking the current event flow for several use cases on different Wayland compositors to understand potential risks and regressions.
Running and collecting logs on Linux:
```shell
WAYLAND_DEBUG=client out/linux/chrome \
--enable-logging=stderr \
--ozone-platform=wayland \
--user-data-dir=/tmp/chr_devel 2>&1 | \
grep -e 'wl_pointer\|wl_data\|wl_keyboard\|extended_drag\|wayland_pointer'
```
As for Lacros:
1. Enable the following `os://flags`:
- \#lacros-only
- \#lacros-wayland-logging
2. Then, run:
```shell
tail -f /var/log/lacros/lacros.log | \
grep -e 'wl_pointer\|wl_data\|wl_keyboard\|extended_drag\|wayland_pointer'
```
PS:
- wl_pointer.frame events are omitted to minimize verbosity
- other unrelated events and log messages are omitted as well
## Exosphere
>[!info] Setup
> Ash: Version 121.0.6167.13 (Official Build) unknown (64-bit)
> Lacros: 121.0.6167.5 (Official Build) unknown-lacros (64-bit)
> Device: Atlas
### When starting
- pointer.leave just after start_drag
- data_device.offer/enter after pointer.leave
- no keyboard.leave when starting
```
[1127859.212]
[email protected](45281797, 384.10937500, 36.10156250)
[1127864.090] ->
[email protected]_data_source(new id wl_data_source@781)
[1127864.224] ->
[email protected]("chromium/x-window")
[1127864.344] ->
[email protected]_actions(2)
[1127864.481] ->
[email protected]_extended_drag_source(new id zcr_extended_drag_source_v1@859, wl_data_source@781, 7)
[1127864.585] ->
[email protected]_drag(wl_data_source@781, wl_surface@441, nil, 177)
[1127879.423]
[email protected](178, wl_surface@441)
[1127879.492]
[email protected]_offer(new id wl_data_offer@4278190088)
[1127879.524]
[email protected]("chromium/x-data-transfer-endpoint")
[1127897.843]
[email protected]_actions(2)
[1127897.870]
[email protected](4)
[1127897.894]
[email protected](179, wl_surface@441, 381.00000000, 35.00000000, wl_data_offer@4278190088)
[1127898.813]
[email protected](45281827, 379.00000000, 35.00000000)
[1127899.260]
[email protected](nil)
[1127899.319]
[email protected](0)
[1127899.348]
[email protected](45281829, 376.00000000, 35.00000000)
```
#### Origin window being dragged
There is a significant variation in drag start event flow, worth noting. When the origin window == dragged window (e.g: single-tab window being dragged):
Observations:
- No data_device.offer and enter events are received, probably because of [this](https://source.chromium.org/chromium/chromium/src/+/main:components/exo/extended_drag_source.cc;l=314-315;drc=90a7f277d1a71dbcf210180e06a3ddfdc0011ffc) 👀
- ⚠️ Side effects:
- when no window is drag-entered, such as in this case, when the drop happens there is no `pointer_grab_owner_` nor preceding pointer.enter (reliably) coming from the compositor, such that we can ensure the drop event will be properly dispatched to upper layer UI code at Lacros side.
- offer/enter pair of events can't be used as a "dnd actually started" marker.
- keyboard.enter before pointer.enter. keyboard.leave received when starting the session, reason is probably the same above.
```
[1429956.611]
[email protected](7884556, 64.19140625, 45.41796875)
[1429957.721] ->
[email protected]_data_source(new id wl_data_source@2659)
[1429957.766] ->
[email protected]("chromium/x-window")
[1429957.794] ->
[email protected]_actions(2)
[1429957.806] ->
[email protected]_extended_drag_source(new id zcr_extended_drag_source_v1@2349, wl_data_source@2659, 7)
[1429957.821] ->
[email protected]_drag(wl_data_source@2659, wl_surface@994, nil, 6415)
[1429959.821] ->
[email protected](wl_surface@994, 46, 29)
[1429960.063]
[email protected](6416, wl_surface@994)
[1429983.971]
[email protected]("")
[1429984.011]
[email protected](2)
```
### When dropping
#### 2. Drag attached and drop
Observations:
- data_device.drop received first
- then data_device.leave
- all drop and tear down data_source events come in before the pointer.enter 👀
- :warning: **NOTE:** The pointer.enter coming later than dnd_drop_performed|dnd_finished is sort of problematic if we want to rely on server events to handle focus on drop.
- no kbd events during drag
```
[2499575.559]
[email protected](46653514, 592.00000000, 38.00000000)
[2499658.498]
[email protected](46653597, 594.00000000, 38.00000000)
[2499867.732]
[email protected]()
[2499867.814] ->
[email protected]()
[2499867.832] ->
[email protected]()
[2499867.878]
[email protected]()
[2499868.385]
[email protected]("")
[2499868.471]
[email protected](2)
[2499868.506]
[email protected]_drop_performed()
[2499868.532]
[email protected]_finished()
[2499868.808] ->
[email protected]()
[2499868.842] ->
[email protected]()
[2500303.361]
[email protected](430, wl_surface@441, 559.64062500, 27.71484375)
[2500314.309]
[email protected](46654249, 532.35546875, 17.95312500)
```
#### 2a. Drag, detach and drop *inside* the detached window
Observations:
- data_device.drop and data_source.dnd_drop_performed received first
- Then data_device.leave
- And data_source target/action + dnd_drop_performed and dnd_finished
- Only after that, pointer.enter, etc. 👀
- No keyboard events.
```
[ 998330.614]
[email protected](49447236, 399.00000000, 186.00000000)
[ 998431.844]
[email protected]()
[ 998431.971] ->
[email protected]()
[ 998432.005] ->
[email protected]()
[ 998432.067]
[email protected]()
[ 998433.808]
[email protected]("")
[ 998433.907]
[email protected](2)
[ 998433.941]
[email protected]_drop_performed()
[ 998433.966]
[email protected]_finished()
[ 998434.252] ->
[email protected]()
[ 998434.281] ->
[email protected]()
[ 998434.307] ->
[email protected]_cursor_shape(wl_pointer@7, 0)
[ 999312.294]
[email protected](455, wl_surface@814, 342.91796875, 29.22265625)
[ 999312.337]
[email protected]()
[ 999312.929]
[email protected](49448217, 343.62109375, 29.59375000)
```
#### 3a. Drag single-tab window (without leaving it) and drop
Observations:
- data_device.drop is not received 👀
- data_source.dnd_drop_performed is received first
- then data_source.dnd_finished
- no data_device.leave before pointer.enter. Actually, no data_device.offer|enter events are received in this case. Also, keyboard.enter before pointer.enter. keyboard.leave received when starting the session. See [[#Origin window being dragged]] for more details.
```
[3174694.952]
[email protected]_drop_performed()
[3174694.968]
[email protected]_finished()
[3174695.118] ->
[email protected]()
[3174695.135] ->
[email protected]()
[3174695.319] ->
[email protected]_cursor_shape(wl_pointer@3, 9)
[3174708.564]
[email protected]_offer(new id wl_data_offer@4278190089)
[3174708.648]
[email protected]("text/plain;charset=utf-8")
...
[3174708.703]
[email protected](wl_data_offer@4278190089)
[3174708.714] ->
[email protected]()
[3174708.754]
[email protected](299, wl_surface@994, array[0])
[3174918.460] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
[3176212.848]
[email protected](300, wl_surface@994, 147.67578125, 29.26562500)
```
#### 4. Drag single-tab window, attach and drop
Observations:
- data_device.drop comes first
- then data_device.leave
- then data_source.dnd_drop_performed and dnd_finished
- only then pointer.enter, etc
```
[2036126.400]
[email protected](4195756, 394.00000000, 33.00000000)
[2036132.171]
[email protected]()
[2036132.338] ->
[email protected]()
[2036132.385] ->
[email protected]()
[2036132.447]
[email protected]()
[2036139.850]
[email protected]("")
[2036140.259]
[email protected](2)
[2036140.310]
[email protected]_drop_performed()
[2036140.334]
[email protected]_finished()
[2036140.551] ->
[email protected]()
[2036140.581] ->
[email protected]()
[2036354.601] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
[2037630.010]
[email protected](5016, wl_surface@994, 346.22265625, 41.70703125)
[2037638.225]
[email protected](4197270, 293.45312500, 53.00000000)
```
### When cancelling (ESC key)
#### 5. Drag attached and cancel
Observations:
- drag is cancelled: data_source.cancelled received
- though data_device.leave is the first one received.
- pointer.enter received only when mouse button is released
- consistent with what happens in Gnome Shell, for example.
- a trailing (?) pointer.button release received after pointer.enter 👀
- No keyboard event received.
>[!bug] Bug [Reported]
> Drive-by finding: Lacros is unexpectedly issuing 2 `extended_drag_source.drag` requests when handling dnd cancellation events flow, probably specifically when processing `wl_data_device.leave` which precedes the `wl_data_device.cancelled`.
>
> Update (2024/05/16): Filed and under discussion at https://issues.chromium.org/329781395
^3c20f2
```
[2860595.498]
[email protected](5020228, 215.00000000, 35.00000000)
[2861443.388]
[email protected]()
[2861443.429] ->
[email protected]()
[2861516.986] ->
[email protected](wl_surface@1750, -395, -56)
[2861517.615] ->
[email protected](wl_surface@1750, 180, 24)
[2861517.951]
[email protected]()
[2861518.025] ->
[email protected]()
[2861518.038] ->
[email protected]()
[2861518.143] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
...
[2866599.141]
[email protected](5135, wl_surface@994, 215.13281250, 35.41406250)
[2866599.158] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
[2866599.638]
[email protected](5136, 5026232, 272, 0)
[2871164.422]
[email protected](5030796, 212.94921875, 24.32031250)
```
#### 6a. Drag, detach and cancel inside the detached window
Observations:
- drag is cancelled: data_source.cancelled received
- though data_device.leave is received first
- pointer enters and leave quickly before mouse button is released. probably while the revert process is taking place at lacros side, ie: dragged surface being destroyed, etc.
- keyboard.key release received for ESC
- final pointer.enter is received only after mouse button is released
- a trailing (?) pointer.button release received after pointer.enter 👀
```
[3391402.279]
[email protected](5551035, 120.00000000, 260.00000000)
[3392615.200]
[email protected]()
[3392615.399] ->
[email protected]()
[3392617.671]
[email protected]()
[3392617.905] ->
[email protected]()
[3392617.937] ->
[email protected]()
[3392617.966] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
[3392657.567]
[email protected](5579, wl_surface@1338, 118.81250000, 158.01953125)
[3392657.664] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
[3392660.664]
[email protected](5581, wl_surface@1338)
[3392660.712]
[email protected](5582, wl_surface@994, array[4])
[3392661.058] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
[3392708.896]
[email protected](5583, nil)
[3392712.248]
[email protected](5584, 5552342, 1, 0)
[3392857.120] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
...
[3412794.883]
[email protected](5585, wl_surface@994, 120.90234375, 260.45703125)
[3412794.931] ->
[email protected]_cursor_shape(wl_pointer@3, 0)
[3412795.528]
[email protected](5586, 5572427, 272, 0)
[3415674.096]
[email protected](5575306, 100.31250000, 263.13281250)
```
#### 7a. Drag single-tab window and cancel
Observations:
- drag is cancelled: data_source.cancelled received
- final pointer.enter is received only after mouse button is released
- no data_device.leave before pointer.enter. Actually, no data_device.offer|enter events are received in this case. Also, keyboard.enter before pointer.enter. keyboard.leave received when starting the session. See [[#Origin window being dragged]] for more details.
- no keyboard.key event
- a trailing (?) pointer.button release received after pointer.enter 👀
```
[ 348726.796]
[email protected]()
[ 348727.535] ->
[email protected]()
[ 348727.748] ->
[email protected]()
[ 348728.016] ->
[email protected]_cursor_shape(wl_pointer@3, 2)
...
[ 350957.538]
[email protected](6386, wl_surface@994, 321.57031250, 103.75000000)
[ 350958.843]
[email protected](6387, 6805557, 272, 0)
[ 357568.575]
[email protected](6812168, 330.16015625, 27.73828125)
```
## Gnome Shell
>[!info] Setup
> Gnome Shell and Mutter 45.4-1
> Chrome 124.0.6326.0 developer build (head bc20e628a0b2)
> Arch Linux with kernel LTS 6.6.20 and nvidia-open-dkms 550.54.14-4
### When starting
- pointer.leave just after start_drag
- data_device.offer/enter after pointer.leave
- keyboard.leave when starting, after data_device.enter (why?)
```
[ 72340.904]
[email protected](86028537, 382.85156250, 31.34375000)
[ 72348.586]
[email protected](86028545, 374.13671875, 30.10156250)
[ 72350.879] ->
[email protected]_data_source(new id wl_data_source@43)
[ 72350.919] ->
[email protected]("chromium/x-window")
[ 72350.942] ->
[email protected]_actions(2)
[173280:173280:0312/204009.356530:ERROR:wayland_window_drag_controller.cc(156)] zcr_extended_drag_v1 extension not available! Window/Tab dragging won't be fully functional.
[ 72350.989] ->
[email protected]_drag(wl_data_source@43, wl_surface@25, nil, 117)
[ 72354.166]
[email protected](118, wl_surface@25)
[ 72354.180]
[email protected](nil)
[ 72354.206]
[email protected]_offer(new id wl_data_offer@4278190080)
[ 72354.212]
[email protected]("chromium/x-window")
[ 72354.217]
[email protected](0)
[ 72354.221]
[email protected](0)
[ 72354.225]
[email protected]_actions(2)
[ 72354.228]
[email protected](119, wl_surface@25, 374.13671875, 30.10156250, wl_data_offer@4278190080)
[ 72354.858] ->
[email protected]_actions(2, 2)
[ 72354.866] ->
[email protected](119, "chromium/x-window")
[ 72354.881]
[email protected](120, wl_surface@25)
[ 72355.151]
[email protected](2)
[ 72355.157]
[email protected](2)
[ 72355.160]
[email protected]("chromium/x-window")
[ 72365.404]
[email protected](86028553, 367.74609375, 30.10156250)
[ 72365.778]
[email protected](86028561, 362.20703125, 30.10156250)
```
### When dropping
#### 1. Drag attached and drop
Observations:
- data_device.drop and data_source.dnd_drop_performed received first
- data_device.leave and then pointer.enter
- pointer.enter (+ others) before data_source.dnd_finished
- :warning: **NOTE:** This one is currently ignored, though it does not cause bugs because we do [this](https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/host/wayland_window_drag_controller.cc;l=595-597;drc=70e628cc669ddafe7f881f3e61dbc1edd67a4ee0). So we're basically faking/assuming some focus changes at client-side. *This happens basically in all test cases where the drop happens inside any chromium window.*
- and then keyboard.enter
- no kbd events during drag
```
[1169020.702]
[email protected](188344759, 529.37109375, 39.79296875)
[1169032.061]
[email protected](188344767, 528.36718750, 40.79687500)
[1171930.996]
[email protected]()
[1171931.037] ->
[email protected]()
[1171931.041] ->
[email protected]()
[1171931.049]
[email protected]_drop_performed()
[1171931.051]
[email protected]()
[1171931.053]
[email protected](182382, wl_surface@25, 528.36718750, 40.79687500)
[1421359:1421359:0301/024029.406790:VERBOSE1:wayland_pointer.cc(81)] Ignoring enter event received during dnd session.
[1171931.061]
[email protected]()
[1171931.064]
[email protected](182383, wl_surface@25, array[0])
[1171931.074]
[email protected](182383, 0, 0, 0, 0)
[1171931.201]
[email protected]_finished()
[1171931.233] ->
[email protected]()
[1171932.390] discarded
[email protected]()
[1223079.961]
[email protected](188398818, 528.36718750, 39.91015625)
```
#### 2a. Drag, detach and drop *inside* the detached window
Observations:
- data_device.drop and data_source.dnd_drop_performed received first
- data_device.leave and then pointer.enter
- This event is ignored *(see explanation above)*
- no keyboard events during drag
- detached window receives keyboard.enter everytime it's created (probably a bug) :eyes:
- but no keyboard events other than keyboard.enter|modifiers
- probably related, no `wl_keyboard.enter` on the detached window upon drop
```
[2409171.376]
[email protected](189584909, 86.87890625, 210.60546875)
[2409197.917]
[email protected](189584925, 85.88671875, 210.60546875)
[2412523.430]
[email protected]()
[2412523.480] ->
[email protected]()
[2412523.484] ->
[email protected]()
[2412523.492]
[email protected]_drop_performed()
[2412523.502]
[email protected]()
[2412523.504]
[email protected](186523, wl_surface@56, 85.88671875, 210.60546875) <----- Ignored
[2412523.512]
[email protected]()
[2412523.653]
[email protected]_finished()
[2412523.683] ->
[email protected]()
[2412523.718] discarded
[email protected]()
[2412523.778] ->
[email protected]_cursor(186511, wl_surface@34, 3, 1)
```
#### 2b. Drag, detach and drop *outside* the detached window
Observations:
- no data_device.drop nor data_source.dnd_drop_performed
- no pointer.enter after data_device.leave
- no keyboard events during drag
- detached window receives keyboard.enter every time it's created (probably a bug) :eyes:
- but no keyboard events other than keyboard.enter|modifiers
- probably related, no keyboard.enter on the detached window upon drop
```
[3837316.720]
[email protected](191013054, 31.08203125, 333.01171875)
[3837324.701]
[email protected](191013062, 21.13671875, 333.01171875)
[3837333.715]
[email protected]()
[3837333.760] ->
[email protected]()
[3837333.772]
[email protected](nil)
...
[3841652.686]
[email protected]()
[3841652.729] ->
[email protected]()
[3841652.791] ->
[email protected]_cursor(189122, wl_surface@34, 3, 1)
```
#### 2c. Drag, detach and drop *inside* a (non-chromium) window
Observations:
- no data_device.drop nor data_source.dnd_drop_performed
- no pointer.enter after data_device.leave
- no keyboard events during drag
- detached window receives keyboard.enter everytime it's created (probably a bug) :eyes:
- but no keyboard events other than keyboard.enter|modifiers
```
[1053340.496]
[email protected]() <--- detached
[1053340.503] ->
[email protected]()
[1053340.509]
[email protected](nil)
[1053496.985]
[email protected](194121, wl_surface@39, array[0]) <--- detached window mapped
[1053496.993]
[email protected](194121, 0, 0, 0, 0)
[1055257.339]
[email protected](nil)
[1055257.377]
[email protected](0)
...
[1063852.792]
[email protected]() <--- dropped
[1063853.232] ->
[email protected]()
...
[1066016.128]
[email protected](194127, wl_surface@39)
```
#### 3a. Drag single-tab window (without leaving it) and drop
Observations:
- data_device.drop and data_source.dnd_drop_performed received first
- data_device.leave and then pointer.enter
- pointer.enter (+ others) before data_source.dnd_finished
- no keyboard events during drag
- detached window receives keyboard.enter everytime it's created (probably a bug) :eyes:
- but no key events other than enter and modifiers
- probably related, no keyboard.enter on the detached window upon drop
```
[2388074.697]
[email protected](198153747, 72.48046875, 38.04296875)
[2388093.159]
[email protected](198153755, 71.47656250, 39.04687500)
[2392723.029]
[email protected]()
[2392723.063] ->
[email protected]()
[2392723.070] ->
[email protected]()
[2392723.078]
[email protected]_drop_performed()
[2392723.089]
[email protected]()
[2392723.091]
[email protected](197002, wl_surface@25, 71.47656250, 39.04687500) <--- ignored!!
[2392723.099]
[email protected]()
[2392723.101]
[email protected](197003, wl_surface@25, array[0])
[2392723.111]
[email protected](197003, 0, 0, 0, 0)
[2392723.231]
[email protected]_finished()
[2392723.263] ->
[email protected]()
[2392723.280] discarded
[email protected]()
```
#### 3b. Drag single-tab window, leave and drop
Observations:
- Mostly behaves as expected
- keyboard.enter after dnd finished :eyes:
```
[1744657.361]
[email protected](197510330, 18.69921875, 41.07812500)
[1744665.429]
[email protected](197510338, 13.13281250, 41.07812500)
[1744674.491]
[email protected]()
[1744674.536] ->
[email protected]()
[1744674.543]
[email protected](nil)
[1752455.344]
[email protected]()
[1752455.414] ->
[email protected]()
[1752455.469]
[email protected](196018, wl_surface@25, array[0])
[1752455.480]
[email protected](196018, 0, 0, 0, 0)
```
#### 4. Drag single-tab window, attach and drop
Observations:
- data_device.drop and data_source.dnd_drop_performed received first
- data_device.leave and then pointer.enter
- pointer.enter (+ other potential pointer events) before data_source.dnd_finished
- no kbd events during drag
- detached window receives keyboard.enter everytime it's created (probably a bug)
- but no key events other than enter and modifiers
- probably related, no keyboard.enter on the detached window upon drop
```
[3394401.247]
[email protected](203455039, 776.60546875, 32.53125000)
[3394411.945]
[email protected](203455049, 777.64062500, 32.53125000)
[3394699.783]
[email protected]()
[3394699.818] ->
[email protected]()
[3394699.821] ->
[email protected]()
[3394699.830]
[email protected]_drop_performed()
[3394699.832]
[email protected]()
[3394699.834]
[email protected](212273, wl_surface@48, 777.64062500, 32.53125000)
[1635839:1635839:0301/040159.423551:VERBOSE1:wayland_pointer.cc(81)] Ignoring enter event received during dnd session.
[3394699.844]
[email protected]()
[3394699.863]
[email protected]_finished()
[3394699.877] ->
[email protected]()
[3394700.290] discarded
[email protected]()
[3394907.735] ->
[email protected]_cursor(212264, wl_surface@34, 3, 1)
[3395964.222]
[email protected](203456604, 777.64062500, 31.77734375)
```
### When cancelling (ESC key)
#### 5. Drag attached and cancel
Observations:
- drag is cancelled: data_source.cancelled received
- pointer.enter is sent only after the mouse button is released.
- keyboard.enter after data_device.leave
- pointer.enter only after mouse button is release :eyes:
```
[4147076.491]
[email protected](204207715, 671.80859375, 48.34765625)
[4147089.341]
[email protected](204207723, 672.85156250, 48.34765625)
[4147385.836]
[email protected]()
[4147385.881] ->
[email protected]()
[4147385.895] ->
[email protected]()
[4147386.666]
[email protected]()
[4147386.674]
[email protected](213367, wl_surface@25, array[4])
[4147386.682]
[email protected](213367, 0, 0, 0, 0)
[4147519.666]
[email protected](213368, 204208160, 1, 0)
...
[4170253.406]
[email protected](213369, wl_surface@25, 944.97656250, 275.34765625) <-- only when mouse button is released
```
#### 6a. Drag, detach and cancel inside the detached window
Observations:
- drag is cancelled: data_source.cancelled received
- data_device.leave and then pointer.enter
- pointer.enter is sent only after the mouse button is released. :eyes:
- detached window receives focus after cancel
- source client receives keyboard.key for esc
```
[ 764343.095]
[email protected](205119950, 137.74218750, 239.16406250)
[ 764350.802]
[email protected](205119958, 136.71093750, 240.19140625)
[ 765029.247]
[email protected]()
[ 765029.307] ->
[email protected]()
[ 765029.317] ->
[email protected]()
[ 765029.350]
[email protected]()
[ 765029.410] ->
[email protected]_cursor(216277, wl_surface@34, 3, 1)
[ 765029.713] ->
[email protected]_cursor(216277, wl_surface@34, 3, 1)
[ 765119.919]
[email protected](216290, 205120727, 1, 0)
```
#### 6b. Drag detach and cancel outside the detached window
Observations:
- drag is cancelled: data_source.cancelled received
- pointer.enter is sent only after the mouse button is released. :eyes:
- detached window receives focus after cancel
- source client receives keyboard.key for esc
```
[ 862942.761]
[email protected](205218550, 37.71093750, 283.48828125)
[ 862950.765]
[email protected](205218558, 18.94140625, 283.48828125)
[ 862960.231]
[email protected]()
[ 862960.270] ->
[email protected]()
[ 862960.280]
[email protected](nil)
[ 865171.802]
[email protected]()
[ 865171.882] ->
[email protected]()
[ 865172.005] ->
[email protected]_cursor(216689, wl_surface@34, 3, 1)
[ 865240.505]
[email protected](216700, 205220848, 1, 0)
...
[ 879941.840]
[email protected](217093, 205435549, 1, 0) <--- only when the mouse button is released
```
#### 7a. Drag single-tab window and cancel
Observations:
- drag is cancelled: data_source.cancelled received
- pointer.enter is sent only after the mouse button is released. :eyes:
- detached window receives focus after cancel
- source client receives keyboard.key for esc
```
[1069359.914]
[email protected](205424967, 437.74609375, 41.51562500)
[1079873.552]
[email protected]()
[1079873.595] ->
[email protected]()
[1079873.604] ->
[email protected]()
[1079873.622]
[email protected]()
[1079873.629]
[email protected](217092, wl_surface@25, array[4])
[1079873.638]
[email protected](217092, 0, 0, 0, 0)
[1079941.840]
[email protected](217093, 205435549, 1, 0)
...
[1085005.541]
[email protected](217094, wl_surface@25, 123.54296875, 10.72265625) <--- only when the mouse button is released
```
#### 7b. Drag single-tab window, leave and cancel
Observations:
- drag is cancelled: data_source.cancelled received
- pointer.enter is sent only after the mouse button is released. :eyes:
- detached window receives focus after cancel
- source client receives keyboard.key for esc
```
[1362502.449]
[email protected](205718110, 14.58593750, 38.90234375)
[1362511.757]
[email protected]()
[1362511.803] ->
[email protected]()
[1362511.814]
[email protected](nil)
[1364234.817]
[email protected]()
[1364234.880] ->
[email protected]()
[1364234.902]
[email protected](217895, wl_surface@25, array[4])
[1364234.911]
[email protected](217895, 0, 0, 0, 0)
[1364326.469]
[email protected](217896, 205719934, 1, 0)
```
## KWin
>[!info] Setup
> KWin 6.0.1
> Chrome 124.0.6326.0 developer build (head bc20e628a0b2)
> Arch Linux with kernel LTS 6.6.20 and nvidia-open-dkms 550.54.14-4
### When starting
- No pointer.leave before data_device.offer/enter 👀
- no keyboard.leave when starting 👀
```
[4081326.576]
[email protected](287368936, 416.45703125, 40.36328125)
[4081328.344] ->
[email protected]_data_source(new id wl_data_source@61)
[4081328.365] ->
[email protected]("chromium/x-window")
[4081328.377] ->
[email protected]_actions(2)
[176684:176684:0311/182034.086152:ERROR:wayland_window_drag_controller.cc(156)] zcr_extended_drag_v1 extension not available! Window/Tab dragging won't be fully functional.
[4081328.413] ->
[email protected]_drag(wl_data_source@61, wl_surface@29, nil, 3967)
[4081330.410]
[email protected]()
[4081330.474]
[email protected]("")
[4081330.488]
[email protected]_offer(new id wl_data_offer@4278190081)
[4081330.490]
[email protected]("chromium/x-window")
[4081330.492]
[email protected]_actions(2)
[4081330.494]
[email protected](3967, wl_surface@29, 416.45703125, 40.36328125, wl_data_offer@4278190081)
[4081330.773] ->
[email protected]_actions(2, 2)
[4081330.778] ->
[email protected](3967, "chromium/x-window")
[4081335.755]
[email protected](2)
[4081335.763]
[email protected](2)
[4081335.766]
[email protected]("chromium/x-window")
[4081335.768]
[email protected](287368944, 418.67578125, 40.36328125)
```
### When dropping
#### 1. Drag attached and drop
Observations:
- data_device.drop and data_source.dnd_drop_performed received first
- similar to Gnome Shell
- though, a pointer.button release is received before the data_device.drop, corresponding to the drop itself 👀
- pointer.leave + pointer.enter before data_source.dnd_finished 👀
- consistent with its behavior on start? ie: no pointer.leave is received before data_device.leave
- then data_source.dnd_finished
- ⚠️ After it, pointer events keep coming right away, assuming the previous pointer.enter was processed. Currently ignored in ozone/wayland.
```
[ 286395.728]
[email protected](287868970, 645.87890625, 33.59765625)
[ 288010.778]
[email protected](5356, 287870574, 272, 0)
[ 288012.306]
[email protected]()
[ 288012.323] ->
[email protected]()
[ 288012.328] ->
[email protected]()
[ 288012.340]
[email protected]_drop_performed()
[ 288012.377]
[email protected](5357, wl_surface@29)
[ 288012.386]
[email protected](5358, wl_surface@29, 645.87890625, 33.59765625)
[ 288012.658]
[email protected]_finished()
[ 288012.667] ->
[email protected]()
[ 288366.903]
[email protected](287870944, 646.76953125, 32.70703125)
[ 288367.202]
[email protected]()
[ 288370.906]
[email protected](287870948, 655.80468750, 21.86718750)
```
#### 2a. Drag, detach and drop *inside* the detached window
Observations:
- data_device.drop and data_source.dnd_drop_performed received first
- similar to Gnome Shell
- though, a pointer.button release is received before the data_device.drop, corresponding to the drop itself 👀
- pointer.leave + pointer.enter before data_source.dnd_finished 👀
- consistent with its behavior on start? ie: no pointer.leave is received before data_device.leave
- then data_source.dnd_finished
- ⚠️ After it, pointer events keep coming right away, assuming the previous pointer.enter was processed. Currently ignored in ozone/wayland.
```
[ 611134.053]
[email protected](667985, 309.66015625, 157.58593750)
[ 611929.504]
[email protected](1260, 668767, 272, 0)
[ 611929.863]
[email protected]()
[ 611929.870] ->
[email protected]()
[ 611929.873] ->
[email protected]()
[ 611929.883]
[email protected]_drop_performed()
[ 611929.907]
[email protected](1261, wl_surface@29)
[ 611929.912]
[email protected](1262, wl_surface@49, 309.66015625, 157.58593750)
[ 611929.963]
[email protected]_finished()
[ 611929.976] ->
[email protected]()
[ 615372.339]
[email protected](672223, 311.58593750, 154.37500000)
```
#### 2b. Drag, detach and drop *outside* the detached window
Observations:
- no data_device.drop, but data_source.dnd_drop_performed is received
- unlike to Gnome Shell, for example
- though, a pointer.button release is received before the data_source.dnd_drop_performed, corresponding to the drop itself 👀
- unlike all other tested compositors, data_source.target events (as well as pointer.frame events !!) keep coming in while dragging outside any toplevel surface, ie: over the desktop shell
- pointer.leave before data_source.dnd_finished 👀
- consistent with its behavior on start? ie: no pointer.leave is received before data_device.leave
- then data_source.dnd_finished
```
[1346009.865]
[email protected]()
[1346016.655]
[email protected]("chromium/x-window")
[1347550.696]
[email protected](3528, 1404383, 272, 0)
[1347551.694]
[email protected]_drop_performed()
[1347551.717]
[email protected](3529, wl_surface@29)
[1347551.724]
[email protected]()
[1347636.192]
[email protected]_finished()
[1347636.204] ->
[email protected]()
```
#### 2c. Drag, detach and drop *inside* a (non-chromium) window
- pointer.button release is received an in other scenarios above.
- data_source.dnd_drop_performed is received
- and then a data_device.leave.
- No data_source.finished nor cancelled received after that 👀
- :luc_check: I've checked and treating data_source.dnd_drop_performed the same as data_source.finished fixes the issue.
- Weirdly enough, pointer.frame keep flowing in even when the surface drag-entered belongs to a different wayland client.
> [!bug] Compositor bug [Fixed]
> Neither `data_source.cancelled` nor `dnd_finished` received for this case, so atm chrome ozone/wayland will become unresponsive after a session terminating like this.
>
> Update (2024/05/16):
> - Upstream bug at [482142 – drag in drop files in Google Chrome renders Chrome unusable](https://bugs.kde.org/show_bug.cgi?id=482142)
> - Fixed by [wayland: send dndFinished to source if target fails to do so (!5733) · Merge requests · Plasma / KWin · GitLab](https://invent.kde.org/plasma/kwin/-/merge_requests/5733)
```
[2016102.324]
[email protected]()
[2034235.862]
[email protected](5476, 2091068, 272, 0)
[2034236.515]
[email protected]_drop_performed()
[2034236.527]
[email protected](5477, wl_surface@29)
[2034236.536]
[email protected]()
```
#### 3a. Drag single-tab window (without leaving it) and drop
Observations:
- data_device.drop received first (along with its pointer.button release counterpart)
- followed by a data_source.dnd_drop_performed
- pointer.leave and a subsequent enter for the very same surface are received in a row
- and then data_source.dnd_finished
```
[3570435.522]
[email protected](3627286, 45.33593750, 251.58984375)
[3570560.644]
[email protected](10023, 3627398, 272, 0)
[3570562.049]
[email protected]()
[3570562.066] ->
[email protected]()
[3570562.071] ->
[email protected]()
[3570562.084]
[email protected]_drop_performed()
[3570562.087]
[email protected](10024, wl_surface@29)
[3570562.097]
[email protected](10025, wl_surface@29, 45.33593750, 251.58984375)
[3570562.243]
[email protected]_finished()
[3570562.249] ->
[email protected]()
[3581944.410]
[email protected](3638795, 44.49218750, 251.58984375)
```
#### 3b. Drag single-tab window, leave and drop
Observations:
- Mostly similar to 3a, except for:
- no data_device.drop. Seemingly sent only when the drop is "successful", which sounds compliant with the current spec. Gnome Shell also does not send it in this scenario.
- no pointer.enter before data_source.dnd_finished, as expected.
```
[3870083.416]
[email protected]()
[3870083.886]
[email protected]("chromium/x-window")
[3871192.328]
[email protected](10957, 3928031, 272, 0)
[3871193.090]
[email protected]_drop_performed()
[3871193.103]
[email protected](10958, wl_surface@29)
[3871193.109]
[email protected]()
[3871212.200]
[email protected]_finished()
[3871212.213] ->
[email protected]()
```
#### 4. Drag single-tab window, attach and drop
Observations:
- data_device.drop received first (along with its pointer.button release counterpart)
- followed by a data_source.dnd_drop_performed
- pointer.leave and a subsequent enter for the window where the tab was attached are received in a row, as expected.
- and then data_source.dnd_finished
```
[4180263.656]
[email protected](4237113, 646.12890625, 34.72265625)
[4180794.468]
[email protected](12330, 4237645, 272, 0)
[4180795.799]
[email protected]()
[4180795.820] ->
[email protected]()
[4180795.829] ->
[email protected]()
[4180795.843]
[email protected]_drop_performed()
[4180795.849]
[email protected](12331, wl_surface@29)
[4180795.858]
[email protected](12331, wl_surface@57, 646.12890625, 34.72265625)
[4180796.460]
[email protected]_finished()
[4180796.490] ->
[email protected]()
[4182490.356]
[email protected](4239341, 646.12890625, 36.41015625)
```
### When cancelling (ESC key)
#### 5. Drag attached and cancel
Observations:
- drag is cancelled.
- data_device.leave comes first 👀
- then data_source.action(0) + cancelled
- after that, pointer.leave
- pointer.enter is received only after mouse button is released as expected. Also consistent with what other compositors do.
- after data_source.cancelled, keyboard focus goes to the (wrongly) created surface, but no keyboard.key is received for ESC, for example.
> [!bug] Bug [Fixed]
> With this event sequence, Chrome ozone/wayland ends up creating a new browser window, in response to the first `data_device.leave` received, as at that point it's not possible to identify if it's a real leave or an upcoming cancellation. Seems like a compositor bug.
>
> Update (2024/05/16): Fixed by [wayland: Send dnd\_cancelled to source before data\_device.leave to target (!5738) · Merge requests · Plasma / KWin · GitLab](https://invent.kde.org/plasma/kwin/-/merge_requests/5738)
```
[ 73812.552]
[email protected](4425629, 659.25000000, 37.74218750)
[ 75956.539]
[email protected]()
[ 75956.564] ->
[email protected]()
[ 76029.945]
[email protected](0)
[ 76029.954]
[email protected]()
[ 76029.958] ->
[email protected]()
[ 76029.965]
[email protected](12852, wl_surface@57)
[ 76029.968]
[email protected]()
[ 76108.724] ->
[email protected]_cursor(12842, nil, 0, 0)
[ 76119.129] ->
[email protected]_cursor(12842, nil, 0, 0)
[ 76128.795]
[email protected](12855, wl_surface@57)
[ 76128.805]
[email protected](12857, wl_surface@47, array[4])
[ 76128.811]
[email protected](12843, 0, 0, 0, 0)
[ 76128.818]
[email protected](nil)
...
[ 84207.955]
[email protected](12862, wl_surface@57, 659.25000000, 37.74218750)
[ 84208.874]
[email protected](12863, 0, 0, 0, 0)
[ 87476.119]
[email protected](4439294, 660.08593750, 36.90625000)
```
#### 6a. Drag, detach and cancel inside the detached window
Observations:
- drag is cancelled.
- data_device.leave comes first (no data_device.drop)
- no data_source.dnd_drop_performed
- and then data_source.cancelled
- pointer.enter is received only after mouse button is released as expected. Also consistent with what other compositors do.
```
[1331132.361]
[email protected](5682951, 927.42578125, 261.34765625)
[1331586.738]
[email protected]()
[1331586.773] ->
[email protected]()
[1331586.793]
[email protected](0)
[1331586.823]
[email protected]()
[1331586.829] ->
[email protected]()
[1331586.849]
[email protected](17149, wl_surface@57)
...
[1336168.950]
[email protected](17151, wl_surface@44, 927.42578125, 261.34765625)
[1343325.481]
[email protected](5695143, 920.05859375, 258.58593750)
```
#### 6b. Drag detach and cancel outside the detached window
Observations:
- drag is cancelled
- data_source.action(0) and then data_source.cancelled come in
- followed by a data_device.leave
```
[1538666.988]
[email protected]()
[1538667.900]
[email protected]("chromium/x-window")
[1539433.196]
[email protected](0)
[1539433.224]
[email protected]()
[1539433.229] ->
[email protected]()
[1539433.242]
[email protected](17863, wl_surface@57)
```
#### 7a. Drag single-tab window and cancel
Observations:
- data_device.leave comes first
- followed by data_source.action(0) + cancelled sequence
- and then a pointer.leave
- pointer.enter is received only after mouse button is released as expected. Also consistent with what other compositors do.
```
[1704687.227]
[email protected](6056505, 558.58203125, 29.10546875)
[1705213.528]
[email protected]()
[1705213.548] ->
[email protected]()
[1705213.558]
[email protected](0)
[1705213.561]
[email protected]()
[1705213.564] ->
[email protected]()
[1705213.576]
[email protected](18591, wl_surface@57)
...
[1710529.206]
[email protected](18593, wl_surface@57, 558.58203125, 29.10546875)
[1711803.078]
[email protected](6063621, 559.43359375, 26.55468750)
```
#### 7b. Drag single-tab window, leave and cancel
Observations:
- followed by data_source.action(0) + cancelled sequence
- and then a pointer.leave
```
[1959997.035]
[email protected]("chromium/x-window")
[1963840.931]
[email protected](0)
[1963840.948]
[email protected]()
[1963840.954] ->
[email protected]()
[1963840.969]
[email protected](19184, wl_surface@57)
[1963840.972]
[email protected]()
```
## Sway
>[!info] Setup
> Sway 1.9-1 / wlroots 0.17.1-1
> Chrome 124.0.6326.0 developer build (head bc20e628a0b2)
> Arch Linux with kernel LTS 6.6.20 and nvidia-open-dkms 550.54.14-4
### When starting
Observations:
- pointer.leave when starting, just before data_device.offer+enter
- no keyboard focus change events
```
[1173026.192]
[email protected](78539288, 363.81250000, 28.53906250)
[1173026.991]
[email protected](78539288, 367.54687500, 28.53906250)
[1173028.229] ->
[email protected]_data_source(new id wl_data_source@47)
[1173028.244] ->
[email protected]("chromium/x-window")
[1173028.259] ->
[email protected]_actions(2)
[149978:149978:0312/183520.099252:ERROR:wayland_window_drag_controller.cc(156)] zcr_extended_drag_v1 extension not available! Window/Tab dragging won't be fully functional.
[1173028.301] ->
[email protected]_drag(wl_data_source@47, wl_surface@8, nil, 135)
[1173031.093]
[email protected](136, wl_surface@8)
[1173031.104]
[email protected]_offer(new id wl_data_offer@4278190080)
[1173031.109]
[email protected]("chromium/x-window")
[1173031.114]
[email protected]_actions(2)
[1173031.118]
[email protected](137, wl_surface@8, 367.54687500, 28.53906250, wl_data_offer@4278190080)
[1173031.698] ->
[email protected]_actions(2, 2)
[1173031.707] ->
[email protected](137, "chromium/x-window")
[1173031.721]
[email protected](0, 367.54687500, 28.53906250)
[1173032.822]
[email protected](2)
[1173032.831]
[email protected](2)
[1173032.835]
[email protected]("chromium/x-window")
[1173044.559]
[email protected](78539298, 367.42578125, 28.53906250)
```
### When dropping
#### 1. Drag attached and drop
Observations:
- data_device.drop comes first
- followed by data_source.dnd_drop_performed and data_device.leave
- keyboard.leave + enter (+ modifiers) for the same surface
- then data_source.dnd_finished, and only then a pointer.enter
```
[1175060.042]
[email protected](78541320, 688.63281250, 21.81640625)
[1175066.683]
[email protected]()
[1175066.707] ->
[email protected]()
[1175066.713] ->
[email protected]()
[1175066.727]
[email protected]_drop_performed()
[1175066.769]
[email protected]()
[1175066.774]
[email protected](138, wl_surface@8)
[1175066.819]
[email protected](140, wl_surface@8, array[0])
[1175066.833]
[email protected](141, 0, 0, 0, 0)
[1175067.428]
[email protected]_finished()
[1175067.433] ->
[email protected]()
[1175068.690] discarded
[email protected]()
[1175515.003]
[email protected](142, wl_surface@8, 688.63281250, 22.98046875)
[1175516.087]
[email protected](78541776, 688.63281250, 23.30468750)
```
#### 2a. Drag, detach and drop *inside* the detached window
Observations:
- data_device.drop comes first
- followed by data_source.dnd_drop_performed and data_device.leave
- keyboard.leave + enter (+ modifiers) for the same surface
- then data_source.dnd_finished
- ⚠️ pointer.enter comes in only when a new mouse interaction happens, eg: in this case a button click. Seems like a Sway (minor) bug
```
[2347520.738]
[email protected](79713782, 111.35937500, 212.10156250)
[2348762.889]
[email protected]()
[2348762.959] ->
[email protected]()
[2348762.978] ->
[email protected]()
[2348763.028]
[email protected]_drop_performed()
[2348763.038]
[email protected]()
[2348763.051]
[email protected](185, wl_surface@36)
[2348763.113]
[email protected](187, wl_surface@51, array[0])
[2348763.160]
[email protected](188, 0, 0, 0, 0)
[2348763.189]
[email protected](nil)
[2348765.232]
[email protected]_finished()
[2348765.249] ->
[email protected]()
[2348765.282] discarded
[email protected]()
...
[2376549.710]
[email protected](189, wl_surface@51, 111.35937500, 212.10156250)
[2376550.774]
[email protected](190, 79742811, 273, 1)
```
#### 2b. Drag, detach and drop *outside* the detached window
Observations:
- no data_device.drop, no data_source.dnd_drop_performed (as expected)
- when starting the "drop" process, keyboard focus change to the newly detached window.
- data_source.selection(null) before data_source.cancelled (comes in other scenarios as well) 👀
```
[3557449.718]
[email protected](80923712, 664.57421875, 340.46484375)
[3557450.347]
[email protected]()
[3557450.353] ->
[email protected]()
..
[3558843.677]
[email protected](415, wl_surface@51) <--- drop happens here
[3558843.717]
[email protected](417, wl_surface@73, array[0])
[3558843.729]
[email protected](418, 0, 0, 0, 0)
[3558843.736]
[email protected](nil)
[3558843.758]
[email protected]()
[3558843.763] ->
[email protected]()
```
#### 2c. Drag, detach and drop *inside* a (non-chromium) window
Observations:
- same as [[#Sway#2b. Drag, detach and drop *outside* the detached window|2b]], though keyboard focus is just unset (as expected)
```
[3972937.798]
[email protected](81339200, 16.63281250, 253.56640625)
[3972943.482]
[email protected](81339206, 16.41406250, 253.56640625)
[3972943.725]
[email protected]()
[3972943.733] ->
[email protected]()
[3972943.748]
[email protected](0)
...
[3982304.537]
[email protected](703, wl_surface@73) <---- drop starts here
[3982304.652]
[email protected]()
[3982304.672] ->
[email protected]()
```
#### 3a. Drag single-tab window (without leaving it) and drop
Observations:
- data_device.drop comes first
- followed by data_source.dnd_drop_performed and data_device.leave
- keyboard.leave + enter (+ modifiers) for the same surface
- then data_source.dnd_finished, and only then a pointer.enter
- basically the same as [[#Sway#1. Drag attached and drop|1]]
```
[4100165.277]
[email protected](81466427, 185.08984375, 160.14843750)
[4100165.540]
[email protected](81466427, 185.08984375, 160.82421875)
[4100239.520]
[email protected]()
[4100239.562] ->
[email protected]()
[4100239.572] ->
[email protected]()
[4100239.597]
[email protected]_drop_performed()
[4100239.603]
[email protected]()
[4100239.609]
[email protected](777, wl_surface@73)
[4100239.641]
[email protected](779, wl_surface@73, array[0])
[4100239.662]
[email protected](780, 0, 0, 0, 0)
[4100239.676]
[email protected](nil)
[4100241.052]
[email protected]_finished()
[4100241.065] ->
[email protected]()
[4100241.088] discarded
[email protected]()
...
[4112452.370]
[email protected](781, wl_surface@73, 184.46875000, 160.76953125)
[4112453.177]
[email protected]()
[4112453.197]
[email protected](81478714, 183.84765625, 161.39062500)
```
#### 3b. Drag single-tab window, leave and drop
Observations:
- same as [[#Sway#2b. Drag, detach and drop *outside* the detached window|2b]]
```
[ 42957.174]
[email protected](81704187, 15.63671875, 75.99218750)
[ 42957.434]
[email protected]()
[ 42957.444] ->
[email protected]()
...
[ 45694.094]
[email protected](789, wl_surface@73) <---- drop starts here
[ 45694.181]
[email protected](791, wl_surface@73, array[0])
[ 45694.205]
[email protected](792, 0, 0, 0, 0)
[ 45694.222]
[email protected](nil)
[ 45694.268]
[email protected]()
[ 45694.280] ->
[email protected]()
```
#### 4. Drag single-tab window, attach and drop
Observations:
- data_device.drop comes first
- followed by data_source.dnd_drop_performed and data_device.leave
- keyboard.leave + enter (+ modifiers) for the same surface
- then data_source.dnd_finished, and only then a pointer.enter
- basically the same as [[#Sway#2a. Drag, detach and drop *inside* the detached window|2a]]
```
[ 197432.368]
[email protected](81858661, 190.33984375, 40.12109375)
[ 200905.554]
[email protected]()
[ 200905.573] ->
[email protected]()
[ 200905.577] ->
[email protected]()
[ 200905.587]
[email protected]_drop_performed()
[ 200905.589]
[email protected]()
[ 200905.591]
[email protected](822, wl_surface@60)
[ 200905.595]
[email protected](824, wl_surface@73, array[0])
[ 200905.606]
[email protected](825, 0, 0, 0, 0)
[ 200905.612]
[email protected](nil)
[ 200905.943]
[email protected]_finished()
[ 200905.946] ->
[email protected]()
[ 200906.321] discarded
[email protected]()
...
[ 202630.364]
[email protected](826, wl_surface@73, 190.33984375, 38.32031250)
[ 202632.476]
[email protected](81863859, 190.33984375, 35.65625000)
```
### When cancelling (ESC key)
All the cancellation test cases are no-op. ESC key press does not cancel the drag session on Sway.