data_offer.set_actions(0, 0) does not result in data_offer.action(0), but data_offer.finish() causes protocol error
The following is a simplified log of Wayland events from a DnD session initiated by Chromium, with Chromium also being the client receiving the drag. The compositor is Sway 1.9. (You can find the full log at https://pastebin.com/bUeubzYY, but note that it contains some additional debug logging from Chromium.)
[ 303555.426] -> wl_data_device_manager@11.create_data_source(new id wl_data_source@68)
[ 303555.450] -> wl_data_source@68.offer("chromium/x-window-drag")
[ 303555.461] -> wl_data_source@68.set_actions(2)
...
[ 303555.515] -> wl_data_device@29.start_drag(wl_data_source@68, wl_surface@52, wl_surface@69, 54633)
...
[ 304768.838] wl_data_device@29.data_offer(new id wl_data_offer@4278190081)
[ 304768.843] wl_data_offer@4278190081.offer("chromium/x-window-drag")
[ 304768.849] wl_data_source@68.action(0)
[ 304768.852] wl_data_offer@4278190081.action(0)
[ 304768.855] wl_data_offer@4278190081.source_actions(2)
[ 304768.858] wl_data_device@29.enter(54639, wl_surface@37, 348.60546875, 163.28906250, wl_data_offer@4278190081)
[ 304768.866] -> wl_data_offer@4278190081.accept(54639, "chromium/x-window-drag")
[ 304769.961] -> wl_data_offer@4278190081.set_actions(0, 0)
[ 304769.980] wl_data_device@29.motion(23831844, 348.60546875, 163.28906250)
[ 304770.078] -> wl_data_offer@4278190081.set_actions(0, 0)
[ 304770.087] wl_data_device@29.motion(23831844, 348.60546875, 163.28906250)
[ 304770.175] -> wl_data_offer@4278190081.set_actions(0, 0)
...
[ 304786.595] wl_data_device@29.motion(23832164, 349.94140625, 50.48437500)
[ 304786.677] -> wl_data_offer@4278190081.set_actions(0, 0)
[ 304786.681] wl_data_device@29.motion(23832171, 349.94140625, 49.48437500)
[ 304856.575] -> wl_data_offer@4278190081.set_actions(2, 2)
[ 304856.586] wl_data_device@29.motion(23832181, 349.94140625, 48.48437500)
[ 304857.362] -> wl_data_offer@4278190081.set_actions(2, 2)
[ 304857.370] wl_data_device@29.motion(23832187, 349.94140625, 46.48437500)
[ 304858.114] -> wl_data_offer@4278190081.set_actions(2, 2)
...
[ 304859.104] wl_data_source@68.target("chromium/x-window-drag")
[ 304859.108] wl_data_device@29.motion(23832201, 349.94140625, 44.48437500)
[ 304859.848] -> wl_data_offer@4278190081.set_actions(2, 2)
[ 304859.855] wl_data_device@29.motion(23832211, 350.94140625, 43.48437500)
[ 304860.602] -> wl_data_offer@4278190081.set_actions(2, 2)
[ 304860.609] wl_data_device@29.motion(23832217, 350.94140625, 42.48437500)
[ 304861.323] -> wl_data_offer@4278190081.set_actions(2, 2)
...
[ 304865.666] wl_data_device@29.motion(23832284, 352.94140625, 35.55859375)
[ 304866.412] -> wl_data_offer@4278190081.set_actions(2, 2)
[ 304866.641] wl_data_source@68.action(2)
[ 304866.651] wl_data_offer@4278190081.action(2)
...
[ 304997.640] wl_data_device@29.motion(23832427, 353.94140625, 51.30468750)
[ 305380.210] -> wl_data_offer@4278190081.set_actions(0, 0)
[ 305381.740] wl_data_device@29.motion(23832434, 355.35156250, 56.94921875)
[ 305381.922] -> wl_data_offer@4278190081.set_actions(0, 0)
[ 305381.929] wl_data_device@29.motion(23832441, 355.35156250, 63.48046875)
[ 305382.043] -> wl_data_offer@4278190081.set_actions(0, 0)
[ 305382.048] wl_data_device@29.motion(23832451, 355.35156250, 69.69531250)
[ 305382.151] -> wl_data_offer@4278190081.set_actions(0, 0)
...
[ 305383.289] wl_data_device@29.drop()
[ 305383.408] -> wl_data_offer@4278190081.finish()
[ 305383.414] -> wl_data_offer@4278190081.destroy()
[ 305383.422] wl_data_source@68.dnd_drop_performed()
...
[ 305404.094] discarded [unknown]@-16777215.[event 2](0 fd, 12 byte)
[408084:408084:0620/173556.870873:ERROR:wayland_event_watcher.cc(43)] libwayland: unknown object (4278190081), message error(ous)
I find the following aspects surprising:
- It takes quite some time for the compositor to send
wl_data_source.action(2)
andwl_data_offer.action(2)
after the client has switched from sendingwl_data_offer.set_actions(0, 0)
towl_data_offer.set_actions(2, 2)
. - Even though the client switches back to sending
wl_data_offer.set_actions(0, 0)
, the compositor never sendswl_data_source.action(0)
orwl_data_offer.action(0)
. - The
wl_data_offer.finish()
call leads to a protocol error. (I've confirmed this by skipping it if the lastwl_data_offer.set_actions()
call set the action to 0.)
Note that aspects (2) and (3) also happen with GNOME 46.2 and weston 13.0.1. (I haven't checked aspect (1) with other compositors than Sway.)
It seems to me all three compositors I have tested this with consider the final action to be 0 / none
, even though never communicating that to the client via a new action()
event. That then leads to the protocol error because the spec for wl_data_offer.finish()
says:
It is also an error to perform this request after a NULL mime type has been set in wl_data_offer.accept or no action was received through wl_data_offer.action.
Can it really be that three compositors are not spec-compliant? Am I missing something? Should we maybe change the spec to read
It is also an error to perform this request after a NULL mime type has been set in wl_data_offer.accept, no action was received through wl_data_offer.action, or set_actions was called with no action.
?