[vlc-commits] xdg-shell: report window size correctly
Rémi Denis-Courmont
git at videolan.org
Mon Jun 18 20:05:57 CEST 2018
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | 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)
More information about the vlc-commits
mailing list