diff options
-rw-r--r-- | include/sway/input/cursor.h | 2 | ||||
-rw-r--r-- | sway/commands/seat/cursor.c | 16 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 5 | ||||
-rw-r--r-- | sway/input/cursor.c | 18 | ||||
-rw-r--r-- | sway/input/seat.c | 8 | ||||
-rw-r--r-- | swaybar/bar.c | 18 | ||||
-rw-r--r-- | swaybar/event_loop.c | 42 |
7 files changed, 63 insertions, 46 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index fcd94437..20c1c903 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -29,7 +29,7 @@ struct sway_cursor { | |||
29 | 29 | ||
30 | void sway_cursor_destroy(struct sway_cursor *cursor); | 30 | void sway_cursor_destroy(struct sway_cursor *cursor); |
31 | struct sway_cursor *sway_cursor_create(struct sway_seat *seat); | 31 | struct sway_cursor *sway_cursor_create(struct sway_seat *seat); |
32 | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time); | 32 | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec); |
33 | void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec, | 33 | void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec, |
34 | uint32_t button, enum wlr_button_state state); | 34 | uint32_t button, enum wlr_button_state state); |
35 | 35 | ||
diff --git a/sway/commands/seat/cursor.c b/sway/commands/seat/cursor.c index 5dad97f1..929384b0 100644 --- a/sway/commands/seat/cursor.c +++ b/sway/commands/seat/cursor.c | |||
@@ -11,7 +11,7 @@ | |||
11 | #include "sway/input/cursor.h" | 11 | #include "sway/input/cursor.h" |
12 | 12 | ||
13 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, | 13 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, |
14 | char *action, char *button_str, uint32_t time); | 14 | char *action, char *button_str); |
15 | 15 | ||
16 | static const char *expected_syntax = "Expected 'cursor <move> <x> <y>' or " | 16 | static const char *expected_syntax = "Expected 'cursor <move> <x> <y>' or " |
17 | "'cursor <set> <x> <y>' or " | 17 | "'cursor <set> <x> <y>' or " |
@@ -29,10 +29,6 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) { | |||
29 | 29 | ||
30 | struct sway_cursor *cursor = seat->cursor; | 30 | struct sway_cursor *cursor = seat->cursor; |
31 | 31 | ||
32 | struct timespec now; | ||
33 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
34 | uint32_t time = now.tv_nsec / 1000; | ||
35 | |||
36 | if (strcasecmp(argv[0], "move") == 0) { | 32 | if (strcasecmp(argv[0], "move") == 0) { |
37 | if (argc < 3) { | 33 | if (argc < 3) { |
38 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); | 34 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); |
@@ -40,7 +36,7 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) { | |||
40 | int delta_x = strtol(argv[1], NULL, 10); | 36 | int delta_x = strtol(argv[1], NULL, 10); |
41 | int delta_y = strtol(argv[2], NULL, 10); | 37 | int delta_y = strtol(argv[2], NULL, 10); |
42 | wlr_cursor_move(cursor->cursor, NULL, delta_x, delta_y); | 38 | wlr_cursor_move(cursor->cursor, NULL, delta_x, delta_y); |
43 | cursor_send_pointer_motion(cursor, time); | 39 | cursor_send_pointer_motion(cursor, 0); |
44 | } else if (strcasecmp(argv[0], "set") == 0) { | 40 | } else if (strcasecmp(argv[0], "set") == 0) { |
45 | if (argc < 3) { | 41 | if (argc < 3) { |
46 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); | 42 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); |
@@ -49,12 +45,12 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) { | |||
49 | float x = strtof(argv[1], NULL) / root_container.width; | 45 | float x = strtof(argv[1], NULL) / root_container.width; |
50 | float y = strtof(argv[2], NULL) / root_container.height; | 46 | float y = strtof(argv[2], NULL) / root_container.height; |
51 | wlr_cursor_warp_absolute(cursor->cursor, NULL, x, y); | 47 | wlr_cursor_warp_absolute(cursor->cursor, NULL, x, y); |
52 | cursor_send_pointer_motion(cursor, time); | 48 | cursor_send_pointer_motion(cursor, 0); |
53 | } else { | 49 | } else { |
54 | if (argc < 2) { | 50 | if (argc < 2) { |
55 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); | 51 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); |
56 | } | 52 | } |
57 | if ((error = press_or_release(cursor, argv[0], argv[1], time))) { | 53 | if ((error = press_or_release(cursor, argv[0], argv[1]))) { |
58 | return error; | 54 | return error; |
59 | } | 55 | } |
60 | } | 56 | } |
@@ -63,7 +59,7 @@ struct cmd_results *seat_cmd_cursor(int argc, char **argv) { | |||
63 | } | 59 | } |
64 | 60 | ||
65 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, | 61 | static struct cmd_results *press_or_release(struct sway_cursor *cursor, |
66 | char *action, char *button_str, uint32_t time) { | 62 | char *action, char *button_str) { |
67 | enum wlr_button_state state; | 63 | enum wlr_button_state state; |
68 | uint32_t button; | 64 | uint32_t button; |
69 | if (strcasecmp(action, "press") == 0) { | 65 | if (strcasecmp(action, "press") == 0) { |
@@ -84,6 +80,6 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor, | |||
84 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); | 80 | return cmd_results_new(CMD_INVALID, "cursor", expected_syntax); |
85 | } | 81 | } |
86 | } | 82 | } |
87 | dispatch_cursor_button(cursor, time, button, state); | 83 | dispatch_cursor_button(cursor, 0, button, state); |
88 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 84 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
89 | } | 85 | } |
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 46eaa84c..cad9156d 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c | |||
@@ -257,11 +257,6 @@ static void handle_map(struct wl_listener *listener, void *data) { | |||
257 | static void handle_destroy(struct wl_listener *listener, void *data) { | 257 | static void handle_destroy(struct wl_listener *listener, void *data) { |
258 | struct sway_xwayland_view *xwayland_view = | 258 | struct sway_xwayland_view *xwayland_view = |
259 | wl_container_of(listener, xwayland_view, destroy); | 259 | wl_container_of(listener, xwayland_view, destroy); |
260 | struct sway_view *view = &xwayland_view->view; | ||
261 | struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; | ||
262 | if (xsurface->mapped) { | ||
263 | handle_unmap(&xwayland_view->unmap, xsurface); | ||
264 | } | ||
265 | view_destroy(&xwayland_view->view); | 260 | view_destroy(&xwayland_view->view); |
266 | } | 261 | } |
267 | 262 | ||
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 5ed4f1f7..831109dc 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -15,6 +15,12 @@ | |||
15 | #include "sway/tree/workspace.h" | 15 | #include "sway/tree/workspace.h" |
16 | #include "wlr-layer-shell-unstable-v1-protocol.h" | 16 | #include "wlr-layer-shell-unstable-v1-protocol.h" |
17 | 17 | ||
18 | static uint32_t get_current_time_msec() { | ||
19 | struct timespec now; | ||
20 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
21 | return now.tv_nsec / 1000; | ||
22 | } | ||
23 | |||
18 | static struct wlr_surface *layer_surface_at(struct sway_output *output, | 24 | static struct wlr_surface *layer_surface_at(struct sway_output *output, |
19 | struct wl_list *layer, double ox, double oy, double *sx, double *sy) { | 25 | struct wl_list *layer, double ox, double oy, double *sx, double *sy) { |
20 | struct sway_layer_surface *sway_layer; | 26 | struct sway_layer_surface *sway_layer; |
@@ -128,7 +134,11 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | |||
128 | return output->swayc; | 134 | return output->swayc; |
129 | } | 135 | } |
130 | 136 | ||
131 | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time) { | 137 | void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec) { |
138 | if (time_msec == 0) { | ||
139 | time_msec = get_current_time_msec(); | ||
140 | } | ||
141 | |||
132 | struct wlr_seat *seat = cursor->seat->wlr_seat; | 142 | struct wlr_seat *seat = cursor->seat->wlr_seat; |
133 | struct wlr_surface *surface = NULL; | 143 | struct wlr_surface *surface = NULL; |
134 | double sx, sy; | 144 | double sx, sy; |
@@ -152,7 +162,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time) { | |||
152 | if (surface != NULL) { | 162 | if (surface != NULL) { |
153 | if (seat_is_input_allowed(cursor->seat, surface)) { | 163 | if (seat_is_input_allowed(cursor->seat, surface)) { |
154 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); | 164 | wlr_seat_pointer_notify_enter(seat, surface, sx, sy); |
155 | wlr_seat_pointer_notify_motion(seat, time, sx, sy); | 165 | wlr_seat_pointer_notify_motion(seat, time_msec, sx, sy); |
156 | } | 166 | } |
157 | } else { | 167 | } else { |
158 | wlr_seat_pointer_clear_focus(seat); | 168 | wlr_seat_pointer_clear_focus(seat); |
@@ -178,6 +188,10 @@ static void handle_cursor_motion_absolute( | |||
178 | 188 | ||
179 | void dispatch_cursor_button(struct sway_cursor *cursor, | 189 | void dispatch_cursor_button(struct sway_cursor *cursor, |
180 | uint32_t time_msec, uint32_t button, enum wlr_button_state state) { | 190 | uint32_t time_msec, uint32_t button, enum wlr_button_state state) { |
191 | if (time_msec == 0) { | ||
192 | time_msec = get_current_time_msec(); | ||
193 | } | ||
194 | |||
181 | struct wlr_surface *surface = NULL; | 195 | struct wlr_surface *surface = NULL; |
182 | double sx, sy; | 196 | double sx, sy; |
183 | struct sway_container *cont = | 197 | struct sway_container *cont = |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 631a273f..d1fc62c4 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -550,9 +550,7 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
550 | wlr_output, seat->cursor->cursor->x, | 550 | wlr_output, seat->cursor->cursor->x, |
551 | seat->cursor->cursor->y)) { | 551 | seat->cursor->cursor->y)) { |
552 | wlr_cursor_warp(seat->cursor->cursor, NULL, x, y); | 552 | wlr_cursor_warp(seat->cursor->cursor, NULL, x, y); |
553 | struct timespec now; | 553 | cursor_send_pointer_motion(seat->cursor, 0); |
554 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
555 | cursor_send_pointer_motion(seat->cursor, now.tv_nsec / 1000); | ||
556 | } | 554 | } |
557 | } | 555 | } |
558 | } | 556 | } |
@@ -565,9 +563,7 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
565 | } | 563 | } |
566 | 564 | ||
567 | if (last_workspace && last_workspace != new_workspace) { | 565 | if (last_workspace && last_workspace != new_workspace) { |
568 | struct timespec now; | 566 | cursor_send_pointer_motion(seat->cursor, 0); |
569 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
570 | cursor_send_pointer_motion(seat->cursor, now.tv_nsec / 1000); | ||
571 | } | 567 | } |
572 | 568 | ||
573 | seat->has_focus = (container != NULL); | 569 | seat->has_focus = (container != NULL); |
diff --git a/swaybar/bar.c b/swaybar/bar.c index d51c4ec7..669cb11a 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c | |||
@@ -401,24 +401,28 @@ void bar_setup(struct swaybar *bar, | |||
401 | render_all_frames(bar); | 401 | render_all_frames(bar); |
402 | } | 402 | } |
403 | 403 | ||
404 | static void display_in(int fd, short mask, void *_bar) { | 404 | static void display_in(int fd, short mask, void *data) { |
405 | struct swaybar *bar = (struct swaybar *)_bar; | 405 | struct swaybar *bar = data; |
406 | if (wl_display_dispatch(bar->display) == -1) { | 406 | if (wl_display_dispatch(bar->display) == -1) { |
407 | bar_teardown(bar); | 407 | bar_teardown(bar); |
408 | exit(0); | 408 | exit(0); |
409 | } | 409 | } |
410 | } | 410 | } |
411 | 411 | ||
412 | static void ipc_in(int fd, short mask, void *_bar) { | 412 | static void ipc_in(int fd, short mask, void *data) { |
413 | struct swaybar *bar = (struct swaybar *)_bar; | 413 | struct swaybar *bar = data; |
414 | if (handle_ipc_readable(bar)) { | 414 | if (handle_ipc_readable(bar)) { |
415 | render_all_frames(bar); | 415 | render_all_frames(bar); |
416 | } | 416 | } |
417 | } | 417 | } |
418 | 418 | ||
419 | static void status_in(int fd, short mask, void *_bar) { | 419 | static void status_in(int fd, short mask, void *data) { |
420 | struct swaybar *bar = (struct swaybar *)_bar; | 420 | struct swaybar *bar = data; |
421 | if (status_handle_readable(bar->status)) { | 421 | if (mask & (POLLHUP | POLLERR)) { |
422 | status_error(bar->status, "[error reading from status command]"); | ||
423 | render_all_frames(bar); | ||
424 | remove_event(fd); | ||
425 | } else if (status_handle_readable(bar->status)) { | ||
422 | render_all_frames(bar); | 426 | render_all_frames(bar); |
423 | } | 427 | } |
424 | } | 428 | } |
diff --git a/swaybar/event_loop.c b/swaybar/event_loop.c index 748372ed..bc4053be 100644 --- a/swaybar/event_loop.c +++ b/swaybar/event_loop.c | |||
@@ -72,24 +72,18 @@ void add_event(int fd, short mask, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | bool remove_event(int fd) { | 74 | bool remove_event(int fd) { |
75 | int index = -1; | 75 | /* |
76 | * Instead of removing events immediately, we mark them for deletion | ||
77 | * and clean them up later. This is so we can call remove_event inside | ||
78 | * an event callback safely. | ||
79 | */ | ||
76 | for (int i = 0; i < event_loop.fds.length; ++i) { | 80 | for (int i = 0; i < event_loop.fds.length; ++i) { |
77 | if (event_loop.fds.items[i].fd == fd) { | 81 | if (event_loop.fds.items[i].fd == fd) { |
78 | index = i; | 82 | event_loop.fds.items[i].fd = -1; |
83 | return true; | ||
79 | } | 84 | } |
80 | } | 85 | } |
81 | if (index != -1) { | 86 | return false; |
82 | free(event_loop.items->items[index]); | ||
83 | |||
84 | --event_loop.fds.length; | ||
85 | memmove(&event_loop.fds.items[index], &event_loop.fds.items[index + 1], | ||
86 | sizeof(struct pollfd) * event_loop.fds.length - index); | ||
87 | |||
88 | list_del(event_loop.items, index); | ||
89 | return true; | ||
90 | } else { | ||
91 | return false; | ||
92 | } | ||
93 | } | 87 | } |
94 | 88 | ||
95 | static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { | 89 | static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { |
@@ -118,11 +112,29 @@ void event_loop_poll() { | |||
118 | struct pollfd pfd = event_loop.fds.items[i]; | 112 | struct pollfd pfd = event_loop.fds.items[i]; |
119 | struct event_item *item = (struct event_item *)event_loop.items->items[i]; | 113 | struct event_item *item = (struct event_item *)event_loop.items->items[i]; |
120 | 114 | ||
121 | if (pfd.revents & pfd.events) { | 115 | // Always send these events |
116 | unsigned events = pfd.events | POLLHUP | POLLERR; | ||
117 | |||
118 | if (pfd.revents & events) { | ||
122 | item->cb(pfd.fd, pfd.revents, item->data); | 119 | item->cb(pfd.fd, pfd.revents, item->data); |
123 | } | 120 | } |
124 | } | 121 | } |
125 | 122 | ||
123 | // Cleanup removed events | ||
124 | int end = 0; | ||
125 | int length = event_loop.fds.length; | ||
126 | for (int i = 0; i < length; ++i) { | ||
127 | if (event_loop.fds.items[i].fd == -1) { | ||
128 | free(event_loop.items->items[i]); | ||
129 | list_del(event_loop.items, i); | ||
130 | --event_loop.fds.length; | ||
131 | } else if (end != i) { | ||
132 | event_loop.fds.items[end++] = event_loop.fds.items[i]; | ||
133 | } else { | ||
134 | end = i + 1; | ||
135 | } | ||
136 | } | ||
137 | |||
126 | // check timers | 138 | // check timers |
127 | // not tested, but seems to work | 139 | // not tested, but seems to work |
128 | for (int i = 0; i < event_loop.timers->length; ++i) { | 140 | for (int i = 0; i < event_loop.timers->length; ++i) { |