Skip to content

Commit ab64fa7

Browse files
committed
wayland: set geometry directly to output resolution for fullscreen
Unfortunately due to the way fractional scaling on wayland works, it can lead to rounding errors when calculating the physical size of the buffer. It's convoluted but essentially the compositor will communicate the logical size back to us. Depending on the fractional scale factor, the communicated size can be truncated in a significant enough way that causes final calculated size to be off by a maximum of two (truncation at both steps). In general, there's nothing we can really do about this but for specifically fullscreen there's an easy enough workaround. Just set the size to be the same as the output. Since we might not have rendered the surface yet (and thus not have an easily accessible wl->current_output), it's easier to just loop through the output list until we have a match. Fixes #17415.
1 parent 102e693 commit ab64fa7

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

video/out/wayland_common.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ static void add_feedback(struct vo_wayland_feedback_pool *fback_pool,
310310
struct wp_presentation_feedback *fback);
311311
static void apply_keepaspect(struct vo_wayland_state *wl, int *width, int *height);
312312
static void get_compositor_preferred_description(struct vo_wayland_state *wl);
313+
static void get_fullscreen_dims(struct vo_wayland_state *wl);
313314
static void get_shape_device(struct vo_wayland_state *wl, struct vo_wayland_seat *s);
314315
static void guess_focus(struct vo_wayland_state *wl);
315316
static void handle_key_input(struct vo_wayland_seat *s, uint32_t key, uint32_t state, bool no_emit);
@@ -1921,6 +1922,8 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
19211922
wl->geometry.x1 = handle_round(wl->scaling, width);
19221923
wl->geometry.y1 = handle_round(wl->scaling, height);
19231924

1925+
get_fullscreen_dims(wl);
1926+
19241927
if (mp_rect_equals(&old_geometry, &wl->geometry))
19251928
return;
19261929

@@ -3128,6 +3131,26 @@ static void get_compositor_preferred_description(struct vo_wayland_state *wl)
31283131
#endif
31293132
}
31303133

3134+
static void get_fullscreen_dims(struct vo_wayland_state *wl)
3135+
{
3136+
if (!wl->opts->fullscreen || !wl->fractional_scale_manager)
3137+
return;
3138+
3139+
// Fractional scaling can have pixel rounding errors (max of 2).
3140+
// For fullscreen, loop through output geometry and find a valid match.
3141+
int width = mp_rect_w(wl->geometry);
3142+
int height = mp_rect_h(wl->geometry);
3143+
struct vo_wayland_output *output;
3144+
wl_list_for_each(output, &wl->output_list, link) {
3145+
if (abs(mp_rect_w(output->geometry) - width <= 2) && abs(mp_rect_h(output->geometry) - height) <= 2) {
3146+
wl->geometry.x1 = mp_rect_w(output->geometry);
3147+
wl->geometry.y1 = mp_rect_h(output->geometry);
3148+
return;
3149+
}
3150+
}
3151+
return;
3152+
}
3153+
31313154
static void get_shape_device(struct vo_wayland_state *wl, struct vo_wayland_seat *s)
31323155
{
31333156
if (!s->cursor_shape_device && wl->cursor_shape_manager) {

0 commit comments

Comments
 (0)