1
0
Fork 0
mirror of https://github.com/Cloudef/bemenu synced 2024-05-17 13:06:15 +02:00

Fix exiting when an unexpected Wayland error occurs.

If an unexpected error was returned from a Wayland API during rendering (e.g.
from wl_display_flush), the code did set input.sym = XKB_KEY_Escape, so that
the next call to poll_key would return BM_KEY_ESCAPE and bemenu would quit.

However, this has been broken since #135, because input.key_pending was not
set, so the "fake" XKB_KEY_Escape is just ignored, bemenu doesn't quit, but
instead, it enters an infinite loop and keeps a CPU core at 100% usage.

The "quick fix" would be to just set input.key_pending wherever input.sym was
set to XKB_KEY_Escape. However, to make error handling less error-prone,
decouple it from input handling and add an error flag to (bm_menu_)render.
This commit is contained in:
Joan Bruguera 2022-07-31 21:17:56 +02:00 committed by Jari Vetoniemi
parent ac30236ff7
commit 8217ae024b
7 changed files with 29 additions and 17 deletions

View File

@ -556,7 +556,10 @@ run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(cons
struct bm_touch touch; struct bm_touch touch;
enum bm_run_result status = BM_RUN_RESULT_RUNNING; enum bm_run_result status = BM_RUN_RESULT_RUNNING;
do { do {
bm_menu_render(menu); if (!bm_menu_render(menu)) {
status = BM_RUN_RESULT_CANCEL;
break;
}
key = bm_menu_poll_key(menu, &unicode); key = bm_menu_poll_key(menu, &unicode);
pointer = bm_menu_poll_pointer(menu); pointer = bm_menu_poll_pointer(menu);
touch = bm_menu_poll_touch(menu); touch = bm_menu_poll_touch(menu);

View File

@ -933,7 +933,7 @@ BM_PUBLIC struct bm_item** bm_menu_get_filtered_items(const struct bm_menu *menu
* *
* @param menu bm_menu instance to be rendered. * @param menu bm_menu instance to be rendered.
*/ */
BM_PUBLIC void bm_menu_render(struct bm_menu *menu); BM_PUBLIC bool bm_menu_render(struct bm_menu *menu);
/** /**
* Trigger filtering of menu manually. * Trigger filtering of menu manually.

View File

@ -103,7 +103,7 @@ struct render_api {
/** /**
* Tells underlying renderer to draw the menu. * Tells underlying renderer to draw the menu.
*/ */
void (*render)(struct bm_menu *menu); bool (*render)(struct bm_menu *menu);
/** /**
* Set vertical alignment of the bar. * Set vertical alignment of the bar.

View File

@ -723,13 +723,15 @@ bm_menu_get_filtered_items(const struct bm_menu *menu, uint32_t *out_nmemb)
return list_get_items(&menu->items, out_nmemb); return list_get_items(&menu->items, out_nmemb);
} }
void bool
bm_menu_render(struct bm_menu *menu) bm_menu_render(struct bm_menu *menu)
{ {
assert(menu); assert(menu);
if (menu->renderer->api.render) if (menu->renderer->api.render)
menu->renderer->api.render(menu); return menu->renderer->api.render(menu);
return true;
} }
void void

View File

@ -176,7 +176,7 @@ draw_line(int32_t pair, int32_t y, const char *fmt, ...)
attroff(COLOR_PAIR(pair)); attroff(COLOR_PAIR(pair));
} }
static void static bool
render(struct bm_menu *menu) render(struct bm_menu *menu)
{ {
if (curses.should_terminate) { if (curses.should_terminate) {
@ -190,7 +190,7 @@ render(struct bm_menu *menu)
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
if ((curses.stdscreen = initscr()) == NULL) if ((curses.stdscreen = initscr()) == NULL)
return; return true;
set_escdelay(25); set_escdelay(25);
flushinp(); flushinp();
@ -280,6 +280,8 @@ render(struct bm_menu *menu)
restore_stdin(); restore_stdin();
curses.should_terminate = true; curses.should_terminate = true;
} }
return true;
} }
static uint32_t static uint32_t

View File

@ -23,14 +23,12 @@ render_windows_if_pending(const struct bm_menu *menu, struct wayland *wayland) {
wl_display_flush(wayland->display); wl_display_flush(wayland->display);
} }
static void static bool
wait_for_events(struct wayland *wayland) { wait_for_events(struct wayland *wayland) {
wl_display_dispatch_pending(wayland->display); wl_display_dispatch_pending(wayland->display);
if (wl_display_flush(wayland->display) < 0 && errno != EAGAIN) { if (wl_display_flush(wayland->display) < 0 && errno != EAGAIN)
wayland->input.sym = XKB_KEY_Escape; return false;
return;
}
struct epoll_event ep[16]; struct epoll_event ep[16];
uint32_t num = epoll_wait(efd, ep, 16, -1); uint32_t num = epoll_wait(efd, ep, 16, -1);
@ -38,11 +36,13 @@ wait_for_events(struct wayland *wayland) {
if (ep[i].data.ptr == &wayland->fds.display) { if (ep[i].data.ptr == &wayland->fds.display) {
if (ep[i].events & EPOLLERR || ep[i].events & EPOLLHUP || if (ep[i].events & EPOLLERR || ep[i].events & EPOLLHUP ||
((ep[i].events & EPOLLIN) && wl_display_dispatch(wayland->display) < 0)) ((ep[i].events & EPOLLIN) && wl_display_dispatch(wayland->display) < 0))
wayland->input.sym = XKB_KEY_Escape; return false;
} else if (ep[i].data.ptr == &wayland->fds.repeat) { } else if (ep[i].data.ptr == &wayland->fds.repeat) {
bm_wl_repeat(wayland); bm_wl_repeat(wayland);
} }
} }
return true;
} }
static void static void
@ -62,14 +62,17 @@ schedule_windows_render_if_dirty(struct bm_menu *menu, struct wayland *wayland)
menu->dirty = false; menu->dirty = false;
} }
static void static bool
render(struct bm_menu *menu) render(struct bm_menu *menu)
{ {
struct wayland *wayland = menu->renderer->internal; struct wayland *wayland = menu->renderer->internal;
schedule_windows_render_if_dirty(menu, wayland); schedule_windows_render_if_dirty(menu, wayland);
wait_for_events(wayland); if (!wait_for_events(wayland))
return false;
render_windows_if_pending(menu, wayland); render_windows_if_pending(menu, wayland);
return true;
} }
static enum bm_key static enum bm_key

View File

@ -6,7 +6,7 @@
#include <unistd.h> #include <unistd.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
static void static bool
render(struct bm_menu *menu) render(struct bm_menu *menu)
{ {
struct x11 *x11 = menu->renderer->internal; struct x11 *x11 = menu->renderer->internal;
@ -16,7 +16,7 @@ render(struct bm_menu *menu)
XEvent ev; XEvent ev;
if (XNextEvent(x11->display, &ev) || XFilterEvent(&ev, x11->window.drawable)) if (XNextEvent(x11->display, &ev) || XFilterEvent(&ev, x11->window.drawable))
return; return true;
switch (ev.type) { switch (ev.type) {
case KeyPress: case KeyPress:
@ -32,6 +32,8 @@ render(struct bm_menu *menu)
} }
break; break;
} }
return true;
} }
static enum bm_key static enum bm_key