summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-04-21 14:45:33 +0200
committerLibravatar GitHub <noreply@github.com>2018-04-21 14:45:33 +0200
commitce70b9c45c65ae09e2d093520683ba77730d3368 (patch)
treef57dd4468446b9f07e55657912ff7843e7451ab3
parentMerge pull request #1836 from emersion/workspace-focus-update-cursor (diff)
parentRemove void * casts (diff)
downloadsway-ce70b9c45c65ae09e2d093520683ba77730d3368.tar.gz
sway-ce70b9c45c65ae09e2d093520683ba77730d3368.tar.zst
sway-ce70b9c45c65ae09e2d093520683ba77730d3368.zip
Merge pull request #1835 from ascent12/swaybar_status_err
Swaybar fix
-rw-r--r--swaybar/bar.c18
-rw-r--r--swaybar/event_loop.c42
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
404static void display_in(int fd, short mask, void *_bar) { 404static 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
412static void ipc_in(int fd, short mask, void *_bar) { 412static 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
419static void status_in(int fd, short mask, void *_bar) { 419static 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
74bool remove_event(int fd) { 74bool 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
95static int timer_item_timer_cmp(const void *_timer_item, const void *_timer) { 89static 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) {