summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/common/common.c8
-rw-r--r--client/common/common.h1
-rw-r--r--lib/bemenu.h5
-rw-r--r--lib/internal.h10
-rw-r--r--lib/menu.c14
-rw-r--r--lib/renderers/wayland/wayland.c13
-rw-r--r--lib/renderers/wayland/wayland.h1
-rw-r--r--lib/renderers/wayland/window.c9
8 files changed, 59 insertions, 2 deletions
diff --git a/client/common/common.c b/client/common/common.c
index f59088c..7633d7f 100644
--- a/client/common/common.c
+++ b/client/common/common.c
@@ -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;
diff --git a/client/common/common.h b/client/common/common.h
index 66587f2..cf258af 100644
--- a/client/common/common.h
+++ b/client/common/common.h
@@ -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[]);
diff --git a/lib/bemenu.h b/lib/bemenu.h
index 14368d7..8b28dfe 100644
--- a/lib/bemenu.h
+++ b/lib/bemenu.h
@@ -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 */
/**
diff --git a/lib/internal.h b/lib/internal.h
index 25169ac..adb06f6 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -91,6 +91,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 */
diff --git a/lib/menu.c b/lib/menu.c
index e29a519..e876126 100644
--- a/lib/menu.c
+++ b/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)
{
diff --git a/lib/renderers/wayland/wayland.c b/lib/renderers/wayland/wayland.c
index a719c7d..442b0f6 100644
--- a/lib/renderers/wayland/wayland.c
+++ b/lib/renderers/wayland/wayland.c
@@ -209,6 +209,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)
{
struct wayland *wayland = menu->renderer->internal;
@@ -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";
diff --git a/lib/renderers/wayland/wayland.h b/lib/renderers/wayland/wayland.h
index 9defb06..c6da458 100644
--- a/lib/renderers/wayland/wayland.h
+++ b/lib/renderers/wayland/wayland.h
@@ -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);
diff --git a/lib/renderers/wayland/window.c b/lib/renderers/wayland/window.c
index 2141eff..55b8690 100644
--- a/lib/renderers/wayland/window.c
+++ b/lib/renderers/wayland/window.c
@@ -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);