aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_xdg_shell_v6.h1
-rw-r--r--types/wlr_xdg_shell_v6.c252
2 files changed, 131 insertions, 122 deletions
diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h
index e13af137..a4afaf3b 100644
--- a/include/wlr/types/wlr_xdg_shell_v6.h
+++ b/include/wlr/types/wlr_xdg_shell_v6.h
@@ -36,6 +36,7 @@ struct wlr_xdg_toplevel_v6_state {
struct wlr_xdg_toplevel_v6 {
struct wl_resource *resource;
struct wlr_xdg_surface_v6 *base;
+ bool added;
struct wlr_xdg_toplevel_v6_state next; // client protocol requests
struct wlr_xdg_toplevel_v6_state pending; // user configure requests
struct wlr_xdg_toplevel_v6_state current;
diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c
index 71c5fb0a..11b44d6d 100644
--- a/types/wlr_xdg_shell_v6.c
+++ b/types/wlr_xdg_shell_v6.c
@@ -265,6 +265,123 @@ static void xdg_shell_create_positioner(struct wl_client *client,
wlr_log(L_DEBUG, "TODO: xdg shell create positioner");
}
+static bool wlr_xdg_surface_v6_toplevel_state_compare(
+ struct wlr_xdg_toplevel_v6 *state) {
+ // is pending state different from current state?
+ if (state->pending.activated != state->current.activated) {
+ return false;
+ }
+ if (state->pending.fullscreen != state->current.fullscreen) {
+ return false;
+ }
+ if (state->pending.maximized != state->current.maximized) {
+ return false;
+ }
+ if (state->pending.resizing != state->current.resizing) {
+ return false;
+ }
+
+ if ((uint32_t)state->base->geometry->width == state->pending.width &&
+ (uint32_t)state->base->geometry->height == state->pending.height) {
+ return true;
+ }
+
+ if (state->pending.width == 0 && state->pending.height == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+static void wlr_xdg_toplevel_v6_send_configure(
+ struct wlr_xdg_surface_v6 *surface,
+ struct wlr_xdg_surface_v6_configure *configure) {
+ assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
+ uint32_t *s;
+ struct wl_array states;
+
+ configure->state = &surface->toplevel_state->pending;
+
+ wl_array_init(&states);
+ if (surface->toplevel_state->pending.maximized) {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED;
+ }
+ if (surface->toplevel_state->pending.fullscreen) {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN;
+ }
+ if (surface->toplevel_state->pending.resizing) {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING;
+ }
+ if (surface->toplevel_state->pending.activated) {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
+ }
+
+ zxdg_toplevel_v6_send_configure(surface->toplevel_state->resource,
+ surface->toplevel_state->pending.width,
+ surface->toplevel_state->pending.height,
+ &states);
+
+ wl_array_release(&states);
+}
+
+static void wlr_xdg_surface_send_configure(void *user_data) {
+ struct wlr_xdg_surface_v6 *surface = user_data;
+ struct wl_display *display = wl_client_get_display(surface->client);
+
+ // TODO handle popups
+ assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
+
+ surface->configure_idle = NULL;
+
+ // TODO handle no memory
+ struct wlr_xdg_surface_v6_configure *configure =
+ calloc(1, sizeof(struct wlr_xdg_surface_v6_configure));
+ wl_list_insert(surface->configure_list.prev, &configure->link);
+ configure->serial = wl_display_next_serial(display);
+
+ wlr_xdg_toplevel_v6_send_configure(surface, configure);
+
+ zxdg_surface_v6_send_configure(surface->resource, configure->serial);
+}
+
+static void wlr_xdg_surface_v6_schedule_configure(
+ struct wlr_xdg_surface_v6 *surface, bool force) {
+ // TODO handle popups
+ assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
+
+ struct wl_display *display = wl_client_get_display(surface->client);
+ struct wl_event_loop *loop = wl_display_get_event_loop(display);
+
+ bool pending_same = !force &&
+ wlr_xdg_surface_v6_toplevel_state_compare(surface->toplevel_state);
+
+ if (surface->configure_idle != NULL) {
+ if (!pending_same) {
+ // configure request already scheduled
+ return;
+ }
+
+ // configure request not necessary anymore
+ wl_event_source_remove(surface->configure_idle);
+ surface->configure_idle = NULL;
+ } else {
+ if (pending_same) {
+ // configure request not necessary
+ return;
+ }
+
+ surface->configure_idle =
+ wl_event_loop_add_idle(
+ loop,
+ wlr_xdg_surface_send_configure,
+ surface);
+ }
+}
+
static void handle_wlr_surface_destroyed(struct wl_listener *listener,
void *data) {
struct wlr_xdg_surface_v6 *xdg_surface =
@@ -274,6 +391,14 @@ static void handle_wlr_surface_destroyed(struct wl_listener *listener,
static void wlr_xdg_surface_v6_toplevel_committed(
struct wlr_xdg_surface_v6 *surface) {
+ if (!surface->toplevel_state->added) {
+ // on the first commit, send a configure request to tell the client it
+ // is added
+ wlr_xdg_surface_v6_schedule_configure(surface, true);
+ surface->toplevel_state->added = true;
+ return;
+ }
+
copy_toplevel_state(&surface->toplevel_state->next,
&surface->toplevel_state->current);
}
@@ -409,130 +534,13 @@ void wlr_xdg_shell_v6_destroy(struct wlr_xdg_shell_v6 *xdg_shell) {
free(xdg_shell);
}
-static bool wlr_xdg_surface_v6_toplevel_state_compare(
- struct wlr_xdg_toplevel_v6 *state) {
- // is pending state different from current state?
- if (state->pending.activated != state->current.activated) {
- return false;
- }
- if (state->pending.fullscreen != state->current.fullscreen) {
- return false;
- }
- if (state->pending.maximized != state->current.maximized) {
- return false;
- }
- if (state->pending.resizing != state->current.resizing) {
- return false;
- }
-
- if ((uint32_t)state->base->geometry->width == state->pending.width &&
- (uint32_t)state->base->geometry->height == state->pending.height) {
- return true;
- }
-
- if (state->pending.width == 0 && state->pending.height == 0) {
- return true;
- }
-
- return false;
-}
-
-static void wlr_xdg_toplevel_v6_send_configure(
- struct wlr_xdg_surface_v6 *surface,
- struct wlr_xdg_surface_v6_configure *configure) {
- assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
- uint32_t *s;
- struct wl_array states;
-
- configure->state = &surface->toplevel_state->pending;
-
- wl_array_init(&states);
- if (surface->toplevel_state->pending.maximized) {
- s = wl_array_add(&states, sizeof(uint32_t));
- *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED;
- }
- if (surface->toplevel_state->pending.fullscreen) {
- s = wl_array_add(&states, sizeof(uint32_t));
- *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN;
- }
- if (surface->toplevel_state->pending.resizing) {
- s = wl_array_add(&states, sizeof(uint32_t));
- *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING;
- }
- if (surface->toplevel_state->pending.activated) {
- s = wl_array_add(&states, sizeof(uint32_t));
- *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
- }
-
- zxdg_toplevel_v6_send_configure(surface->toplevel_state->resource,
- surface->toplevel_state->pending.width,
- surface->toplevel_state->pending.height,
- &states);
-
- wl_array_release(&states);
-}
-
-static void wlr_xdg_surface_send_configure(void *user_data) {
- struct wlr_xdg_surface_v6 *surface = user_data;
- struct wl_display *display = wl_client_get_display(surface->client);
-
- // TODO handle popups
- assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
-
- surface->configure_idle = NULL;
-
- // TODO handle no memory
- struct wlr_xdg_surface_v6_configure *configure =
- calloc(1, sizeof(struct wlr_xdg_surface_v6_configure));
- wl_list_insert(surface->configure_list.prev, &configure->link);
- configure->serial = wl_display_next_serial(display);
-
- wlr_xdg_toplevel_v6_send_configure(surface, configure);
-
- zxdg_surface_v6_send_configure(surface->resource, configure->serial);
-}
-
-static void wlr_xdg_surface_v6_schedule_configure(
- struct wlr_xdg_surface_v6 *surface) {
- // TODO handle popups
- assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
-
- struct wl_display *display = wl_client_get_display(surface->client);
- struct wl_event_loop *loop = wl_display_get_event_loop(display);
-
- bool pending_same =
- wlr_xdg_surface_v6_toplevel_state_compare(surface->toplevel_state);
-
- if (surface->configure_idle != NULL) {
- if (!pending_same) {
- // configure request already scheduled
- return;
- }
-
- // configure request not necessary anymore
- wl_event_source_remove(surface->configure_idle);
- surface->configure_idle = NULL;
- } else {
- if (pending_same) {
- // configure request not necessary
- return;
- }
-
- surface->configure_idle =
- wl_event_loop_add_idle(
- loop,
- wlr_xdg_surface_send_configure,
- surface);
- }
-}
-
void wlr_xdg_toplevel_v6_set_size(struct wlr_xdg_surface_v6 *surface,
uint32_t width, uint32_t height) {
assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
surface->toplevel_state->pending.width = width;
surface->toplevel_state->pending.height = height;
- wlr_xdg_surface_v6_schedule_configure(surface);
+ wlr_xdg_surface_v6_schedule_configure(surface, false);
}
void wlr_xdg_toplevel_v6_set_activated(struct wlr_xdg_surface_v6 *surface,
@@ -540,7 +548,7 @@ void wlr_xdg_toplevel_v6_set_activated(struct wlr_xdg_surface_v6 *surface,
assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
surface->toplevel_state->pending.activated = activated;
- wlr_xdg_surface_v6_schedule_configure(surface);
+ wlr_xdg_surface_v6_schedule_configure(surface, false);
}
void wlr_xdg_toplevel_v6_set_maximized(struct wlr_xdg_surface_v6 *surface,
@@ -548,7 +556,7 @@ void wlr_xdg_toplevel_v6_set_maximized(struct wlr_xdg_surface_v6 *surface,
assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
surface->toplevel_state->pending.maximized = maximized;
- wlr_xdg_surface_v6_schedule_configure(surface);
+ wlr_xdg_surface_v6_schedule_configure(surface, false);
}
void wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface,
@@ -556,7 +564,7 @@ void wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface,
assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
surface->toplevel_state->pending.fullscreen = fullscreen;
- wlr_xdg_surface_v6_schedule_configure(surface);
+ wlr_xdg_surface_v6_schedule_configure(surface, false);
}
void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface,
@@ -564,5 +572,5 @@ void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface,
assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
surface->toplevel_state->pending.fullscreen = resizing;
- wlr_xdg_surface_v6_schedule_configure(surface);
+ wlr_xdg_surface_v6_schedule_configure(surface, false);
}