From 74bc16910a773b697c16bbc004142858ffe8c835 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sun, 19 Feb 2023 12:42:21 -0500 Subject: [PATCH] xdg: Use view_center() for parent-relative centering - Add optional struct wlr_box* ref argument to view_center() - Perform margin adjustment within view_center() - Expose view_output() to fetch parent's output --- include/view.h | 4 +++- src/view.c | 36 ++++++++++++++++++------------------ src/xdg.c | 15 +++------------ src/xwayland.c | 3 ++- 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/include/view.h b/include/view.h index 777056c8..ead6d6cf 100644 --- a/include/view.h +++ b/include/view.h @@ -129,9 +129,11 @@ void view_move_resize(struct view *view, struct wlr_box geo); void view_move(struct view *view, int x, int y); void view_moved(struct view *view); void view_minimize(struct view *view, bool minimized); +struct output *view_output(struct view *view); void view_store_natural_geometry(struct view *view); /* output is optional, defaults to current nearest output */ -void view_center(struct view *view, struct output *output); +void view_center(struct view *view, struct output *output, + const struct wlr_box *ref); void view_restore_to(struct view *view, struct wlr_box geometry); void view_set_untiled(struct view *view); void view_maximize(struct view *view, bool maximize, diff --git a/src/view.c b/src/view.c index 2ff89055..e4ee48c3 100644 --- a/src/view.c +++ b/src/view.c @@ -222,7 +222,7 @@ view_minimize(struct view *view, bool minimized) } /* view_output - return the output that a view is mostly on */ -static struct output * +struct output * view_output(struct view *view) { assert(view); @@ -239,7 +239,7 @@ view_output(struct view *view) static bool view_compute_centered_position(struct view *view, struct output *output, - int w, int h, int *x, int *y) + const struct wlr_box *ref, int w, int h, int *x, int *y) { if (w <= 0 || h <= 0) { wlr_log(WLR_ERROR, "view has empty geometry, not centering"); @@ -256,8 +256,13 @@ view_compute_centered_position(struct view *view, struct output *output, struct wlr_box usable = output_usable_area_in_layout_coords(output); int width = w + margin.left + margin.right; int height = h + margin.top + margin.bottom; - *x = usable.x + (usable.width - width) / 2; - *y = usable.y + (usable.height - height) / 2; + + /* If reference box is NULL then center to usable area */ + if (!ref) { + ref = &usable; + } + *x = ref->x + (ref->width - width) / 2; + *y = ref->y + (ref->height - height) / 2; /* If view is bigger than usable area, just top/left align it */ if (*x < usable.x) { @@ -267,13 +272,8 @@ view_compute_centered_position(struct view *view, struct output *output, *y = usable.y; } -#if HAVE_XWAYLAND - /* TODO: refactor xwayland.c functions to get rid of this */ - if (view->type == LAB_XWAYLAND_VIEW) { - *x += margin.left; - *y += margin.top; - } -#endif + *x += margin.left; + *y += margin.top; return true; } @@ -283,7 +283,7 @@ set_fallback_geometry(struct view *view) { view->natural_geometry.width = LAB_FALLBACK_WIDTH; view->natural_geometry.height = LAB_FALLBACK_HEIGHT; - view_compute_centered_position(view, NULL, + view_compute_centered_position(view, NULL, NULL, view->natural_geometry.width, view->natural_geometry.height, &view->natural_geometry.x, @@ -315,12 +315,12 @@ view_store_natural_geometry(struct view *view) } void -view_center(struct view *view, struct output *output) +view_center(struct view *view, struct output *output, const struct wlr_box *ref) { assert(view); int x, y; - if (view_compute_centered_position(view, output, view->pending.width, - view->pending.height, &x, &y)) { + if (view_compute_centered_position(view, output, ref, + view->pending.width, view->pending.height, &x, &y)) { view_move(view, x, y); } } @@ -336,8 +336,8 @@ view_apply_natural_geometry(struct view *view) } else { /* reposition if original geometry is offscreen */ struct wlr_box box = view->natural_geometry; - if (view_compute_centered_position(view, NULL, box.width, - box.height, &box.x, &box.y)) { + if (view_compute_centered_position(view, NULL, NULL, + box.width, box.height, &box.x, &box.y)) { view_move_resize(view, box); } } @@ -744,7 +744,7 @@ view_adjust_for_layout_change(struct view *view) /* reposition view if it's offscreen */ if (!wlr_output_layout_intersects(view->server->output_layout, NULL, &view->pending)) { - view_center(view, NULL); + view_center(view, NULL, NULL); } } if (view->toplevel.handle) { diff --git a/src/xdg.c b/src/xdg.c index c9e1a3c3..99b54b75 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -273,12 +273,12 @@ lookup_view_by_xdg_toplevel(struct server *server, static void position_xdg_toplevel_view(struct view *view) { - struct wlr_xdg_surface *xdg_surface = xdg_surface_from_view(view); struct wlr_xdg_toplevel *parent_xdg_toplevel = xdg_toplevel_from_view(view)->parent; if (!parent_xdg_toplevel) { - view_center(view, output_from_cursor_coords(view->server)); + view_center(view, output_from_cursor_coords(view->server), + NULL); } else { /* * If child-toplevel-views, we center-align relative to their @@ -287,17 +287,8 @@ position_xdg_toplevel_view(struct view *view) struct view *parent = lookup_view_by_xdg_toplevel( view->server, parent_xdg_toplevel); assert(parent); - int center_x = parent->current.x + parent->current.width / 2; - int center_y = parent->current.y + parent->current.height / 2; - view->current.x = center_x - - xdg_surface->current.geometry.width / 2; - view->current.y = center_y - - xdg_surface->current.geometry.height / 2; + view_center(view, view_output(parent), &parent->pending); } - - struct border margin = ssd_get_margin(view->ssd); - view->current.x += margin.left; - view->current.y += margin.top; } static const char * diff --git a/src/xwayland.c b/src/xwayland.c index 8f94b105..14d4951d 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -440,7 +440,8 @@ set_initial_position(struct view *view, /* Just make sure the view is on-screen */ view_adjust_for_layout_change(view); } else { - view_center(view, output_from_cursor_coords(view->server)); + view_center(view, output_from_cursor_coords(view->server), + NULL); } }