diff --git a/include/view.h b/include/view.h index 2df867cf..d7c0d498 100644 --- a/include/view.h +++ b/include/view.h @@ -52,7 +52,7 @@ struct view { * * Many view functions (e.g. view_center(), view_fullscreen(), * view_maximize(), etc.) allow specifying a particular output - * by setting view->output explicitly before calling them. + * by calling view_set_output() beforehand. */ struct output *output; struct workspace *workspace; @@ -131,6 +131,7 @@ struct xdg_toplevel_view { }; void view_set_activated(struct view *view); +void view_set_output(struct view *view, struct output *output); void view_close(struct view *view); /** diff --git a/src/view.c b/src/view.c index c69451ac..1ea34012 100644 --- a/src/view.c +++ b/src/view.c @@ -111,6 +111,7 @@ static void view_discover_output(struct view *view) { assert(view); + assert(!view->fullscreen); view->output = output_nearest_to(view->server, view->current.x + view->current.width / 2, view->current.y + view->current.height / 2); @@ -144,6 +145,18 @@ view_set_activated(struct view *view) view->server->focused_view = view; } +void +view_set_output(struct view *view, struct output *output) +{ + assert(view); + assert(!view->fullscreen); + if (!output_is_usable(output)) { + wlr_log(WLR_ERROR, "invalid output set for view"); + return; + } + view->output = output; +} + void view_close(struct view *view) { @@ -786,6 +799,11 @@ void view_on_output_destroy(struct view *view) { assert(view); + /* + * This is the only time we modify view->output for a fullscreen + * view. We expect view_adjust_for_layout_change() to be called + * shortly afterward, which will exit fullscreen. + */ view->output = NULL; } @@ -938,7 +956,7 @@ view_snap_to_edge(struct view *view, const char *direction, view_store_natural_geometry(view); } view_set_untiled(view); - view->output = output; + view_set_output(view, output); view->tiled = edge; view_apply_tiled_geometry(view); } diff --git a/src/xdg.c b/src/xdg.c index 47475f14..82e59ced 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -179,7 +179,7 @@ handle_request_maximize(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, request_maximize); if (!view->mapped && !view->output) { - view->output = output_nearest_to_cursor(view->server); + view_set_output(view, output_nearest_to_cursor(view->server)); } view_maximize(view, xdg_toplevel_from_view(view)->requested.maximized, /*store_natural_geometry*/ true); @@ -191,14 +191,8 @@ set_fullscreen_from_request(struct view *view, { if (!view->fullscreen && requested->fullscreen && requested->fullscreen_output) { - struct output *output = output_from_wlr_output(view->server, - requested->fullscreen_output); - if (output_is_usable(output)) { - view->output = output; - } else { - wlr_log(WLR_ERROR, - "invalid output in fullscreen request"); - } + view_set_output(view, output_from_wlr_output(view->server, + requested->fullscreen_output)); } view_set_fullscreen(view, requested->fullscreen); } @@ -208,7 +202,7 @@ handle_request_fullscreen(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, request_fullscreen); if (!view->mapped && !view->output) { - view->output = output_nearest_to_cursor(view->server); + view_set_output(view, output_nearest_to_cursor(view->server)); } set_fullscreen_from_request(view, &xdg_toplevel_from_view(view)->requested); @@ -315,7 +309,7 @@ position_xdg_toplevel_view(struct view *view) struct view *parent = lookup_view_by_xdg_toplevel( view->server, parent_xdg_toplevel); assert(parent); - view->output = parent->output; + view_set_output(view, parent->output); view_center(view, &parent->pending); } } @@ -341,7 +335,7 @@ xdg_toplevel_view_map(struct view *view) } view->mapped = true; if (!view->output) { - view->output = output_nearest_to_cursor(view->server); + view_set_output(view, output_nearest_to_cursor(view->server)); } struct wlr_xdg_surface *xdg_surface = xdg_surface_from_view(view); view->surface = xdg_surface->surface; diff --git a/src/xwayland.c b/src/xwayland.c index 765f0f16..49f290d3 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -96,7 +96,7 @@ ensure_initial_geometry_and_output(struct view *view) * Just use the cursor output since we don't know yet * whether the surface position is meaningful. */ - view->output = output_nearest_to_cursor(view->server); + view_set_output(view, output_nearest_to_cursor(view->server)); } }