xwayland: Be more selective about updating natural geometry

For maximized/fullscreen/tiled views, interpret ConfigureRequest as
updating the natural geometry only if it's still zero. Wait as long as
possible before setting the fallback geometry in order to prefer any
geometry we might get from ConfigureRequests.

Fixes an issue with xfce4-terminal (XWayland mode), where after tiling,
the natural geometry was incorrectly overwritten with the tiled
geometry.

Fixes: 09599861ac
("xwayland: Fix size issue when starting VLC fullscreen")
This commit is contained in:
John Lindgren 2023-02-17 09:26:35 -05:00
parent 49c9466039
commit ee3d229948
2 changed files with 43 additions and 42 deletions

View file

@ -279,21 +279,6 @@ view_compute_centered_position(struct view *view, int w, int h, int *x, int *y)
return true;
}
static void
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,
view->natural_geometry.width,
view->natural_geometry.height,
&view->natural_geometry.x,
&view->natural_geometry.y);
}
#undef LAB_FALLBACK_WIDTH
#undef LAB_FALLBACK_HEIGHT
void
view_store_natural_geometry(struct view *view)
{
@ -303,14 +288,7 @@ view_store_natural_geometry(struct view *view)
return;
}
/**
* If an application was started maximized or fullscreened, its
* natural_geometry width/height may still be zero in which case we set
* some fallback values. This is the case with foot and Qt applications.
*/
if (wlr_box_empty(&view->pending)) {
set_fallback_geometry(view);
} else {
if (!wlr_box_empty(&view->pending)) {
view->natural_geometry = view->pending;
}
}
@ -329,19 +307,32 @@ view_center(struct view *view)
static void
view_apply_natural_geometry(struct view *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, box.width, box.height,
&box.x, &box.y)) {
view_move_resize(view, box);
}
assert(view);
assert(view_is_floating(view));
struct wlr_box box = view->natural_geometry;
/**
* If an application was started maximized or fullscreened, its
* natural_geometry width/height may still be zero in which case we set
* some fallback values. This is the case with foot and Qt applications.
*/
if (wlr_box_empty(&box)) {
box.width = LAB_FALLBACK_WIDTH;
box.height = LAB_FALLBACK_HEIGHT;
view_compute_centered_position(view, box.width, box.height,
&box.x, &box.y);
} else if (!wlr_output_layout_intersects(view->server->output_layout,
NULL, &box)) {
/*
* Try to reposition if original geometry is offscreen.
* If the repositioning fails (e.g. no usable output) we
* will just restore the original geometry as-is.
*/
view_compute_centered_position(view, box.width, box.height,
&box.x, &box.y);
}
view_move_resize(view, box);
}
static void

View file

@ -307,15 +307,25 @@ handle_request_configure(struct wl_listener *listener, void *data)
/*
* If a configure request is received while maximized/
* fullscreen/tiled, update the natural geometry only. This
* appears to be the desired behavior e.g. when starting VLC in
* fullscreen mode.
* fullscreen/tiled, we use some heuristics to update the
* natural geometry, but otherwise ignore the request.
*
* This is not 100% reliable since we don't really know what the
* application is trying to do. Some (e.g. VLC starting in
* fullscreen) do use ConfigureRequest to set natural geometry.
* Others (e.g. xfce4-terminal) use ConfigureRequest in an
* attempt to enforce size increments (which we ignore for
* maximized/fullscreen/tiled windows).
*/
if (!view_is_floating(view)) {
view->natural_geometry.x = event->x;
view->natural_geometry.y = event->y;
view->natural_geometry.width = width;
view->natural_geometry.height = height;
if (!view->natural_geometry.x && !view->natural_geometry.y) {
view->natural_geometry.x = event->x;
view->natural_geometry.y = event->y;
}
if (wlr_box_empty(&view->natural_geometry)) {
view->natural_geometry.width = width;
view->natural_geometry.height = height;
}
return;
}