Application windows
We have shaved many yaks to get here, but it's time: XDG toplevel is the interface which we will finally use to display an application window. The XDG toplevel interface has many requests and events for managing application windows, including dealing with minimized and maximized states, setting window titles, and so on. We'll be discussing each part of it in detail in future chapters, so let's just concern ourselves with the basics now.
Based on our knowledge from the last chapter, we know that we can obtain an
xdg_surface from a wl_surface, but that it only constitutes the first step:
bringing a surface into the fold of XDG shell. The next step is to turn that XDG
surface into an XDG toplevel — a "top-level" application window, so named
for its top-level position in the hierarchy of windows and popup menus we will
eventually create with XDG shell. To create one of these, we can use the
appropriate request from the xdg_surface interface:
<request name="get_toplevel">
  <arg name="id" type="new_id" interface="xdg_toplevel"/>
</request>
This new xdg_toplevel interface puts many requests and events at our disposal
for managing the lifecycle of application windows. Chapter 10 explores these in
depth, but I know you're itching to get something on-screen. If you follow these
steps, handling the configure and ack_configure riggings for XDG surface
discussed in the previous chapter, and attach and commit a wl_buffer to our
wl_surface, an application window will appear and present your buffer's
contents to the user. Example code which does just this is provided in the next
chapter. It also leverages one additional XDG toplevel request which we haven't
covered yet:
<request name="set_title">
  <arg name="title" type="string"/>
</request>
This should be fairly self-explanatory. There's a similar one that we don't use in the example code, but which may be appropriate for your application:
<request name="set_app_id">
  <arg name="app_id" type="string"/>
</request>
The title is often shown in window decorations, taskbars, etc, whereas the app ID is used to identify your application or group your windows together. You might utilize these by setting your window title to "Application windows — The Wayland Protocol — Firefox", and your app ID to "firefox".
In summary, the following steps will take you from zero to a window on-screen:
- Bind to 
wl_compositorand use it to create awl_surface. - Bind to 
xdg_wm_baseand use it to create anxdg_surfacewith yourwl_surface. - Create an 
xdg_toplevelfrom thexdg_surfacewithxdg_surface.get_toplevel. - Configure a listener for the 
xdg_surfaceand await theconfigureevent. - Bind to the buffer allocation mechanism of your choosing (such as 
wl_shm) and allocate a shared buffer, then render your content to it. - Use 
wl_surface.attachto attach thewl_bufferto thewl_surface. - Use 
xdg_surface.ack_configure, passing it the serial fromconfigure, acknowledging that you have prepared a suitable frame. - Send a 
wl_surface.commitrequest. 
Turn the page to see these steps in action.