mirror of
https://github.com/labwc/labwc.git
synced 2025-11-01 22:58:47 -04:00
view: ensure that floating views don't overlap top panels
The top_left_edge_boundary_check() function in xwayland.c ensures that views trying to position themselves at 0,0 don't end up with a titlebar offscreen. However, it doesn't take into account the usable area and thus these views can still end up overlapping a top panel. Also, there is no good reason for top_left_edge_boundary_check() to be xwayland-specific. This logic should really be part of view_adjust_for_layout_change(). To fix all this, add a new view_adjust_floating_geometry() function, which replaces the existing similar (and duplicated) logic in view_apply_natural_geometry() and view_adjust_for_layout_change(). view_adjust_for_layout_change() is already being called from xwayland's set_initial_position(), so top_left_edge_boundary_check() is now redundant and can just be deleted. Lightly tested with waybar and feh --geometry 640x480+0+0. The feh window is now correctly positioned below waybar, even if started before waybar (in that case, the feh window is moved when waybar starts).
This commit is contained in:
parent
984aeb0b0b
commit
57075ce864
3 changed files with 49 additions and 33 deletions
64
src/view.c
64
src/view.c
|
|
@ -542,6 +542,7 @@ bool
|
|||
view_compute_centered_position(struct view *view, const struct wlr_box *ref,
|
||||
int w, int h, int *x, int *y)
|
||||
{
|
||||
assert(view);
|
||||
if (w <= 0 || h <= 0) {
|
||||
wlr_log(WLR_ERROR, "view has empty geometry, not centering");
|
||||
return false;
|
||||
|
|
@ -577,6 +578,47 @@ view_compute_centered_position(struct view *view, const struct wlr_box *ref,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
view_adjust_floating_geometry(struct view *view, struct wlr_box *geometry)
|
||||
{
|
||||
assert(view);
|
||||
if (!output_is_usable(view->output)) {
|
||||
wlr_log(WLR_ERROR, "view has no output, not positioning");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool adjusted = false;
|
||||
/*
|
||||
* First check whether the view is onscreen. For now, "onscreen"
|
||||
* is defined as even one pixel of the client area being visible.
|
||||
*/
|
||||
if (wlr_output_layout_intersects(view->server->output_layout,
|
||||
NULL, geometry)) {
|
||||
/*
|
||||
* If onscreen, then make sure the titlebar is also
|
||||
* visible (and not overlapping any panels/docks)
|
||||
*/
|
||||
struct border margin = ssd_get_margin(view->ssd);
|
||||
struct wlr_box usable =
|
||||
output_usable_area_in_layout_coords(view->output);
|
||||
|
||||
if (geometry->x < usable.x + margin.left) {
|
||||
geometry->x = usable.x + margin.left;
|
||||
adjusted = true;
|
||||
}
|
||||
if (geometry->y < usable.y + margin.top) {
|
||||
geometry->y = usable.y + margin.top;
|
||||
adjusted = true;
|
||||
}
|
||||
} else {
|
||||
/* If offscreen, then just center the view */
|
||||
adjusted = view_compute_centered_position(view, NULL,
|
||||
geometry->width, geometry->height,
|
||||
&geometry->x, &geometry->y);
|
||||
}
|
||||
return adjusted;
|
||||
}
|
||||
|
||||
static void
|
||||
set_fallback_geometry(struct view *view)
|
||||
{
|
||||
|
|
@ -630,19 +672,9 @@ view_apply_natural_geometry(struct view *view)
|
|||
assert(view);
|
||||
assert(view_is_floating(view));
|
||||
|
||||
struct wlr_output_layout *layout = view->server->output_layout;
|
||||
if (wlr_output_layout_intersects(layout, NULL, &view->natural_geometry)
|
||||
|| wl_list_empty(&layout->outputs)) {
|
||||
/* restore to original geometry */
|
||||
view_move_resize(view, view->natural_geometry);
|
||||
} 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)) {
|
||||
view_move_resize(view, box);
|
||||
}
|
||||
}
|
||||
struct wlr_box geometry = view->natural_geometry;
|
||||
view_adjust_floating_geometry(view, &geometry);
|
||||
view_move_resize(view, geometry);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1147,9 +1179,9 @@ view_adjust_for_layout_change(struct view *view)
|
|||
view_apply_natural_geometry(view);
|
||||
} else {
|
||||
/* reposition view if it's offscreen */
|
||||
if (!wlr_output_layout_intersects(view->server->output_layout,
|
||||
NULL, &view->pending)) {
|
||||
view_center(view, NULL);
|
||||
struct wlr_box geometry = view->pending;
|
||||
if (view_adjust_floating_geometry(view, &geometry)) {
|
||||
view_move_resize(view, geometry);
|
||||
}
|
||||
}
|
||||
if (view->toplevel.handle) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue