summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--generated/wayland/meson.build6
-rw-r--r--video/out/wayland_common.c70
-rw-r--r--video/out/wayland_common.h5
-rw-r--r--wscript5
-rw-r--r--wscript_build.py14
5 files changed, 88 insertions, 12 deletions
diff --git a/generated/wayland/meson.build b/generated/wayland/meson.build
index bf0138183e..ec2dc6e7f4 100644
--- a/generated/wayland/meson.build
+++ b/generated/wayland/meson.build
@@ -19,6 +19,12 @@ if features['wayland_protocols_1_31']
protocols += [[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml']]
endif
+features += {'wayland_protocols_1_32': wayland['deps'][2].version().version_compare('>=1.32')}
+if features['wayland_protocols_1_32']
+ protocols += [[wl_protocol_dir, 'staging/cursor-shape/cursor-shape-v1.xml'],
+ [wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml']] # required by cursor-shape
+endif
+
foreach p: protocols
xml = join_paths(p)
wl_protocols_source += custom_target(xml.underscorify() + '_c',
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;
diff --git a/wscript b/wscript
index d6f34717dd..758a9469ff 100644
--- a/wscript
+++ b/wscript
@@ -559,6 +559,11 @@ video_output_features = [
'deps': 'wayland',
'func': check_pkg_config('wayland-protocols >= 1.31'),
} , {
+ 'name': 'wayland-protocols-1-32',
+ 'desc': 'wayland-protocols version 1.32+',
+ 'deps': 'wayland',
+ 'func': check_pkg_config('wayland-protocols >= 1.32'),
+ } , {
'name': 'memfd_create',
'desc': "Linux's memfd_create()",
'deps': 'wayland',
diff --git a/wscript_build.py b/wscript_build.py
index 9650bf94d3..1de54698ea 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -163,6 +163,20 @@ def build(ctx):
protocol = "staging/fractional-scale/fractional-scale-v1",
target = "generated/wayland/fractional-scale-v1.h")
+ if ctx.dependency_satisfied('wayland-protocols-1-32'):
+ ctx.wayland_protocol_code(proto_dir = ctx.env.WL_PROTO_DIR,
+ protocol = "staging/cursor-shape/cursor-shape-v1",
+ target = "generated/wayland/cursor-shape-v1.c")
+ ctx.wayland_protocol_header(proto_dir = ctx.env.WL_PROTO_DIR,
+ protocol = "staging/cursor-shape/cursor-shape-v1",
+ target = "generated/wayland/cursor-shape-v1.h")
+ ctx.wayland_protocol_code(proto_dir = ctx.env.WL_PROTO_DIR,
+ protocol = "unstable/tablet/tablet-unstable-v2",
+ target = "generated/wayland/tablet-unstable-v2.c")
+ ctx.wayland_protocol_header(proto_dir = ctx.env.WL_PROTO_DIR,
+ protocol = "unstable/tablet/tablet-unstable-v2",
+ target = "generated/wayland/tablet-unstable-v2.h")
+
ctx(features = "ebml_header", target = "generated/ebml_types.h")
ctx(features = "ebml_definitions", target = "generated/ebml_defs.inc")