mirror of
https://github.com/Cloudef/bemenu
synced 2025-02-16 06:36:48 +00: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:
parent
ac30236ff7
commit
8217ae024b
@ -556,7 +556,10 @@ run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(cons
|
||||
struct bm_touch touch;
|
||||
enum bm_run_result status = BM_RUN_RESULT_RUNNING;
|
||||
do {
|
||||
bm_menu_render(menu);
|
||||
if (!bm_menu_render(menu)) {
|
||||
status = BM_RUN_RESULT_CANCEL;
|
||||
break;
|
||||
}
|
||||
key = bm_menu_poll_key(menu, &unicode);
|
||||
pointer = bm_menu_poll_pointer(menu);
|
||||
touch = bm_menu_poll_touch(menu);
|
||||
|
@ -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.
|
||||
*/
|
||||
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.
|
||||
|
@ -103,7 +103,7 @@ struct render_api {
|
||||
/**
|
||||
* 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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
bm_menu_render(struct bm_menu *menu)
|
||||
{
|
||||
assert(menu);
|
||||
|
||||
if (menu->renderer->api.render)
|
||||
menu->renderer->api.render(menu);
|
||||
return menu->renderer->api.render(menu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -176,7 +176,7 @@ draw_line(int32_t pair, int32_t y, const char *fmt, ...)
|
||||
attroff(COLOR_PAIR(pair));
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
render(struct bm_menu *menu)
|
||||
{
|
||||
if (curses.should_terminate) {
|
||||
@ -190,7 +190,7 @@ render(struct bm_menu *menu)
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
if ((curses.stdscreen = initscr()) == NULL)
|
||||
return;
|
||||
return true;
|
||||
|
||||
set_escdelay(25);
|
||||
flushinp();
|
||||
@ -280,6 +280,8 @@ render(struct bm_menu *menu)
|
||||
restore_stdin();
|
||||
curses.should_terminate = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
|
@ -23,14 +23,12 @@ render_windows_if_pending(const struct bm_menu *menu, struct wayland *wayland) {
|
||||
wl_display_flush(wayland->display);
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
wait_for_events(struct wayland *wayland) {
|
||||
wl_display_dispatch_pending(wayland->display);
|
||||
|
||||
if (wl_display_flush(wayland->display) < 0 && errno != EAGAIN) {
|
||||
wayland->input.sym = XKB_KEY_Escape;
|
||||
return;
|
||||
}
|
||||
if (wl_display_flush(wayland->display) < 0 && errno != EAGAIN)
|
||||
return false;
|
||||
|
||||
struct epoll_event ep[16];
|
||||
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].events & EPOLLERR || ep[i].events & EPOLLHUP ||
|
||||
((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) {
|
||||
bm_wl_repeat(wayland);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -62,14 +62,17 @@ schedule_windows_render_if_dirty(struct bm_menu *menu, struct wayland *wayland)
|
||||
menu->dirty = false;
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
render(struct bm_menu *menu)
|
||||
{
|
||||
struct wayland *wayland = menu->renderer->internal;
|
||||
|
||||
schedule_windows_render_if_dirty(menu, wayland);
|
||||
wait_for_events(wayland);
|
||||
if (!wait_for_events(wayland))
|
||||
return false;
|
||||
render_windows_if_pending(menu, wayland);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum bm_key
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <unistd.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
static void
|
||||
static bool
|
||||
render(struct bm_menu *menu)
|
||||
{
|
||||
struct x11 *x11 = menu->renderer->internal;
|
||||
@ -16,7 +16,7 @@ render(struct bm_menu *menu)
|
||||
|
||||
XEvent ev;
|
||||
if (XNextEvent(x11->display, &ev) || XFilterEvent(&ev, x11->window.drawable))
|
||||
return;
|
||||
return true;
|
||||
|
||||
switch (ev.type) {
|
||||
case KeyPress:
|
||||
@ -32,6 +32,8 @@ render(struct bm_menu *menu)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum bm_key
|
||||
|
Loading…
Reference in New Issue
Block a user