xdg-shell: Replace the set_* atrocity with a new approach
authorJasper St. Pierre <jstpierre@mecheye.net>
Sat, 8 Feb 2014 23:29:49 +0000 (18:29 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 19 Feb 2014 17:50:40 +0000 (09:50 -0800)
Rather than require that the client implement two methods for every state,
simply have one global request, change_state, and one global event,
request_change_state.

clients/simple-egl.c
clients/simple-shm.c
clients/window.c
desktop-shell/shell.c
protocol/xdg-shell.xml

index b00b2cc..675662f 100644 (file)
@@ -95,7 +95,7 @@ struct window {
        struct xdg_surface *xdg_surface;
        EGLSurface egl_surface;
        struct wl_callback *callback;
-       int fullscreen, configured, opaque, buffer_size, frame_sync;
+       int fullscreen, opaque, buffer_size, frame_sync;
 };
 
 static const char *vert_shader_text =
@@ -281,23 +281,25 @@ handle_surface_configure(void *data, struct xdg_surface *surface,
 }
 
 static void
-handle_surface_request_set_maximized(void *data, struct xdg_surface *xdg_surface)
+handle_surface_change_state(void *data, struct xdg_surface *xdg_surface,
+                           uint32_t state,
+                           uint32_t value,
+                           uint32_t serial)
 {
-}
+       struct window *window = data;
 
-static void
-handle_surface_request_unset_maximized(void *data, struct xdg_surface *xdg_surface)
-{
-}
+       switch (state) {
+       case XDG_SURFACE_STATE_FULLSCREEN:
+               window->fullscreen = value;
 
-static void
-handle_surface_request_set_fullscreen(void *data, struct xdg_surface *xdg_surface)
-{
-}
+               if (!value)
+                       handle_surface_configure(window, window->xdg_surface,
+                                                window->window_size.width,
+                                                window->window_size.height);
+               break;
+       }
 
-static void
-handle_surface_request_unset_fullscreen(void *data, struct xdg_surface *xdg_surface)
-{
+       xdg_surface_ack_change_state(xdg_surface, state, value, serial);
 }
 
 static void
@@ -318,54 +320,13 @@ handle_surface_delete(void *data, struct xdg_surface *xdg_surface)
 
 static const struct xdg_surface_listener xdg_surface_listener = {
        handle_surface_configure,
-       handle_surface_request_set_maximized,
-       handle_surface_request_unset_maximized,
-       handle_surface_request_set_fullscreen,
-       handle_surface_request_unset_fullscreen,
+       handle_surface_change_state,
        handle_surface_activated,
        handle_surface_deactivated,
        handle_surface_delete,
 };
 
 static void
-configure_callback(void *data, struct wl_callback *callback, uint32_t  time)
-{
-       struct window *window = data;
-
-       wl_callback_destroy(callback);
-
-       window->configured = 1;
-}
-
-static struct wl_callback_listener configure_callback_listener = {
-       configure_callback,
-};
-
-static void
-set_fullscreen(struct window *window, int fullscreen)
-{
-       struct wl_callback *callback;
-
-       window->fullscreen = fullscreen;
-       window->configured = 0;
-
-       if (fullscreen) {
-               xdg_surface_set_fullscreen(window->xdg_surface);
-               callback = wl_display_sync(window->display->display);
-               wl_callback_add_listener(callback,
-                                        &configure_callback_listener,
-                                        window);
-
-       } else {
-               xdg_surface_unset_fullscreen(window->xdg_surface);
-               handle_surface_configure(window, window->xdg_surface,
-                                        window->window_size.width,
-                                        window->window_size.height);
-               window->configured = 1;
-       }
-}
-
-static void
 create_surface(struct window *window)
 {
        struct display *display = window->display;
@@ -396,7 +357,9 @@ create_surface(struct window *window)
        if (!window->frame_sync)
                eglSwapInterval(display->egl.dpy, 0);
 
-       set_fullscreen(window, window->fullscreen);
+       xdg_surface_request_change_state(window->xdg_surface,
+                                        XDG_SURFACE_STATE_FULLSCREEN,
+                                        window->fullscreen, 0);
 }
 
 static void
@@ -453,9 +416,6 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
        if (callback)
                wl_callback_destroy(callback);
 
-       if (!window->configured)
-               return;
-
        gettimeofday(&tv, NULL);
        time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
        if (window->frames == 0)
@@ -657,7 +617,9 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
        struct display *d = data;
 
        if (key == KEY_F11 && state)
-               set_fullscreen(d->window, d->window->fullscreen ^ 1);
+               xdg_surface_request_change_state(d->window->xdg_surface,
+                                                XDG_SURFACE_STATE_FULLSCREEN,
+                                                !d->window->fullscreen, 0);
        else if (key == KEY_ESC && state)
                running = 0;
 }
