vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Mon Jun 18 20:52:04 2018 +0300| [15b4e1b7ca2f82701c90e839dc93e86bb4208224] | committer: Rémi Denis-Courmont
xdg-shell: report window size correctly If a dimension is zero, then we get to choose it, so we pick the last dimension requested by the core - rather than the current dimension. If a dimension is non-zero, we have to use the value regardless of what the core requested. This fixes incorrect video sizes in fullscreen, maximized or tiled windows. Note: Some window managers may exhibit a bug here, whereby they do not reset the window dimensions to zero after leaving fullscreen/maximized state. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=15b4e1b7ca2f82701c90e839dc93e86bb4208224 --- modules/video_output/wayland/xdg-shell.c | 81 +++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/modules/video_output/wayland/xdg-shell.c b/modules/video_output/wayland/xdg-shell.c index dd95fac9f7..03cc5475a2 100644 --- a/modules/video_output/wayland/xdg-shell.c +++ b/modules/video_output/wayland/xdg-shell.c @@ -81,9 +81,22 @@ struct vout_window_sys_t uint32_t default_output; - unsigned width; - unsigned height; - bool fullscreen; + struct + { + unsigned width; + unsigned height; + } set; + struct + { + unsigned width; + unsigned height; + struct + { + unsigned width; + unsigned height; + bool fullscreen; + } latch; + } wm; # ifdef XDG_SHELL_UNSTABLE bool unstable; #endif @@ -94,6 +107,7 @@ struct vout_window_sys_t struct wl_cursor *cursor; struct wl_surface *cursor_surface; + vlc_mutex_t lock; vlc_thread_t thread; }; @@ -144,6 +158,18 @@ static void *Thread(void *data) //return NULL; } +static void ReportSize(vout_window_t *wnd) +{ + vout_window_sys_t *sys = wnd->sys; + /* Zero wm.width or zero wm.height means the client should choose. + * DO NOT REPORT those values to video output... */ + unsigned width = sys->wm.width ? sys->wm.width : sys->set.width; + unsigned height = sys->wm.height ? sys->wm.height : sys->set.height; + + vout_window_ReportSize(wnd, width, height); + xdg_surface_set_window_geometry(sys->surface, 0, 0, width, height); +} + static int Control(vout_window_t *wnd, int cmd, va_list ap) { vout_window_sys_t *sys = wnd->sys; @@ -159,16 +185,11 @@ static int Control(vout_window_t *wnd, int cmd, va_list ap) unsigned width = va_arg(ap, unsigned); unsigned height = va_arg(ap, unsigned); - /* Unlike X11, the client basically gets to choose its size, which - * is the size of the buffer attached to the surface. - * Note that it is unspecified who "wins" in case of a race - * (e.g. if trying to resize the window, and changing the zoom - * at the same time). With X11, the race is arbitrated by the X11 - * server. With Wayland, it is arbitrated in the client windowing - * code. In this case, it is arbitrated by the window core code. - */ - vout_window_ReportSize(wnd, width, height); - xdg_surface_set_window_geometry(sys->surface, 0, 0, width, height); + vlc_mutex_lock(&sys->lock); + sys->set.width = width; + sys->set.height = height; + ReportSize(wnd); + vlc_mutex_unlock(&sys->lock); break; } @@ -222,8 +243,10 @@ static void xdg_toplevel_configure_cb(void *data, const uint32_t *state; msg_Dbg(wnd, "new configuration: %"PRId32"x%"PRId32, width, height); + sys->wm.latch.width = width; + sys->wm.latch.height = height; + sys->wm.latch.fullscreen = false; - sys->fullscreen = false; wl_array_for_each(state, states) { msg_Dbg(wnd, " - state 0x%04"PRIX32, *state); @@ -231,18 +254,11 @@ static void xdg_toplevel_configure_cb(void *data, switch (*state) { case XDG_TOPLEVEL_STATE_FULLSCREEN: - sys->fullscreen = true; + sys->wm.latch.fullscreen = true; break; } } - /* Zero width or zero height means client (we) should choose. - * DO NOT REPORT those values to video output... */ - if (width != 0) - sys->width = width; - if (height != 0) - sys->height = height; - (void) toplevel; } @@ -266,14 +282,17 @@ static void xdg_surface_configure_cb(void *data, struct xdg_surface *surface, vout_window_t *wnd = data; vout_window_sys_t *sys = wnd->sys; - vout_window_ReportSize(wnd, sys->width, sys->height); + vlc_mutex_lock(&sys->lock); + sys->wm.width = sys->wm.latch.width; + sys->wm.height = sys->wm.latch.height; + ReportSize(wnd); + vlc_mutex_unlock(&sys->lock); - if (sys->fullscreen) + if (sys->wm.latch.fullscreen) vout_window_ReportFullscreen(wnd, NULL); else vout_window_ReportWindowed(wnd); - xdg_surface_set_window_geometry(surface, 0, 0, sys->width, sys->height); xdg_surface_ack_configure(surface, serial); } @@ -448,11 +467,16 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg) sys->deco_manager = NULL; sys->deco = NULL; sys->default_output = var_InheritInteger(wnd, "wl-output"); - sys->width = cfg->width; - sys->height = cfg->height; - sys->fullscreen = false; + sys->wm.width = 0; + sys->wm.height = 0; + sys->wm.latch.width = 0; + sys->wm.latch.height = 0; + sys->wm.latch.fullscreen = false; + sys->set.width = cfg->width; + sys->set.height = cfg->height; wl_list_init(&sys->outputs); wl_list_init(&sys->seats); + vlc_mutex_init(&sys->lock); wnd->sys = sys; wnd->handle.wl = NULL; @@ -613,6 +637,7 @@ static void Close(vout_window_t *wnd) vlc_cancel(sys->thread); vlc_join(sys->thread, NULL); + vlc_mutex_destroy(&sys->lock); seat_destroy_all(&sys->seats); output_destroy_all(&sys->outputs); if (sys->deco != NULL) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
