summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2014-05-06 08:50:47 -0400
committerKristian Høgsberg <krh@bitplanet.net>2014-05-12 23:34:05 -0700
commit5befdda84fe7cb2fb6d5d8986a5b8552a1372b8a (patch)
tree91b4d64e1f880f5e1aeb8162dc8aa9c8721bff4f
parentab2c10813766e3cd3f5228385eb4984565fb2f26 (diff)
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.
-rw-r--r--clients/window.c11
-rw-r--r--desktop-shell/shell.c21
-rw-r--r--protocol/xdg-shell.xml6
3 files changed, 30 insertions, 8 deletions
diff --git a/clients/window.c b/clients/window.c
index 9ec12c7e..6149618a 100644
--- a/clients/window.c
+++ b/clients/window.c
@@ -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;
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 574681fd..d7cd9c82 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -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);
diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml
index d3d6a377..19f9651d 100644
--- a/protocol/xdg-shell.xml
+++ b/protocol/xdg-shell.xml
@@ -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">