summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2023-05-19 17:07:25 -0500
committerDudemanguy <random342@airmail.cc>2023-07-09 18:10:19 +0000
commit589da09e5a9f3bebf0fe3e81f191f988fd85ecc2 (patch)
treefd4e8b305588abb543248cb83344978b2511a010 /video
parentfc3e28f1e9be65e4c41812a84e86fbade7317847 (diff)
downloadmpv-589da09e5a9f3bebf0fe3e81f191f988fd85ecc2.tar.bz2
mpv-589da09e5a9f3bebf0fe3e81f191f988fd85ecc2.tar.xz
wayland: add cursor-shape-v1 support
This protocol no longer requires us to draw a separate cursor surface and all of that horrible stuff. We can just ask the compositor for the default cursor instead since that's literally all mpv cares about.
Diffstat (limited to 'video')
-rw-r--r--video/out/wayland_common.c70
-rw-r--r--video/out/wayland_common.h5
2 files changed, 63 insertions, 12 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 36dc0f6934..8f0e5838ac 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -51,6 +51,10 @@
#include "generated/wayland/fractional-scale-v1.h"
#endif
+#if HAVE_WAYLAND_PROTOCOLS_1_32
+#include "generated/wayland/cursor-shape-v1.h"
+#endif
+
#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 22
#define HAVE_WAYLAND_1_22
#endif
@@ -180,6 +184,7 @@ static int spawn_cursor(struct vo_wayland_state *wl);
static void add_feedback(struct vo_wayland_feedback_pool *fback_pool,
struct wp_presentation_feedback *fback);
+static void get_shape_device(struct vo_wayland_state *wl);
static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b);
static void guess_focus(struct vo_wayland_state *wl);
static void remove_feedback(struct vo_wayland_feedback_pool *fback_pool,
@@ -482,6 +487,7 @@ static void seat_handle_caps(void *data, struct wl_seat *seat,
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wl->pointer) {
wl->pointer = wl_seat_get_pointer(seat);
+ get_shape_device(wl);
wl_pointer_add_listener(wl->pointer, &pointer_listener, wl);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->pointer) {
wl_pointer_destroy(wl->pointer);
@@ -1295,6 +1301,12 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
}
#endif
+#if HAVE_WAYLAND_PROTOCOLS_1_32
+ if (!strcmp(interface, wp_cursor_shape_manager_v1_interface.name) && found++) {
+ wl->cursor_shape_manager = wl_registry_bind(reg, id, &wp_cursor_shape_manager_v1_interface, 1);
+ }
+#endif
+
if (!strcmp(interface, wp_presentation_interface.name) && found++) {
wl->presentation = wl_registry_bind(reg, id, &wp_presentation_interface, 1);
wp_presentation_add_listener(wl->presentation, &pres_listener, wl);
@@ -1529,7 +1541,18 @@ static int get_mods(struct vo_wayland_state *wl)
return modifiers;
}
-static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b) {
+static void get_shape_device(struct vo_wayland_state *wl)
+{
+#if HAVE_WAYLAND_PROTOCOLS_1_32
+ if (!wl->cursor_shape_device && wl->cursor_shape_manager) {
+ wl->cursor_shape_device = wp_cursor_shape_manager_v1_get_pointer(wl->cursor_shape_manager,
+ wl->pointer);
+ }
+#endif
+}
+
+static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b)
+{
// euclidean algorithm
int larger;
int smaller;
@@ -1673,21 +1696,33 @@ static void set_content_type(struct vo_wayland_state *wl)
#endif
}
+static void set_cursor_shape(struct vo_wayland_state *wl)
+{
+#if HAVE_WAYLAND_PROTOCOLS_1_32
+ wp_cursor_shape_device_v1_set_shape(wl->cursor_shape_device, wl->pointer_id,
+ WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
+#endif
+}
+
static int set_cursor_visibility(struct vo_wayland_state *wl, bool on)
{
wl->cursor_visible = on;
if (on) {
- if (spawn_cursor(wl))
- return VO_FALSE;
- struct wl_cursor_image *img = wl->default_cursor->images[0];
- struct wl_buffer *buffer = wl_cursor_image_get_buffer(img);
- if (!buffer)
- return VO_FALSE;
- wl_pointer_set_cursor(wl->pointer, wl->pointer_id, wl->cursor_surface,
- img->hotspot_x/wl->scaling, img->hotspot_y/wl->scaling);
- wl_surface_set_buffer_scale(wl->cursor_surface, wl->scaling);
- wl_surface_attach(wl->cursor_surface, buffer, 0, 0);
- wl_surface_damage_buffer(wl->cursor_surface, 0, 0, img->width, img->height);
+ if (wl->cursor_shape_device) {
+ set_cursor_shape(wl);
+ } else {
+ if (spawn_cursor(wl))
+ return VO_FALSE;
+ struct wl_cursor_image *img = wl->default_cursor->images[0];
+ struct wl_buffer *buffer = wl_cursor_image_get_buffer(img);
+ if (!buffer)
+ return VO_FALSE;
+ wl_pointer_set_cursor(wl->pointer, wl->pointer_id, wl->cursor_surface,
+ img->hotspot_x/wl->scaling, img->hotspot_y/wl->scaling);
+ wl_surface_set_buffer_scale(wl->cursor_surface, wl->scaling);
+ wl_surface_attach(wl->cursor_surface, buffer, 0, 0);
+ wl_surface_damage_buffer(wl->cursor_surface, 0, 0, img->width, img->height);
+ }
wl_surface_commit(wl->cursor_surface);
} else {
wl_pointer_set_cursor(wl->pointer, wl->pointer_id, NULL, 0, 0);
@@ -1780,6 +1815,9 @@ static void set_window_bounds(struct vo_wayland_state *wl)
static int spawn_cursor(struct vo_wayland_state *wl)
{
+ /* Don't use this if we have cursor-shape. */
+ if (wl->cursor_shape_device)
+ return 0;
/* Reuse if size is identical */
if (!wl->pointer || wl->allocated_cursor_scale == wl->scaling)
return 0;
@@ -2315,6 +2353,14 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->subcompositor)
wl_subcompositor_destroy(wl->subcompositor);
+#if HAVE_WAYLAND_PROTOCOLS_1_32
+ if (wl->cursor_shape_device)
+ wp_cursor_shape_device_v1_destroy(wl->cursor_shape_device);
+
+ if (wl->cursor_shape_manager)
+ wp_cursor_shape_manager_v1_destroy(wl->cursor_shape_manager);
+#endif
+
if (wl->cursor_surface)
wl_surface_destroy(wl->cursor_surface);
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index 32394a24a0..1a26c7faaa 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -88,6 +88,11 @@ struct vo_wayland_state {
void *content_type;
int current_content_type;
+ /* cursor-shape */
+ /* TODO: unvoid these if required wayland protocols is bumped to 1.32+ */
+ void *cursor_shape_manager;
+ void *cursor_shape_device;
+
/* fractional-scale */
/* TODO: unvoid these if required wayland protocols is bumped to 1.31+ */
void *fractional_scale_manager;