@@ -845,8 +807,6 @@ main(int argc, char **argv)
         * queued up as a side effect. */
        while (running && ret != -1) {
                wl_display_dispatch_pending(display.display);
-               while (!window.configured)
-                       wl_display_dispatch(display.display);
                redraw(&window, NULL, 0);
        }
 
index db2da5d..f84d08c 100644 (file)
@@ -120,22 +120,10 @@ handle_configure(void *data, struct xdg_surface *surface,
 }
 
 static void
-handle_request_set_maximized(void *data, struct xdg_surface *xdg_surface)
-{
-}
-
-static void
-handle_request_unset_maximized(void *data, struct xdg_surface *xdg_surface)
-{
-}
-
-static void
-handle_request_set_fullscreen(void *data, struct xdg_surface *xdg_surface)
-{
-}
-
-static void
-handle_request_unset_fullscreen(void *data, struct xdg_surface *xdg_surface)
+handle_change_state(void *data, struct xdg_surface *xdg_surface,
+                   uint32_t state,
+                   uint32_t value,
+                   uint32_t serial)
 {
 }
 
@@ -157,10 +145,7 @@ handle_delete(void *data, struct xdg_surface *xdg_surface)
 
 static const struct xdg_surface_listener xdg_surface_listener = {
        handle_configure,
-       handle_request_set_maximized,
-       handle_request_unset_maximized,
-       handle_request_set_fullscreen,
-       handle_request_unset_fullscreen,
+       handle_change_state,
        handle_activated,
        handle_deactivated,
        handle_delete,
index 4dd6b36..e5fa541 100644 (file)
@@ -3750,6 +3750,9 @@ window_do_resize(struct window *window)
                surface_set_synchronized(surface);
                surface_resize(surface);
        }
+
+       if (!window->fullscreen && !window->maximized)
+               window->saved_allocation = window->pending_allocation;
 }
 
 static void
@@ -3839,31 +3842,29 @@ handle_surface_configure(void *data, struct xdg_surface *xdg_surface,
 }
 
 static void
-handle_surface_request_set_maximized(void *data, struct xdg_surface *xdg_surface)
+handle_surface_change_state(void *data, struct xdg_surface *xdg_surface,
+                           uint32_t state,
+                           uint32_t value,
+                           uint32_t serial)
 {
        struct window *window = data;
-       window_set_maximized(window, 1);
-}
 
-static void
-handle_surface_request_unset_maximized(void *data, struct xdg_surface *xdg_surface)
-{
-       struct window *window = data;
-       window_set_maximized(window, 0);
-}
+       switch (state) {
+       case XDG_SURFACE_STATE_MAXIMIZED:
+               window->maximized = value;
+               break;
+       case XDG_SURFACE_STATE_FULLSCREEN:
+               window->fullscreen = value;
+               break;
+       }
 
-static void
-handle_surface_request_set_fullscreen(void *data, struct xdg_surface *xdg_surface)
-{
-       struct window *window = data;
-       window_set_fullscreen(window, 1);
-}
+       if (!window->fullscreen && !window->maximized)
+               window_schedule_resize(window,
+                                      window->saved_allocation.width,
+                                      window->saved_allocation.height);
 
-static void
-handle_surface_request_unset_fullscreen(void *data, struct xdg_surface *xdg_surface)
-{
-       struct window *window = data;
-       window_set_fullscreen(window, 0);
+       xdg_surface_ack_change_state(xdg_surface, state, value, serial);
+       window_schedule_redraw(window);
 }
 
 static void
@@ -3889,10 +3890,7 @@ handle_surface_delete(void *data, struct xdg_surface *xdg_surface)
 
 static const struct xdg_surface_listener xdg_surface_listener = {
        handle_surface_configure,
-       handle_surface_request_set_maximized,
-       handle_surface_request_unset_maximized,
-       handle_surface_request_set_fullscreen,
-       handle_surface_request_unset_fullscreen,
+       handle_surface_change_state,
        handle_surface_activated,
        handle_surface_deactivated,
        handle_surface_delete,
@@ -4125,39 +4123,6 @@ window_schedule_redraw(struct window *window)
        window_schedule_redraw_task(window);
 }
 
