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.
This commit is contained in:
Jasper St. Pierre 2014-05-06 08:50:47 -04:00 committed by Kristian Høgsberg
parent ab2c108137
commit 5befdda84f
3 changed files with 30 additions and 8 deletions

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

View file

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

View file

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