Hello community, here is the log from the commit of package bemenu for openSUSE:Factory checked in at 2019-12-28 13:40:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/bemenu (Old) and /work/SRC/openSUSE:Factory/.bemenu.new.6675 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "bemenu" Sat Dec 28 13:40:22 2019 rev:2 rq:759688 version:0.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/bemenu/bemenu.changes 2019-03-22 15:07:12.369502897 +0100 +++ /work/SRC/openSUSE:Factory/.bemenu.new.6675/bemenu.changes 2019-12-28 13:40:28.678931738 +0100 @@ -1,0 +2,22 @@ +Fri Dec 27 13:37:31 UTC 2019 - Michael Vetter <[email protected]> + +- Update to 0.3.0: + * Uses default the monospace 10 font now to match dmenu + and to be more robust + * Hidpi support for wayland +- Add bemenu-0.3.0-curses.patch: + See https://github.com/Cloudef/bemenu/pull/77 + +------------------------------------------------------------------- +Wed Oct 30 13:15:01 UTC 2019 - Michael Vetter <[email protected]> + +- Update to 0.2.0: + * wayland: implement a proper repaint cycle + * Add options for renderers + * Add option to respect panel position + * x11: add pango as dependency of the x11 rendere + * bemenu: add --line-height / -H option + * Add C-g shortcut to x11 and wayland + * Add manpage + +------------------------------------------------------------------- Old: ---- 0.1.0.tar.gz New: ---- 0.3.0.tar.gz bemenu-0.3.0-curses.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ bemenu.spec ++++++ --- /var/tmp/diff_new_pack.bPzLtf/_old 2019-12-28 13:40:29.430932117 +0100 +++ /var/tmp/diff_new_pack.bPzLtf/_new 2019-12-28 13:40:29.438932121 +0100 @@ -18,19 +18,22 @@ %define bcond_with curses Name: bemenu -Version: 0.1.0 +Version: 0.3.0 Release: 0 Summary: Dynamic menu library and client program inspired by dmenu License: MIT Group: System/GUI/Other URL: https://github.com/Cloudef/bemenu Source0: https://github.com/Cloudef/bemenu/archive/%{version}.tar.gz +# https://github.com/Cloudef/bemenu/pull/77 +Patch0: bemenu-0.3.0-curses.patch BuildRequires: Mesa-devel BuildRequires: cmake BuildRequires: gcc-c++ BuildRequires: pango-devel BuildRequires: pkgconfig BuildRequires: pkgconfig(cairo) +BuildRequires: pkgconfig(ncurses) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-server) BuildRequires: pkgconfig(x11) @@ -46,8 +49,8 @@ %package -n libbemenu0 Summary: Dynamic menu library inspired by dmenu -Group: Development/Libraries/C and C++ # you need renderers +Group: Development/Libraries/C and C++ Requires: %{name} %description -n libbemenu0 @@ -66,6 +69,7 @@ %prep %setup -q +%patch0 -p1 %if %{with curses} # fix colliding name with our ncurses library specifics @@ -75,7 +79,6 @@ %build %cmake -DCMAKE_SHARED_LINKER_FLAGS="-Wl,--as-needed -Wl,-z,now" - make %{?_smp_mflags} VERBOSE=1 %install @@ -94,5 +97,7 @@ %files %{_bindir}/%{name}* %{_libdir}/%{name} +%{_mandir}/man1/bemenu-run.1%{?ext_man} +%{_mandir}/man1/bemenu.1%{?ext_man} %changelog ++++++ 0.1.0.tar.gz -> 0.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/.gitignore new/bemenu-0.3.0/.gitignore --- old/bemenu-0.1.0/.gitignore 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/.gitignore 2019-12-20 13:26:04.000000000 +0100 @@ -16,6 +16,8 @@ *.exe *.out *.app +/client/bemenu +/client/bemenu-run # Vim swap files .*.swp @@ -38,3 +40,19 @@ *~ *.backup *.old + +# CMake +CMakeFiles +CTestTestfile.cmake +Makefile +cmake_install.cmake +CMakeCache.txt +CMakeDoxyfile.in +CMakeDoxygenDefaults.cmake +DartConfiguration.tcl +Doxyfile + +# Generated source files +/lib/version.h +/lib/renderers/wayland/wayland-*-client-protocol.h +/lib/renderers/wayland/wayland-*-protocol.c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/CMakeLists.txt new/bemenu-0.3.0/CMakeLists.txt --- old/bemenu-0.1.0/CMakeLists.txt 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/CMakeLists.txt 2019-12-20 13:26:04.000000000 +0100 @@ -2,9 +2,13 @@ PROJECT(bemenu C) SET(BEMENU_NAME "bemenu") SET(BEMENU_DESCRIPTION "Dynamic menu library and client program inspired by dmenu") -SET(BEMENU_VERSION "0.1.0") +SET(BEMENU_VERSION "0.3.0") SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMake) +OPTION(BEMENU_CURSES_RENDERER "Build curses backend" ON) +OPTION(BEMENU_X11_RENDERER "Build X11 backend" ON) +OPTION(BEMENU_WAYLAND_RENDERER "Build wayland renderer" OFF) + INCLUDE(CTest) INCLUDE(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA1) @@ -23,5 +27,6 @@ # Generate documentation (make doxygen) ADD_SUBDIRECTORY(doxygen) +ADD_SUBDIRECTORY(man) # vim: set ts=8 sw=4 tw=0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/README.md new/bemenu-0.3.0/README.md --- old/bemenu-0.1.0/README.md 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/README.md 2019-12-20 13:26:04.000000000 +0100 @@ -6,6 +6,20 @@ Dynamic menu library and client program inspired by dmenu +## Renderers + +bemenu supports three different renderers: + +- ncurses +- X11 +- Wayland + +Enable/disable the renderers by appending these CMake options when executing `cmake <dir>`: + +- `-DBEMENU_CURSES_RENDERER=[OFF|ON]` +- `-DBEMENU_X11_RENDERER=[OFF|ON]` +- `-DBEMENU_WAYLAND_RENDERER=[OFF|ON]` + ## License * [GNU GPLv3 (or any later version)](LICENSE-CLIENT) for client program[s] and other sources except library and bindings diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/client/bemenu-run.c new/bemenu-0.3.0/client/bemenu-run.c --- old/bemenu-0.1.0/client/bemenu-run.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/client/bemenu-run.c 2019-12-20 13:26:04.000000000 +0100 @@ -66,6 +66,8 @@ if ((f = strcspn(state->path, ":")) > 0) { state->path += f + (path[f] ? 1 : 0); path[f] = 0; + } else { + state->path += 1; } if (!*path) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/client/common/common.c new/bemenu-0.3.0/client/common/common.c --- old/bemenu-0.1.0/client/common/common.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/client/common/common.c 2019-12-20 13:26:04.000000000 +0100 @@ -66,7 +66,7 @@ " -w, --wrap wraps cursor selection.\n" " -l, --list list items vertically with the given number of lines.\n" " -p, --prompt defines the prompt text to be displayed.\n" - " -P, --prefix text to shown before highlighted item.\n" + " -P, --prefix text to show before highlighted item.\n" " -I, --index select item at index automatically.\n" " --scrollbar display scrollbar. (always, autohide)\n" " --ifne only display menu if there are items.\n\n" @@ -84,7 +84,9 @@ " -b, --bottom appears at the bottom of the screen. (wx)\n" " -f, --grab show the menu before reading stdin. (wx)\n" + " -n, --no-overlap adjust geometry to not overlap with panels. (w)\n" " -m, --monitor index of monitor where menu will appear. (x)\n" + " -H, --line-height defines the height to make each menu line (0 = default height). (wx)\n" " --fn defines the font to be used ('name [size]'). (wx)\n" " --tb defines the title background color. (wx)\n" " --tf defines the title foreground color. (wx)\n" @@ -122,7 +124,9 @@ { "bottom", no_argument, 0, 'b' }, { "grab", no_argument, 0, 'f' }, + { "no-overlap", no_argument, 0, 'n' }, { "monitor", required_argument, 0, 'm' }, + { "line-height", required_argument, 0, 'H' }, { "fn", required_argument, 0, 0x101 }, { "tb", required_argument, 0, 0x102 }, { "tf", required_argument, 0, 0x103 }, @@ -146,7 +150,7 @@ * or parse them before running getopt.. */ for (;;) { - int32_t opt = getopt_long(*argc, *argv, "hviwl:I:p:P:I:bfm:", opts, NULL); + int32_t opt = getopt_long(*argc, *argv, "hviwl:I:p:P:I:bfm:H:n", opts, NULL); if (opt < 0) break; @@ -192,7 +196,13 @@ case 'm': client->monitor = strtol(optarg, NULL, 10); break; + case 'n': + client->no_overlap = true; + break; + case 'H': + client->line_height = strtol(optarg, NULL, 10); + break; case 0x101: client->font = optarg; break; @@ -257,6 +267,7 @@ return NULL; bm_menu_set_font(menu, client->font); + bm_menu_set_line_height(menu, client->line_height); bm_menu_set_title(menu, client->title); bm_menu_set_prefix(menu, client->prefix); bm_menu_set_filter_mode(menu, client->filter_mode); @@ -284,6 +295,7 @@ { bm_menu_set_highlighted_index(menu, client->selected); bm_menu_grab_keyboard(menu, true); + bm_menu_set_panel_overlap(menu, !client->no_overlap); if (client->ifne && !bm_menu_get_items(menu, NULL)) return BM_RUN_RESULT_CANCEL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/client/common/common.h new/bemenu-0.3.0/client/common/common.h --- old/bemenu-0.1.0/client/common/common.h 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/client/common/common.h 2019-12-20 13:26:04.000000000 +0100 @@ -10,6 +10,7 @@ const char *title; const char *prefix; const char *font; + uint32_t line_height; uint32_t lines; uint32_t selected; uint32_t monitor; @@ -17,6 +18,7 @@ bool grab; bool wrap; bool ifne; + bool no_overlap; }; void parse_args(struct client *client, int *argc, char **argv[]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/bemenu.h new/bemenu-0.3.0/lib/bemenu.h --- old/bemenu-0.1.0/lib/bemenu.h 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/bemenu.h 2019-12-20 13:26:04.000000000 +0100 @@ -386,6 +386,23 @@ const char* bm_menu_get_font(const struct bm_menu *menu); /** + * Set size of line in pixels. + * Some renderers such as ncurses may ignore this when it does not make sense. + * + * @param menu bm_menu instance where to set line height. + * @param line_height 0 for default line height, > 0 for that many pixels. + */ +void bm_menu_set_line_height(struct bm_menu *menu, uint32_t line_height); + +/** + * Get size of line in pixels. + * + * @param menu bm_menu instance where to get line height. + * @return uint32_t for max amount of vertical lines to be shown. + */ +uint32_t bm_menu_get_line_height(struct bm_menu *menu); + +/** * Set a hexadecimal color for element. * * @param menu bm_menu instance where to set color. @@ -472,6 +489,11 @@ */ bool bm_menu_is_keyboard_grabbed(struct bm_menu *menu); +/** + * Tell the renderer to position the menu that it can overlap panels. + */ +void bm_menu_set_panel_overlap(struct bm_menu *menu, bool overlap); + /** @} Properties */ /** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/internal.h new/bemenu-0.3.0/lib/internal.h --- old/bemenu-0.1.0/lib/internal.h 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/internal.h 2019-12-20 13:26:04.000000000 +0100 @@ -91,6 +91,11 @@ void (*grab_keyboard)(const struct bm_menu *menu, bool grab); /** + * Control overlap with panels + */ + void (*set_overlap)(const struct bm_menu *menu, bool overlap); + + /** * Version of the plugin. * Should match BM_PLUGIN_VERSION or failure. */ @@ -220,6 +225,11 @@ struct bm_font font; /** + * Line height. + */ + uint32_t line_height; + + /** * Colors. */ struct bm_hex_color colors[BM_COLOR_LAST]; @@ -296,6 +306,11 @@ * Is menu grabbed? */ bool grabbed; + + /** + * Should the menu overlap panels + */ + bool overlap; }; /* library.c */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/menu.c new/bemenu-0.3.0/lib/menu.c --- old/bemenu-0.1.0/lib/menu.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/menu.c 2019-12-20 13:26:04.000000000 +0100 @@ -9,7 +9,7 @@ /** * Default font. */ -static const char *default_font = "Fixed 9"; +static const char *default_font = "monospace 10"; /** * Default hexadecimal colors. @@ -266,6 +266,20 @@ return menu->font.name; } +void +bm_menu_set_line_height(struct bm_menu *menu, uint32_t line_height) +{ + assert(menu); + menu->line_height = line_height; +} + +uint32_t +bm_menu_get_line_height(struct bm_menu *menu) +{ + assert(menu); + return menu->line_height; +} + bool bm_menu_set_color(struct bm_menu *menu, enum bm_color color, const char *hex) { @@ -370,6 +384,20 @@ return menu->grabbed; } +void +bm_menu_set_panel_overlap(struct bm_menu *menu, bool overlap) +{ + assert(menu); + + if (menu->overlap == overlap) + return; + + menu->overlap = overlap; + + if (menu->renderer->api.set_overlap) + menu->renderer->api.set_overlap(menu, overlap); +} + bool bm_menu_add_items_at(struct bm_menu *menu, struct bm_item *item, uint32_t index) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/CMakeLists.txt new/bemenu-0.3.0/lib/renderers/CMakeLists.txt --- old/bemenu-0.1.0/lib/renderers/CMakeLists.txt 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/CMakeLists.txt 2019-12-20 13:26:04.000000000 +0100 @@ -1,8 +1,20 @@ -SET(RENDERERS - "curses" - "wayland" - "x11" -) +SET(RENDERERS "") + +IF(BEMENU_CURSES_RENDERER) + LIST(APPEND RENDERERS "curses") +ENDIF() + +IF(BEMENU_X11_RENDERER) + LIST(APPEND RENDERERS "x11") +ENDIF() + +IF(BEMENU_WAYLAND_RENDERER) + LIST(APPEND RENDERERS "wayland") +ENDIF() + +IF(NOT RENDERERS) + MESSAGE(FATAL_ERROR "At least one renderer should be enabled") +ENDIF() ADD_DEFINITIONS(-DPANGO_DISABLE_DEPRECATED) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/cairo.h new/bemenu-0.3.0/lib/renderers/cairo.h --- old/bemenu-0.1.0/lib/renderers/cairo.h 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/cairo.h 2019-12-20 13:26:04.000000000 +0100 @@ -12,6 +12,7 @@ cairo_t *cr; cairo_surface_t *surface; PangoContext *pango; + int scale; }; struct cairo_color { @@ -129,6 +130,10 @@ if (!ret) return false; + + assert(cairo->scale > 0); + cairo_scale(cairo->cr, cairo->scale, cairo->scale); + PangoLayout *layout = bm_pango_get_layout(cairo, paint, buffer); pango_cairo_update_layout(cairo->cr, layout); @@ -152,6 +157,8 @@ result->x_advance = width + paint->box.rx; result->height = height + paint->box.by + paint->box.ty; + + cairo_identity_matrix(cairo->cr); return true; } @@ -166,10 +173,12 @@ } __attribute__((unused)) static void -bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *out_result) +bm_cairo_paint(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *out_result) { assert(cairo && menu && out_result); + uint32_t height = fmin(menu->line_height, max_height); + memset(out_result, 0, sizeof(struct cairo_paint_result)); out_result->displayed = 1; @@ -189,21 +198,23 @@ ascii_height = result.height; paint.baseline = result.baseline; + int32_t vpadding = height == 0 ? 2 : (height - ascii_height) / 2; + memset(&result, 0, sizeof(result)); uint32_t title_x = 0; if (menu->title) { bm_cairo_color_from_menu_color(menu, BM_COLOR_TITLE_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_TITLE_BG, &paint.bg); - paint.pos = (struct pos){ result.x_advance, 2 }; - paint.box = (struct box){ 4, 8, 2, 2, 0, ascii_height }; + paint.pos = (struct pos){ result.x_advance, vpadding }; + paint.box = (struct box){ 4, 8, vpadding, vpadding, 0, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, "%s", menu->title); title_x = result.x_advance; } bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg); - paint.pos = (struct pos){ (menu->title ? 2 : 0) + result.x_advance, 2 }; - paint.box = (struct box){ (menu->title ? 2 : 4), 0, 2, 2, width - paint.pos.x, ascii_height }; + paint.pos = (struct pos){ (menu->title ? 2 : 0) + result.x_advance, vpadding }; + paint.box = (struct box){ (menu->title ? 2 : 4), 0, vpadding, vpadding, width - paint.pos.x, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, "%s", (menu->filter ? menu->filter : "")); const uint32_t titleh = result.height; out_result->height = titleh; @@ -247,12 +258,12 @@ } if (menu->prefix && highlighted) { - paint.pos = (struct pos){ 0, 2 + posy }; - paint.box = (struct box){ 4 + spacing_x, 0, 2, 2, width - paint.pos.x, ascii_height }; + paint.pos = (struct pos){ 0, vpadding + posy }; + paint.box = (struct box){ 4 + spacing_x, 0, vpadding, vpadding, width - paint.pos.x, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, "%s %s", menu->prefix, (items[i]->text ? items[i]->text : "")); } else { - paint.pos = (struct pos){ 0, 2 + posy }; - paint.box = (struct box){ 4 + spacing_x + prefix_x, 0, 2, 2, width - paint.pos.x, ascii_height }; + paint.pos = (struct pos){ 0, vpadding + posy }; + paint.box = (struct box){ 4 + spacing_x + prefix_x, 0, vpadding, vpadding, width - paint.pos.x, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : "")); } @@ -283,13 +294,13 @@ uint32_t cl = fmin(title_x + result.x_advance, width / 4); if (menu->wrap || menu->index > 0) { - paint.pos = (struct pos){ cl, 2 }; - paint.box = (struct box){ 1, 2, 2, 2, 0, ascii_height }; + paint.pos = (struct pos){ cl, vpadding }; + paint.box = (struct box){ 1, 2, vpadding, vpadding, 0, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, "<"); cl += result.x_advance + 1; } - for (uint32_t i = menu->index; i < count && cl < width; ++i) { + for (uint32_t i = menu->index; i < count && cl < (width/cairo->scale); ++i) { bool highlighted = (items[i] == bm_menu_get_highlighted_item(menu)); if (highlighted) { @@ -303,8 +314,8 @@ bm_cairo_color_from_menu_color(menu, BM_COLOR_ITEM_BG, &paint.bg); } - paint.pos = (struct pos){ cl, 2 }; - paint.box = (struct box){ 2, 4, 2, 2, 0, ascii_height }; + paint.pos = (struct pos){ cl, vpadding }; + paint.box = (struct box){ 2, 4, vpadding, vpadding, 0, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : "")); cl += result.x_advance + 2; out_result->displayed += (cl < width); @@ -315,8 +326,8 @@ bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_FG, &paint.fg); bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg); bm_pango_get_text_extents(cairo, &paint, &result, ">"); - paint.pos = (struct pos){ width - result.x_advance - 2, 2 }; - paint.box = (struct box){ 1, 2, 2, 2, 0, ascii_height }; + paint.pos = (struct pos){ width/cairo->scale - result.x_advance - 2, vpadding }; + paint.box = (struct box){ 1, 2, vpadding, vpadding, 0, ascii_height }; bm_cairo_draw_line(cairo, &paint, &result, ">"); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/curses/CMakeLists.txt new/bemenu-0.3.0/lib/renderers/curses/CMakeLists.txt --- old/bemenu-0.1.0/lib/renderers/curses/CMakeLists.txt 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/curses/CMakeLists.txt 2019-12-20 13:26:04.000000000 +0100 @@ -1,10 +1,8 @@ SET(CURSES_NEED_NCURSES TRUE) -FIND_PACKAGE(Curses) +FIND_PACKAGE(Curses REQUIRED) -if (CURSES_FOUND) - INCLUDE_DIRECTORIES(${CURSES_INCLUDE_DIRS}) - ADD_LIBRARY(bemenu-renderer-curses SHARED curses.c) - SET_TARGET_PROPERTIES(bemenu-renderer-curses PROPERTIES PREFIX "") - TARGET_LINK_LIBRARIES(bemenu-renderer-curses ${BEMENU_LIBRARIES} ${CURSES_LIBRARY} m) - INSTALL(TARGETS bemenu-renderer-curses DESTINATION "${CMAKE_INSTALL_LIBDIR}/bemenu") -endif () +INCLUDE_DIRECTORIES(${CURSES_INCLUDE_DIRS}) +ADD_LIBRARY(bemenu-renderer-curses SHARED curses.c) +SET_TARGET_PROPERTIES(bemenu-renderer-curses PROPERTIES PREFIX "") +TARGET_LINK_LIBRARIES(bemenu-renderer-curses ${BEMENU_LIBRARIES} ${CURSES_LIBRARY} m) +INSTALL(TARGETS bemenu-renderer-curses DESTINATION "${CMAKE_INSTALL_LIBDIR}/bemenu") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/wayland/CMakeLists.txt new/bemenu-0.3.0/lib/renderers/wayland/CMakeLists.txt --- old/bemenu-0.1.0/lib/renderers/wayland/CMakeLists.txt 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/wayland/CMakeLists.txt 2019-12-20 13:26:04.000000000 +0100 @@ -1,15 +1,17 @@ -FIND_PACKAGE(Wayland) -FIND_PACKAGE(Cairo) -FIND_PACKAGE(Pango) -FIND_PACKAGE(XKBCommon) +FIND_PACKAGE(Wayland REQUIRED) +FIND_PACKAGE(Cairo REQUIRED) +FIND_PACKAGE(Pango REQUIRED) +FIND_PACKAGE(XKBCommon REQUIRED) -if (WAYLAND_FOUND AND CAIRO_FOUND AND PANGO_FOUND AND XKBCOMMON_FOUND) - INCLUDE(Wayland) - WAYLAND_ADD_PROTOCOL_CLIENT(proto-layer-shell "wlr-layer-shell-unstable-v1.xml" layer-shell) - WAYLAND_ADD_PROTOCOL_CLIENT(proto-xdg-shell "xdg-shell.xml" xdg-shell) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${WAYLAND_CLIENT_INCLUDE_DIR} ${XKBCOMMON_INCLUDE_DIR} ${CAIRO_INCLUDE_DIRS} ${PANGO_INCLUDE_DIRS}) - ADD_LIBRARY(bemenu-renderer-wayland SHARED wayland.c registry.c window.c ${proto-layer-shell} ${proto-xdg-shell}) - SET_TARGET_PROPERTIES(bemenu-renderer-wayland PROPERTIES PREFIX "") - TARGET_LINK_LIBRARIES(bemenu-renderer-wayland ${BEMENU_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES} ${XKBCOMMON_LIBRARIES} ${CAIRO_LIBRARIES} ${PANGO_LIBRARIES} m) - INSTALL(TARGETS bemenu-renderer-wayland DESTINATION "${CMAKE_INSTALL_LIBDIR}/bemenu") +if (CMAKE_SYSTEM_NAME MATCHES "DragonFly" OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + PKG_CHECK_MODULES(EPOLL_SHIM REQUIRED epoll-shim) endif () + +INCLUDE(Wayland) +WAYLAND_ADD_PROTOCOL_CLIENT(proto-layer-shell "wlr-layer-shell-unstable-v1.xml" layer-shell) +WAYLAND_ADD_PROTOCOL_CLIENT(proto-xdg-shell "xdg-shell.xml" xdg-shell) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${WAYLAND_CLIENT_INCLUDE_DIR} ${XKBCOMMON_INCLUDE_DIR} ${CAIRO_INCLUDE_DIRS} ${PANGO_INCLUDE_DIRS} ${EPOLL_SHIM_INCLUDE_DIRS}) +ADD_LIBRARY(bemenu-renderer-wayland SHARED wayland.c registry.c window.c ${proto-layer-shell} ${proto-xdg-shell}) +SET_TARGET_PROPERTIES(bemenu-renderer-wayland PROPERTIES PREFIX "") +TARGET_LINK_LIBRARIES(bemenu-renderer-wayland ${BEMENU_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES} ${XKBCOMMON_LIBRARIES} ${CAIRO_LIBRARIES} ${PANGO_LIBRARIES} ${EPOLL_SHIM_LIBRARIES} m) +INSTALL(TARGETS bemenu-renderer-wayland DESTINATION "${CMAKE_INSTALL_LIBDIR}/bemenu") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/wayland/registry.c new/bemenu-0.3.0/lib/renderers/wayland/registry.c --- old/bemenu-0.1.0/lib/renderers/wayland/registry.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/wayland/registry.c 2019-12-20 13:26:04.000000000 +0100 @@ -243,7 +243,11 @@ static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t scale) { - (void)data, (void)wl_output, (void)scale; + (void)wl_output; + struct output *output = data; + + assert(scale > 0); + output->scale = scale; } static void @@ -271,7 +275,7 @@ struct wayland *wayland = data; if (strcmp(interface, "wl_compositor") == 0) { - wayland->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1); + wayland->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 3); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { wayland->layer_shell = wl_registry_bind(registry, id, &zwlr_layer_shell_v1_interface, 1); } else if (strcmp(interface, "wl_seat") == 0) { @@ -284,6 +288,7 @@ struct wl_output *wl_output = wl_registry_bind(registry, id, &wl_output_interface, 2); struct output *output = calloc(1, sizeof(struct output)); output->output = wl_output; + output->scale = 1; wl_list_insert(&wayland->outputs, &output->link); wl_output_add_listener(wl_output, &output_listener, output); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/wayland/wayland.c new/bemenu-0.3.0/lib/renderers/wayland/wayland.c --- old/bemenu-0.1.0/lib/renderers/wayland/wayland.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/wayland/wayland.c 2019-12-20 13:26:04.000000000 +0100 @@ -25,6 +25,13 @@ return; } + struct window *window; + wl_list_for_each(window, &wayland->windows, link) { + if (window->render_pending) + bm_wl_window_render(window, wayland->display, menu); + } + wl_display_flush(wayland->display); + struct epoll_event ep[16]; uint32_t num = epoll_wait(efd, ep, 16, -1); for (uint32_t i = 0; i < num; ++i) { @@ -38,10 +45,10 @@ } if (wayland->input.code != wayland->input.last_code) { - struct window *window; - wl_list_for_each(window, &wayland->windows, link) { - bm_wl_window_render(window, wayland->display, menu); + wl_list_for_each(window, &wayland->windows, link) { + bm_wl_window_schedule_render(window); } + wayland->input.last_code = wayland->input.code; } } @@ -115,6 +122,8 @@ case XKB_KEY_Return: return (mods & MOD_CTRL ? BM_KEY_CONTROL_RETURN : (mods & MOD_SHIFT ? BM_KEY_SHIFT_RETURN : BM_KEY_RETURN)); + case XKB_KEY_g: + if (!(mods & MOD_CTRL)) return BM_KEY_UNICODE; case XKB_KEY_Escape: return BM_KEY_ESCAPE; @@ -202,6 +211,18 @@ } static void +set_overlap(const struct bm_menu *menu, bool overlap) +{ + struct wayland *wayland = menu->renderer->internal; + assert(wayland); + + struct window *window; + wl_list_for_each(window, &wayland->windows, link) { + bm_wl_window_set_overlap(window, wayland->display, overlap); + } +} + +static void destructor(struct bm_menu *menu) { struct wayland *wayland = menu->renderer->internal; @@ -257,16 +278,21 @@ struct wl_surface *surface; if (!(surface = wl_compositor_create_surface(wayland->compositor))) goto fail; + + wl_surface_set_buffer_scale(surface, output->scale); + struct window *window = calloc(1, sizeof(struct window)); window->bottom = menu->bottom; + window->scale = output->scale; if (!bm_wl_window_create(window, wayland->display, wayland->shm, output->output, wayland->layer_shell, surface)) goto fail; window->notify.render = bm_cairo_paint; window->max_height = output->height; + window->render_pending = true; wl_list_insert(&wayland->windows, &window->link); } - if (!efd && (efd = epoll_create(EPOLL_CLOEXEC)) < 0) + if (!efd && (efd = epoll_create1(EPOLL_CLOEXEC)) < 0) goto fail; struct epoll_event ep; @@ -295,6 +321,7 @@ api->render = render; api->set_bottom = set_bottom; api->grab_keyboard = grab_keyboard; + api->set_overlap = set_overlap; api->priorty = BM_PRIO_GUI; api->version = BM_PLUGIN_VERSION; return "wayland"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/wayland/wayland.h new/bemenu-0.3.0/lib/renderers/wayland/wayland.h --- old/bemenu-0.1.0/lib/renderers/wayland/wayland.h 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/wayland/wayland.h 2019-12-20 13:26:04.000000000 +0100 @@ -81,12 +81,14 @@ struct wl_shm *shm; struct buffer buffers[2]; uint32_t width, height, max_height; + int32_t scale; uint32_t displayed; struct wl_list link; bool bottom; + bool render_pending; struct { - void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result); + void (*render)(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result); } notify; }; @@ -94,6 +96,7 @@ struct wl_output *output; struct wl_list link; int height; + int scale; }; struct wayland { @@ -117,9 +120,11 @@ void bm_wl_repeat(struct wayland *wayland); bool bm_wl_registry_register(struct wayland *wayland); void bm_wl_registry_destroy(struct wayland *wayland); +void bm_wl_window_schedule_render(struct window *window); void bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu); void bm_wl_window_set_bottom(struct window *window, struct wl_display *display, bool bottom); void bm_wl_window_grab_keyboard(struct window *window, struct wl_display *display, bool grab); +void bm_wl_window_set_overlap(struct window *window, struct wl_display *display, bool overlap); bool bm_wl_window_create(struct window *window, struct wl_display *display, struct wl_shm *shm, struct wl_output *output, struct zwlr_layer_shell_v1 *layer_shell, struct wl_surface *surface); void bm_wl_window_destroy(struct window *window); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/wayland/window.c new/bemenu-0.3.0/lib/renderers/wayland/window.c --- old/bemenu-0.1.0/lib/renderers/wayland/window.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/wayland/window.c 2019-12-20 13:26:04.000000000 +0100 @@ -107,7 +107,7 @@ } static bool -create_buffer(struct wl_shm *shm, struct buffer *buffer, int32_t width, int32_t height, uint32_t format) +create_buffer(struct wl_shm *shm, struct buffer *buffer, int32_t width, int32_t height, uint32_t format, int32_t scale) { int fd = -1; struct wl_shm_pool *pool = NULL; @@ -151,6 +151,7 @@ goto fail; } + buffer->cairo.scale = scale; buffer->width = width; buffer->height = height; return true; @@ -181,10 +182,10 @@ if (!buffer) return NULL; - if (window->width != buffer->width || window->height != buffer->height) + if (window->width * window->scale != buffer->width || window->height * window->scale != buffer->height) destroy_buffer(buffer); - if (!buffer->buffer && !create_buffer(window->shm, buffer, window->width, window->height, WL_SHM_FORMAT_ARGB8888)) + if (!buffer->buffer && !create_buffer(window->shm, buffer, window->width * window->scale, window->height * window->scale, WL_SHM_FORMAT_ARGB8888, window->scale)) return NULL; return buffer; @@ -197,6 +198,7 @@ struct window *window = data; wl_callback_destroy(callback); window->frame_cb = NULL; + window->render_pending = true; } static const struct wl_callback_listener listener = { @@ -204,10 +206,21 @@ }; void +bm_wl_window_schedule_render(struct window *window) +{ + assert(window); + if (window->frame_cb) + return; + + window->frame_cb = wl_surface_frame(window->surface); + wl_callback_add_listener(window->frame_cb, &listener, window); + wl_surface_commit(window->surface); +} + +void bm_wl_window_render(struct window *window, struct wl_display *display, const struct bm_menu *menu) { assert(window && menu); - struct buffer *buffer; for (int tries = 0; tries < 2; ++tries) { if (!(buffer = next_buffer(window))) { @@ -219,7 +232,7 @@ break; struct cairo_paint_result result; - window->notify.render(&buffer->cairo, buffer->width, fmin(buffer->height, window->max_height), window->max_height, menu, &result); + window->notify.render(&buffer->cairo, buffer->width, window->max_height * window->scale, menu, &result); window->displayed = result.displayed; if (window->height == result.height) @@ -232,13 +245,11 @@ destroy_buffer(buffer); } - window->frame_cb = wl_surface_frame(window->surface); - wl_callback_add_listener(window->frame_cb, &listener, window); - wl_surface_damage(window->surface, 0, 0, buffer->width, buffer->height); wl_surface_attach(window->surface, buffer->buffer, 0, 0); wl_surface_commit(window->surface); buffer->busy = true; + window->render_pending = false; } void @@ -300,6 +311,14 @@ wl_display_roundtrip(display); } +void +bm_wl_window_set_overlap(struct window *window, struct wl_display *display, bool overlap) +{ + zwlr_layer_surface_v1_set_exclusive_zone(window->layer_surface, overlap ? -1 : 0); + wl_surface_commit(window->surface); + wl_display_roundtrip(display); +} + bool bm_wl_window_create(struct window *window, struct wl_display *display, struct wl_shm *shm, struct wl_output *output, struct zwlr_layer_shell_v1 *layer_shell, struct wl_surface *surface) { @@ -307,7 +326,6 @@ if (layer_shell && (window->layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, surface, output, ZWLR_LAYER_SHELL_V1_LAYER_TOP, "menu"))) { zwlr_layer_surface_v1_add_listener(window->layer_surface, &layer_surface_listener, window); - zwlr_layer_surface_v1_set_exclusive_zone(window->layer_surface, -1); zwlr_layer_surface_v1_set_anchor(window->layer_surface, (window->bottom ? ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM : ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP) | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); zwlr_layer_surface_v1_set_size(window->layer_surface, 0, 32); wl_surface_commit(surface); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/x11/CMakeLists.txt new/bemenu-0.3.0/lib/renderers/x11/CMakeLists.txt --- old/bemenu-0.1.0/lib/renderers/x11/CMakeLists.txt 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/x11/CMakeLists.txt 2019-12-20 13:26:04.000000000 +0100 @@ -1,10 +1,9 @@ -FIND_PACKAGE(X11) -FIND_PACKAGE(Cairo) +FIND_PACKAGE(X11 REQUIRED) +FIND_PACKAGE(Cairo REQUIRED) +FIND_PACKAGE(Pango REQUIRED) -if (X11_FOUND AND X11_Xinerama_FOUND AND CAIRO_FOUND AND PANGO_FOUND) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${X11_INCLUDE_DIR} ${X11_Xinerama_INCLUDE_PATH} ${CAIRO_INCLUDE_DIRS} ${PANGO_INCLUDE_DIRS}) - ADD_LIBRARY(bemenu-renderer-x11 SHARED x11.c window.c xkb_unicode.c) - SET_TARGET_PROPERTIES(bemenu-renderer-x11 PROPERTIES PREFIX "") - TARGET_LINK_LIBRARIES(bemenu-renderer-x11 ${BEMENU_LIBRARIES} ${X11_LIBRARIES} ${X11_Xinerama_LIB} ${CAIRO_LIBRARIES} ${PANGO_LIBRARIES} m) - INSTALL(TARGETS bemenu-renderer-x11 DESTINATION "${CMAKE_INSTALL_LIBDIR}/bemenu") -endif () +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${X11_INCLUDE_DIR} ${X11_Xinerama_INCLUDE_PATH} ${CAIRO_INCLUDE_DIRS} ${PANGO_INCLUDE_DIRS}) +ADD_LIBRARY(bemenu-renderer-x11 SHARED x11.c window.c xkb_unicode.c) +SET_TARGET_PROPERTIES(bemenu-renderer-x11 PROPERTIES PREFIX "") +TARGET_LINK_LIBRARIES(bemenu-renderer-x11 ${BEMENU_LIBRARIES} ${X11_LIBRARIES} ${X11_Xinerama_LIB} ${CAIRO_LIBRARIES} ${PANGO_LIBRARIES} m) +INSTALL(TARGETS bemenu-renderer-x11 DESTINATION "${CMAKE_INSTALL_LIBDIR}/bemenu") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/x11/window.c new/bemenu-0.3.0/lib/renderers/x11/window.c --- old/bemenu-0.1.0/lib/renderers/x11/window.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/x11/window.c 2019-12-20 13:26:04.000000000 +0100 @@ -25,6 +25,7 @@ goto fail; } + buffer->cairo.scale = 1; buffer->width = width; buffer->height = height; buffer->created = true; @@ -72,7 +73,7 @@ cairo_push_group(buffer->cairo.cr); struct cairo_paint_result result; - window->notify.render(&buffer->cairo, buffer->width, buffer->height, window->max_height, menu, &result); + window->notify.render(&buffer->cairo, buffer->width, window->max_height, menu, &result); window->displayed = result.displayed; cairo_pop_group_to_source(buffer->cairo.cr); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/x11/x11.c new/bemenu-0.3.0/lib/renderers/x11/x11.c --- old/bemenu-0.1.0/lib/renderers/x11/x11.c 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/x11/x11.c 2019-12-20 13:26:04.000000000 +0100 @@ -101,6 +101,8 @@ case XK_Return: return (mods & MOD_CTRL ? BM_KEY_CONTROL_RETURN : (mods & MOD_SHIFT ? BM_KEY_SHIFT_RETURN : BM_KEY_RETURN)); + case XK_g: + if (!(mods & MOD_CTRL)) return BM_KEY_UNICODE; case XK_Escape: return BM_KEY_ESCAPE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/lib/renderers/x11/x11.h new/bemenu-0.3.0/lib/renderers/x11/x11.h --- old/bemenu-0.1.0/lib/renderers/x11/x11.h 2019-03-03 19:46:30.000000000 +0100 +++ new/bemenu-0.3.0/lib/renderers/x11/x11.h 2019-12-20 13:26:04.000000000 +0100 @@ -36,7 +36,7 @@ bool bottom; struct { - void (*render)(struct cairo *cairo, uint32_t width, uint32_t height, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result); + void (*render)(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result); } notify; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/man/CMakeLists.txt new/bemenu-0.3.0/man/CMakeLists.txt --- old/bemenu-0.1.0/man/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/bemenu-0.3.0/man/CMakeLists.txt 2019-12-20 13:26:04.000000000 +0100 @@ -0,0 +1,2 @@ +include(GNUInstallDirs) +install(FILES ./bemenu.1 ./bemenu-run.1 DESTINATION "${CMAKE_INSTALL_MANDIR}/man1/") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/man/bemenu-run.1 new/bemenu-0.3.0/man/bemenu-run.1 --- old/bemenu-0.1.0/man/bemenu-run.1 1970-01-01 01:00:00.000000000 +0100 +++ new/bemenu-0.3.0/man/bemenu-run.1 2019-12-20 13:26:04.000000000 +0100 @@ -0,0 +1 @@ +.so man1/bemenu.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.1.0/man/bemenu.1 new/bemenu-0.3.0/man/bemenu.1 --- old/bemenu-0.1.0/man/bemenu.1 1970-01-01 01:00:00.000000000 +0100 +++ new/bemenu-0.3.0/man/bemenu.1 2019-12-20 13:26:04.000000000 +0100 @@ -0,0 +1,194 @@ +.TH bemenu 1 2019-08-07 + +.SH NAME +bemenu \- Dynamic menu inspired by +.BR dmenu (1) + +.SH SYNOPSIS +.B bemenu +.RB [ -hviw ] +.RB [ -l +.IR lines ] +.RB [ -p +.IR prompt ] +.RB [ -P +.IR prefix ] +.RB [ -I +.IR index ] +.RB [ --scrollbar +.IR when ] +.RB [ --ifne ] +.RI [ backend-options ] + +.B bemenu-run ... + +.SH DESCRIPTION +.B bemenu +is a dynamic menu for +.BR tty (4) +(using +.BR ncurses (3)), +X11 and/or Wayland, inspired by +.RB dmenu (1). +It reads a list of newline-separated items from standard input. +When the user selects an item and presses Return, +their choice is printed to standard output and bemenu terminates. +Entering text will narrow the items to those matching the tokens in the input. + +.B bemenu-run +is a special-case invocation of +.BR bemenu , +where the input is a list of executables in the $PATH directories, +and the selection gets executed. + +.SH OPTIONS +.TP +.B \-h, \-\-help +Display bemenu help and exit. + +.TP +.B \-v, \-\-version +Display bemenu version and exit. + +.TP +.B \-i, \-\-ignorecase +Match items case-insensitively. + +.TP +.B \-w, \-\-wrap +Wraps cursor selection. + +.TP +.BI \-l \ NUMBER ,\ \-\-list= NUMBER +Lists items vertically with the given \fINUMBER\fR of lines. + +.TP +.BI \-p \ PROMPT ,\ \-\-prompt= PROMPT +Defines the \fIPROMPT\fR text to be displayed. + +.TP +.BI \-P \ PREFIX ,\ \-\-prefix= PREFIX +Text to show before highlighted item. + +.TP +.BI \-I \ INDEX ,\ \-\-index= INDEX +Select item at \fIINDEX\fR automatically. + +.TP +.BI \-\-scrollbar= WHEN +Display a scrollbar. +Valid values for \fIWHEN\fR are: +.RS +.TP +.I always +Always show the scrollbar. +.TP +.I autohide +Show scrollbar only when necessary. +.RE + +.TP +.B \-\-ifne +Only displays the menu when there are items. + +.SS Backend-specific Options + +These options are only available on backends specified in the parentheses +(Curses, Wayland and/or X11). + +.TP +.BR "\-b, \-\-bottom" +(Wayland, X11) The menu will appear at the bottom of the screen. + +.TP +.BR "\-f, \-\-grab" +(Wayland, X11) Show the menu before reading the standard input. + +.TP +.BR "\-n, \-\-no\-overlap" +(Wayland) Adjust geometry to not overlap with panels. + +.TP +.BI \-m " INDEX" ", \-\-monitor=" INDEX +(X11) Specify \fIINDEX\fR of the monitor where the menu should appear. + +.TP +.BI \-H " HEIGHT" ", \-\-line\-height=" HEIGHT +(Wayland, X11) Defines the \fIHEIGHT\fR to make each menu line. Use \fI0\fR for default height. + +.TP +.BI \-\-fn " NAME [SIZE]" +(Wayland, X11) Defines the font to be used. + +.TP +.BI \-\-tb= COLOR +(Wayland, X11) Defines the title background \fICOLOR\fR. + +.TP +.BI \-\-tf= COLOR +(Wayland, X11) Defines the title foreground \fICOLOR\fR. + +.TP +.BI \-\-fb= COLOR +(Wayland, X11) Defines the filter background \fICOLOR\fR. + +.TP +.BI \-\-ff= COLOR +(Wayland, X11) Defines the filter foreground \fICOLOR\fR. + +.TP +.BI \-\-nb= COLOR +(Wayland, X11) Defines the normal background \fICOLOR\fR. + +.TP +.BI \-\-nf= COLOR +(Wayland, X11) Defines the normal foreground \fICOLOR\fR. + +.TP +.BI \-\-hb= COLOR +(Wayland, X11) Defines the highlighted background \fICOLOR\fR. + +.TP +.BI \-\-hf= COLOR +(Wayland, X11) Defines the highlighted foreground \fICOLOR\fR. + +.TP +.BI \-\-sb= COLOR +(Wayland, X11) Defines the selected background \fICOLOR\fR. + +.TP +.BI \-\-sf= COLOR +(Wayland, X11) Defines the selected foreground \fICOLOR\fR. + +.TP +.BI \-\-scb= COLOR +(Wayland, X11) Defines the scrollbar background \fICOLOR\fR. + +.TP +.BI \-\-scf= COLOR +(Wayland, X11) Defines the scrollbar foreground \fICOLOR\fR. + +.SH EXIT STATUS + +0 when the user selects an option, 1 when the user aborts the selection. + +.SH ENVIRONMENT + +.TP +.B BEMENU_BACKEND +.RS +If set, the appropriate backend will be forced. +If empty, one of the GUI backends (Wayland, X11) will be selected automatically. + +The accepted values are: +.TP +.I curses +.BR ncurses (3) +based terminal backend. +.TP +.I wayland +Wayland backend. +.TP +.I x11 +X11 backend. +.RE ++++++ bemenu-0.3.0-curses.patch ++++++ diff -urEbw bemenu-0.3.0/lib/renderers/curses/curses.c bemenu-0.3.0.new/lib/renderers/curses/curses.c --- bemenu-0.3.0/lib/renderers/curses/curses.c 2019-12-20 13:26:04.000000000 +0100 +++ bemenu-0.3.0.new/lib/renderers/curses/curses.c 2019-12-27 14:43:43.828529240 +0100 @@ -24,7 +24,7 @@ #endif static struct curses { - WINDOW *stdscr; + WINDOW *stdscreen; struct sigaction abrt_action; struct sigaction segv_action; struct sigaction winch_action; @@ -87,14 +87,14 @@ curses.blen = 0; } - if (!curses.stdscr) + if (!curses.stdscreen) return; reopen_stdin_stdout(); refresh(); endwin(); restore_stdin_stdout(); - curses.stdscr = NULL; + curses.stdscreen = NULL; } static void @@ -108,7 +108,7 @@ resize_handler(int sig) { (void)sig; - if (!curses.stdscr) + if (!curses.stdscreen) return; refresh(); @@ -121,7 +121,7 @@ assert(fmt); size_t ncols; - if ((ncols = getmaxx(curses.stdscr)) <= 0) + if ((ncols = getmaxx(curses.stdscreen)) <= 0) return; va_list args; @@ -182,17 +182,17 @@ curses.should_terminate = false; } - if (!curses.stdscr) { + if (!curses.stdscreen) { store_stdin_stdout(); reopen_stdin_stdout(); setlocale(LC_CTYPE, ""); - if ((curses.stdscr = initscr()) == NULL) + if ((curses.stdscreen = initscr()) == NULL) return; set_escdelay(25); flushinp(); - keypad(curses.stdscr, true); + keypad(curses.stdscreen, true); curs_set(1); noecho(); raw(); @@ -205,7 +205,7 @@ erase(); - uint32_t ncols = getmaxx(curses.stdscr); + uint32_t ncols = getmaxx(curses.stdscreen); uint32_t title_len = (menu->title ? strlen(menu->title) + 1 : 0); if (title_len >= ncols) @@ -229,7 +229,7 @@ } uint32_t count, cl = 0; - const uint32_t lines = fmax(getmaxy(curses.stdscr), 1) - 1; + const uint32_t lines = fmax(getmaxy(curses.stdscreen), 1) - 1; if (lines > 1) { uint32_t displayed = 0; struct bm_item **items = bm_menu_get_filtered_items(menu, &count); @@ -279,7 +279,7 @@ get_displayed_count(const struct bm_menu *menu) { (void)menu; - return (curses.stdscr ? getmaxy(curses.stdscr) : 0); + return (curses.stdscreen ? getmaxy(curses.stdscreen) : 0); } static enum bm_key @@ -290,7 +290,7 @@ *unicode = 0; curses.polled_once = true; - if (!curses.stdscr || curses.should_terminate) + if (!curses.stdscreen || curses.should_terminate) return BM_KEY_NONE; get_wch((wint_t*)unicode); @@ -406,7 +406,7 @@ constructor(struct bm_menu *menu) { (void)menu; - assert(!curses.stdscr && "bemenu supports only one curses instance"); + assert(!curses.stdscreen && "bemenu supports only one curses instance"); memset(&curses, 0, sizeof(curses)); curses.old_stdin = -1;
