Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 66 additions & 26 deletions video/out/wayland_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ static void set_surface_scaling(struct vo_wayland_state *wl);
static void update_output_scaling(struct vo_wayland_state *wl);
static void update_output_geometry(struct vo_wayland_state *wl);
static void destroy_offer(struct vo_wayland_data_offer *o);
static void apply_toplevel_config(struct vo_wayland_state *wl);
static void apply_decorations(struct vo_wayland_state *wl);
#if HAVE_WAYLAND_PROTOCOLS_1_48
static char *session_file(void *talloc_ctx, const char *session, struct vo *vo);
static char *read_session_id(void *talloc_ctx, struct vo_wayland_state *wl, const char *path);
Expand Down Expand Up @@ -1777,7 +1779,12 @@ static const struct xdg_wm_base_listener xdg_wm_base_listener = {
static void handle_surface_config(void *data, struct xdg_surface *surface,
uint32_t serial)
{
struct vo_wayland_state *wl = data;

apply_decorations(wl);
apply_toplevel_config(wl);
xdg_surface_ack_configure(surface, serial);
wl->pending_vo_events |= VO_EVENT_EXPOSE;
}

static const struct xdg_surface_listener xdg_surface_listener = {
Expand All @@ -1788,55 +1795,75 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
int32_t width, int32_t height, struct wl_array *states)
{
struct vo_wayland_state *wl = data;
struct mp_vo_opts *opts = wl->opts;
struct mp_rect old_geometry = wl->geometry;
struct vo_wayland_toplevel_pending_state *pending = &wl->pending_state;
struct vo_wayland_toplevel_pending_flags *flags = &pending->flags;

if (width < 0 || height < 0) {
MP_WARN(wl, "Compositor sent negative width/height values. Treating them as zero.\n");
width = height = 0;
}

bool is_maximized = false;
bool is_fullscreen = false;
bool is_activated = false;
bool is_resizing = false;
bool is_suspended = false;
bool is_tiled = false;
pending->width = width;
pending->height = height;
*flags = (struct vo_wayland_toplevel_pending_flags){ 0 };

enum xdg_toplevel_state *state;
wl_array_for_each(state, states) {
switch (*state) {
case XDG_TOPLEVEL_STATE_FULLSCREEN:
is_fullscreen = true;
flags->is_fullscreen = true;
break;
case XDG_TOPLEVEL_STATE_RESIZING:
is_resizing = true;
flags->is_resizing = true;
break;
case XDG_TOPLEVEL_STATE_ACTIVATED:
is_activated = true;
/*
* If we get an ACTIVATED state, we know it cannot be
* minimized, but it may not have been minimized
* previously, so we can't detect the exact state.
*/
opts->window_minimized = false;
m_config_cache_write_opt(wl->opts_cache,
&opts->window_minimized);
flags->is_activated = true;
break;
case XDG_TOPLEVEL_STATE_TILED_TOP:
case XDG_TOPLEVEL_STATE_TILED_LEFT:
case XDG_TOPLEVEL_STATE_TILED_RIGHT:
case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
is_tiled = true;
flags->is_tiled = true;
break;
case XDG_TOPLEVEL_STATE_MAXIMIZED:
is_maximized = true;
flags->is_maximized = true;
break;
case XDG_TOPLEVEL_STATE_SUSPENDED:
is_suspended = true;
flags->is_suspended = true;
break;
}
}
}

static void apply_toplevel_config(struct vo_wayland_state *wl)
{
struct mp_vo_opts *opts = wl->opts;
struct mp_rect old_geometry = wl->geometry;
struct vo_wayland_toplevel_pending_state *pending = &wl->pending_state;
struct vo_wayland_toplevel_pending_flags *flags = &pending->flags;

wl->bounded_width = pending->bounded_width;
wl->bounded_height = pending->bounded_height;

int32_t width = pending->width;
int32_t height = pending->height;
bool is_maximized = flags->is_maximized;
bool is_fullscreen = flags->is_fullscreen;
bool is_activated = flags->is_activated;
bool is_resizing = flags->is_resizing;
bool is_suspended = flags->is_suspended;
bool is_tiled = flags->is_tiled;

if (is_activated) {
/*
* If we get an ACTIVATED state, we know it cannot be
* minimized, but it may not have been minimized
* previously, so we can't detect the exact state.
*/
opts->window_minimized = false;
m_config_cache_write_opt(wl->opts_cache,
&opts->window_minimized);
}
/* Only update the toplevel state values if either mpv already has
* configured its initial geometry or if the compositor gives us some
* initial state to use. */
Expand Down Expand Up @@ -1934,8 +1961,6 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel,
mp_rect_w(old_geometry), mp_rect_h(old_geometry),
mp_rect_w(wl->geometry), mp_rect_h(wl->geometry));
wl->pending_vo_events |= VO_EVENT_RESIZE;
} else if (wl->resizing) {
wl->pending_vo_events |= VO_EVENT_EXPOSE;
}

wl->override_surface_local = width == 0 || height == 0 || wl->reconfigured;
Expand All @@ -1953,8 +1978,8 @@ static void handle_configure_bounds(void *data, struct xdg_toplevel *xdg_topleve
int32_t width, int32_t height)
{
struct vo_wayland_state *wl = data;
wl->bounded_width = handle_round(wl->scaling, width);
wl->bounded_height = handle_round(wl->scaling, height);
wl->pending_state.bounded_width = handle_round(wl->scaling, width);
wl->pending_state.bounded_height = handle_round(wl->scaling, height);
}

static void handle_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel,
Expand Down Expand Up @@ -2488,7 +2513,22 @@ static void configure_decorations(void *data,
uint32_t mode)
{
struct vo_wayland_state *wl = data;
struct vo_wayland_toplevel_pending_state *pending = &wl->pending_state;

pending->new_decoration_mode = mode;
}

static void apply_decorations(struct vo_wayland_state *wl)
{
struct mp_vo_opts *opts = wl->opts;
struct vo_wayland_toplevel_pending_state *pending = &wl->pending_state;
uint32_t mode = pending->new_decoration_mode;

if (mode == 0) {
return;
}

pending->new_decoration_mode = 0;

if (wl->requested_decoration && mode != wl->requested_decoration) {
MP_DBG(wl,
Expand Down
19 changes: 19 additions & 0 deletions video/out/wayland_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ struct drm_format {
uint64_t modifier;
};

struct vo_wayland_toplevel_pending_flags {
bool is_maximized;
bool is_fullscreen;
bool is_activated;
bool is_resizing;
bool is_suspended;
bool is_tiled;
};

struct vo_wayland_toplevel_pending_state {
int32_t bounded_width;
int32_t bounded_height;
int32_t width;
int32_t height;
struct vo_wayland_toplevel_pending_flags flags;
uint32_t new_decoration_mode;
};

struct vo_wayland_state {
struct m_config_cache *opts_cache;
struct mp_log *log;
Expand Down Expand Up @@ -69,6 +87,7 @@ struct vo_wayland_state {
bool override_surface_local;

/* State */
struct vo_wayland_toplevel_pending_state pending_state;
bool activated;
bool focused;
bool frame_wait;
Expand Down
Loading