summaryrefslogtreecommitdiff
path: root/desktop-shell/shell.c
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2014-04-10 10:41:46 -0700
committerKristian Høgsberg <krh@bitplanet.net>2014-05-12 23:33:59 -0700
commitab2c10813766e3cd3f5228385eb4984565fb2f26 (patch)
tree0cffdb6233af7cce53489f742c0dab5fd6438bac /desktop-shell/shell.c
parentc815d62b8516044cc98b93e6f03e9123b20190a6 (diff)
downloadweston-ab2c10813766e3cd3f5228385eb4984565fb2f26.tar.gz
weston-ab2c10813766e3cd3f5228385eb4984565fb2f26.tar.bz2
weston-ab2c10813766e3cd3f5228385eb4984565fb2f26.zip
xdg-shell: Rework the state system
The states system, so far, has been a complicated mix of weird APIs that solved a real race condition, but have been particularly ugly for both compositors and clients to implement.
Diffstat (limited to 'desktop-shell/shell.c')
-rw-r--r--desktop-shell/shell.c146
1 files changed, 77 insertions, 69 deletions
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index ea0e049d..574681fd 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -3418,86 +3418,73 @@ xdg_surface_resize(struct wl_client *client, struct wl_resource *resource,
}
static void
-xdg_surface_set_output(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *output_resource)
+xdg_surface_ack_configure(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t serial)
{
struct shell_surface *shsurf = wl_resource_get_user_data(resource);
- struct weston_output *output;
-
- if (output_resource)
- output = wl_resource_get_user_data(output_resource);
- else
- output = NULL;
- shsurf->recommended_output = output;
+ if (shsurf->state_requested) {
+ shsurf->next_state = shsurf->requested_state;
+ shsurf->state_changed = true;
+ shsurf->state_requested = false;
+ }
}
static void
-xdg_surface_change_state(struct shell_surface *shsurf,
- uint32_t state, uint32_t value, uint32_t serial)
+xdg_surface_set_maximized(struct wl_client *client,
+ struct wl_resource *resource)
{
- xdg_surface_send_change_state(shsurf->resource, state, value, serial);
+ struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+
shsurf->state_requested = true;
+ shsurf->requested_state.maximized = true;
+ set_maximized(shsurf, NULL);
+}
- switch (state) {
- case XDG_SURFACE_STATE_MAXIMIZED:
- shsurf->requested_state.maximized = value;
- if (value)
- set_maximized(shsurf, NULL);
- break;
- case XDG_SURFACE_STATE_FULLSCREEN:
- shsurf->requested_state.fullscreen = value;
+static void
+xdg_surface_unset_maximized(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ struct shell_surface *shsurf = wl_resource_get_user_data(resource);
- if (value)
- set_fullscreen(shsurf,
- WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
- 0, shsurf->recommended_output);
- break;
- }
+ shsurf->state_requested = true;
+ shsurf->requested_state.maximized = false;
+ shsurf->client->send_configure(shsurf->surface, 0, 0);
}
static void
-xdg_surface_request_change_state(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t state,
- uint32_t value,
- uint32_t serial)
+xdg_surface_set_fullscreen(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *output_resource)
{
struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+ struct weston_output *output;
- /* The client can't know what the current state is, so we need
- to always send a state change in response. */
+ shsurf->state_requested = true;
+ shsurf->requested_state.fullscreen = true;
- if (shsurf->type != SHELL_SURFACE_TOPLEVEL)
- return;
+ if (output_resource)
+ output = wl_resource_get_user_data(output_resource);
+ else
+ output = NULL;
- switch (state) {
- case XDG_SURFACE_STATE_MAXIMIZED:
- case XDG_SURFACE_STATE_FULLSCREEN:
- break;
- default:
- /* send error? ignore? send change state with value 0? */
- return;
- }
+ shsurf->recommended_output = output;
- xdg_surface_change_state(shsurf, state, value, serial);
+ set_fullscreen(shsurf,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ 0, shsurf->recommended_output);
}
static void
-xdg_surface_ack_change_state(struct wl_client *client,
- struct wl_resource *resource,
- uint32_t state,
- uint32_t value,
- uint32_t serial)
+xdg_surface_unset_fullscreen(struct wl_client *client,
+ struct wl_resource *resource)
{
struct shell_surface *shsurf = wl_resource_get_user_data(resource);
- if (shsurf->state_requested) {
- shsurf->next_state = shsurf->requested_state;
- shsurf->state_changed = true;
- shsurf->state_requested = false;
- }
+ shsurf->state_requested = true;
+ shsurf->requested_state.fullscreen = false;
+ shsurf->client->send_configure(shsurf->surface, 0, 0);
}
static void
@@ -3521,10 +3508,12 @@ static const struct xdg_surface_interface xdg_surface_implementation = {
xdg_surface_set_app_id,
xdg_surface_move,
xdg_surface_resize,
- xdg_surface_set_output,
- xdg_surface_request_change_state,
- xdg_surface_ack_change_state,
- xdg_surface_set_minimized
+ xdg_surface_ack_configure,
+ xdg_surface_set_maximized,
+ xdg_surface_unset_maximized,
+ xdg_surface_set_fullscreen,
+ xdg_surface_unset_fullscreen,
+ xdg_surface_set_minimized,
};
static void
@@ -3532,11 +3521,28 @@ xdg_send_configure(struct weston_surface *surface,
int32_t width, int32_t height)
{
struct shell_surface *shsurf = get_shell_surface(surface);
+ uint32_t *s;
+ struct wl_array states;
+ uint32_t serial;
assert(shsurf);
- if (shsurf->resource)
- xdg_surface_send_configure(shsurf->resource, width, height);
+ if (!shsurf->resource)
+ return;
+
+ wl_array_init(&states);
+ if (shsurf->requested_state.fullscreen) {
+ s = wl_array_add(&states, sizeof *s);
+ *s = XDG_SURFACE_STATE_FULLSCREEN;
+ } else if (shsurf->requested_state.maximized) {
+ s = wl_array_add(&states, sizeof *s);
+ *s = XDG_SURFACE_STATE_MAXIMIZED;
+ }
+
+ serial = wl_display_next_serial(shsurf->surface->compositor->wl_display);
+ xdg_surface_send_configure(shsurf->resource, width, height, &states, serial);
+
+ wl_array_release(&states);
}
static const struct weston_shell_client xdg_client = {
@@ -4107,7 +4113,6 @@ maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void
struct weston_surface *focus = seat->keyboard->focus;
struct weston_surface *surface;
struct shell_surface *shsurf;
- uint32_t serial;
surface = weston_surface_get_main_surface(focus);
if (surface == NULL)
@@ -4120,9 +4125,10 @@ maximize_binding(struct weston_seat *seat, uint32_t time, uint32_t button, void
if (!shell_surface_is_xdg_surface(shsurf))
return;
- serial = wl_display_next_serial(seat->compositor->wl_display);
- xdg_surface_change_state(shsurf, XDG_SURFACE_STATE_MAXIMIZED,
- !shsurf->state.maximized, serial);
+ shsurf->state_requested = true;
+ shsurf->requested_state.maximized = !shsurf->state.maximized;
+ if (shsurf->requested_state.maximized)
+ set_maximized(shsurf, NULL);
}
static void
@@ -4131,7 +4137,6 @@ fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, voi
struct weston_surface *focus = seat->keyboard->focus;
struct weston_surface *surface;
struct shell_surface *shsurf;
- uint32_t serial;
surface = weston_surface_get_main_surface(focus);
if (surface == NULL)
@@ -4144,9 +4149,12 @@ fullscreen_binding(struct weston_seat *seat, uint32_t time, uint32_t button, voi
if (!shell_surface_is_xdg_surface(shsurf))
return;
- serial = wl_display_next_serial(seat->compositor->wl_display);
- xdg_surface_change_state(shsurf, XDG_SURFACE_STATE_FULLSCREEN,
- !shsurf->state.fullscreen, serial);
+ shsurf->state_requested = true;
+ shsurf->requested_state.fullscreen = !shsurf->state.fullscreen;
+ if (shsurf->requested_state.fullscreen)
+ set_fullscreen(shsurf,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ 0, shsurf->recommended_output);
}
static void