-static void
-configure_sync_callback(void *data,
-                       struct wl_callback *callback, uint32_t time)
-{
-       struct window *window = data;
-
-       DBG("scheduling redraw from maximize sync callback\n");
-
-       wl_callback_destroy(callback);
-
-       window->redraw_task_scheduled = 0;
-       window_schedule_redraw_task(window);
-}
-
-static struct wl_callback_listener configure_sync_callback_listener = {
-       configure_sync_callback,
-};
-
-static void
-window_delay_redraw(struct window *window)
-{
-       struct wl_callback *callback;
-
-       DBG("delay scheduled redraw for maximize configure\n");
-       if (window->redraw_task_scheduled)
-               wl_list_remove(&window->redraw_task.link);
-
-       window->redraw_task_scheduled = 1;
-       callback = wl_display_sync(window->display->display);
-       wl_callback_add_listener(callback,
-                                &configure_sync_callback_listener, window);
-}
-
 int
 window_is_fullscreen(struct window *window)
 {
@@ -4173,13 +4138,10 @@ window_set_fullscreen(struct window *window, int fullscreen)
        if (window->fullscreen == fullscreen)
                return;
 
-       window->fullscreen = fullscreen;
-       if (window->fullscreen)
-               xdg_surface_set_fullscreen(window->xdg_surface);
-       else
-               xdg_surface_unset_fullscreen(window->xdg_surface);
-
-       window_delay_redraw(window);
+       xdg_surface_request_change_state(window->xdg_surface,
+                                        XDG_SURFACE_STATE_FULLSCREEN,
+                                        fullscreen ? 1 : 0,
+                                        0);
 }
 
 int
@@ -4197,13 +4159,10 @@ window_set_maximized(struct window *window, int maximized)
        if (window->maximized == maximized)
                return;
 
-       window->maximized = maximized;
-       if (window->maximized)
-               xdg_surface_set_maximized(window->xdg_surface);
-       else
-               xdg_surface_unset_maximized(window->xdg_surface);
-
-       window_delay_redraw(window);
+       xdg_surface_request_change_state(window->xdg_surface,
+                                        XDG_SURFACE_STATE_MAXIMIZED,
+                                        maximized ? 1 : 0,
+                                        0);
 }
 
 void
index 7811962..3b01462 100644 (file)
@@ -161,8 +161,9 @@ struct shell_surface {
                bool maximized;
                bool fullscreen;
                bool relative;
-       } state, next_state; /* surface states */
+       } state, next_state, requested_state; /* surface states */
        bool state_changed;
+       bool state_requested;
 
        int focus_count;
 };
