diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-12-17 15:37:15 -0500 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-12-25 13:31:56 +0100 |
commit | 5fca74a1f1704281e86114b567707486875c4e05 (patch) | |
tree | 706f16acd2cc9d1f45e7378bfa1cbe8082c2472e | |
parent | Change mouse buttons to x11 map and libevdev names (diff) | |
download | sway-5fca74a1f1704281e86114b567707486875c4e05.tar.gz sway-5fca74a1f1704281e86114b567707486875c4e05.tar.zst sway-5fca74a1f1704281e86114b567707486875c4e05.zip |
Implement hide_cursor <timeout> command
Allows the cursor to be hidden after a specified timeout in
milliseconds
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 2 | ||||
-rw-r--r-- | include/sway/input/cursor.h | 7 | ||||
-rw-r--r-- | sway/commands.c | 1 | ||||
-rw-r--r-- | sway/commands/hide_cursor.c | 33 | ||||
-rw-r--r-- | sway/config.c | 2 | ||||
-rw-r--r-- | sway/input/cursor.c | 45 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway.5.scd | 6 |
9 files changed, 91 insertions, 7 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h index 1f2376d0..89e18c66 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -133,6 +133,7 @@ sway_cmd cmd_force_display_urgency_hint; | |||
133 | sway_cmd cmd_force_focus_wrapping; | 133 | sway_cmd cmd_force_focus_wrapping; |
134 | sway_cmd cmd_fullscreen; | 134 | sway_cmd cmd_fullscreen; |
135 | sway_cmd cmd_gaps; | 135 | sway_cmd cmd_gaps; |
136 | sway_cmd cmd_hide_cursor; | ||
136 | sway_cmd cmd_hide_edge_borders; | 137 | sway_cmd cmd_hide_edge_borders; |
137 | sway_cmd cmd_include; | 138 | sway_cmd cmd_include; |
138 | sway_cmd cmd_input; | 139 | sway_cmd cmd_input; |
diff --git a/include/sway/config.h b/include/sway/config.h index 6afb471a..7ee2ec71 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -436,6 +436,8 @@ struct sway_config { | |||
436 | enum edge_border_types hide_edge_borders; | 436 | enum edge_border_types hide_edge_borders; |
437 | enum edge_border_types saved_edge_borders; | 437 | enum edge_border_types saved_edge_borders; |
438 | 438 | ||
439 | int hide_cursor_timeout; | ||
440 | |||
439 | // border colors | 441 | // border colors |
440 | struct { | 442 | struct { |
441 | struct border_colors focused; | 443 | struct border_colors focused; |
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index f7e82721..8677f1b1 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _SWAY_INPUT_CURSOR_H | 1 | #ifndef _SWAY_INPUT_CURSOR_H |
2 | #define _SWAY_INPUT_CURSOR_H | 2 | #define _SWAY_INPUT_CURSOR_H |
3 | #include <stdbool.h> | ||
3 | #include <stdint.h> | 4 | #include <stdint.h> |
5 | #include <wlr/types/wlr_surface.h> | ||
4 | #include "sway/input/seat.h" | 6 | #include "sway/input/seat.h" |
5 | 7 | ||
6 | #define SWAY_CURSOR_PRESSED_BUTTONS_CAP 32 | 8 | #define SWAY_CURSOR_PRESSED_BUTTONS_CAP 32 |
@@ -21,6 +23,8 @@ struct sway_cursor { | |||
21 | 23 | ||
22 | const char *image; | 24 | const char *image; |
23 | struct wl_client *image_client; | 25 | struct wl_client *image_client; |
26 | struct wlr_surface *image_surface; | ||
27 | int hotspot_x, hotspot_y; | ||
24 | 28 | ||
25 | struct wl_listener motion; | 29 | struct wl_listener motion; |
26 | struct wl_listener motion_absolute; | 30 | struct wl_listener motion_absolute; |
@@ -38,6 +42,9 @@ struct sway_cursor { | |||
38 | 42 | ||
39 | struct wl_listener request_set_cursor; | 43 | struct wl_listener request_set_cursor; |
40 | 44 | ||
45 | struct wl_event_source *hide_source; | ||
46 | bool hidden; | ||
47 | |||
41 | // Mouse binding state | 48 | // Mouse binding state |
42 | uint32_t pressed_buttons[SWAY_CURSOR_PRESSED_BUTTONS_CAP]; | 49 | uint32_t pressed_buttons[SWAY_CURSOR_PRESSED_BUTTONS_CAP]; |
43 | size_t pressed_button_count; | 50 | size_t pressed_button_count; |
diff --git a/sway/commands.c b/sway/commands.c index f6d1cc3e..eda29c65 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -86,6 +86,7 @@ static struct cmd_handler handlers[] = { | |||
86 | { "force_focus_wrapping", cmd_force_focus_wrapping }, | 86 | { "force_focus_wrapping", cmd_force_focus_wrapping }, |
87 | { "fullscreen", cmd_fullscreen }, | 87 | { "fullscreen", cmd_fullscreen }, |
88 | { "gaps", cmd_gaps }, | 88 | { "gaps", cmd_gaps }, |
89 | { "hide_cursor", cmd_hide_cursor }, | ||
89 | { "hide_edge_borders", cmd_hide_edge_borders }, | 90 | { "hide_edge_borders", cmd_hide_edge_borders }, |
90 | { "include", cmd_include }, | 91 | { "include", cmd_include }, |
91 | { "input", cmd_input }, | 92 | { "input", cmd_input }, |
diff --git a/sway/commands/hide_cursor.c b/sway/commands/hide_cursor.c new file mode 100644 index 00000000..3778fcff --- /dev/null +++ b/sway/commands/hide_cursor.c | |||
@@ -0,0 +1,33 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | ||
2 | #include <string.h> | ||
3 | #include "sway/commands.h" | ||
4 | #include "sway/config.h" | ||
5 | #include "sway/input/cursor.h" | ||
6 | #include "sway/input/seat.h" | ||
7 | #include "stringop.h" | ||
8 | |||
9 | struct cmd_results *cmd_hide_cursor(int argc, char **argv) { | ||
10 | struct cmd_results *error = NULL; | ||
11 | if ((error = checkarg(argc, "hide_cursor", EXPECTED_EQUAL_TO, 1))) { | ||
12 | return error; | ||
13 | } | ||
14 | |||
15 | char *end; | ||
16 | int timeout = strtol(argv[0], &end, 10); | ||
17 | if (*end) { | ||
18 | return cmd_results_new(CMD_INVALID, "hide_cursor", | ||
19 | "Expected an integer timeout"); | ||
20 | } | ||
21 | if (timeout < 100 && timeout != 0) { | ||
22 | timeout = 100; | ||
23 | } | ||
24 | config->hide_cursor_timeout = timeout; | ||
25 | |||
26 | struct sway_seat *seat; | ||
27 | wl_list_for_each(seat, &server.input->seats, link) { | ||
28 | wl_event_source_timer_update(seat->cursor->hide_source, | ||
29 | config->hide_cursor_timeout); | ||
30 | } | ||
31 | |||
32 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
33 | } | ||
diff --git a/sway/config.c b/sway/config.c index d4b7d466..bb18c739 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -257,6 +257,8 @@ static void config_defaults(struct sway_config *config) { | |||
257 | config->hide_edge_borders = E_NONE; | 257 | config->hide_edge_borders = E_NONE; |
258 | config->saved_edge_borders = E_NONE; | 258 | config->saved_edge_borders = E_NONE; |
259 | 259 | ||
260 | config->hide_cursor_timeout = 0; | ||
261 | |||
260 | // border colors | 262 | // border colors |
261 | set_color(config->border_colors.focused.border, 0x4C7899); | 263 | set_color(config->border_colors.focused.border, 0x4C7899); |
262 | set_color(config->border_colors.focused.background, 0x285577); | 264 | set_color(config->border_colors.focused.background, 0x285577); |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 444fe81d..53ff3a22 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -590,6 +590,23 @@ void cursor_rebase(struct sway_cursor *cursor) { | |||
590 | cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy); | 590 | cursor_do_rebase(cursor, time_msec, cursor->previous.node, surface, sx, sy); |
591 | } | 591 | } |
592 | 592 | ||
593 | static int hide_notify(void *data) { | ||
594 | struct sway_cursor *cursor = data; | ||
595 | wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); | ||
596 | cursor->hidden = true; | ||
597 | return 1; | ||
598 | } | ||
599 | |||
600 | static void handle_activity(struct sway_cursor *cursor) { | ||
601 | wl_event_source_timer_update(cursor->hide_source, | ||
602 | config->hide_cursor_timeout); | ||
603 | wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); | ||
604 | if (cursor->hidden) { | ||
605 | cursor->hidden = false; | ||
606 | cursor_set_image(cursor, NULL, cursor->image_client); | ||
607 | } | ||
608 | } | ||
609 | |||
593 | void cursor_send_pointer_motion(struct sway_cursor *cursor, | 610 | void cursor_send_pointer_motion(struct sway_cursor *cursor, |
594 | uint32_t time_msec) { | 611 | uint32_t time_msec) { |
595 | if (time_msec == 0) { | 612 | if (time_msec == 0) { |
@@ -680,11 +697,11 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
680 | 697 | ||
681 | static void handle_cursor_motion(struct wl_listener *listener, void *data) { | 698 | static void handle_cursor_motion(struct wl_listener *listener, void *data) { |
682 | struct sway_cursor *cursor = wl_container_of(listener, cursor, motion); | 699 | struct sway_cursor *cursor = wl_container_of(listener, cursor, motion); |
683 | wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); | ||
684 | struct wlr_event_pointer_motion *event = data; | 700 | struct wlr_event_pointer_motion *event = data; |
685 | wlr_cursor_move(cursor->cursor, event->device, | 701 | wlr_cursor_move(cursor->cursor, event->device, |
686 | event->delta_x, event->delta_y); | 702 | event->delta_x, event->delta_y); |
687 | cursor_send_pointer_motion(cursor, event->time_msec); | 703 | cursor_send_pointer_motion(cursor, event->time_msec); |
704 | handle_activity(cursor); | ||
688 | transaction_commit_dirty(); | 705 | transaction_commit_dirty(); |
689 | } | 706 | } |
690 | 707 | ||
@@ -692,10 +709,10 @@ static void handle_cursor_motion_absolute( | |||
692 | struct wl_listener *listener, void *data) { | 709 | struct wl_listener *listener, void *data) { |
693 | struct sway_cursor *cursor = | 710 | struct sway_cursor *cursor = |
694 | wl_container_of(listener, cursor, motion_absolute); | 711 | wl_container_of(listener, cursor, motion_absolute); |
695 | wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); | ||
696 | struct wlr_event_pointer_motion_absolute *event = data; | 712 | struct wlr_event_pointer_motion_absolute *event = data; |
697 | wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); | 713 | wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); |
698 | cursor_send_pointer_motion(cursor, event->time_msec); | 714 | cursor_send_pointer_motion(cursor, event->time_msec); |
715 | handle_activity(cursor); | ||
699 | transaction_commit_dirty(); | 716 | transaction_commit_dirty(); |
700 | } | 717 | } |
701 | 718 | ||
@@ -976,10 +993,10 @@ void dispatch_cursor_button(struct sway_cursor *cursor, | |||
976 | 993 | ||
977 | static void handle_cursor_button(struct wl_listener *listener, void *data) { | 994 | static void handle_cursor_button(struct wl_listener *listener, void *data) { |
978 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); | 995 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); |
979 | wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); | ||
980 | struct wlr_event_pointer_button *event = data; | 996 | struct wlr_event_pointer_button *event = data; |
981 | dispatch_cursor_button(cursor, event->device, | 997 | dispatch_cursor_button(cursor, event->device, |
982 | event->time_msec, event->button, event->state); | 998 | event->time_msec, event->button, event->state); |
999 | handle_activity(cursor); | ||
983 | transaction_commit_dirty(); | 1000 | transaction_commit_dirty(); |
984 | } | 1001 | } |
985 | 1002 | ||
@@ -1087,9 +1104,9 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor, | |||
1087 | 1104 | ||
1088 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { | 1105 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { |
1089 | struct sway_cursor *cursor = wl_container_of(listener, cursor, axis); | 1106 | struct sway_cursor *cursor = wl_container_of(listener, cursor, axis); |
1090 | wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); | ||
1091 | struct wlr_event_pointer_axis *event = data; | 1107 | struct wlr_event_pointer_axis *event = data; |
1092 | dispatch_cursor_axis(cursor, event); | 1108 | dispatch_cursor_axis(cursor, event); |
1109 | handle_activity(cursor); | ||
1093 | transaction_commit_dirty(); | 1110 | transaction_commit_dirty(); |
1094 | } | 1111 | } |
1095 | 1112 | ||
@@ -1280,10 +1297,12 @@ static void handle_request_set_cursor(struct wl_listener *listener, | |||
1280 | return; | 1297 | return; |
1281 | } | 1298 | } |
1282 | 1299 | ||
1283 | wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, | ||
1284 | event->hotspot_y); | ||
1285 | cursor->image = NULL; | 1300 | cursor->image = NULL; |
1286 | cursor->image_client = focused_client; | 1301 | cursor->image_client = focused_client; |
1302 | cursor->image_surface = event->surface; | ||
1303 | cursor->hotspot_x = event->hotspot_x; | ||
1304 | cursor->hotspot_y = event->hotspot_y; | ||
1305 | cursor_set_image(cursor, NULL, cursor->image_client); | ||
1287 | } | 1306 | } |
1288 | 1307 | ||
1289 | void cursor_set_image(struct sway_cursor *cursor, const char *image, | 1308 | void cursor_set_image(struct sway_cursor *cursor, const char *image, |
@@ -1291,9 +1310,16 @@ void cursor_set_image(struct sway_cursor *cursor, const char *image, | |||
1291 | if (!(cursor->seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) { | 1310 | if (!(cursor->seat->wlr_seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) { |
1292 | return; | 1311 | return; |
1293 | } | 1312 | } |
1294 | if (!image) { | 1313 | if (cursor->hidden) { |
1314 | return; | ||
1315 | } | ||
1316 | if (!image && cursor->image_surface) { | ||
1317 | wlr_cursor_set_surface(cursor->cursor, cursor->image_surface, | ||
1318 | cursor->hotspot_x, cursor->hotspot_y); | ||
1319 | } else if (!image) { | ||
1295 | wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); | 1320 | wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); |
1296 | } else if (!cursor->image || strcmp(cursor->image, image) != 0) { | 1321 | } else if (!cursor->image || strcmp(cursor->image, image) != 0) { |
1322 | cursor->image_surface = NULL; | ||
1297 | wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, | 1323 | wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, |
1298 | cursor->cursor); | 1324 | cursor->cursor); |
1299 | } | 1325 | } |
@@ -1306,6 +1332,8 @@ void sway_cursor_destroy(struct sway_cursor *cursor) { | |||
1306 | return; | 1332 | return; |
1307 | } | 1333 | } |
1308 | 1334 | ||
1335 | wl_event_source_remove(cursor->hide_source); | ||
1336 | |||
1309 | wlr_xcursor_manager_destroy(cursor->xcursor_manager); | 1337 | wlr_xcursor_manager_destroy(cursor->xcursor_manager); |
1310 | wlr_cursor_destroy(cursor->cursor); | 1338 | wlr_cursor_destroy(cursor->cursor); |
1311 | free(cursor); | 1339 | free(cursor); |
@@ -1329,6 +1357,9 @@ struct sway_cursor *sway_cursor_create(struct sway_seat *seat) { | |||
1329 | cursor->seat = seat; | 1357 | cursor->seat = seat; |
1330 | wlr_cursor_attach_output_layout(wlr_cursor, root->output_layout); | 1358 | wlr_cursor_attach_output_layout(wlr_cursor, root->output_layout); |
1331 | 1359 | ||
1360 | cursor->hide_source = wl_event_loop_add_timer(server.wl_event_loop, | ||
1361 | hide_notify, cursor); | ||
1362 | |||
1332 | // input events | 1363 | // input events |
1333 | wl_signal_add(&wlr_cursor->events.motion, &cursor->motion); | 1364 | wl_signal_add(&wlr_cursor->events.motion, &cursor->motion); |
1334 | cursor->motion.notify = handle_cursor_motion; | 1365 | cursor->motion.notify = handle_cursor_motion; |
diff --git a/sway/meson.build b/sway/meson.build index 2f977fd2..48ce6b45 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -56,6 +56,7 @@ sway_sources = files( | |||
56 | 'commands/force_focus_wrapping.c', | 56 | 'commands/force_focus_wrapping.c', |
57 | 'commands/fullscreen.c', | 57 | 'commands/fullscreen.c', |
58 | 'commands/gaps.c', | 58 | 'commands/gaps.c', |
59 | 'commands/hide_cursor.c', | ||
59 | 'commands/hide_edge_borders.c', | 60 | 'commands/hide_edge_borders.c', |
60 | 'commands/kill.c', | 61 | 'commands/kill.c', |
61 | 'commands/mark.c', | 62 | 'commands/mark.c', |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index e6abef56..2befcfac 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -477,6 +477,12 @@ The default colors are: | |||
477 | This affects new workspaces only, and is used when the workspace doesn't | 477 | This affects new workspaces only, and is used when the workspace doesn't |
478 | have its own gaps settings (see: workspace <ws> gaps ...). | 478 | have its own gaps settings (see: workspace <ws> gaps ...). |
479 | 479 | ||
480 | *hide\_cursor* <timeout> | ||
481 | Hides the cursor image after the specified _timeout_ (in milliseconds) | ||
482 | has elapsed with no activity on that cursor. A timeout of 0 (default) | ||
483 | disables hiding the cursor. The minimal timeout is 100 and any value less | ||
484 | than that (aside from 0), will be increased to 100. | ||
485 | |||
480 | *hide\_edge\_borders* none|vertical|horizontal|both|smart|smart\_no\_gaps | 486 | *hide\_edge\_borders* none|vertical|horizontal|both|smart|smart\_no\_gaps |
481 | Hides window borders adjacent to the screen edges. Default is _none_. | 487 | Hides window borders adjacent to the screen edges. Default is _none_. |
482 | 488 | ||