1
0
Fork 0
mirror of https://github.com/Cloudef/bemenu synced 2024-05-18 21:46:15 +02:00

redesigned vertical alignment

single enum determines if the menu is at the top, in the center,
or at the bottom. implemented in wayland and x11 renderers.
This commit is contained in:
lunacb 2021-10-17 12:33:37 -04:00 committed by Jari Vetoniemi
parent bddeea05b6
commit a96ed87472
10 changed files with 118 additions and 115 deletions

View File

@ -1,3 +1,5 @@
#include "internal.h"
#include "common.h"
#include <stdlib.h>
#include <string.h>
@ -193,7 +195,7 @@ usage(FILE *out, const char *name)
" (...) 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. (w)\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"
@ -463,9 +465,11 @@ menu_with_options(struct client *client)
bm_menu_set_hmargin_size(menu, client->hmargin_size);
if (client->center) {
bm_menu_set_center(menu, client->center);
bm_menu_set_align(menu, BM_ALIGN_CENTER);
} else if (client->bottom) {
bm_menu_set_bottom(menu, 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)

View File

@ -115,6 +115,26 @@ enum bm_priorty {
BM_PRIO_GUI,
};
/**
* 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.
*
@ -501,30 +521,21 @@ BM_PUBLIC void bm_menu_set_scrollbar(struct bm_menu *menu, enum bm_scrollbar_mod
BM_PUBLIC enum bm_scrollbar_mode bm_menu_get_scrollbar(struct bm_menu *menu);
/**
* Display menu at center 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 center mode for.
* @param center true for center mode, false for top mode.
* @param menu bm_menu to set alignment for.
* @param align alignment to set
*/
BM_PUBLIC void bm_menu_set_center(struct bm_menu *menu, bool center);
BM_PUBLIC void bm_menu_set_align(struct bm_menu *menu, enum bm_align align);
/**
* Display menu at bottom of the screen.
* This may be no-op on some renderers (curses, wayland)
* Get 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 get alignment for.
* @return alignment for the menu
*/
BM_PUBLIC void bm_menu_set_bottom(struct bm_menu *menu, bool bottom);
/**
* Is menu being displayed at bottom of the screen?
*
* @param menu bm_menu instance where to get bottom mode from.
* @return true if bottom mode, false otherwise.
*/
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.

View File

@ -78,20 +78,15 @@ struct render_api {
void (*render)(const struct bm_menu *menu);
/**
* Set menu to appear from bottom of the screen.
* Set vertical alignment of the bar.
*/
void (*set_bottom)(const struct bm_menu *menu, bool bottom);
void (*set_align)(const struct bm_menu *menu, enum bm_align align);
/**
* Set horizontal margin.
*/
void (*set_hmargin_size)(const struct bm_menu *menu, uint32_t margin);
/**
* Set menu to appear from center of the screen.
*/
void (*set_center)(const struct bm_menu *menu, bool center);
/**
* Set monitor indeax where menu will appear
*/
@ -330,14 +325,9 @@ struct bm_menu {
bool wrap;
/**
* Is menu shown from center?
* Vertical alignment.
*/
bool center;
/**
* Is menu shown from bottom?
*/
bool bottom;
enum bm_align align;
/**
* Horizontal margin.

View File

@ -355,38 +355,24 @@ bm_menu_get_scrollbar(struct bm_menu *menu)
}
void
bm_menu_set_center(struct bm_menu *menu, bool center)
bm_menu_set_align(struct bm_menu *menu, enum bm_align align)
{
assert(menu);
assert(menu);
if (menu->center == center)
return;
if(menu->align == align)
return;
menu->center = center;
menu->align = align;
if (menu->renderer->api.set_center)
menu->renderer->api.set_center(menu, center);
if (menu->renderer->api.set_align)
menu->renderer->api.set_align(menu, align);
}
void
bm_menu_set_bottom(struct bm_menu *menu, bool bottom)
enum bm_align
bm_menu_get_align(struct bm_menu *menu)
{
assert(menu);
if (menu->bottom == bottom)
return;
menu->bottom = bottom;
if (menu->renderer->api.set_bottom)
menu->renderer->api.set_bottom(menu, bottom);
}
bool
bm_menu_get_bottom(struct bm_menu *menu)
{
assert(menu);
return menu->bottom;
assert(menu);
return menu->align;
}
void

View File

@ -228,18 +228,6 @@ get_displayed_count(const struct bm_menu *menu)
return max;
}
static void
set_bottom(const struct bm_menu *menu, bool bottom)
{
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);
}
}
static void
set_hmargin_size(const struct bm_menu *menu, uint32_t margin)
{
@ -253,14 +241,14 @@ set_hmargin_size(const struct bm_menu *menu, uint32_t margin)
}
static void
set_center(const struct bm_menu *menu, bool center)
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_center(window, wayland->display, center);
bm_wl_window_set_align(window, wayland->display, align);
}
}
@ -329,7 +317,7 @@ recreate_windows(const struct bm_menu *menu, struct wayland *wayland)
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");
@ -457,8 +445,7 @@ register_renderer(struct render_api *api)
api->get_displayed_count = get_displayed_count;
api->poll_key = poll_key;
api->render = render;
api->set_center = set_center;
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;

View File

@ -1,6 +1,8 @@
#ifndef _BM_WAYLAND_H_
#define _BM_WAYLAND_H_
#include "internal.h"
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
@ -88,8 +90,8 @@ struct window {
int32_t scale;
uint32_t displayed;
struct wl_list link;
bool bottom;
bool center;
enum bm_align align;
uint32_t align_anchor;
bool render_pending;
struct {
@ -130,9 +132,8 @@ 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_set_hmargin_size(struct window *window, struct wl_display *display, uint32_t margin);
void bm_wl_window_set_center(struct window *window, struct wl_display *display, bool center);
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);

View File

@ -206,6 +206,22 @@ static const struct wl_callback_listener listener = {
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)
{
@ -302,19 +318,6 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
.closed = layer_surface_closed,
};
void
bm_wl_window_set_bottom(struct window *window, struct wl_display *display, bool bottom)
{
if (window->bottom == bottom)
return;
window->bottom = bottom;
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_hmargin_size(struct window *window, struct wl_display *display, uint32_t margin)
{
@ -323,7 +326,7 @@ bm_wl_window_set_hmargin_size(struct window *window, struct wl_display *display,
window->hmargin_size = margin;
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_anchor(window->layer_surface, window->align_anchor);
zwlr_layer_surface_v1_set_size(window->layer_surface, get_window_width(window), window->height);
wl_surface_commit(window->surface);
@ -331,14 +334,16 @@ bm_wl_window_set_hmargin_size(struct window *window, struct wl_display *display,
}
void
bm_wl_window_set_center(struct window *window, struct wl_display *display, bool center)
bm_wl_window_set_align(struct window *window, struct wl_display *display, enum bm_align align)
{
if (window->center == center)
return;
if(window->align == align)
return;
window->center = center;
window->align = align;
zwlr_layer_surface_v1_set_anchor(window->layer_surface, 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);
wl_surface_commit(window->surface);
wl_display_roundtrip(display);
}
@ -366,7 +371,8 @@ 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_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);

View File

@ -104,11 +104,15 @@ bm_x11_window_render(struct window *window, const struct bm_menu *menu)
}
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 {
XMoveResizeWindow(window->display, window->drawable, window->x, 0, 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) {
@ -191,14 +195,26 @@ bm_x11_window_set_monitor(struct window *window, int32_t monitor)
}
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);
}
@ -216,12 +232,12 @@ bm_x11_window_set_monitor(struct window *window, int32_t monitor)
}
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->bottom == bottom)
if(window->align == align)
return;
window->bottom = bottom;
window->align = align;
bm_x11_window_set_monitor(window, window->monitor);
}

View File

@ -199,11 +199,11 @@ get_displayed_count(const struct bm_menu *menu)
}
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_bottom(&x11->window, bottom);
bm_x11_window_set_align(&x11->window, align);
}
static void
@ -276,7 +276,7 @@ constructor(struct bm_menu *menu)
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;
@ -295,7 +295,7 @@ register_renderer(struct render_api *api)
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;

View File

@ -1,6 +1,8 @@
#ifndef _BM_X11_H_
#define _BM_X11_H_
#include "internal.h"
#include <X11/Xlib.h>
#include <X11/keysym.h>
@ -36,7 +38,7 @@ struct window {
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);
@ -51,7 +53,7 @@ struct x11 {
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);