@@ -2288,8 +2289,6 @@ set_fullscreen(struct shell_surface *shsurf,
        shsurf->fullscreen.type = method;
        shsurf->fullscreen.framerate = framerate;
 
-       shsurf->next_state.fullscreen = true;
-       shsurf->state_changed = true;
        shsurf->type = SHELL_SURFACE_TOPLEVEL;
 
        shsurf->client->send_configure(shsurf->surface, 0,
@@ -2358,6 +2357,9 @@ shell_surface_set_fullscreen(struct wl_client *client,
 
        surface_clear_next_states(shsurf);
        set_fullscreen(shsurf, method, framerate, output);
+
+       shsurf->next_state.fullscreen = true;
+       shsurf->state_changed = true;
 }
 
 static void
@@ -2416,8 +2418,6 @@ set_maximized(struct shell_surface *shsurf,
                                       shsurf->output->width,
                                       shsurf->output->height - panel_height);
 
-       shsurf->next_state.maximized = true;
-       shsurf->state_changed = true;
        shsurf->type = SHELL_SURFACE_TOPLEVEL;
 }
 
@@ -2459,6 +2459,9 @@ shell_surface_set_maximized(struct wl_client *client,
 
        surface_clear_next_states(shsurf);
        set_maximized(shsurf, output);
+
+       shsurf->next_state.maximized = true;
+       shsurf->state_changed = true;
 }
 
 /* This is only ever called from set_surface_type(), so there’s no need to
@@ -3243,87 +3246,95 @@ xdg_surface_set_output(struct wl_client *client,
 }
 
 static void
-xdg_surface_set_fullscreen(struct wl_client *client,
-                          struct wl_resource *resource)
+xdg_surface_set_fullscreen(struct shell_surface *shsurf, int serial)
 {
-       struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+       shsurf->requested_state.fullscreen = true;
+       shsurf->state_requested = true;
 
-       if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
-               return;
+       xdg_surface_send_change_state(shsurf->resource,
+                                     XDG_SURFACE_STATE_FULLSCREEN, 1, serial);
 
-       if (!shsurf->next_state.fullscreen)
-               set_fullscreen(shsurf,
-                              WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
-                              0, shsurf->recommended_output);
+       set_fullscreen(shsurf,
+                      WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+                      0, shsurf->recommended_output);
 }
 
 static void
-xdg_surface_unset_fullscreen(struct wl_client *client,
-                            struct wl_resource *resource)
+xdg_surface_unset_fullscreen(struct shell_surface *shsurf, int serial)
 {
-       struct shell_surface *shsurf = wl_resource_get_user_data(resource);
-       int32_t width, height;
+       shsurf->requested_state.fullscreen = false;
+       shsurf->state_requested = true;
 
-       if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
-               return;
+       xdg_surface_send_change_state(shsurf->resource,
+                                     XDG_SURFACE_STATE_FULLSCREEN, 0, serial);
+}
 
-       if (!shsurf->next_state.fullscreen)
-               return;
+static void
+xdg_surface_set_maximized(struct shell_surface *shsurf, int serial)
+{
+       shsurf->requested_state.maximized = true;
+       shsurf->state_requested = true;
 
-       shsurf->next_state.fullscreen = false;
-       shsurf->state_changed = true;
+       set_maximized(shsurf, NULL);
 
-       if (shsurf->saved_size_valid) {
-               width = shsurf->saved_width;
-               height = shsurf->saved_height;
-               shsurf->saved_size_valid = false;
-       } else {
-               width = shsurf->surface->width;
-               height = shsurf->surface->height;
-       }
+       xdg_surface_send_change_state(shsurf->resource,
+                                     XDG_SURFACE_STATE_MAXIMIZED, 1, serial);
+}
+static void
+xdg_surface_unset_maximized(struct shell_surface *shsurf, int serial)
+{
+       shsurf->requested_state.maximized = false;
+       shsurf->state_requested = true;
 
-       shsurf->client->send_configure(shsurf->surface, 0, width, height);
+       xdg_surface_send_change_state(shsurf->resource,
+                                     XDG_SURFACE_STATE_MAXIMIZED, 0, serial);
 }
 
 static void
-xdg_surface_set_maximized(struct wl_client *client,
-                         struct wl_resource *resource)
+xdg_surface_request_change_state(struct wl_client *client,
+                                struct wl_resource *resource,
+                                uint32_t state,
+                                uint32_t value,
+                                uint32_t serial)
 {
        struct shell_surface *shsurf = wl_resource_get_user_data(resource);
 
+       /* The client can't know what the current state is, so we need
+          to always send a state change in response. */
+
        if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
                return;
 
-       if (!shsurf->next_state.maximized)
-               set_maximized(shsurf, NULL);
+       switch (state) {
+       case XDG_SURFACE_STATE_MAXIMIZED:
+               if (value)
+                       xdg_surface_set_maximized(shsurf, serial);
+               else
+                       xdg_surface_unset_maximized(shsurf, serial);
+               break;
+       case XDG_SURFACE_STATE_FULLSCREEN:
+               if (value)
+                       xdg_surface_set_fullscreen(shsurf, serial);
+               else
+                       xdg_surface_unset_fullscreen(shsurf, serial);
+               break;
+       }
 }
 
 static void
