mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 04:45:58 +01:00
cursor: add wlr_cursor_set_xcursor()
This keeps track of the last set XCursor. If it hasn't changed, skip the texture upload. In the future, support for animated XCursors can be added. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3436
This commit is contained in:
parent
58a2f8bd5c
commit
da04b066ea
4 changed files with 40 additions and 4 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
|
|
||||||
struct wlr_input_device;
|
struct wlr_input_device;
|
||||||
|
struct wlr_xcursor_manager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlr_cursor implements the behavior of the "cursor", that is, the image on the
|
* wlr_cursor implements the behavior of the "cursor", that is, the image on the
|
||||||
|
@ -146,6 +147,14 @@ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
|
||||||
int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x,
|
int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x,
|
||||||
int32_t hotspot_y, float scale);
|
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
|
* 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
|
* image. The surface position is subtracted from the hotspot. A NULL surface
|
||||||
|
|
|
@ -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
|
* scale factors. struct wlr_cursor will take over from this point and ensure
|
||||||
* the correct cursor is used on each output, assuming a
|
* the correct cursor is used on each output, assuming a
|
||||||
* struct wlr_output_layout is attached to it.
|
* 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,
|
void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager,
|
||||||
const char *name, struct wlr_cursor *cursor);
|
const char *name, struct wlr_cursor *cursor);
|
||||||
|
|
|
@ -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
|
/* 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
|
* default. This is what makes the cursor image appear when you move it
|
||||||
* around the screen, not over any views. */
|
* around the screen, not over any views. */
|
||||||
wlr_xcursor_manager_set_cursor_image(
|
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "default");
|
||||||
server->cursor_mgr, "default", server->cursor);
|
|
||||||
}
|
}
|
||||||
if (surface) {
|
if (surface) {
|
||||||
/*
|
/*
|
||||||
|
@ -927,9 +926,8 @@ int main(int argc, char *argv[]) {
|
||||||
/* Creates an xcursor manager, another wlroots utility which loads up
|
/* Creates an xcursor manager, another wlroots utility which loads up
|
||||||
* Xcursor themes to source cursor images from and makes sure that cursor
|
* Xcursor themes to source cursor images from and makes sure that cursor
|
||||||
* images are available at all scale factors on the screen (necessary for
|
* 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);
|
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
|
* wlr_cursor *only* displays an image on screen. It does not move around
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/types/wlr_tablet_tool.h>
|
#include <wlr/types/wlr_tablet_tool.h>
|
||||||
#include <wlr/types/wlr_touch.h>
|
#include <wlr/types/wlr_touch.h>
|
||||||
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
#include <wlr/util/box.h>
|
#include <wlr/util/box.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "types/wlr_output.h"
|
#include "types/wlr_output.h"
|
||||||
|
@ -65,6 +66,9 @@ struct wlr_cursor_output_cursor {
|
||||||
struct wl_listener surface_commit;
|
struct wl_listener surface_commit;
|
||||||
struct wl_listener surface_destroy;
|
struct wl_listener surface_destroy;
|
||||||
struct wl_listener output_commit;
|
struct wl_listener output_commit;
|
||||||
|
|
||||||
|
// only when using an XCursor as the cursor image
|
||||||
|
struct wlr_xcursor *xcursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_cursor_state {
|
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->surface_commit.link);
|
||||||
wl_list_init(&output_cursor->output_commit.link);
|
wl_list_init(&output_cursor->output_commit.link);
|
||||||
output_cursor->surface = NULL;
|
output_cursor->surface = NULL;
|
||||||
|
|
||||||
|
output_cursor->xcursor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_cursor_output_commit_surface(
|
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(
|
static void output_cursor_output_handle_surface_destroy(
|
||||||
struct wl_listener *listener, void *data) {
|
struct wl_listener *listener, void *data) {
|
||||||
struct wlr_cursor_output_cursor *output_cursor =
|
struct wlr_cursor_output_cursor *output_cursor =
|
||||||
|
|
Loading…
Reference in a new issue