mirror of
https://github.com/Cloudef/bemenu
synced 2024-11-23 01:12:01 +01:00
Add relative width option
It works on Wayland and X11 and acts as a complement to margin. Exact behavior is as follows: - If width factor is 0, width minus margin is used. - If width multiplied by factor is greater than width minus margin, width minus is used. (so margin may be used to make sure that bemenu is at least N pixels away from the view border) - Otherwise width multiplied by factor is used. I think it's fine to disable warnings about floating point numbers comparision. We don't do any arithmetics on them anyway, so we can't suffer from inaccuracy.
This commit is contained in:
parent
192736c554
commit
43255bbbe8
@ -10,7 +10,7 @@ GIT_TAG = $(shell git tag --points-at HEAD 2>/dev/null || cat VERSION)
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
|
||||
WARNINGS = -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-aliasing=3 -Wstrict-overflow=5 -Wstack-usage=12500 \
|
||||
-Wfloat-equal -Wcast-align -Wpointer-arith -Wchar-subscripts -Warray-bounds=2 -Wno-unknown-warning-option
|
||||
-Wcast-align -Wpointer-arith -Wchar-subscripts -Warray-bounds=2 -Wno-unknown-warning-option
|
||||
|
||||
override CFLAGS ?= -g -O2 $(WARNINGS) $(EXTRA_WARNINGS)
|
||||
override CFLAGS += -std=c99
|
||||
|
@ -201,6 +201,7 @@ usage(FILE *out, const char *name)
|
||||
" -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"
|
||||
" -W, --width-factor defines the relative width factor of the menu (from 0 to 1). (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"
|
||||
@ -243,44 +244,45 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
assert(client && argc && argv);
|
||||
|
||||
static const struct option opts[] = {
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
|
||||
{ "ignorecase", no_argument, 0, 'i' },
|
||||
{ "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' },
|
||||
{ "password", no_argument, 0, 'x' },
|
||||
{ "scrollbar", required_argument, 0, 0x100 },
|
||||
{ "ifne", no_argument, 0, 0x115 },
|
||||
{ "fork", no_argument, 0, 0x116 },
|
||||
{ "no-exec", no_argument, 0, 0x117 },
|
||||
{ "ignorecase", no_argument, 0, 'i' },
|
||||
{ "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' },
|
||||
{ "password", no_argument, 0, 'x' },
|
||||
{ "scrollbar", required_argument, 0, 0x100 },
|
||||
{ "ifne", no_argument, 0, 0x115 },
|
||||
{ "fork", no_argument, 0, 0x116 },
|
||||
{ "no-exec", no_argument, 0, 0x117 },
|
||||
|
||||
{ "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 },
|
||||
{ "fb", required_argument, 0, 0x104 },
|
||||
{ "ff", required_argument, 0, 0x105 },
|
||||
{ "nb", required_argument, 0, 0x106 },
|
||||
{ "nf", required_argument, 0, 0x107 },
|
||||
{ "hb", required_argument, 0, 0x108 },
|
||||
{ "hf", required_argument, 0, 0x109 },
|
||||
{ "sb", required_argument, 0, 0x110 },
|
||||
{ "sf", required_argument, 0, 0x111 },
|
||||
{ "scb", required_argument, 0, 0x112 },
|
||||
{ "scf", required_argument, 0, 0x113 },
|
||||
{ "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' },
|
||||
{ "width-factor", required_argument, 0, 'W' },
|
||||
{ "ch", required_argument, 0, 0x118 },
|
||||
{ "fn", required_argument, 0, 0x101 },
|
||||
{ "tb", required_argument, 0, 0x102 },
|
||||
{ "tf", required_argument, 0, 0x103 },
|
||||
{ "fb", required_argument, 0, 0x104 },
|
||||
{ "ff", required_argument, 0, 0x105 },
|
||||
{ "nb", required_argument, 0, 0x106 },
|
||||
{ "nf", required_argument, 0, 0x107 },
|
||||
{ "hb", required_argument, 0, 0x108 },
|
||||
{ "hf", required_argument, 0, 0x109 },
|
||||
{ "sb", required_argument, 0, 0x110 },
|
||||
{ "sf", required_argument, 0, 0x111 },
|
||||
{ "scb", required_argument, 0, 0x112 },
|
||||
{ "scf", required_argument, 0, 0x113 },
|
||||
|
||||
{ "disco", no_argument, 0, 0x114 },
|
||||
{ 0, 0, 0, 0 }
|
||||
@ -296,7 +298,7 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
for (optind = 0;;) {
|
||||
int32_t opt;
|
||||
|
||||
if ((opt = getopt_long(*argc, *argv, "hviwxcl:I:p:P:I:bfm:H:M:ns", opts, NULL)) < 0)
|
||||
if ((opt = getopt_long(*argc, *argv, "hviwxcl:I:p:P:I:bfm:H:M:W:ns", opts, NULL)) < 0)
|
||||
break;
|
||||
|
||||
switch (opt) {
|
||||
@ -369,6 +371,9 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
||||
case 'M':
|
||||
client->hmargin_size = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case 'W':
|
||||
client->width_factor = strtof(optarg, NULL);
|
||||
break;
|
||||
case 0x118:
|
||||
client->cursor_height = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
@ -462,7 +467,7 @@ menu_with_options(struct client *client)
|
||||
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);
|
||||
bm_menu_set_width(menu, client->hmargin_size, client->width_factor);
|
||||
|
||||
if (client->center) {
|
||||
bm_menu_set_align(menu, BM_ALIGN_CENTER);
|
||||
|
@ -18,6 +18,7 @@ struct client {
|
||||
uint32_t selected;
|
||||
uint32_t monitor;
|
||||
uint32_t hmargin_size;
|
||||
float width_factor;
|
||||
bool bottom;
|
||||
bool center;
|
||||
bool grab;
|
||||
|
14
lib/bemenu.h
14
lib/bemenu.h
@ -539,13 +539,14 @@ BM_PUBLIC void bm_menu_set_align(struct bm_menu *menu, enum bm_align align);
|
||||
BM_PUBLIC enum bm_align bm_menu_get_align(struct bm_menu *menu);
|
||||
|
||||
/**
|
||||
* Set the horizontal margin of the bar.
|
||||
* Set the horizontal margin and the relative width factor of the bar.
|
||||
*
|
||||
* @param menu bm_menu to set horizontal margin for.
|
||||
* @param margin margin to set.
|
||||
* @param factor factor to set.
|
||||
*/
|
||||
|
||||
BM_PUBLIC void bm_menu_set_hmargin_size(struct bm_menu *menu, uint32_t margin);
|
||||
BM_PUBLIC void bm_menu_set_width(struct bm_menu *menu, uint32_t margin, float factor);
|
||||
|
||||
/**
|
||||
* Get the horizontal margin of the bar.
|
||||
@ -556,6 +557,15 @@ BM_PUBLIC void bm_menu_set_hmargin_size(struct bm_menu *menu, uint32_t margin);
|
||||
|
||||
BM_PUBLIC uint32_t bm_menu_get_hmargin_size(struct bm_menu *menu);
|
||||
|
||||
/**
|
||||
* Get the relative width factor of the bar.
|
||||
*
|
||||
* @param menu bm_menu to get relative width factor from.
|
||||
* @return relative width factor of the menu.
|
||||
*/
|
||||
|
||||
BM_PUBLIC float bm_menu_get_width_factor(struct bm_menu *menu);
|
||||
|
||||
/**
|
||||
* Display menu at monitor index.
|
||||
* Indices start at 0, a value of -1 can be passed for the active monitor (default).
|
||||
|
@ -83,9 +83,9 @@ struct render_api {
|
||||
void (*set_align)(const struct bm_menu *menu, enum bm_align align);
|
||||
|
||||
/**
|
||||
* Set horizontal margin.
|
||||
* Set horizontal margin and relative width factor.
|
||||
*/
|
||||
void (*set_hmargin_size)(const struct bm_menu *menu, uint32_t margin);
|
||||
void (*set_width)(const struct bm_menu *menu, uint32_t margin, float factor);
|
||||
|
||||
/**
|
||||
* Set monitor indeax where menu will appear
|
||||
@ -334,6 +334,11 @@ struct bm_menu {
|
||||
*/
|
||||
uint32_t hmargin_size;
|
||||
|
||||
/**
|
||||
* Relative width factor.
|
||||
*/
|
||||
float width_factor;
|
||||
|
||||
/**
|
||||
* Is menu grabbed?
|
||||
*/
|
||||
|
16
lib/menu.c
16
lib/menu.c
@ -376,17 +376,18 @@ bm_menu_get_align(struct bm_menu *menu)
|
||||
}
|
||||
|
||||
void
|
||||
bm_menu_set_hmargin_size(struct bm_menu *menu, uint32_t margin)
|
||||
bm_menu_set_width(struct bm_menu *menu, uint32_t margin, float factor)
|
||||
{
|
||||
assert(menu);
|
||||
|
||||
if(menu->hmargin_size == margin)
|
||||
if(menu->hmargin_size == margin && menu->width_factor == factor)
|
||||
return;
|
||||
|
||||
menu->hmargin_size = margin;
|
||||
menu->width_factor = factor;
|
||||
|
||||
if(menu->renderer->api.set_hmargin_size)
|
||||
menu->renderer->api.set_hmargin_size(menu, margin);
|
||||
if(menu->renderer->api.set_width)
|
||||
menu->renderer->api.set_width(menu, margin, factor);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -396,6 +397,13 @@ bm_menu_get_hmargin_size(struct bm_menu *menu)
|
||||
return menu->hmargin_size;
|
||||
}
|
||||
|
||||
float
|
||||
bm_menu_get_width_factor(struct bm_menu *menu)
|
||||
{
|
||||
assert(menu);
|
||||
return menu->width_factor;
|
||||
}
|
||||
|
||||
void
|
||||
bm_menu_set_monitor(struct bm_menu *menu, int32_t monitor)
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ poll_key(const struct bm_menu *menu, unsigned int *unicode)
|
||||
wayland->input.code = 0;
|
||||
|
||||
if (!wayland->input.key_pending)
|
||||
return BM_KEY_UNICODE;
|
||||
return BM_KEY_UNICODE;
|
||||
wayland->input.key_pending = false;
|
||||
|
||||
switch (sym) {
|
||||
@ -232,14 +232,14 @@ get_displayed_count(const struct bm_menu *menu)
|
||||
}
|
||||
|
||||
static void
|
||||
set_hmargin_size(const struct bm_menu *menu, uint32_t margin)
|
||||
set_width(const struct bm_menu *menu, uint32_t margin, float factor)
|
||||
{
|
||||
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);
|
||||
bm_wl_window_set_width(window, wayland->display, margin, factor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,6 +322,7 @@ recreate_windows(const struct bm_menu *menu, struct wayland *wayland)
|
||||
struct window *window = calloc(1, sizeof(struct window));
|
||||
window->align = menu->align;
|
||||
window->hmargin_size = menu->hmargin_size;
|
||||
window->width_factor = menu->width_factor;
|
||||
|
||||
const char *scale = getenv("BEMENU_SCALE");
|
||||
if (scale) {
|
||||
@ -449,7 +450,7 @@ register_renderer(struct render_api *api)
|
||||
api->poll_key = poll_key;
|
||||
api->render = render;
|
||||
api->set_align = set_align;
|
||||
api->set_hmargin_size = set_hmargin_size;
|
||||
api->set_width = set_width;
|
||||
api->grab_keyboard = grab_keyboard;
|
||||
api->set_overlap = set_overlap;
|
||||
api->set_monitor = set_monitor;
|
||||
|
@ -87,6 +87,7 @@ struct window {
|
||||
struct buffer buffers[2];
|
||||
uint32_t width, height, max_height;
|
||||
uint32_t hmargin_size;
|
||||
float width_factor;
|
||||
int32_t scale;
|
||||
uint32_t displayed;
|
||||
struct wl_list link;
|
||||
@ -132,7 +133,7 @@ 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_hmargin_size(struct window *window, struct wl_display *display, uint32_t margin);
|
||||
void bm_wl_window_set_width(struct window *window, struct wl_display *display, uint32_t margin, float factor);
|
||||
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);
|
||||
|
@ -305,7 +305,10 @@ layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *layer_surface)
|
||||
static uint32_t
|
||||
get_window_width(struct window *window)
|
||||
{
|
||||
uint32_t width = window->width - 2 * window->hmargin_size;
|
||||
uint32_t width = window->width * ((window->width_factor != 0) ? window->width_factor : 1);
|
||||
|
||||
if(width > window->width - 2 * window->hmargin_size)
|
||||
width = window->width - 2 * window->hmargin_size;
|
||||
|
||||
if(width < WINDOW_MIN_WIDTH || 2 * window->hmargin_size > window->width)
|
||||
width = WINDOW_MIN_WIDTH;
|
||||
@ -319,12 +322,13 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||
};
|
||||
|
||||
void
|
||||
bm_wl_window_set_hmargin_size(struct window *window, struct wl_display *display, uint32_t margin)
|
||||
bm_wl_window_set_width(struct window *window, struct wl_display *display, uint32_t margin, float factor)
|
||||
{
|
||||
if(window->hmargin_size == margin)
|
||||
if(window->hmargin_size == margin && window->width_factor == factor)
|
||||
return;
|
||||
|
||||
window->hmargin_size = margin;
|
||||
window->width_factor = factor;
|
||||
|
||||
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);
|
||||
|
@ -66,7 +66,10 @@ next_buffer(struct window *window)
|
||||
static uint32_t
|
||||
get_window_width(struct window *window)
|
||||
{
|
||||
uint32_t width = window->width - 2 * window->hmargin_size;
|
||||
uint32_t width = window->width * ((window->width_factor != 0) ? window->width_factor : 1);
|
||||
|
||||
if(width > window->width - 2 * window->hmargin_size)
|
||||
width = window->width - 2 * window->hmargin_size;
|
||||
|
||||
if(width < WINDOW_MIN_WIDTH || 2 * window->hmargin_size > window->width)
|
||||
width = WINDOW_MIN_WIDTH;
|
||||
@ -242,12 +245,13 @@ 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)
|
||||
bm_x11_window_set_width(struct window *window, uint32_t margin, float factor)
|
||||
{
|
||||
if(window->hmargin_size == margin)
|
||||
if(window->hmargin_size == margin && window->width_factor == factor)
|
||||
return;
|
||||
|
||||
window->hmargin_size = margin;
|
||||
window->width_factor = factor;
|
||||
window->width = window->orig_width;
|
||||
window->x = window->orig_x;
|
||||
window->width = get_window_width(window);
|
||||
|
@ -210,11 +210,11 @@ set_align(const struct bm_menu *menu, enum bm_align align)
|
||||
}
|
||||
|
||||
static void
|
||||
set_hmargin_size(const struct bm_menu *menu, uint32_t margin)
|
||||
set_width(const struct bm_menu *menu, uint32_t margin, float factor)
|
||||
{
|
||||
struct x11 *x11 = menu->renderer->internal;
|
||||
assert(x11);
|
||||
bm_x11_window_set_hmargin_size(&x11->window, margin);
|
||||
bm_x11_window_set_width(&x11->window, margin, factor);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -299,7 +299,7 @@ register_renderer(struct render_api *api)
|
||||
api->poll_key = poll_key;
|
||||
api->render = render;
|
||||
api->set_align = set_align;
|
||||
api->set_hmargin_size = set_hmargin_size;
|
||||
api->set_width = set_width;
|
||||
api->set_monitor = set_monitor;
|
||||
api->grab_keyboard = grab_keyboard;
|
||||
api->priorty = BM_PRIO_GUI;
|
||||
|
@ -35,6 +35,7 @@ struct window {
|
||||
uint32_t x, y, width, height, max_height;
|
||||
uint32_t orig_width, orig_x;
|
||||
uint32_t hmargin_size;
|
||||
float width_factor;
|
||||
uint32_t displayed;
|
||||
|
||||
int32_t monitor;
|
||||
@ -54,7 +55,7 @@ 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_align(struct window *window, enum bm_align align);
|
||||
void bm_x11_window_set_hmargin_size(struct window *window, uint32_t margin);
|
||||
void bm_x11_window_set_width(struct window *window, uint32_t margin, float factor);
|
||||
bool bm_x11_window_create(struct window *window, Display *display);
|
||||
void bm_x11_window_destroy(struct window *window);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user