-xdg_surface_unset_maximized(struct wl_client *client,
-                           struct wl_resource *resource)
+xdg_surface_ack_change_state(struct wl_client *client,
+                            struct wl_resource *resource,
+                            uint32_t state,
+                            uint32_t value,
+                            uint32_t serial)
 {
        struct shell_surface *shsurf = wl_resource_get_user_data(resource);
-       int32_t width, height;
-
-       if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
-               return;
-
-       if (!shsurf->next_state.maximized)
-               return;
 
-       shsurf->next_state.maximized = false;
-       shsurf->state_changed = true;
-
-       if (shsurf->saved_size_valid) {
-               width = shsurf->saved_width;
-               height = shsurf->saved_height;
-               shsurf->saved_size_valid = false;
-       } else {
-               width = shsurf->surface->width;
-               height = shsurf->surface->height;
+       if (shsurf->state_requested) {
+               shsurf->next_state = shsurf->requested_state;
+               shsurf->state_changed = true;
+               shsurf->state_requested = false;
        }
-
-       shsurf->client->send_configure(shsurf->surface, 0, width, height);
 }
 
 static const struct xdg_surface_interface xdg_surface_implementation = {
@@ -3335,10 +3346,8 @@ static const struct xdg_surface_interface xdg_surface_implementation = {
        xdg_surface_move,
        xdg_surface_resize,
        xdg_surface_set_output,
-       xdg_surface_set_fullscreen,
-       xdg_surface_unset_fullscreen,
-       xdg_surface_set_maximized,
-       xdg_surface_unset_maximized,
+       xdg_surface_request_change_state,
+       xdg_surface_ack_change_state,
        NULL /* set_minimized */
 };
 
@@ -3925,9 +3934,9 @@ maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void
                return;
 
        if (shsurf->state.maximized)
-               xdg_surface_send_request_unset_maximized(shsurf->resource);
+               xdg_surface_unset_maximized(shsurf, wl_display_next_serial(seat->compositor->wl_display));
        else
-               xdg_surface_send_request_set_maximized(shsurf->resource);
+               xdg_surface_set_maximized(shsurf, wl_display_next_serial(seat->compositor->wl_display));
 }
 
 static void
@@ -3949,9 +3958,9 @@ fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, voi
                return;
 
        if (shsurf->state.fullscreen)
-               xdg_surface_send_request_unset_fullscreen(shsurf->resource);
+               xdg_surface_unset_fullscreen(shsurf, wl_display_next_serial(seat->compositor->wl_display));
        else
-               xdg_surface_send_request_set_fullscreen(shsurf->resource);
+               xdg_surface_set_fullscreen(shsurf, wl_display_next_serial(seat->compositor->wl_display));
 }
 
 static void
index 4a1d08a..e690740 100644 (file)
       <arg name="output" type="object" interface="wl_output" allow-null="true"/>
     </request>
 
-    <event name="request_set_fullscreen">
-      <description summary="server requests that the client set fullscreen">
-       Event sent from the compositor to the client requesting that the client
-       goes to a fullscreen state. It's the client job to call set_fullscreen
-       and really trigger the fullscreen state.
+    <enum name="state">
+      <description summary="types of state on the surface">
+        The different state values used on the surface. This is designed for
+        state values like maximized, fullscreen. It is paired with the
+        request_change_state event to ensure that both the client and the
+        compositor setting the state can be synchronized.
+
+        States set in this way are double-buffered. They will get applied on
+        the next commit.
+
+        Desktop environments may extend this enum by taking up a range of
+        values and documenting the range they chose in this description.
+        They are not required to document the values for the range that they
+        chose. Ideally, any good extensions from a desktop environment should
+        make its way into standardization into this enum.
+
+        The current reserved ranges are:
+
+        0x0000 - 0x0FFF: xdg-shell core values, documented below.
+        0x1000 - 0x1FFF: GNOME
       </description>
-    </event>
-
-    <event name="request_unset_fullscreen">
-      <description summary="server requests that the client unset fullscreen">
-       Event sent from the compositor to the client requesting that the client
-       leaves the fullscreen state. It's the client job to call
-       unset_fullscreen and really leave the fullscreen state.
-      </description>
-    </event>
-
-    <request name="set_fullscreen">
-      <description summary="set the surface state as fullscreen">
-       Set the surface as fullscreen.
-
-       After this request, the compositor should send a configure event
-       informing the output size.
-
-       This request informs the compositor that the next attached buffer
-       committed will be in a fullscreen state. The buffer size should be the
-       same size as the size informed in the configure event, if the client
-       doesn't want to leave any empty area.
-
-       In other words: the next attached buffer after set_maximized is the new
-       maximized buffer. And the surface will be positioned at the maximized
-       position on commit.
-
-       A simple way to synchronize and wait for the correct configure event is
-       to use a wl_display.sync request right after the set_fullscreen
-       request. When the sync callback returns, the last configure event
-       received just before it will be the correct one, and should contain the
-       right size for the surface to maximize.
-
-       Setting one state won't unset another state. Use
-       xdg_surface.unset_fullscreen for unsetting it.
-      </description>
-    </request>
+      <entry name="maximized" value="1" summary="the surface is maximized">
+        A non-zero value indicates the surface is maximized. Otherwise,
+        the surface is unmaximized.
+      </entry>
+      <entry name="fullscreen" value="2" summary="the surface is fullscreen">
+        A non-zero value indicates the surface is fullscreen. Otherwise,
+        the surface is not fullscreen.
+      </entry>
+    </enum>
 
