mirror of
https://github.com/Cloudef/bemenu
synced 2024-06-13 21:17:00 +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:
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;
|
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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue