wlr_xdg_toplevel: store pending fullscreen output

Since the fullscreen request may be made before the toplevel's surface
is mapped, the requested fullscreen output needs to be stored so it
can be retrieved on map (along with the existing fullscreen property).

This commit makes the required changes for wlr_xdg_toplevel.
This commit is contained in:
Brian Ashworth 2019-03-24 21:09:55 -04:00 committed by emersion
parent b4f821ca31
commit 4e614683b7
3 changed files with 37 additions and 2 deletions

View File

@ -105,6 +105,12 @@ struct wlr_xdg_toplevel_state {
uint32_t width, height;
uint32_t max_width, max_height;
uint32_t min_width, min_height;
// Since the fullscreen request may be made before the toplevel's surface
// is mapped, this is used to store the requested fullscreen output (if
// any) for wlr_xdg_toplevel::client_pending.
struct wlr_output *fullscreen_output;
struct wl_listener fullscreen_output_destroy;
};
struct wlr_xdg_toplevel {

View File

@ -459,6 +459,11 @@ void reset_xdg_surface(struct wlr_xdg_surface *xdg_surface) {
wl_resource_set_user_data(xdg_surface->toplevel->resource, NULL);
xdg_surface->toplevel->resource = NULL;
if (xdg_surface->toplevel->client_pending.fullscreen_output) {
struct wlr_xdg_toplevel_state *client_pending =
&xdg_surface->toplevel->client_pending;
wl_list_remove(&client_pending->fullscreen_output_destroy.link);
}
free(xdg_surface->toplevel);
xdg_surface->toplevel = NULL;
break;

View File

@ -375,6 +375,30 @@ static void xdg_toplevel_handle_unset_maximized(struct wl_client *client,
wlr_signal_emit_safe(&surface->toplevel->events.request_maximize, surface);
}
static void handle_fullscreen_output_destroy(struct wl_listener *listener,
void *data) {
struct wlr_xdg_toplevel_state *state =
wl_container_of(listener, state, fullscreen_output_destroy);
state->fullscreen_output = NULL;
wl_list_remove(&state->fullscreen_output_destroy.link);
}
static void store_fullscreen_pending(struct wlr_xdg_surface *surface,
bool fullscreen, struct wlr_output *output) {
struct wlr_xdg_toplevel_state *state = &surface->toplevel->client_pending;
state->fullscreen = fullscreen;
if (state->fullscreen_output) {
wl_list_remove(&state->fullscreen_output_destroy.link);
}
state->fullscreen_output = output;
if (state->fullscreen_output) {
state->fullscreen_output_destroy.notify =
handle_fullscreen_output_destroy;
wl_signal_add(&state->fullscreen_output->events.destroy,
&state->fullscreen_output_destroy);
}
}
static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
struct wl_resource *resource, struct wl_resource *output_resource) {
struct wlr_xdg_surface *surface =
@ -385,7 +409,7 @@ static void xdg_toplevel_handle_set_fullscreen(struct wl_client *client,
output = wlr_output_from_resource(output_resource);
}
surface->toplevel->client_pending.fullscreen = true;
store_fullscreen_pending(surface, true, output);
struct wlr_xdg_toplevel_set_fullscreen_event event = {
.surface = surface,
@ -401,7 +425,7 @@ static void xdg_toplevel_handle_unset_fullscreen(struct wl_client *client,
struct wlr_xdg_surface *surface =
wlr_xdg_surface_from_toplevel_resource(resource);
surface->toplevel->client_pending.fullscreen = false;
store_fullscreen_pending(surface, false, NULL);
struct wlr_xdg_toplevel_set_fullscreen_event event = {
.surface = surface,