`new_surface` and related events have inconsistent semantics
wlroots' shell implementations have a new_surface
events which are used to notify a compositor about new surface role objects. Contrary to what the name means, the event sometimes is delayed until some additional specific conditions apply:
-
For
wlr_xdg_shell
andwlr_layer_shell_v1
, the event is only emitted after the client has performed an initial commit. Before that, a compositor has no control over the surface or wlroots behavior regarding that surface.For
wlr_xdg_shell
specifically, this means:- A configure is always scheduled, meaning that if a compositor wants to request some specific configuration, it has to do it while in a
new_surface
handler. - A compositor has no way to handle state requests for
xdg_toplevel
objects directly. Currently, this problem is "solved" by storing the requested states inwlr_xdg_toplevel.requested
, but the order of requested states isn't preserved which means a compositor can't differentiate between e.g.xdg_toplevel.set_maximized; xdg_toplevel.set_fullscreen
andxdg_toplevel.set_fullscreen; xdg_toplevel.set_maximized
request sequences sent before the initial commit.
- A configure is always scheduled, meaning that if a compositor wants to request some specific configuration, it has to do it while in a
-
For
wlr_xwayland
,new_surface
has been recently (!4050 (merged)) updated to be emitted only after a X11 window and awl_surface
have been associated with each other. This has revealed to be erroneous, similarly to thexdg_toplevel
state requests problem mentioned above. -
As
wlr_session_lock_v1
doesn't require additional setup on the protocol level, itsnew_surface
event is emitted immediately upon receiving the corresponding request from the client.
There are also several related events:
-
wlr_xdg_surface.events.new_popup
, which is emitted when axdg_surface.get_popup
request is received, i.e. beforewlr_xdg_shell.events.new_surface
, which one may find to be counterintuitive. -
wlr_layer_surface_v1.events.new_popup
, which is emitted when azwlr_layer_surface_v1.get_popup
request is received. Similar to above. -
wlr_surface.events.new_subsurface
, which is delayed until the parent surface commit.
Proposal
Update all new_*
events to do exactly what it says on the tin and be emitted right when a corresponding Wayland object is created.
- For
wlr_xdg_shell
, I also propose addingnew_toplevel
andnew_popup
(?) events, emitted when you'd expect them to be,as well aswlr_xdg_surface.events.initial_commit
, which would allow to properly handle surface remapping as well.-
wlr_xdg_shell.events.new_surface
would become less useful. Custom role (such asxdg_pip
orxdg_splash
) implementations might or might not need it, but for now it's not really relevant aswlr_xdg_surface_role
is a closed enum. -
wlr_xdg_surface.events.new_popup
would be emitted immediately afterwlr_xdg_shell.events.new_popup
, should the latter be added.
-
Forwlr_layer_shell_v1
,wlr_layer_surface_v1.events.initial_commit
would be introduced as well.- For
wlr_xwayland
, see !4053 (merged). - For
wlr_subcompositor
,wlr_surface.events.new_subsurface
would be emitted onwl_subcompositor.get_subsurface
as it was before 0fcc8422.- Maybe introduce
wlr_subcompositor.events.new_subsurface
for Consistency™.
- Maybe introduce
For wlr_xdg_shell
and wlr_layer_shell_v1
, initial_commit
state fields would be introduced to mark which commits should be responded to with a configure event.
This approach adds some more complexity on the compositor side, for example:
- For
xdg_toplevel
objects, a compositor would have to listen towlr_xdg_shell.events.new_toplevel
, then towlr_surface.events.commit
, send a configure, and wait for the surface to become mapped. - For Xwayland surfaces, a compositor would have to listen to
wlr_xwayland.events.new_surface
, then towlr_xwayland_surface.events.associate
, and wait for the to become mapped.For convenience,wlr_xwayland_surface.events.{map,unmap}
can be preserved, as proposed on IRC.
However, I believe such change is still worth it as it allows for more correct and flexible compositor implementations.