diff --git a/video/out/gl_wayland.c b/video/out/gl_wayland.c index 0381177292..cb684eb09d 100644 --- a/video/out/gl_wayland.c +++ b/video/out/gl_wayland.c @@ -39,74 +39,42 @@ struct egl_context { } egl; }; -static void egl_resize_func(struct vo_wayland_state *wl, - uint32_t edges, - int32_t width, - int32_t height, - void *user_data) +static void egl_resize(struct vo_wayland_state *wl, + struct egl_context *ctx) { - struct egl_context *ctx = user_data; - int32_t minimum_size = 150; - int32_t x, y; - float temp_aspect = width / (float) MPMAX(height, 1); + int32_t x = wl->window.sh_x; + int32_t y = wl->window.sh_y; + int32_t width = wl->window.sh_width; + int32_t height = wl->window.sh_height; - if (!ctx->egl_window) - return; - - /* get the real window size of the window */ + // get the real size of the window + // this improves moving the window while resizing it wl_egl_window_get_attached_size(ctx->egl_window, &wl->window.width, &wl->window.height); - if (width < minimum_size) - width = minimum_size; - if (height < minimum_size) - height = minimum_size; - - /* if only the height is changed we have to calculate the width - * in any other case we calculate the height */ - switch (edges) { - case WL_SHELL_SURFACE_RESIZE_TOP: - case WL_SHELL_SURFACE_RESIZE_BOTTOM: - width = wl->window.aspect * height; - break; - case WL_SHELL_SURFACE_RESIZE_LEFT: - case WL_SHELL_SURFACE_RESIZE_RIGHT: - case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference - case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT: - case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT: - case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT: - height = (1 / wl->window.aspect) * width; - break; - default: - if (wl->window.aspect < temp_aspect) - width = wl->window.aspect * height; - else - height = (1 / wl->window.aspect) * width; - break; - } - - - if (edges & WL_SHELL_SURFACE_RESIZE_LEFT) - x = wl->window.width - width; - else - x = 0; - - if (edges & WL_SHELL_SURFACE_RESIZE_TOP) - y = wl->window.height - height; - else - y = 0; - MP_VERBOSE(ctx, "resizing %dx%d -> %dx%d\n", wl->window.width, - wl->window.height, width, height); + wl->window.height, + width, + height); + + if (x != 0) + x = wl->window.width - width; + + if (y != 0) + y = wl->window.height - height; + wl_egl_window_resize(ctx->egl_window, width, height, x, y); wl->window.width = width; wl->window.height = height; /* set size for mplayer */ - wl->vo->dwidth = width; - wl->vo->dheight = height; + wl->vo->dwidth = wl->window.width; + wl->vo->dheight = wl->window.height; + + wl->vo->want_redraw = true; + wl->window.events = 0; } static bool egl_create_context(struct vo_wayland_state *wl, @@ -217,9 +185,6 @@ static bool config_window_wayland(struct MPGLContext *ctx, egl_ctx->log = mp_log_new(egl_ctx, wl->log, "EGL"); - wl->window.resize_func = egl_resize_func; - wl->window.resize_func_data = (void*) egl_ctx; - if (!vo_wayland_config(ctx->vo, d_width, d_height, flags)) return false; @@ -262,7 +227,12 @@ static void releaseGlContext_wayland(MPGLContext *ctx) static void swapGlBuffers_wayland(MPGLContext *ctx) { struct egl_context * egl_ctx = ctx->priv; + struct vo_wayland_state *wl = ctx->vo->wayland; + eglSwapBuffers(egl_ctx->egl.dpy, egl_ctx->egl_surface); + + if (wl->window.events & VO_EVENT_RESIZE) + egl_resize(wl, egl_ctx); } void mpgl_set_backend_wayland(MPGLContext *ctx) diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 9e58a3617e..7f9803befc 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -56,10 +56,10 @@ static int lookupkey(int key); static void hide_cursor(struct vo_wayland_state * wl); static void show_cursor(struct vo_wayland_state * wl); -static void resize_window(struct vo_wayland_state *wl, - uint32_t edges, - int32_t width, - int32_t height); +static void shedule_resize(struct vo_wayland_state *wl, + uint32_t edges, + int32_t width, + int32_t height); static void vo_wayland_fullscreen (struct vo *vo); @@ -127,7 +127,7 @@ static void ssurface_handle_configure(void *data, int32_t height) { struct vo_wayland_state *wl = data; - resize_window(wl, edges, width, height); + shedule_resize(wl, edges, width, height); } static void ssurface_handle_popup_done(void *data, @@ -545,20 +545,62 @@ static void show_cursor (struct vo_wayland_state *wl) wl_surface_commit(wl->cursor.surface); } -static void resize_window(struct vo_wayland_state *wl, - uint32_t edges, - int32_t width, - int32_t height) +static void shedule_resize(struct vo_wayland_state *wl, + uint32_t edges, + int32_t width, + int32_t height) { - MP_VERBOSE(wl, "resizing %dx%d -> %dx%d\n", wl->window.width, - wl->window.height, width, height); - if (wl->window.resize_func && wl->window.resize_func_data) { - wl->window.resize_func(wl, edges, width, height, - wl->window.resize_func_data); - wl->window.events |= VO_EVENT_RESIZE; + int32_t minimum_size = 150; + int32_t x, y; + float temp_aspect = width / (float) MPMAX(height, 1); + + if (width < minimum_size) + width = minimum_size; + + if (height < minimum_size) + height = minimum_size; + + /* if only the height is changed we have to calculate the width + * in any other case we calculate the height */ + switch (edges) { + case WL_SHELL_SURFACE_RESIZE_TOP: + case WL_SHELL_SURFACE_RESIZE_BOTTOM: + width = wl->window.aspect * height; + break; + case WL_SHELL_SURFACE_RESIZE_LEFT: + case WL_SHELL_SURFACE_RESIZE_RIGHT: + case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference + case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT: + case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT: + case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT: + height = (1 / wl->window.aspect) * width; + break; + default: + if (wl->window.aspect < temp_aspect) + width = wl->window.aspect * height; + else + height = (1 / wl->window.aspect) * width; + break; } + + wl->vo->dwidth = width; + wl->vo->dheight = height; + + if (edges & WL_SHELL_SURFACE_RESIZE_LEFT) + x = wl->window.width - width; else - MP_WARN(wl, "no resizing possible\n"); + x = 0; + + if (edges & WL_SHELL_SURFACE_RESIZE_TOP) + y = wl->window.height - height; + else + y = 0; + + wl->window.sh_width = width; + wl->window.sh_height = height; + wl->window.sh_x = x; + wl->window.sh_y = y; + wl->window.events |= VO_EVENT_RESIZE; } @@ -747,7 +789,7 @@ static void vo_wayland_fullscreen (struct vo *vo) else { MP_VERBOSE(wl, "leaving fullscreen\n"); wl_shell_surface_set_toplevel(wl->window.shell_surface); - resize_window(wl, 0, wl->window.p_width, wl->window.p_height); + shedule_resize(wl, 0, wl->window.p_width, wl->window.p_height); } } @@ -755,7 +797,6 @@ static int vo_wayland_check_events (struct vo *vo) { struct vo_wayland_state *wl = vo->wayland; struct wl_display *dp = wl->display.display; - int ret; wl_display_dispatch_pending(dp); wl_display_flush(dp); @@ -780,10 +821,8 @@ static int vo_wayland_check_events (struct vo *vo) wl_display_flush(dp); } - ret = wl->window.events; - wl->window.events = 0; - - return ret; + // window events are reset by the resizing code + return wl->window.events; } static void vo_wayland_update_screeninfo (struct vo *vo) diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index bb26f756a2..7e6f000c24 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -65,24 +65,17 @@ struct vo_wayland_state { struct { int32_t width; int32_t height; - int32_t p_width; // previous sizes for leaving fullscreen + int32_t p_width; // previous sizes for leaving fullscreen int32_t p_height; + int32_t sh_width; // sheduled width for resizing + int32_t sh_height; + int32_t sh_x; // x, y calculated with the drag edges for moving + int32_t sh_y; float aspect; struct wl_surface *surface; struct wl_shell_surface *shell_surface; int events; /* mplayer events (VO_EVENT_RESIZE) */ - - /* Because the egl windows have a special resize windw function we have to - * register it first before doing any resizing. - * This makes us independet from the output driver */ - void (*resize_func) (struct vo_wayland_state *wl, - uint32_t edges, - int32_t width, - int32_t height, - void *user_data); - - void *resize_func_data; } window; struct {