From de6a452039262fdd2700a6319346db744565f8e6 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 2 Feb 2014 01:35:46 +0100 Subject: x11: fix race condition when setting aspect when leaving fullscreen vo_opengl creates a hidden X11 window to probe the OpenGL context. It must do that before creating a visible window, because VO creation and VO config are separate phases. There's a race condition involving the hidden window: when starting with --fs, and then leaving fullscreen, the unfullscreened window is sometimes set to the aspect ratio of the hidden window. I'm not sure why the window size itself uses the correct size (but corrupted by the wrong aspect), but that's perhaps because the window manager is free to ignore the size hint while honoring the aspect, or something equally messed up. It turns out this happens because x11_common.c thinks the size of the hidden window is the size of the unfullscreened window. This in turn happens because vo_x11_update_geometry() reads the size of the hidden window when called in vo_x11_fullscreen() (called from vo_x11_config_vo_window()) when mapping the fullscreen window. At that point, the window could be mapped, but not necessarily. If it's not mapped, it will get the size of the unfullscreened window... I think. One could fix this by actively waiting until the window is mapped. Try to pick a less hacky approach instead, and never read the window size until MapNotify is received. vo_x11_create_window() needs a hack, because we'd possibly set the VO's size to 0, resulting e.g. in vdpau to fail initialization. (It'll print error messages until a proper resize is received.) Conflicts: video/out/x11_common.c --- video/out/x11_common.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 9b5d5cb929..2c29242af6 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -826,6 +826,8 @@ int vo_x11_check_events(struct vo *vo) break; } case MapNotify: + x11->window_hidden = false; + vo_x11_update_geometry(vo); x11->vo_hint.win_gravity = x11->old_gravity; XSetWMNormalHints(display, x11->window, &x11->vo_hint); x11->fs_flip = 0; @@ -1129,13 +1131,18 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y, vo_x11_set_wm_icon(x11); vo_x11_update_window_title(vo); + + // The real size is only known when the window is mapped, which + // unfortunately happens asynchronous to VO initialization. At least + // vdpau needs a _some_ window size, though. + x11->win_width = w; + x11->win_height = h; } static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h) { struct vo_x11_state *x11 = vo->x11; - x11->window_hidden = false; vo_x11_move_resize(vo, true, true, x, y, w, h); if (!vo->opts->border) vo_x11_decoration(vo, 0); @@ -1342,6 +1349,8 @@ static void vo_x11_update_geometry(struct vo *vo) int dummy_int; Window dummy_win; Window win = vo->opts->WinID > 0 ? vo->opts->WinID : x11->window; + if (x11->window_hidden) + return; XGetGeometry(x11->display, win, &dummy_win, &dummy_int, &dummy_int, &w, &h, &dummy_int, &dummy_uint); if (w <= INT_MAX && h <= INT_MAX) { -- cgit v1.2.3