feat: add option cursor_hide_timeout

This commit is contained in:
DreamMaoMao 2025-05-13 18:13:55 +08:00
parent 7f4c62ffe4
commit 29d9d12b23
3 changed files with 68 additions and 8 deletions

View file

@ -139,6 +139,7 @@ typedef struct {
unsigned int ov_tab_mode;
int overviewgappi;
int overviewgappo;
unsigned int cursor_hide_timeout;
unsigned int axis_bind_apply_timeout;
unsigned int focus_on_activate;
@ -864,6 +865,8 @@ void parse_config_line(Config *config, const char *line) {
config->overviewgappi = atoi(value);
} else if (strcmp(key, "overviewgappo") == 0) {
config->overviewgappo = atoi(value);
} else if (strcmp(key, "cursor_hide_timeout") == 0) {
config->cursor_hide_timeout = atoi(value);
} else if (strcmp(key, "axis_bind_apply_timeout") == 0) {
config->axis_bind_apply_timeout = atoi(value);
} else if (strcmp(key, "focus_on_activate") == 0) {
@ -1691,6 +1694,7 @@ void override_config(void) {
ov_tab_mode = config.ov_tab_mode;
overviewgappi = config.overviewgappi;
overviewgappo = config.overviewgappo;
cursor_hide_timeout = config.cursor_hide_timeout;
axis_bind_apply_timeout = config.axis_bind_apply_timeout;
focus_on_activate = config.focus_on_activate;
numlockon = config.numlockon;
@ -1788,6 +1792,7 @@ void set_value_default() {
config.borderpx = borderpx;
config.overviewgappi = overviewgappi; /* overview时 窗口与边缘 缝隙大小 */
config.overviewgappo = overviewgappo; /* overview时 窗口与窗口 缝隙大小 */
config.cursor_hide_timeout = cursor_hide_timeout;
config.warpcursor = warpcursor; /* Warp cursor to focused client */

View file

@ -57,6 +57,7 @@ int no_border_when_single = 0;
int snap_distance = 30;
int enable_floating_snap = 0;
unsigned int cursor_size = 24;
unsigned int cursor_hide_timeout = 0;
unsigned int swipe_min_threshold = 20;

View file

@ -633,6 +633,8 @@ static void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer,
static void client_set_pending_state(Client *c);
static void set_rect_size(struct wlr_scene_rect *rect, int width, int height);
static Client *center_select(Monitor *m);
static void handlecursoractivity(void);
static int hidecursor(void *data);
#include "dispatch/dispatch.h"
@ -712,6 +714,15 @@ struct vec2 *baked_points_open;
struct vec2 *baked_points_tag;
struct vec2 *baked_points_close;
static struct wl_event_source *hide_source;
static bool cursor_hidden = false;
static struct {
enum wp_cursor_shape_device_v1_shape shape;
struct wlr_surface *surface;
int hotspot_x;
int hotspot_y;
} last_cursor;
#include "config/preset_config.h"
struct Pertag {
@ -2365,6 +2376,7 @@ axisnotify(struct wl_listener *listener, void *data) {
int ji;
unsigned int adir;
// IDLE_NOTIFY_ACTIVITY;
handlecursoractivity();
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
keyboard = wlr_seat_get_keyboard(seat);
@ -2531,6 +2543,7 @@ buttonpress(struct wl_listener *listener, void *data) {
struct wlr_surface *old_pointer_focus_surface =
seat->pointer_state.focused_surface;
handlecursoractivity();
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
switch (event->state) {
@ -2627,10 +2640,14 @@ void setcursorshape(struct wl_listener *listener, void *data) {
/* This can be sent by any client, so we check to make sure this one is
* actually has pointer focus first. If so, we can tell the cursor to
* use the provided cursor shape. */
if (event->seat_client == seat->pointer_state.focused_client)
if (event->seat_client == seat->pointer_state.focused_client) {
last_cursor.shape = event->shape;
last_cursor.surface = NULL;
if (!cursor_hidden)
wlr_cursor_set_xcursor(cursor, cursor_mgr,
wlr_cursor_shape_v1_name(event->shape));
}
}
void cleanuplisteners(void) {
wl_list_remove(&cursor_axis.link);
@ -4516,6 +4533,7 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
}
wlr_cursor_move(cursor, device, dx, dy);
handlecursoractivity();
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
/* Update selmon (even while dragging a window) */
@ -4549,7 +4567,7 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
/* If there's no client surface under the cursor, set the cursor image to a
* default. This is what makes the cursor image appear when you move it
* off of a client or over its border. */
if (!surface && !seat->drag)
if (!surface && !seat->drag && !cursor_hidden)
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
if (c && c->mon && !c->animation.running &&
@ -5242,6 +5260,7 @@ run(char *startup_cmd) {
* monitor when displayed here */
wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y);
wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr");
handlecursoractivity();
run_exec();
run_exec_once();
@ -5268,8 +5287,13 @@ void setcursor(struct wl_listener *listener, void *data) {
* hardware cursor on the output that it's currently on and continue to
* do so as the cursor moves between outputs. */
if (event->seat_client == seat->pointer_state.focused_client) {
wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x,
event->hotspot_y);
last_cursor.shape = 0;
last_cursor.surface = event->surface;
last_cursor.hotspot_x = event->hotspot_x;
last_cursor.hotspot_y = event->hotspot_y;
if (!cursor_hidden)
wlr_cursor_set_surface(cursor, event->surface,
event->hotspot_x, event->hotspot_y);
}
}
@ -5927,6 +5951,8 @@ void setup(void) {
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
wl_signal_add(&cursor_shape_mgr->events.request_set_shape,
&request_set_cursor_shape);
hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
hidecursor, cursor);
/*
* Configures a seat, which is a single "seat" at which a user sits and
@ -6245,6 +6271,32 @@ void set_proportion(const Arg *arg) {
}
}
void
handlecursoractivity(void)
{
wl_event_source_timer_update(hide_source, cursor_hide_timeout * 1000);
if (!cursor_hidden)
return;
cursor_hidden = false;
if (last_cursor.shape)
wlr_cursor_set_xcursor(cursor, cursor_mgr,
wlr_cursor_shape_v1_name(last_cursor.shape));
else
wlr_cursor_set_surface(cursor, last_cursor.surface,
last_cursor.hotspot_x, last_cursor.hotspot_y);
}
int
hidecursor(void *data)
{
wlr_cursor_unset_image(cursor);
cursor_hidden = true;
return 1;
}
void increase_proportion(const Arg *arg) {
if (selmon->sel) {
unsigned int max_client_width =
@ -6967,6 +7019,8 @@ void virtualpointer(struct wl_listener *listener, void *data) {
wlr_cursor_attach_input_device(cursor, device);
if (event->suggested_output)
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
handlecursoractivity();
}
Monitor *xytomon(double x, double y) {