forked from RepoMirrors/bemenu
Add option to respect panel position (#48)
* implement option to make menu respect panel boundaries * fixup! implement option to make menu respect panel boundaries
This commit is contained in:
parent
b375ef8b0b
commit
38069992ec
@ -84,6 +84,7 @@ usage(FILE *out, const char *name)
|
||||
|
||||
" -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"
|
||||
" --fn defines the font to be used ('name [size]'). (wx)\n"
|
||||
" --tb defines the title background color. (wx)\n"
|
||||
@ -122,6 +123,7 @@ parse_args(struct client *client, int *argc, char **argv[])
|
||||
|
||||
{ "bottom", no_argument, 0, 'b' },
|
||||
{ "grab", no_argument, 0, 'f' },
|
||||
{ "no-overlap", no_argument, 0, 'n' },
|
||||
{ "monitor", required_argument, 0, 'm' },
|
||||
{ "fn", required_argument, 0, 0x101 },
|
||||
{ "tb", required_argument, 0, 0x102 },
|
||||
@ -146,7 +148,7 @@ parse_args(struct client *client, int *argc, char **argv[])
|
||||
* 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:n", opts, NULL);
|
||||
if (opt < 0)
|
||||
break;
|
||||
|
||||
@ -192,6 +194,9 @@ parse_args(struct client *client, int *argc, char **argv[])
|
||||
case 'm':
|
||||
client->monitor = strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case 'n':
|
||||
client->no_overlap = true;
|
||||
break;
|
||||
|
||||
case 0x101:
|
||||
client->font = optarg;
|
||||
@ -284,6 +289,7 @@ run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(stru
|
||||
{
|
||||
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;
|
||||
|
@ -17,6 +17,7 @@ struct client {
|
||||
bool grab;
|
||||
bool wrap;
|
||||
bool ifne;
|
||||
bool no_overlap;
|
||||
};
|
||||
|
||||
void parse_args(struct client *client, int *argc, char **argv[]);
|
||||
|
@ -472,6 +472,11 @@ void bm_menu_grab_keyboard(struct bm_menu *menu, bool grab);
|
||||
*/
|
||||
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 */
|
||||
|
||||
/**
|
||||
|
@ -90,6 +90,11 @@ struct render_api {
|
||||
*/
|
||||
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.
|
||||
@ -296,6 +301,11 @@ struct bm_menu {
|
||||
* Is menu grabbed?
|
||||
*/
|
||||
bool grabbed;
|
||||
|
||||
/**
|
||||
* Should the menu overlap panels
|
||||
*/
|
||||
bool overlap;
|
||||
};
|
||||
|
||||
/* library.c */
|
||||
|
14
lib/menu.c
14
lib/menu.c
@ -370,6 +370,20 @@ bm_menu_is_keyboard_grabbed(struct bm_menu *menu)
|
||||
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)
|
||||
{
|
||||
|
@ -208,6 +208,18 @@ grab_keyboard(const struct bm_menu *menu, bool grab)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -303,6 +315,7 @@ register_renderer(struct render_api *api)
|
||||
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";
|
||||
|
@ -122,6 +122,7 @@ 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);
|
||||
|
||||
|
@ -310,6 +310,14 @@ bm_wl_window_grab_keyboard(struct window *window, struct wl_display *display, bo
|
||||
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)
|
||||
{
|
||||
@ -317,7 +325,6 @@ bm_wl_window_create(struct window *window, struct wl_display *display, struct wl
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user