diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 2ce8d49..d833e8d 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -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 */ diff --git a/src/config/preset_config.h b/src/config/preset_config.h index 29cbbc2..364352a 100644 --- a/src/config/preset_config.h +++ b/src/config/preset_config.h @@ -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; diff --git a/src/maomao.c b/src/maomao.c index 325e6c6..578d308 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -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,9 +2640,13 @@ 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) - wlr_cursor_set_xcursor(cursor, cursor_mgr, - wlr_cursor_shape_v1_name(event->shape)); + 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) { @@ -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(); @@ -5267,10 +5286,15 @@ void setcursor(struct wl_listener *listener, void *data) { * use the provided surface as the cursor image. It will set the * 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); - } + if (event->seat_client == seat->pointer_state.focused_client) { + 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); + } } void // 0.5 @@ -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) {