xdg-shell: Turn the resizing heuristics into an explicit state
authorJasper St. Pierre <jstpierre@mecheye.net>
Tue, 6 May 2014 12:50:47 +0000 (08:50 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Tue, 13 May 2014 06:34:05 +0000 (23:34 -0700)
Currently, there's a race condition. When resizing from the left, and
a client attaches a buffer after the resize ends, you suddenly see the
buffer jump to the right, because the resize ended while multiple
attaches were in-flight. Making resize a state can fix this, as the
server can now know exactly when the resize ended, and whether a commit
was before or after that place.

We don't implement the correct tracking in this commit; that's left as
an exercise to the reader.

Additionally, clients like terminals might want to display resize popups
to display the number of cells when in a resize. They can use the hint
here to figure out whether they are resizing.

clients/window.c
desktop-shell/shell.c
protocol/xdg-shell.xml

index 9ec12c7..6149618 100644 (file)
@@ -2387,7 +2387,6 @@ frame_handle_status(struct window_frame *frame, struct input *input,
        if ((status & FRAME_STATUS_RESIZE) && window->xdg_surface) {
                input_ungrab(input);
 
-               window->resizing = 1;
                xdg_surface_resize(window->xdg_surface,
                                   input_get_seat(input),
                                   window->display->serial,
@@ -2623,12 +2622,6 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
        input->pointer_enter_serial = serial;
        input->pointer_focus = window;
 
-       if (window->resizing) {
-               window->resizing = 0;
-               /* Schedule a redraw to free the pool */
-               window_schedule_redraw(window);
-       }
-
        input->sx = sx;
        input->sy = sy;
 
@@ -3873,6 +3866,7 @@ handle_surface_configure(void *data, struct xdg_surface *xdg_surface,
 
        window->maximized = 0;
        window->fullscreen = 0;
+       window->resizing = 0;
 
        wl_array_for_each(p, states) {
                uint32_t state = *p;
@@ -3883,6 +3877,9 @@ handle_surface_configure(void *data, struct xdg_surface *xdg_surface,
                case XDG_SURFACE_STATE_FULLSCREEN:
                        window->fullscreen = 1;
                        break;
+               case XDG_SURFACE_STATE_RESIZING:
+                       window->resizing = 1;
+                       break;
                default:
                        /* Unknown state */
                        break;
index 574681f..d7cd9c8 100644 (file)
@@ -352,12 +352,26 @@ shell_grab_start(struct shell_grab *grab,
 }
 
 static void
+shell_surface_state_changed(struct shell_surface *shsurf)
+{
+       if (shell_surface_is_xdg_surface(shsurf)) {
+               shsurf->client->send_configure(shsurf->surface,
+                                              shsurf->surface->width,
+                                              shsurf->surface->height);
+       }
+}
+
+static void
 shell_grab_end(struct shell_grab *grab)
 {
        if (grab->shsurf) {
                wl_list_remove(&grab->shsurf_destroy_listener.link);
                grab->shsurf->grabbed = 0;
-               grab->shsurf->resize_edges = 0;
+
+               if (grab->shsurf->resize_edges) {
+                       grab->shsurf->resize_edges = 0;
+                       shell_surface_state_changed(grab->shsurf);
+               }
        }
 
        weston_pointer_end_grab(grab->grab.pointer);
@@ -1769,6 +1783,7 @@ surface_resize(struct shell_surface *shsurf,
                                        &resize->width, &resize->height);
 
        shsurf->resize_edges = edges;
+       shell_surface_state_changed(shsurf);
        shell_grab_start(&resize->base, &resize_grab_interface, shsurf,
                         seat->pointer, edges);
 
@@ -3538,6 +3553,10 @@ xdg_send_configure(struct weston_surface *surface,
                s = wl_array_add(&states, sizeof *s);
                *s = XDG_SURFACE_STATE_MAXIMIZED;
        }
+       if (shsurf->resize_edges != 0) {
+               s = wl_array_add(&states, sizeof *s);
+               *s = XDG_SURFACE_STATE_RESIZING;
+       }
 
        serial = wl_display_next_serial(shsurf->surface->compositor->wl_display);
        xdg_surface_send_configure(shsurf->resource, width, height, &states, serial);
index d3d6a37..19f9651 100644 (file)
         The surface is fullscreen. The window geometry specified in the configure
         event must be obeyed by the client.
       </entry>
+      <entry name="resizing" value="3">
+        The surface is being resized. The window geometry specified in the
+        configure event is a maximum; the client cannot resize beyond it.
+        Clients that have aspect ratio or cell sizing configuration can use
+        a smaller size, however.
+      </entry>
     </enum>
 
     <event name="configure">