mirror of
https://github.com/mpv-player/mpv
synced 2024-12-23 15:22:09 +00:00
wayland: reworked resizing
This fixes 2 bugs: * Resizing very fast breaks the aspect of the window and the width and height don't match with the video anymore * Pressing 'f' for fullscreen very fast can overwrite the backup variables for the previous width and height. Also includes a better aspect calculation with fluid resizing.
This commit is contained in:
parent
c653697610
commit
2c6c842719
@ -39,49 +39,52 @@ struct egl_context {
|
||||
};
|
||||
|
||||
static void egl_resize_func(struct vo_wayland_state *wl,
|
||||
struct egl_context *ctx)
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
void *user_data)
|
||||
{
|
||||
int32_t x, y, scaled_height;
|
||||
double ratio;
|
||||
int minimum_size = 50;
|
||||
struct vo_wayland_window *w = wl->window;
|
||||
struct egl_context *ctx = user_data;
|
||||
int32_t minimum_size = 150;
|
||||
int32_t x, y;
|
||||
|
||||
if (wl->window->pending_width < minimum_size)
|
||||
wl->window->pending_width = minimum_size;
|
||||
if (wl->window->pending_height < minimum_size)
|
||||
wl->window->pending_height = minimum_size;
|
||||
/* get the real window size of the window */
|
||||
wl_egl_window_get_attached_size(ctx->egl_window,
|
||||
&wl->window->width,
|
||||
&wl->window->height);
|
||||
|
||||
ratio = (double) wl->vo->aspdat.orgw / wl->vo->aspdat.orgh;
|
||||
scaled_height = wl->window->pending_height * ratio;
|
||||
if (wl->window->pending_width > scaled_height) {
|
||||
wl->window->pending_height = wl->window->pending_width / ratio;
|
||||
} else {
|
||||
wl->window->pending_width = scaled_height;
|
||||
}
|
||||
if (width < minimum_size)
|
||||
width = minimum_size;
|
||||
if (height < minimum_size)
|
||||
height = minimum_size;
|
||||
|
||||
if (wl->window->edges & WL_SHELL_SURFACE_RESIZE_LEFT)
|
||||
x = wl->window->width - wl->window->pending_width;
|
||||
/* if only the height is changed we have to calculate the width
|
||||
* in any other case we calculate the height */
|
||||
if (edges == WL_SHELL_SURFACE_RESIZE_BOTTOM ||
|
||||
edges == WL_SHELL_SURFACE_RESIZE_TOP)
|
||||
width = wl->vo->aspdat.asp * height;
|
||||
else
|
||||
height = (1 / wl->vo->aspdat.asp) * width;
|
||||
|
||||
if (edges & WL_SHELL_SURFACE_RESIZE_LEFT)
|
||||
x = w->width - width;
|
||||
else
|
||||
x = 0;
|
||||
|
||||
if (wl->window->edges & WL_SHELL_SURFACE_RESIZE_TOP)
|
||||
y = wl->window->height - wl->window->pending_height;
|
||||
if (edges & WL_SHELL_SURFACE_RESIZE_TOP)
|
||||
y = w->height - height;
|
||||
else
|
||||
y = 0;
|
||||
|
||||
wl_egl_window_resize(ctx->egl_window,
|
||||
wl->window->pending_width,
|
||||
wl->window->pending_height,
|
||||
x, y);
|
||||
wl_egl_window_resize(ctx->egl_window, width, height, x, y);
|
||||
|
||||
wl->window->width = wl->window->pending_width;
|
||||
wl->window->height = wl->window->pending_height;
|
||||
w->width = width;
|
||||
w->height = height;
|
||||
|
||||
/* set size for mplayer */
|
||||
wl->vo->dwidth = wl->window->pending_width;
|
||||
wl->vo->dheight = wl->window->pending_height;
|
||||
wl->window->events |= VO_EVENT_RESIZE;
|
||||
wl->window->edges = 0;
|
||||
wl->window->resize_needed = 0;
|
||||
wl->vo->dwidth = width;
|
||||
wl->vo->dheight = height;
|
||||
}
|
||||
|
||||
static bool egl_create_context(struct vo_wayland_state *wl,
|
||||
@ -166,6 +169,7 @@ static void egl_create_window(struct vo_wayland_state *wl,
|
||||
egl_ctx->egl.ctx);
|
||||
|
||||
wl_display_dispatch_pending(wl->display->display);
|
||||
|
||||
}
|
||||
|
||||
static bool config_window_wayland(struct MPGLContext *ctx,
|
||||
@ -178,8 +182,8 @@ static bool config_window_wayland(struct MPGLContext *ctx,
|
||||
bool enable_alpha = !!(flags & VOFLAG_ALPHA);
|
||||
bool ret = false;
|
||||
|
||||
wl->window->pending_width = d_width;
|
||||
wl->window->pending_height = d_height;
|
||||
wl->window->resize_func = egl_resize_func;
|
||||
wl->window->resize_func_data = (void*) egl_ctx;
|
||||
wl->window->width = d_width;
|
||||
wl->window->height = d_height;
|
||||
|
||||
@ -202,7 +206,7 @@ static bool config_window_wayland(struct MPGLContext *ctx,
|
||||
else {
|
||||
/* If the window exists just resize it */
|
||||
if (egl_ctx->egl_window)
|
||||
egl_resize_func(wl, egl_ctx);
|
||||
egl_resize_func(wl, 0, d_width, d_height, egl_ctx);
|
||||
|
||||
else {
|
||||
/* If the context exists and the hidden flag is unset then
|
||||
@ -231,18 +235,7 @@ 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);
|
||||
|
||||
/* resize window after the buffers have swapped
|
||||
* makes resizing more fluid */
|
||||
if (wl->window->resize_needed) {
|
||||
wl_egl_window_get_attached_size(egl_ctx->egl_window,
|
||||
&wl->window->width,
|
||||
&wl->window->height);
|
||||
egl_resize_func(wl, egl_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void mpgl_set_backend_wayland(MPGLContext *ctx)
|
||||
|
@ -59,6 +59,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);
|
||||
|
||||
|
||||
/*** wayland interface ***/
|
||||
@ -71,16 +75,6 @@ static void ssurface_handle_ping(void *data,
|
||||
wl_shell_surface_pong(shell_surface, serial);
|
||||
}
|
||||
|
||||
static void ssurface_schedule_resize(struct vo_wayland_window *window,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
window->pending_width = width;
|
||||
window->pending_height = height;
|
||||
window->resize_needed = 1;
|
||||
window->events |= VO_EVENT_RESIZE;
|
||||
}
|
||||
|
||||
static void ssurface_handle_configure(void *data,
|
||||
struct wl_shell_surface *shell_surface,
|
||||
uint32_t edges,
|
||||
@ -88,9 +82,7 @@ static void ssurface_handle_configure(void *data,
|
||||
int32_t height)
|
||||
{
|
||||
struct vo_wayland_state *wl = data;
|
||||
|
||||
wl->window->edges = edges;
|
||||
ssurface_schedule_resize(wl->window, width, height);
|
||||
resize_window(wl, edges, width, height);
|
||||
}
|
||||
|
||||
static void ssurface_handle_popup_done(void *data,
|
||||
@ -560,6 +552,21 @@ static void show_cursor (struct vo_wayland_state *wl)
|
||||
display->cursor.mouse_waiting_hide = true;
|
||||
}
|
||||
|
||||
static void resize_window(struct vo_wayland_state *wl,
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
struct vo_wayland_window *w = wl->window;
|
||||
if (w->resize_func && w->resize_func_data) {
|
||||
w->resize_func(wl, edges, width, height, w->resize_func_data);
|
||||
w->events |= VO_EVENT_RESIZE;
|
||||
}
|
||||
else
|
||||
mp_msg(MSGT_VO, MSGL_WARN, "[waylnad] No resizing possible!\n");
|
||||
}
|
||||
|
||||
|
||||
static bool create_display (struct vo_wayland_state *wl)
|
||||
{
|
||||
struct vo_wayland_display *d = wl->display;
|
||||
@ -742,8 +749,7 @@ void vo_wayland_fullscreen (struct vo *vo)
|
||||
|
||||
else {
|
||||
wl_shell_surface_set_toplevel(wl->window->shell_surface);
|
||||
ssurface_schedule_resize(wl->window, wl->window->p_width,
|
||||
wl->window->p_height);
|
||||
resize_window(wl, 0, wl->window->p_width, wl->window->p_height);
|
||||
wl->window->type = TYPE_TOPLEVEL;
|
||||
vo->opts->fs = false;
|
||||
|
||||
|
@ -35,6 +35,8 @@ enum vo_wayland_window_type {
|
||||
};
|
||||
|
||||
struct vo;
|
||||
struct vo_wayland_state;
|
||||
|
||||
|
||||
struct vo_wayland_output {
|
||||
uint32_t id; /* unique name */
|
||||
@ -81,17 +83,23 @@ struct vo_wayland_window {
|
||||
int32_t p_width;
|
||||
int32_t p_height;
|
||||
|
||||
int32_t pending_width;
|
||||
int32_t pending_height;
|
||||
uint32_t edges;
|
||||
int resize_needed;
|
||||
|
||||
struct wl_surface *surface;
|
||||
struct wl_shell_surface *shell_surface;
|
||||
|
||||
int events; /* mplayer events */
|
||||
int events; /* mplayer events (VO_EVENT_RESIZE) */
|
||||
|
||||
enum vo_wayland_window_type type; /* is fullscreen */
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
struct vo_wayland_input {
|
||||
|
Loading…
Reference in New Issue
Block a user