aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-12-17 15:37:15 -0500
committerLibravatar emersion <contact@emersion.fr>2018-12-25 13:31:56 +0100
commit5fca74a1f1704281e86114b567707486875c4e05 (patch)
tree706f16acd2cc9d1f45e7378bfa1cbe8082c2472e
parentChange mouse buttons to x11 map and libevdev names (diff)
downloadsway-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.h1
-rw-r--r--include/sway/config.h2
-rw-r--r--include/sway/input/cursor.h7
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/hide_cursor.c33
-rw-r--r--sway/config.c2
-rw-r--r--sway/input/cursor.c45
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd6
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;
133sway_cmd cmd_force_focus_wrapping; 133sway_cmd cmd_force_focus_wrapping;
134sway_cmd cmd_fullscreen; 134sway_cmd cmd_fullscreen;
135sway_cmd cmd_gaps; 135sway_cmd cmd_gaps;
136sway_cmd cmd_hide_cursor;
136sway_cmd cmd_hide_edge_borders; 137sway_cmd cmd_hide_edge_borders;
137sway_cmd cmd_include; 138sway_cmd cmd_include;
138sway_cmd cmd_input; 139sway_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
9struct 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
593static 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
600static 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
593void cursor_send_pointer_motion(struct sway_cursor *cursor, 610void 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
681static void handle_cursor_motion(struct wl_listener *listener, void *data) { 698static 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
977static void handle_cursor_button(struct wl_listener *listener, void *data) { 994static 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
1088static void handle_cursor_axis(struct wl_listener *listener, void *data) { 1105static 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
1289void cursor_set_image(struct sway_cursor *cursor, const char *image, 1308void 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