aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_cursor.h9
-rw-r--r--include/wlr/types/wlr_xcursor_manager.h2
-rw-r--r--tinywl/tinywl.c6
-rw-r--r--types/wlr_cursor.c27
4 files changed, 40 insertions, 4 deletions
diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h
index 06ae2f1f..f3c7e970 100644
--- a/include/wlr/types/wlr_cursor.h
+++ b/include/wlr/types/wlr_cursor.h
@@ -14,6 +14,7 @@
#include <wlr/types/wlr_output.h>
struct wlr_input_device;
+struct wlr_xcursor_manager;
/**
* wlr_cursor implements the behavior of the "cursor", that is, the image on the
@@ -147,6 +148,14 @@ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
int32_t hotspot_y, float scale);
/**
+ * Set the cursor image from an XCursor theme.
+ *
+ * The image will be loaded from the struct wlr_xcursor_manager.
+ */
+void wlr_cursor_set_xcursor(struct wlr_cursor *cur,
+ struct wlr_xcursor_manager *manager, const char *name);
+
+/**
* Set the cursor surface. The surface can be committed to update the cursor
* image. The surface position is subtracted from the hotspot. A NULL surface
* commit hides the cursor.
diff --git a/include/wlr/types/wlr_xcursor_manager.h b/include/wlr/types/wlr_xcursor_manager.h
index f7781ca6..7d7b19ab 100644
--- a/include/wlr/types/wlr_xcursor_manager.h
+++ b/include/wlr/types/wlr_xcursor_manager.h
@@ -62,6 +62,8 @@ struct wlr_xcursor *wlr_xcursor_manager_get_xcursor(
* scale factors. struct wlr_cursor will take over from this point and ensure
* the correct cursor is used on each output, assuming a
* struct wlr_output_layout is attached to it.
+ *
+ * Deprecated: wlr_cursor_set_xcursor() should be used instead.
*/
void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager,
const char *name, struct wlr_cursor *cursor);
diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c
index bfabac6e..e6e3ceee 100644
--- a/tinywl/tinywl.c
+++ b/tinywl/tinywl.c
@@ -449,8 +449,7 @@ static void process_cursor_motion(struct tinywl_server *server, uint32_t time) {
/* If there's no view under the cursor, set the cursor image to a
* default. This is what makes the cursor image appear when you move it
* around the screen, not over any views. */
- wlr_xcursor_manager_set_cursor_image(
- server->cursor_mgr, "default", server->cursor);
+ wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "default");
}
if (surface) {
/*
@@ -927,9 +926,8 @@ int main(int argc, char *argv[]) {
/* Creates an xcursor manager, another wlroots utility which loads up
* Xcursor themes to source cursor images from and makes sure that cursor
* images are available at all scale factors on the screen (necessary for
- * HiDPI support). We add a cursor theme at scale factor 1 to begin with. */
+ * HiDPI support). */
server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
- wlr_xcursor_manager_load(server.cursor_mgr, 1);
/*
* wlr_cursor *only* displays an image on screen. It does not move around
diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c
index 3d5c8b22..cce37e81 100644
--- a/types/wlr_cursor.c
+++ b/types/wlr_cursor.c
@@ -11,6 +11,7 @@
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_tablet_tool.h>
#include <wlr/types/wlr_touch.h>
+#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/util/box.h>
#include <wlr/util/log.h>
#include "types/wlr_output.h"
@@ -65,6 +66,9 @@ struct wlr_cursor_output_cursor {
struct wl_listener surface_commit;
struct wl_listener surface_destroy;
struct wl_listener output_commit;
+
+ // only when using an XCursor as the cursor image
+ struct wlr_xcursor *xcursor;
};
struct wlr_cursor_state {
@@ -380,6 +384,8 @@ static void cursor_output_cursor_reset_image(
wl_list_init(&output_cursor->surface_commit.link);
wl_list_init(&output_cursor->output_commit.link);
output_cursor->surface = NULL;
+
+ output_cursor->xcursor = NULL;
}
static void output_cursor_output_commit_surface(
@@ -419,6 +425,27 @@ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
}
}
+void wlr_cursor_set_xcursor(struct wlr_cursor *cur,
+ struct wlr_xcursor_manager *manager, const char *name) {
+ struct wlr_cursor_output_cursor *output_cursor;
+ wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
+ float scale = output_cursor->output_cursor->output->scale;
+ wlr_xcursor_manager_load(manager, scale);
+ struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor(manager, name, scale);
+ if (xcursor == NULL || output_cursor->xcursor == xcursor) {
+ continue;
+ }
+
+ cursor_output_cursor_reset_image(output_cursor);
+ output_cursor->xcursor = xcursor;
+
+ struct wlr_xcursor_image *image = xcursor->images[0];
+ wlr_output_cursor_set_image(output_cursor->output_cursor,
+ image->buffer, 4 * image->width, image->width, image->height,
+ image->hotspot_x, image->hotspot_y);
+ }
+}
+
static void output_cursor_output_handle_surface_destroy(
struct wl_listener *listener, void *data) {
struct wlr_cursor_output_cursor *output_cursor =