diff --git a/client/common/common.c b/client/common/common.c index 1100456..317a96c 100644 --- a/client/common/common.c +++ b/client/common/common.c @@ -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); diff --git a/lib/bemenu.h b/lib/bemenu.h index 892584b..bba8a94 100644 --- a/lib/bemenu.h +++ b/lib/bemenu.h @@ -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. diff --git a/lib/internal.h b/lib/internal.h index cfa200d..b99a4d8 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -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. diff --git a/lib/menu.c b/lib/menu.c index e7d338f..af92866 100644 --- a/lib/menu.c +++ b/lib/menu.c @@ -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 diff --git a/lib/renderers/curses/curses.c b/lib/renderers/curses/curses.c index b95869c..e067efd 100644 --- a/lib/renderers/curses/curses.c +++ b/lib/renderers/curses/curses.c @@ -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 diff --git a/lib/renderers/wayland/wayland.c b/lib/renderers/wayland/wayland.c index 1cfeedc..f5bb33d 100644 --- a/lib/renderers/wayland/wayland.c +++ b/lib/renderers/wayland/wayland.c @@ -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 diff --git a/lib/renderers/x11/x11.c b/lib/renderers/x11/x11.c index 8d9d002..b0dc00d 100644 --- a/lib/renderers/x11/x11.c +++ b/lib/renderers/x11/x11.c @@ -6,7 +6,7 @@ #include #include -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