xdg-shell: Turn the resizing heuristics into an explicit state

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.
dev
Jasper St. Pierre 11 years ago committed by Kristian Høgsberg
parent ab2c108137
commit 5befdda84f
  1. 11
      clients/window.c
  2. 21
      desktop-shell/shell.c
  3. 6
      protocol/xdg-shell.xml

@ -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;

@ -351,13 +351,27 @@ 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);

@ -270,6 +270,12 @@
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">

Loading…
Cancel
Save