-    <request name="unset_fullscreen">
-      <description summary="unset the surface state as fullscreen">
-       Unset the surface fullscreen state.
+    <request name="request_change_state">
+      <description summary="client requests to change a surface's state">
+        This asks the compositor to change the state. If the compositor wants
+        to change the state, it will send a change_state event with the same
+        state_type, value, and serial, and the event flow continues as if it
+        it was initiated by the compositor.
 
-       Same negotiation as set_fullscreen must be used.
+        If the compositor does not want to change the state, it will send a
+        change_state to the client with the old value of the state.
       </description>
+      <arg name="state_type" type="uint" summary="the state to set"/>
+      <arg name="value" type="uint" summary="the value to change the state to"/>
+      <arg name="serial" type="uint" summary="an event serial">
+        This serial is so the client can know which change_state event corresponds
+        to which request_change_state request it sent out.
+      </arg>
     </request>
 
-    <event name="request_set_maximized">
-      <description summary="server requests that the client set maximized">
-       Event sent from the compositor to the client requesting that the client
-       goes to a maximized state. It's the client job to call set_maximized
-       and really trigger the maximized state.
+    <event name="change_state">
+      <description summary="compositor wants to change a surface's state">
+        This event tells the client to change a surface's state. The client
+        should respond with an ack_change_state request to the compositor to
+        guarantee that the compositor knows that the client has seen it.
       </description>
-    </event>
 
-    <event name="request_unset_maximized">
-      <description summary="server requests that the client unset maximized">
-       Event sent from the compositor to the client requesting that the client
-       leaves the maximized state. It's the client job to call unset_maximized
-       and really leave the maximized state.
-      </description>
+      <arg name="state_type" type="uint" summary="the state to set"/>
+      <arg name="value" type="uint" summary="the value to change the state to"/>
+      <arg name="serial" type="uint" summary="a serial for the compositor's own tracking"/>
     </event>
 
-    <request name="set_maximized">
-      <description summary="set the surface state as maximized">
-       Set the surface as maximized.
-
-       After this request, the compositor will send a configure event
-       informing the output size minus panel and other MW decorations.
-
-       This request informs the compositor that the next attached buffer
-       committed will be in a maximized state. The buffer size should be the
-       same size as the size informed in the configure event, if the client
-       doesn't want to leave any empty area.
-
-       In other words: the next attached buffer after set_maximized is the new
-       maximized buffer. And the surface will be positioned at the maximized
-       position on commit.
+    <request name="ack_change_state">
+      <description summary="ack a change_state event">
+        When a change_state event is received, a client should then ack it
+        using the ack_change_state request to ensure that the compositor
+        knows the client has seen the event.
 
-       A simple way to synchronize and wait for the correct configure event is
-       to use a wl_display.sync request right after the set_maximized request.
-       When the sync callback returns, the last configure event received just
-       before it will be the correct one, and should contain the right size
-       for the surface to maximize.
+        By this point, the state is confirmed, and the next attach should
+        contain the buffer drawn for the new state value.
 
-       Setting one state won't unset another state. Use
-       xdg_surface.unset_maximized for unsetting it.
-      </description>
-    </request>
-
-    <request name="unset_maximized">
-      <description summary="unset the surface state as maximized">
-       Unset the surface maximized state.
-
-       Same negotiation as set_maximized must be used.
+        The values here need to be the same as the values in the cooresponding
+        change_state event.
       </description>
+      <arg name="state_type" type="uint" summary="the state to set"/>
+      <arg name="value" type="uint" summary="the value to change the state to"/>
+      <arg name="serial" type="uint" summary="a serial to pass to change_state"/>
     </request>
 
     <request name="set_minimized">
-      <description summary="set the surface state as minimized">
-       Set the surface minimized state.
-
-       Setting one state won't unset another state.
+      <description summary="minimize the surface">
+        Minimize the surface.
       </description>
     </request>