Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package bemenu for openSUSE:Factory checked in at 2021-12-07 00:00:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/bemenu (Old) and /work/SRC/openSUSE:Factory/.bemenu.new.31177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "bemenu" Tue Dec 7 00:00:05 2021 rev:10 rq:935980 version:0.6.4 Changes: -------- --- /work/SRC/openSUSE:Factory/bemenu/bemenu.changes 2021-07-22 22:44:10.639135924 +0200 +++ /work/SRC/openSUSE:Factory/.bemenu.new.31177/bemenu.changes 2021-12-07 00:01:25.320131569 +0100 @@ -1,0 +2,15 @@ +Mon Dec 6 10:49:27 UTC 2021 - Michael Vetter <[email protected]> + +- Update to 0.6.4: + * fix scaling caused issue on window redimension on wayland #197 + * add -c center mode on wayland #198 + * Add option to configure cursor height #201 + * Add -s to disable title spacing on entries #203 + * Fix incorrect line height #207 + * lib/renderers/curses/curses.c: always use "%s"-style + format for printf()-style functions #211 + * Add horizontal alignment and improve center alignment #209 + * Add paste functionality #210 + * Instruction for installing dependencies #214 + +------------------------------------------------------------------- Old: ---- 0.6.3.tar.gz New: ---- 0.6.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ bemenu.spec ++++++ --- /var/tmp/diff_new_pack.PV3U9c/_old 2021-12-07 00:01:25.936129390 +0100 +++ /var/tmp/diff_new_pack.PV3U9c/_new 2021-12-07 00:01:25.940129377 +0100 @@ -18,7 +18,7 @@ %define bcond_with curses Name: bemenu -Version: 0.6.3 +Version: 0.6.4 Release: 0 Summary: Dynamic menu library and client program inspired by dmenu License: MIT ++++++ 0.6.3.tar.gz -> 0.6.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/README.md new/bemenu-0.6.4/README.md --- old/bemenu-0.6.3/README.md 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/README.md 2021-12-03 09:04:37.000000000 +0100 @@ -69,6 +69,16 @@ | x11 | x11, xinerama, cairo, pango, pangocairo | | Wayland | wayland-client, wayland-protocols, cairo, pango, pangocairo, xkbcommon | +Currently, pasting from clipboard is done at runtime with `wl-paste -t text/plain` and `xclip -t text/plain -out`, attempted in that order. + +### Installing the dependencies + +#### Ubuntu 20.04 + +```sh +sudo apt install wayland-protocols libcairo-dev libpango1.0-dev libxkbcommon-dev libwayland-dev +``` + ## Environment variables | Variable | Description | Value | @@ -131,6 +141,7 @@ | Ctrl + k | Kill text after cursor | | Ctrl + w | Kill all text in filter | | Ctrl + m | Execute selected item | +| Ctrl + y | Paste clipboard | ## Projects using bemenu diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/VERSION new/bemenu-0.6.4/VERSION --- old/bemenu-0.6.3/VERSION 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/VERSION 2021-12-03 09:04:37.000000000 +0100 @@ -1 +1 @@ -0.6.3 +0.6.4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/client/common/common.c new/bemenu-0.6.4/client/common/common.c --- old/bemenu-0.6.3/client/common/common.c 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/client/common/common.c 2021-12-03 09:04:37.000000000 +0100 @@ -1,3 +1,5 @@ +#include "internal.h" + #include "common.h" #include <stdlib.h> #include <string.h> @@ -175,6 +177,7 @@ " -P, --prefix text to show before highlighted item.\n" " -I, --index select item at index automatically.\n" " -x, --password hide input.\n" + " -s, --no-spacing disable the title spacing on entries.\n" " --scrollbar display scrollbar. (none (default), always, autohide)\n" " --ifne only display menu if there are items.\n" " --fork always fork. (bemenu-run)\n" @@ -192,10 +195,13 @@ " (...) At end of help indicates the backend support for option.\n\n" " -b, --bottom appears at the bottom of the screen. (wx)\n" + " -c, --center appears at the center 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. (wx)\n" " -H, --line-height defines the height to make each menu line (0 = default height). (wx)\n" + " -M, --margin defines the empty space on either side of the menu. (wx)\n" + " --ch defines the height of the cursor (0 = scales with line 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" @@ -244,6 +250,7 @@ { "filter", required_argument, 0, 'F' }, { "wrap", no_argument, 0, 'w' }, { "list", required_argument, 0, 'l' }, + { "center", no_argument, 0, 'c' }, { "prompt", required_argument, 0, 'p' }, { "index", required_argument, 0, 'I' }, { "prefix", required_argument, 0, 'P' }, @@ -256,8 +263,11 @@ { "bottom", no_argument, 0, 'b' }, { "grab", no_argument, 0, 'f' }, { "no-overlap", no_argument, 0, 'n' }, + { "no-spacing", no_argument, 0, 's' }, { "monitor", required_argument, 0, 'm' }, { "line-height", required_argument, 0, 'H' }, + { "margin", required_argument, 0, 'M' }, + { "ch", required_argument, 0, 0x118 }, { "fn", required_argument, 0, 0x101 }, { "tb", required_argument, 0, 0x102 }, { "tf", required_argument, 0, 0x103 }, @@ -286,7 +296,7 @@ for (optind = 0;;) { int32_t opt; - if ((opt = getopt_long(*argc, *argv, "hviwxl:I:p:P:I:bfm:H:n", opts, NULL)) < 0) + if ((opt = getopt_long(*argc, *argv, "hviwxcl:I:p:P:I:bfm:H:M:ns", opts, NULL)) < 0) break; switch (opt) { @@ -309,6 +319,9 @@ case 'l': client->lines = strtol(optarg, NULL, 10); break; + case 'c': + client->center = true; + break; case 'p': client->title = optarg; break; @@ -346,10 +359,19 @@ case 'n': client->no_overlap = true; break; + case 's': + client->no_spacing = true; + break; case 'H': client->line_height = strtol(optarg, NULL, 10); break; + case 'M': + client->hmargin_size = strtol(optarg, NULL, 10); + break; + case 0x118: + client->cursor_height = strtol(optarg, NULL, 10); + break; case 0x101: client->font = optarg; break; @@ -428,17 +450,27 @@ bm_menu_set_font(menu, client->font); bm_menu_set_line_height(menu, client->line_height); + bm_menu_set_cursor_height(menu, client->cursor_height); bm_menu_set_title(menu, client->title); bm_menu_set_prefix(menu, client->prefix); bm_menu_set_filter_mode(menu, client->filter_mode); bm_menu_set_lines(menu, client->lines); bm_menu_set_wrap(menu, client->wrap); - bm_menu_set_bottom(menu, client->bottom); bm_menu_set_monitor(menu, client->monitor); bm_menu_set_monitor_name(menu, client->monitor_name); bm_menu_set_scrollbar(menu, client->scrollbar); bm_menu_set_panel_overlap(menu, !client->no_overlap); + bm_menu_set_spacing(menu, !client->no_spacing); bm_menu_set_password(menu, client->password); + bm_menu_set_hmargin_size(menu, client->hmargin_size); + + if (client->center) { + bm_menu_set_align(menu, BM_ALIGN_CENTER); + } else if (client->bottom) { + bm_menu_set_align(menu, BM_ALIGN_BOTTOM); + } else { + bm_menu_set_align(menu, BM_ALIGN_TOP); + } for (uint32_t i = 0; i < BM_COLOR_LAST; ++i) bm_menu_set_color(menu, i, client->colors[i]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/client/common/common.h new/bemenu-0.6.4/client/common/common.h --- old/bemenu-0.6.3/client/common/common.h 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/client/common/common.h 2021-12-03 09:04:37.000000000 +0100 @@ -13,14 +13,18 @@ const char *font; const char *initial_filter; uint32_t line_height; + uint32_t cursor_height; uint32_t lines; uint32_t selected; uint32_t monitor; + uint32_t hmargin_size; bool bottom; + bool center; bool grab; bool wrap; bool ifne; bool no_overlap; + bool no_spacing; bool force_fork, fork; bool no_exec; bool password; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/bemenu.h new/bemenu-0.6.4/lib/bemenu.h --- old/bemenu-0.6.3/lib/bemenu.h 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/bemenu.h 2021-12-03 09:04:37.000000000 +0100 @@ -116,6 +116,26 @@ }; /** + * Vertical position of the menu. + */ +enum bm_align { + /** + * Menu is at the top of the screen. + */ + BM_ALIGN_TOP, + + /** + * Menu is at the bottom of the screen. + */ + BM_ALIGN_BOTTOM, + + /** + * Menu is in the center of the screen. + */ + BM_ALIGN_CENTER, +}; + +/** * Get name of the renderer. * * @param renderer bm_renderer instance. @@ -212,6 +232,7 @@ BM_KEY_LINE_DELETE_LEFT, BM_KEY_LINE_DELETE_RIGHT, BM_KEY_WORD_DELETE, + BM_KEY_PASTE, BM_KEY_TAB, BM_KEY_SHIFT_TAB, BM_KEY_ESCAPE, @@ -449,6 +470,23 @@ BM_PUBLIC uint32_t bm_menu_get_line_height(struct bm_menu *menu); /** + * Set height of cursor in pixels. + * Some renderers such as ncurses may ignore this when it does not make sense. + * + * @param menu bm_menu instance where to set cursor height. + * @param cursor_height 0 for default cursor height, > 0 for that many pixels. + */ +BM_PUBLIC void bm_menu_set_cursor_height(struct bm_menu *menu, uint32_t cursor_height); + +/** + * Get height of cursor in pixels. + * + * @param menu bm_menu instance where to get cursor height. + * @return uint32_t for max amount of vertical cursors to be shown. + */ +BM_PUBLIC uint32_t bm_menu_get_cursor_height(struct bm_menu *menu); + +/** * Set a hexadecimal color for element. * * @param menu bm_menu instance where to set color. @@ -484,21 +522,39 @@ BM_PUBLIC enum bm_scrollbar_mode bm_menu_get_scrollbar(struct bm_menu *menu); /** - * Display menu at bottom of the screen. - * This may be no-op on some renderers (curses, wayland) + * Set the vertical alignment of the bar. * - * @param menu bm_menu instance to set bottom mode for. - * @param bottom true for bottom mode, false for top mode. + * @param menu bm_menu to set alignment for. + * @param align alignment to set */ -BM_PUBLIC void bm_menu_set_bottom(struct bm_menu *menu, bool bottom); +BM_PUBLIC void bm_menu_set_align(struct bm_menu *menu, enum bm_align align); /** - * Is menu being displayed at bottom of the screen? + * Get the vertical alignment of the bar. * - * @param menu bm_menu instance where to get bottom mode from. - * @return true if bottom mode, false otherwise. + * @param menu bm_menu to get alignment for. + * @return alignment for the menu */ -BM_PUBLIC bool bm_menu_get_bottom(struct bm_menu *menu); + +BM_PUBLIC enum bm_align bm_menu_get_align(struct bm_menu *menu); + +/** + * Set the horizontal margin of the bar. + * + * @param menu bm_menu to set horizontal margin for. + * @param margin margin to set. + */ + +BM_PUBLIC void bm_menu_set_hmargin_size(struct bm_menu *menu, uint32_t margin); + +/** + * Get the horizontal margin of the bar. + * + * @param menu bm_menu to get horizontal margin from. + * @return horizontal margin of the menu + */ + +BM_PUBLIC uint32_t bm_menu_get_hmargin_size(struct bm_menu *menu); /** * Display menu at monitor index. @@ -558,6 +614,14 @@ BM_PUBLIC void bm_menu_set_password(struct bm_menu *menu, bool password); /** + * Space entries with title. + * + * @param menu bm_menu instance to set password mode for. + * @param spacing true to enable title spacing + */ +BM_PUBLIC void bm_menu_set_spacing(struct bm_menu *menu, bool spacing); + +/** * Is password mode activated and input hidden? * * @param menu bm_menu instance where to get password mode from. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/internal.h new/bemenu-0.6.4/lib/internal.h --- old/bemenu-0.6.3/lib/internal.h 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/internal.h 2021-12-03 09:04:37.000000000 +0100 @@ -18,6 +18,9 @@ #include <stddef.h> /* for size_t */ #include <stdarg.h> +//minimum allowed window width when setting margin +#define WINDOW_MIN_WIDTH 80 + /** * Destructor function pointer for some list calls. */ @@ -75,9 +78,14 @@ void (*render)(const struct bm_menu *menu); /** - * Set menu to appear from bottom of the screen. + * Set vertical alignment of the bar. + */ + void (*set_align)(const struct bm_menu *menu, enum bm_align align); + + /** + * Set horizontal margin. */ - void (*set_bottom)(const struct bm_menu *menu, bool bottom); + void (*set_hmargin_size)(const struct bm_menu *menu, uint32_t margin); /** * Set monitor indeax where menu will appear @@ -234,6 +242,11 @@ uint32_t line_height; /** + * Cursor height. + */ + uint32_t cursor_height; + + /** * Colors. */ struct bm_hex_color colors[BM_COLOR_LAST]; @@ -312,9 +325,14 @@ bool wrap; /** - * Is menu shown from bottom? + * Vertical alignment. */ - bool bottom; + enum bm_align align; + + /** + * Horizontal margin. + */ + uint32_t hmargin_size; /** * Is menu grabbed? @@ -330,6 +348,11 @@ * Should the input be hidden */ bool password; + + /** + * Should the entry should follow the title spacing + */ + bool spacing; }; /* library.c */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/menu.c new/bemenu-0.6.4/lib/menu.c --- old/bemenu-0.6.3/lib/menu.c 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/menu.c 2021-12-03 09:04:37.000000000 +0100 @@ -296,6 +296,20 @@ return menu->line_height; } +void +bm_menu_set_cursor_height(struct bm_menu *menu, uint32_t cursor_height) +{ + assert(menu); + menu->cursor_height = cursor_height; +} + +uint32_t +bm_menu_get_cursor_height(struct bm_menu *menu) +{ + assert(menu); + return menu->cursor_height; +} + bool bm_menu_set_color(struct bm_menu *menu, enum bm_color color, const char *hex) { @@ -341,24 +355,45 @@ } void -bm_menu_set_bottom(struct bm_menu *menu, bool bottom) +bm_menu_set_align(struct bm_menu *menu, enum bm_align align) { assert(menu); - if (menu->bottom == bottom) + if(menu->align == align) return; - menu->bottom = bottom; + menu->align = align; - if (menu->renderer->api.set_bottom) - menu->renderer->api.set_bottom(menu, bottom); + if (menu->renderer->api.set_align) + menu->renderer->api.set_align(menu, align); } -bool -bm_menu_get_bottom(struct bm_menu *menu) +enum bm_align +bm_menu_get_align(struct bm_menu *menu) +{ + assert(menu); + return menu->align; +} + +void +bm_menu_set_hmargin_size(struct bm_menu *menu, uint32_t margin) +{ + assert(menu); + + if(menu->hmargin_size == margin) + return; + + menu->hmargin_size = margin; + + if(menu->renderer->api.set_hmargin_size) + menu->renderer->api.set_hmargin_size(menu, margin); +} + +uint32_t +bm_menu_get_hmargin_size(struct bm_menu *menu) { assert(menu); - return menu->bottom; + return menu->hmargin_size; } void @@ -434,6 +469,17 @@ } void +bm_menu_set_spacing(struct bm_menu *menu, bool spacing) +{ + assert(menu); + + if (menu->spacing == spacing) + return; + + menu->spacing = spacing; +} + +void bm_menu_set_password(struct bm_menu *menu, bool password) { assert(menu); @@ -789,6 +835,26 @@ } break; + case BM_KEY_PASTE: + { + FILE *clipboard; + clipboard = popen("wl-paste -t text/plain", "r"); + if (!clipboard) { + clipboard = popen("xclip -t text/plain -out", "r"); + } + if (!clipboard) { + break; + } + int c; + while ((c = fgetc(clipboard)) != EOF) { + size_t width; + menu->cursor += bm_unicode_insert(&menu->filter, &menu->filter_size, menu->cursor, c, &width); + menu->curses_cursor += width; + } + pclose(clipboard); + } + break; + case BM_KEY_UNICODE: { size_t width; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/cairo_renderer.h new/bemenu-0.6.4/lib/renderers/cairo_renderer.h --- old/bemenu-0.6.3/lib/renderers/cairo_renderer.h 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/cairo_renderer.h 2021-12-03 09:04:37.000000000 +0100 @@ -25,6 +25,7 @@ const char *font; int32_t baseline; uint32_t cursor; + uint32_t cursor_height; bool draw_cursor; struct box { @@ -131,11 +132,12 @@ height = paint->box.h > 0 ? paint->box.h : height; int base = pango_layout_get_baseline(layout) / PANGO_SCALE; + uint32_t line_height = height + paint->box.by + paint->box.ty; cairo_set_source_rgba(cairo->cr, paint->bg.r, paint->bg.b, paint->bg.g, paint->bg.a); cairo_rectangle(cairo->cr, paint->pos.x - paint->box.lx, paint->pos.y - paint->box.ty, (paint->box.w > 0 ? paint->box.w : width) + paint->box.rx + paint->box.lx, - height + paint->box.by + paint->box.ty); + line_height); cairo_fill(cairo->cr); cairo_set_source_rgba(cairo->cr, paint->fg.r, paint->fg.b, paint->fg.g, paint->fg.a); @@ -152,15 +154,16 @@ rect.width = result.x_advance * PANGO_SCALE; } + uint32_t cursor_height = fmin(paint->cursor_height == 0 ? line_height : paint->cursor_height, line_height); cairo_set_source_rgba(cairo->cr, paint->fg.r, paint->fg.b, paint->fg.g, paint->fg.a); cairo_rectangle(cairo->cr, - paint->pos.x + paint->box.lx + rect.x / PANGO_SCALE, paint->pos.y - paint->box.ty, - rect.width / PANGO_SCALE, height + paint->box.by + paint->box.ty); + paint->pos.x + paint->box.lx + rect.x / PANGO_SCALE, paint->pos.y - paint->box.ty + ((line_height - cursor_height) / 2), + rect.width / PANGO_SCALE, cursor_height); cairo_fill(cairo->cr); cairo_rectangle(cairo->cr, paint->pos.x + paint->box.lx + rect.x / PANGO_SCALE, paint->pos.y - paint->box.ty, - rect.width / PANGO_SCALE, height + paint->box.by + paint->box.ty); + rect.width / PANGO_SCALE, line_height); cairo_clip(cairo->cr); cairo_set_source_rgba(cairo->cr, paint->bg.r, paint->bg.b, paint->bg.g, paint->bg.a); @@ -172,7 +175,7 @@ g_object_unref(layout); result->x_advance = width + paint->box.rx; - result->height = height + paint->box.by + paint->box.ty; + result->height = line_height; cairo_identity_matrix(cairo->cr); return true; @@ -211,19 +214,10 @@ assert(cairo && menu && out_result); max_height /= cairo->scale; - uint32_t height = fmin(menu->line_height, max_height); memset(out_result, 0, sizeof(struct cairo_paint_result)); out_result->displayed = 1; - cairo_set_source_rgba(cairo->cr, 0, 0, 0, 0); - cairo_rectangle(cairo->cr, 0, 0, width, height); - - cairo_save(cairo->cr); - cairo_set_operator(cairo->cr, CAIRO_OPERATOR_CLEAR); - cairo_paint(cairo->cr); - cairo_restore(cairo->cr); - struct cairo_paint paint = {0}; paint.font = menu->font.name; @@ -234,7 +228,16 @@ ascii_height = result.height; paint.baseline = result.baseline; - int32_t vpadding = height == 0 ? 2 : (height - ascii_height) / 2; + uint32_t height = fmin(fmax(menu->line_height, ascii_height), max_height); + uint32_t vpadding = (height - ascii_height)/2; + + cairo_set_source_rgba(cairo->cr, 0, 0, 0, 0); + cairo_rectangle(cairo->cr, 0, 0, width, height); + + cairo_save(cairo->cr); + cairo_set_operator(cairo->cr, CAIRO_OPERATOR_CLEAR); + cairo_paint(cairo->cr); + cairo_restore(cairo->cr); memset(&result, 0, sizeof(result)); uint32_t title_x = 0; @@ -242,7 +245,7 @@ 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, vpadding }; - paint.box = (struct box){ 4, 8, vpadding, vpadding, 0, ascii_height }; + paint.box = (struct box){ 4, 8, vpadding, -vpadding, 0, height }; bm_cairo_draw_line(cairo, &paint, &result, "%s", menu->title); title_x = result.x_advance; } @@ -251,8 +254,9 @@ bm_cairo_color_from_menu_color(menu, BM_COLOR_FILTER_BG, &paint.bg); paint.draw_cursor = true; paint.cursor = menu->cursor; + paint.cursor_height = menu->cursor_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 }; + paint.box = (struct box){ (menu->title ? 2 : 4), 0, vpadding, -vpadding, width - paint.pos.x, height }; const char *filter_text = (menu->filter ? menu->filter : ""); if (menu->password) { @@ -273,7 +277,7 @@ /* vertical mode */ const bool scrollbar = (menu->scrollbar > BM_SCROLLBAR_NONE && (menu->scrollbar != BM_SCROLLBAR_AUTOHIDE || count > lines) ? true : false); - uint32_t spacing_x = title_x, spacing_y = 0; // 0 == variable width spacing + uint32_t spacing_x = menu->spacing ? title_x : 0, spacing_y = 0; // 0 == variable width spacing if (lines > max_height / titleh) { /* there is more lines than screen can fit, enter fixed spacing mode */ lines = max_height / titleh - 1; @@ -290,7 +294,7 @@ if (scrollbar) { bm_pango_get_text_extents(cairo, &paint, &result, "#"); scrollbar_w = result.x_advance; - spacing_x += (title_x < scrollbar_w ? scrollbar_w - title_x : 0); + spacing_x += (spacing_x < scrollbar_w ? scrollbar_w : 0); } uint32_t posy = titleh; @@ -310,12 +314,12 @@ } if (menu->prefix && highlighted) { - paint.pos = (struct pos){ spacing_x, vpadding + posy }; - paint.box = (struct box){ 4, 0, vpadding, vpadding, width - paint.pos.x, ascii_height }; + paint.pos = (struct pos){ spacing_x, posy+vpadding }; + paint.box = (struct box){ 4, 0, vpadding, -vpadding, width - paint.pos.x, height }; bm_cairo_draw_line(cairo, &paint, &result, "%s %s", menu->prefix, (items[i]->text ? items[i]->text : "")); } else { - paint.pos = (struct pos){ spacing_x, vpadding + posy }; - paint.box = (struct box){ 4 + prefix_x, 0, vpadding, vpadding, width - paint.pos.x, ascii_height }; + paint.pos = (struct pos){ spacing_x, posy+vpadding }; + paint.box = (struct box){ 4 + prefix_x, 0, vpadding, -vpadding, width - paint.pos.x, height }; bm_cairo_draw_line(cairo, &paint, &result, "%s", (items[i]->text ? items[i]->text : "")); } @@ -355,7 +359,7 @@ if (count > 0) { paint.pos = (struct pos){ cl, vpadding }; - paint.box = (struct box){ 1, 2, vpadding, vpadding, 0, ascii_height }; + paint.box = (struct box){ 1, 2, vpadding, -vpadding, 0, height }; bm_cairo_draw_line(cairo, &paint, &result, (count > 0 && (menu->wrap || menu->index > 0) ? "<" : " ")); cl += result.x_advance + 1; } @@ -375,7 +379,7 @@ } paint.pos = (struct pos){ cl, vpadding }; - paint.box = (struct box){ 2, 4, vpadding, vpadding, 0, ascii_height }; + paint.box = (struct box){ 2, 4, vpadding, -vpadding, 0, 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); @@ -387,7 +391,7 @@ 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/cairo->scale - result.x_advance - 2, vpadding }; - paint.box = (struct box){ 1, 2, vpadding, vpadding, 0, ascii_height }; + paint.box = (struct box){ 1, 2, vpadding, -vpadding, 0, height }; bm_cairo_draw_line(cairo, &paint, &result, ">"); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/curses/curses.c new/bemenu-0.6.4/lib/renderers/curses/curses.c --- old/bemenu-0.6.3/lib/renderers/curses/curses.c 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/curses/curses.c 2021-12-03 09:04:37.000000000 +0100 @@ -231,7 +231,7 @@ if (menu->title && title_len > 0) { attron(COLOR_PAIR(1)); - mvprintw(0, 0, menu->title); + mvprintw(0, 0, "%s", menu->title); attroff(COLOR_PAIR(1)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/wayland/wayland.c new/bemenu-0.6.4/lib/renderers/wayland/wayland.c --- old/bemenu-0.6.3/lib/renderers/wayland/wayland.c 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/wayland/wayland.c 2021-12-03 09:04:37.000000000 +0100 @@ -177,6 +177,9 @@ case XKB_KEY_m: return (mods & MOD_CTRL ? BM_KEY_RETURN : BM_KEY_UNICODE); + case XKB_KEY_y: + return (mods & MOD_CTRL ? BM_KEY_PASTE : BM_KEY_UNICODE); + case XKB_KEY_1: if ((mods & MOD_ALT)) return BM_KEY_CUSTOM_1; break; @@ -229,14 +232,26 @@ } static void -set_bottom(const struct bm_menu *menu, bool bottom) +set_hmargin_size(const struct bm_menu *menu, uint32_t margin) +{ + struct wayland *wayland = menu->renderer->internal; + assert(wayland); + + struct window *window; + wl_list_for_each(window, &wayland->windows, link) { + bm_wl_window_set_hmargin_size(window, wayland->display, margin); + } +} + +static void +set_align(const struct bm_menu *menu, enum bm_align align) { struct wayland *wayland = menu->renderer->internal; assert(wayland); struct window *window; wl_list_for_each(window, &wayland->windows, link) { - bm_wl_window_set_bottom(window, wayland->display, bottom); + bm_wl_window_set_align(window, wayland->display, align); } } @@ -305,7 +320,8 @@ wl_surface_set_buffer_scale(surface, output->scale); struct window *window = calloc(1, sizeof(struct window)); - window->bottom = menu->bottom; + window->align = menu->align; + window->hmargin_size = menu->hmargin_size; const char *scale = getenv("BEMENU_SCALE"); if (scale) { @@ -432,7 +448,8 @@ api->get_displayed_count = get_displayed_count; api->poll_key = poll_key; api->render = render; - api->set_bottom = set_bottom; + api->set_align = set_align; + api->set_hmargin_size = set_hmargin_size; api->grab_keyboard = grab_keyboard; api->set_overlap = set_overlap; api->set_monitor = set_monitor; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/wayland/wayland.h new/bemenu-0.6.4/lib/renderers/wayland/wayland.h --- old/bemenu-0.6.3/lib/renderers/wayland/wayland.h 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/wayland/wayland.h 2021-12-03 09:04:37.000000000 +0100 @@ -1,6 +1,8 @@ #ifndef _BM_WAYLAND_H_ #define _BM_WAYLAND_H_ +#include "internal.h" + #include <wayland-client.h> #include <xkbcommon/xkbcommon.h> @@ -84,10 +86,12 @@ struct wl_shm *shm; struct buffer buffers[2]; uint32_t width, height, max_height; + uint32_t hmargin_size; int32_t scale; uint32_t displayed; struct wl_list link; - bool bottom; + enum bm_align align; + uint32_t align_anchor; bool render_pending; struct { @@ -128,7 +132,8 @@ 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_set_hmargin_size(struct window *window, struct wl_display *display, uint32_t margin); +void bm_wl_window_set_align(struct window *window, struct wl_display *display, enum bm_align align); 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); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/wayland/window.c new/bemenu-0.6.4/lib/renderers/wayland/window.c --- old/bemenu-0.6.3/lib/renderers/wayland/window.c 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/wayland/window.c 2021-12-03 09:04:37.000000000 +0100 @@ -206,6 +206,22 @@ frame_callback }; +static uint32_t +get_align_anchor(enum bm_align align) +{ + uint32_t anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + + if(align == BM_ALIGN_TOP) { + anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; + } else if(align == BM_ALIGN_CENTER) { + anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + } else { + anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + } + + return anchor; +} + void bm_wl_window_schedule_render(struct window *window) { @@ -236,11 +252,11 @@ window->notify.render(&buffer->cairo, buffer->width, window->max_height, menu, &result); window->displayed = result.displayed; - if (window->height == result.height) + if (window->height == result.height / window->scale) break; - window->height = result.height; - zwlr_layer_surface_v1_set_size(window->layer_surface, 0, window->height); + window->height = result.height / window->scale; + zwlr_layer_surface_v1_set_size(window->layer_surface, window->width, window->height); wl_surface_commit(window->surface); wl_display_roundtrip(display); destroy_buffer(buffer); @@ -286,20 +302,48 @@ exit(1); } +static uint32_t +get_window_width(struct window *window) +{ + uint32_t width = window->width - 2 * window->hmargin_size; + + if(width < WINDOW_MIN_WIDTH || 2 * window->hmargin_size > window->width) + width = WINDOW_MIN_WIDTH; + + return width; +} + static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { .configure = layer_surface_configure, .closed = layer_surface_closed, }; void -bm_wl_window_set_bottom(struct window *window, struct wl_display *display, bool bottom) +bm_wl_window_set_hmargin_size(struct window *window, struct wl_display *display, uint32_t margin) { - if (window->bottom == bottom) + if(window->hmargin_size == margin) return; - window->bottom = bottom; + window->hmargin_size = margin; + + zwlr_layer_surface_v1_set_anchor(window->layer_surface, window->align_anchor); + zwlr_layer_surface_v1_set_size(window->layer_surface, get_window_width(window), window->height); - 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); + wl_surface_commit(window->surface); + wl_display_roundtrip(display); +} + +void +bm_wl_window_set_align(struct window *window, struct wl_display *display, enum bm_align align) +{ + if(window->align == align) + return; + + window->align = align; + + window->align_anchor = get_align_anchor(window->align); + + zwlr_layer_surface_v1_set_anchor(window->layer_surface, window->align_anchor); wl_surface_commit(window->surface); wl_display_roundtrip(display); } @@ -327,10 +371,14 @@ 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_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); + window->align_anchor = get_align_anchor(window->align); + zwlr_layer_surface_v1_set_anchor(window->layer_surface, window->align_anchor); zwlr_layer_surface_v1_set_size(window->layer_surface, 0, 32); + wl_surface_commit(surface); wl_display_roundtrip(display); + + zwlr_layer_surface_v1_set_size(window->layer_surface, get_window_width(window), 32); } else { return false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/x11/window.c new/bemenu-0.6.4/lib/renderers/x11/window.c --- old/bemenu-0.6.3/lib/renderers/x11/window.c 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/x11/window.c 2021-12-03 09:04:37.000000000 +0100 @@ -1,3 +1,4 @@ +#include "internal.h" #include "x11.h" #include <stdlib.h> @@ -62,6 +63,17 @@ return buffer; } +static uint32_t +get_window_width(struct window *window) +{ + uint32_t width = window->width - 2 * window->hmargin_size; + + if(width < WINDOW_MIN_WIDTH || 2 * window->hmargin_size > window->width) + width = WINDOW_MIN_WIDTH; + + return width; +} + void bm_x11_window_render(struct window *window, const struct bm_menu *menu) { @@ -92,11 +104,15 @@ } if (oldw != window->width || oldh != window->height) { - if (window->bottom) { - XMoveResizeWindow(window->display, window->drawable, window->x, window->max_height - window->height, window->width, window->height); - } else { - XResizeWindow(window->display, window->drawable, window->width, window->height); + uint32_t win_y = 0; + + if(window->align == BM_ALIGN_CENTER) { + win_y = (window->max_height - window->height) / 2; + } else if(window->align == BM_ALIGN_BOTTOM) { + win_y = window->max_height - window->height; } + + XMoveResizeWindow(window->display, window->drawable, window->x, win_y, window->width, window->height); } if (buffer->created) { @@ -179,17 +195,34 @@ } window->x = info[i].x_org; - window->y = info[i].y_org + (window->bottom ? info[i].height - window->height : 0); + window->y = info[i].y_org; + if(window->align == BM_ALIGN_CENTER) { + window->y += (info[i].height - window->height) / 2; + } else if(window->align == BM_ALIGN_BOTTOM) { + window->y += info[i].height - window->height; + } + window->width = info[i].width; window->max_height = info[i].height; XFree(info); } else { window->max_height = DisplayHeight(window->display, window->screen); window->x = 0; - window->y = (window->bottom ? window->max_height - window->height : 0); + if(window->align == BM_ALIGN_CENTER) { + window->y = (window->max_height - window->height) / 2; + } else if(window->align == BM_ALIGN_BOTTOM) { + window->y = window->max_height - window->height; + } else { + window->y = 0; + } window->width = DisplayWidth(window->display, window->screen); } + window->orig_width = window->width; + window->orig_x = window->x; + window->width = get_window_width(window); + window->x += (window->orig_width - window->width) / 2; + #undef INTERSECT } @@ -199,12 +232,26 @@ } void -bm_x11_window_set_bottom(struct window *window, bool bottom) +bm_x11_window_set_align(struct window *window, enum bm_align align) +{ + if(window->align == align) + return; + + window->align = align; + bm_x11_window_set_monitor(window, window->monitor); +} + +void +bm_x11_window_set_hmargin_size(struct window *window, uint32_t margin) { - if (window->bottom == bottom) + if(window->hmargin_size == margin) return; - window->bottom = bottom; + window->hmargin_size = margin; + window->width = window->orig_width; + window->x = window->orig_x; + window->width = get_window_width(window); + window->x += (window->orig_width - window->width) / 2; bm_x11_window_set_monitor(window, window->monitor); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/x11/x11.c new/bemenu-0.6.4/lib/renderers/x11/x11.c --- old/bemenu-0.6.3/lib/renderers/x11/x11.c 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/x11/x11.c 2021-12-03 09:04:37.000000000 +0100 @@ -144,6 +144,9 @@ case XK_w: return (mods & MOD_CTRL ? BM_KEY_WORD_DELETE : BM_KEY_UNICODE); + case XK_y: + return (mods & MOD_CTRL ? BM_KEY_PASTE : BM_KEY_UNICODE); + case XK_j: return (mods & MOD_ALT ? BM_KEY_DOWN : BM_KEY_UNICODE); @@ -199,11 +202,19 @@ } static void -set_bottom(const struct bm_menu *menu, bool bottom) +set_align(const struct bm_menu *menu, enum bm_align align) +{ + struct x11 *x11 = menu->renderer->internal; + assert(x11); + bm_x11_window_set_align(&x11->window, align); +} + +static void +set_hmargin_size(const struct bm_menu *menu, uint32_t margin) { struct x11 *x11 = menu->renderer->internal; assert(x11); - bm_x11_window_set_bottom(&x11->window, bottom); + bm_x11_window_set_hmargin_size(&x11->window, margin); } static void @@ -268,7 +279,7 @@ XSetClassHint(x11->window.display, x11->window.drawable, (XClassHint[]){{.res_name = (menu->title ? menu->title : "bemenu"), .res_class = "bemenu"}}); - x11->window.bottom = menu->bottom; + x11->window.align = menu->align; bm_x11_window_set_monitor(&x11->window, menu->monitor); x11->window.notify.render = bm_cairo_paint; @@ -287,7 +298,8 @@ api->get_displayed_count = get_displayed_count; api->poll_key = poll_key; api->render = render; - api->set_bottom = set_bottom; + api->set_align = set_align; + api->set_hmargin_size = set_hmargin_size; api->set_monitor = set_monitor; api->grab_keyboard = grab_keyboard; api->priorty = BM_PRIO_GUI; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/lib/renderers/x11/x11.h new/bemenu-0.6.4/lib/renderers/x11/x11.h --- old/bemenu-0.6.3/lib/renderers/x11/x11.h 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/lib/renderers/x11/x11.h 2021-12-03 09:04:37.000000000 +0100 @@ -1,6 +1,8 @@ #ifndef _BM_X11_H_ #define _BM_X11_H_ +#include "internal.h" + #include <X11/Xlib.h> #include <X11/keysym.h> @@ -31,10 +33,12 @@ struct buffer buffer; uint32_t x, y, width, height, max_height; + uint32_t orig_width, orig_x; + uint32_t hmargin_size; uint32_t displayed; int32_t monitor; - bool bottom; + enum bm_align align; struct { void (*render)(struct cairo *cairo, uint32_t width, uint32_t max_height, const struct bm_menu *menu, struct cairo_paint_result *result); @@ -49,7 +53,8 @@ void bm_x11_window_render(struct window *window, const struct bm_menu *menu); void bm_x11_window_key_press(struct window *window, XKeyEvent *ev); void bm_x11_window_set_monitor(struct window *window, int32_t monitor); -void bm_x11_window_set_bottom(struct window *window, bool bottom); +void bm_x11_window_set_align(struct window *window, enum bm_align align); +void bm_x11_window_set_hmargin_size(struct window *window, uint32_t margin); bool bm_x11_window_create(struct window *window, Display *display); void bm_x11_window_destroy(struct window *window); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bemenu-0.6.3/man/bemenu.1.in new/bemenu-0.6.4/man/bemenu.1.in --- old/bemenu-0.6.3/man/bemenu.1.in 2021-07-22 02:11:41.000000000 +0200 +++ new/bemenu-0.6.4/man/bemenu.1.in 2021-12-03 09:04:37.000000000 +0100 @@ -1,4 +1,4 @@ -.Dd March 29, 2021 +.Dd November 1, 2021 .Dt BEMENU 1 .Os .Sh NAME @@ -268,6 +268,8 @@ Remove all characters after the cursor. .It Cm C-w Clear the filter. +.It Cm C-y +Paste the clipboard. .It Cm M- Ns Op 0\(en9 Print selected items and exit with a custom error code. See
