Shell surface
In order for our surface to be displayed on the screen, we need to assign it a role. There is no uniform mechanism for assigning roles in Wayland; each role has its own way to assign it to a surface. For example, to give a surface the role of a cursor, we use wl_pointer.set_cursor
request, passing the surface as an argument.
For some other roles it's more complicated because those roles come with some additional functionality that needs to be implemented should a surface take that role. The role we're going to use in order to make a surface into a desktop-style window is shell surface.
One way to think about it is to imagine that shell surface is a subclass of surface that has additional functionality implemented on it. This subclassing is done in a somewhat interesting way: you call additional methods on a new object of type wl_shell_surface
. You create that object with wl_shell.get_shell_surface
request, which gives the surface the role of a shell surface.
Another way to think about it is that the surface (that has the role of a shell surface) and its shell surface are indeed two different objects, two distinct, but related, entities. The shell surface, in this case, represents a window, and the surface is responsible for its content.
wl_shell_surface
has a lot of functionality, like handling resizes, but we won't go into detail about it. That's because wl_shell
and wl_shell_surface
are deprecated and superseded by xdg_sell protocol extension. The only reason we're using wl_shell_surface
here is because we want to stick to core Wayland protocol for now.
Put this into the code before attaching the buffer:
struct wl_shell_surface *shell_surface = wl_shell_get_shell_surface(shell, surface);
wl_shell_surface_set_toplevel(shell_surface);