diff options
Diffstat (limited to 'swaybar')
-rw-r--r-- | swaybar/bar.c | 18 | ||||
-rw-r--r-- | swaybar/event_loop.c | 42 |
2 files changed, 38 insertions, 22 deletions
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) { |