From 64bea4f511394f09e9ceca3fab8c5f18ed35a87d Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Mon, 20 Feb 2023 16:22:01 -0500 Subject: [PATCH] view: Attempt to keep non-floating views on the same output - Make view_discover_output() static - Call view_discover_output() only for floating views - Deprecate view_output(); make it use view->output when possible --- include/view.h | 1 - src/view.c | 71 ++++++++++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/include/view.h b/include/view.h index abc8b6ce..cd64a694 100644 --- a/include/view.h +++ b/include/view.h @@ -151,7 +151,6 @@ void view_move_to_workspace(struct view *view, struct workspace *workspace); void view_set_decorations(struct view *view, bool decorations); void view_toggle_fullscreen(struct view *view); void view_adjust_for_layout_change(struct view *view); -void view_discover_output(struct view *view); void view_move_to_edge(struct view *view, const char *direction); void view_snap_to_edge(struct view *view, const char *direction, bool store_natural_geometry); diff --git a/src/view.c b/src/view.c index 9bd38757..dbcbe2f4 100644 --- a/src/view.c +++ b/src/view.c @@ -102,6 +102,31 @@ view_get_edge_snap_box(struct view *view, struct output *output, return dst; } +/* + * At present, a view can only 'enter' one output at a time, although the view + * may span multiple outputs. Ideally we would handle multiple outputs, but + * this method is the simplest form of what we want. + */ +static void +view_discover_output(struct view *view) +{ + assert(view); + view->output = output_nearest_to(view->server, + view->current.x + view->current.width / 2, + view->current.y + view->current.height / 2); +} + +/* deprecated */ +struct output * +view_output(struct view *view) +{ + assert(view); + if (!output_is_usable(view->output)) { + view_discover_output(view); + } + return view->output; +} + static void _view_set_activated(struct view *view, bool activated) { @@ -156,7 +181,14 @@ view_moved(struct view *view) assert(view); wlr_scene_node_set_position(&view->scene_tree->node, view->current.x, view->current.y); - view_discover_output(view); + /* + * Only floating views change output when moved. Non-floating + * views (maximized/tiled/fullscreen) are tied to a particular + * output when they enter that state. + */ + if (view_is_floating(view)) { + view_discover_output(view); + } ssd_update_geometry(view->ssd); cursor_update_focus(view->server); if (view->toplevel.handle) { @@ -221,16 +253,6 @@ view_minimize(struct view *view, bool minimized) } } -/* view_output - return the output that a view is mostly on */ -struct output * -view_output(struct view *view) -{ - assert(view); - return output_nearest_to(view->server, - view->current.x + view->current.width / 2, - view->current.y + view->current.height / 2); -} - static bool view_compute_centered_position(struct view *view, struct output *output, const struct wlr_box *ref, int w, int h, int *x, int *y) @@ -741,8 +763,13 @@ view_adjust_for_layout_change(struct view *view) set_fullscreen(view, false); } - /* Rediscover nearest output as it may have changed */ - view_discover_output(view); + /* + * Floating views are always assigned to the nearest output. + * Maximized/tiled views remain on the same output if possible. + */ + if (view_is_floating(view) || !output_is_usable(view->output)) { + view_discover_output(view); + } if (!view_apply_special_geometry(view)) { if (was_fullscreen) { @@ -761,24 +788,6 @@ view_adjust_for_layout_change(struct view *view) } } -/* - * At present, a view can only 'enter' one output at a time, although the view - * may span multiple outputs. Ideally we would handle multiple outputs, but - * this method is the simplest form of what we want. - */ -void -view_discover_output(struct view *view) -{ - assert(view); - /* - * Fullscreen views are tied to a particular output so don't - * auto-discover output for them. - */ - if (!view->fullscreen) { - view->output = view_output(view); - } -} - void view_evacuate_region(struct view *view) {