aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkolunmi <kolunmi@tutanota.com>2023-03-18 10:58:33 -0700
committerkolunmi <kolunmi@tutanota.com>2023-03-18 10:58:33 -0700
commitb1e0f996c22538fb1495daa7e70641f9b3bfc090 (patch)
tree697e1b888cf8a4284cca436038da755a11de8b88
parentc91e728fd6e50824b1216d730d2c26a44a5b7954 (diff)
downloaddwlb-b1e0f996c22538fb1495daa7e70641f9b3bfc090.tar.gz
add -custom-title and -center-title options
-rw-r--r--config.def.h24
-rw-r--r--dwlb.c283
2 files changed, 192 insertions, 115 deletions
diff --git a/config.def.h b/config.def.h
index 79fbc63..83d7481 100644
--- a/config.def.h
+++ b/config.def.h
@@ -1,14 +1,21 @@
// use ipc functionality
static bool ipc = false;
-
-// bar properties
+// initially hide all bars
static bool hidden = false;
+// initially draw all bars at the bottom
static bool bottom = false;
+// hide vacant tags
static bool hide_vacant = false;
-
+// vertical pixel padding above and below text
+static uint32_t vertical_padding = 1;
+// allow in-line color commands in status text
+static bool status_commands = true;
+// center title text
+static bool center_title = false;
+// use title space as status text element
+static bool custom_title = false;
// font
static char *fontstr = "monospace:size=16";
-
// tag names if ipc is disabled
static char *tags_noipc[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
@@ -21,12 +28,3 @@ static pixman_color_t inactive_fg_color = { .red = 0xbbbb, .green = 0xbbbb, .blu
static pixman_color_t inactive_bg_color = { .red = 0x2222, .green = 0x2222, .blue = 0x2222, .alpha = 0xffff, };
static pixman_color_t urgent_fg_color = { .red = 0x2222, .green = 0x2222, .blue = 0x2222, .alpha = 0xffff, };
static pixman_color_t urgent_bg_color = { .red = 0xeeee, .green = 0xeeee, .blue = 0xeeee, .alpha = 0xffff, };
-
-// vertical pixel padding above and below text
-static uint32_t vertical_padding = 1;
-
-// allow in-line color commands in status text
-static bool status_commands = true;
-
-// do not display current window title
-static bool no_title = false;
diff --git a/dwlb.c b/dwlb.c
index 99c8001..78acdb9 100644
--- a/dwlb.c
+++ b/dwlb.c
@@ -80,8 +80,10 @@
" -no-hide-vacant-tags display empty and inactive tags\n" \
" -status-commands enable in-line commands in status text\n" \
" -no-status-commands disable in-line commands in status text\n" \
- " -no-title do not display current window title\n" \
- " -no-no-title display current window title\n" \
+ " -center-title center title text on bar\n" \
+ " -no-center-title do not center title text on bar\n" \
+ " -custom-title do not display window title and treat the area as another status text element; see -title command\n" \
+ " -no-custom-title display current window title as normal\n" \
" -font [FONT] specify a font\n" \
" -tags [NUMBER] [FIRST]...[LAST] if ipc is disabled, specify custom tag names\n" \
" -vertical-padding [PIXELS] specify vertical pixel padding above and below text\n" \
@@ -93,6 +95,7 @@
" -urgent-bg-color [COLOR] specify background color of urgent tags\n" \
"Commands\n" \
" -status [OUTPUT] [TEXT] set status text\n" \
+ " -title [OUTPUT] [TEXT] set title text, if -custom-title is enabled\n" \
" -show [OUTPUT] show bar\n" \
" -hide [OUTPUT] hide bar\n" \
" -toggle-visibility [OUTPUT] toggle bar visibility\n" \
@@ -107,14 +110,22 @@ typedef struct {
pixman_color_t color;
bool bg;
char *start;
-} StatusColor;
+} Color;
typedef struct {
uint32_t btn;
uint32_t x1;
uint32_t x2;
char command[128];
-} StatusButton;
+} Button;
+
+typedef struct {
+ char text[2048];
+ Color *colors;
+ uint32_t colors_l, colors_c;
+ Button *buttons;
+ uint32_t buttons_l, buttons_c;
+} CustomText;
typedef struct {
struct wl_output *wl_output;
@@ -132,14 +143,9 @@ typedef struct {
uint32_t stride, bufsize;
uint32_t mtags, ctags, urg, sel;
- char layout[32];
+ char *layout, *window_title;
uint32_t layout_idx, last_layout_idx;
- char title[1024], status[1024];
-
- StatusColor *status_colors;
- uint32_t status_colors_l, status_colors_c;
- StatusButton *status_buttons;
- uint32_t status_buttons_l, status_buttons_c;
+ CustomText title, status;
bool hidden, bottom;
bool redraw;
@@ -230,7 +236,7 @@ draw_text(char *text,
uint32_t max_x,
uint32_t buf_height,
uint32_t padding,
- StatusColor *colors,
+ Color *colors,
uint32_t colors_l)
{
if (!text || !*text || !max_x)
@@ -413,19 +419,34 @@ draw_frame(Bar *bar)
&inactive_fg_color, &inactive_bg_color, bar->width,
bar->height, bar->textpadding, NULL, 0);
- uint32_t status_width = TEXT_WIDTH(bar->status, bar->width - x, bar->textpadding);
- draw_text(bar->status, bar->width - status_width, y, foreground,
+ uint32_t status_width = TEXT_WIDTH(bar->status.text, bar->width - x, bar->textpadding);
+ draw_text(bar->status.text, bar->width - status_width, y, foreground,
background, &inactive_fg_color, &inactive_bg_color,
bar->width, bar->height, bar->textpadding,
- bar->status_colors, bar->status_colors_l);
-
- if (!no_title) {
- x = draw_text(bar->title, x, y, foreground, background,
- bar->sel ? &active_fg_color : &inactive_fg_color,
- bar->sel ? &active_bg_color : &inactive_bg_color,
- bar->width - status_width, bar->height, bar->textpadding,
- NULL, 0);
+ bar->status.colors, bar->status.colors_l);
+
+ uint32_t nx;
+ if (center_title) {
+ uint32_t title_width = TEXT_WIDTH(custom_title ? bar->title.text : bar->window_title, bar->width - status_width - x, 0);
+ nx = MAX(x, MIN((bar->width - title_width) / 2, bar->width - status_width - title_width));
+ } else {
+ nx = MIN(x + bar->textpadding, bar->width - status_width);
}
+ pixman_image_fill_boxes(PIXMAN_OP_SRC, background,
+ bar->sel ? &active_bg_color : &inactive_bg_color, 1,
+ &(pixman_box32_t){
+ .x1 = x, .x2 = nx,
+ .y1 = 0, .y2 = bar->height
+ });
+ x = nx;
+
+ x = draw_text(custom_title ? bar->title.text : bar->window_title,
+ x, y, foreground, background,
+ bar->sel ? &active_fg_color : &inactive_fg_color,
+ bar->sel ? &active_bg_color : &inactive_bg_color,
+ bar->width - status_width, bar->height, 0,
+ custom_title ? bar->title.colors : NULL,
+ custom_title ? bar->title.colors_l : 0);
pixman_image_fill_boxes(PIXMAN_OP_SRC, background,
bar->sel ? &active_bg_color : &inactive_bg_color, 1,
@@ -637,17 +658,32 @@ pointer_frame(void *data, struct wl_pointer *pointer)
znet_tapesoftware_dwl_wm_monitor_v1_set_layout(seat->bar->dwl_wm_monitor, 2);
}
} else {
- uint32_t status_x = seat->bar->width - TEXT_WIDTH(seat->bar->status, seat->bar->width - x, seat->bar->textpadding);
+ uint32_t status_x = seat->bar->width - TEXT_WIDTH(seat->bar->status.text, seat->bar->width - x, seat->bar->textpadding);
if (seat->pointer_x < status_x) {
/* Clicked on title */
-
+ if (custom_title) {
+ if (center_title) {
+ uint32_t title_width = TEXT_WIDTH(seat->bar->title.text, status_x - x, 0);
+ x = MAX(x, MIN((seat->bar->width - title_width) / 2, status_x - title_width));
+ } else {
+ x = MIN(x + seat->bar->textpadding, status_x);
+ }
+ for (i = 0; i < seat->bar->title.buttons_l; i++) {
+ if (seat->pointer_button == seat->bar->title.buttons[i].btn
+ && seat->pointer_x >= x + seat->bar->title.buttons[i].x1
+ && seat->pointer_x < x + seat->bar->title.buttons[i].x2) {
+ shell_command(seat->bar->title.buttons[i].command);
+ break;
+ }
+ }
+ }
} else {
/* Clicked on status */
- for (i = 0; i < seat->bar->status_buttons_l; i++) {
- if (seat->pointer_button == seat->bar->status_buttons[i].btn
- && seat->pointer_x >= status_x + seat->bar->textpadding + seat->bar->status_buttons[i].x1
- && seat->pointer_x < status_x + seat->bar->textpadding + seat->bar->status_buttons[i].x2) {
- shell_command(seat->bar->status_buttons[i].command);
+ for (i = 0; i < seat->bar->status.buttons_l; i++) {
+ if (seat->pointer_button == seat->bar->status.buttons[i].btn
+ && seat->pointer_x >= status_x + seat->bar->textpadding + seat->bar->status.buttons[i].x1
+ && seat->pointer_x < status_x + seat->bar->textpadding + seat->bar->status.buttons[i].x2) {
+ shell_command(seat->bar->status.buttons[i].command);
break;
}
}
@@ -794,27 +830,26 @@ dwl_wm_monitor_layout(void *data, struct znet_tapesoftware_dwl_wm_monitor_v1 *dw
{
Bar *bar = (Bar *)data;
- if (strcmp(bar->layout, layouts[layout]) != 0) {
- snprintf(bar->layout, sizeof bar->layout, "%s", layouts[layout]);
- bar->last_layout_idx = bar->layout_idx;
- bar->layout_idx = layout;
- bar->redraw = true;
- }
+ bar->layout = layouts[layout];
+ bar->last_layout_idx = bar->layout_idx;
+ bar->layout_idx = layout;
+ bar->redraw = true;
}
static void
dwl_wm_monitor_title(void *data, struct znet_tapesoftware_dwl_wm_monitor_v1 *dwl_wm_monitor,
const char *title)
{
- if (no_title)
+ if (custom_title)
return;
-
+
Bar *bar = (Bar *)data;
-
- if (strcmp(bar->title, title) != 0) {
- snprintf(bar->title, sizeof bar->title, "%s", title);
- bar->redraw = true;
- }
+
+ if (bar->window_title)
+ free(bar->window_title);
+ if (!(bar->window_title = strdup(title)))
+ EDIE("strdup");
+ bar->redraw = true;
}
static void
@@ -872,9 +907,6 @@ setup_bar(Bar *bar)
bar->bottom = bottom;
bar->hidden = hidden;
- if (!ipc)
- snprintf(bar->layout, sizeof bar->layout, "[]=");
-
bar->xdg_output = zxdg_output_manager_v1_get_xdg_output(output_manager, bar->wl_output);
if (!bar->xdg_output)
DIE("Could not create xdg_output");
@@ -931,14 +963,20 @@ handle_global(void *data, struct wl_registry *registry,
static void
teardown_bar(Bar *bar)
{
+ if (bar->status.colors)
+ free(bar->status.colors);
+ if (bar->status.buttons)
+ free(bar->status.buttons);
+ if (bar->title.colors)
+ free(bar->title.colors);
+ if (bar->title.buttons)
+ free(bar->title.buttons);
+ if (!ipc && bar->layout)
+ free(bar->layout);
if (ipc)
znet_tapesoftware_dwl_wm_monitor_v1_destroy(bar->dwl_wm_monitor);
if (bar->xdg_output_name)
free(bar->xdg_output_name);
- if (bar->status_colors)
- free(bar->status_colors);
- if (bar->status_buttons)
- free(bar->status_buttons);
if (!bar->hidden) {
zwlr_layer_surface_v1_destroy(bar->layer_surface);
wl_surface_destroy(bar->wl_surface);
@@ -1065,15 +1103,19 @@ read_stdin(void)
bar->redraw = true;
}
} else if (!strcmp(wordbeg, "layout")) {
- if (strcmp(bar->layout, wordend) != 0) {
- snprintf(bar->layout, sizeof bar->layout, "%s", wordend);
- bar->redraw = true;
- }
+ if (bar->layout)
+ free(bar->layout);
+ if (!(bar->layout = strdup(wordend)))
+ EDIE("strdup");
+ bar->redraw = true;
} else if (!strcmp(wordbeg, "title")) {
- if (strcmp(bar->title, wordend) != 0) {
- snprintf(bar->title, sizeof bar->title, "%s", wordend);
- bar->redraw = true;
- }
+ if (custom_title)
+ continue;
+ if (bar->window_title)
+ free(bar->window_title);
+ if (!(bar->window_title = strdup(wordend)))
+ EDIE("strdup");
+ bar->redraw = true;
} else if (!strcmp(wordbeg, "selmon")) {
ADVANCE();
if ((val = atoi(wordbeg)) != bar->sel) {
@@ -1140,9 +1182,9 @@ parse_color(const char *str, pixman_color_t *clr)
}
static void
-set_status(Bar *bar, char *text)
+parse_into_customtext(CustomText *ct, char *text)
{
- bar->status_colors_l = bar->status_buttons_l = 0;
+ ct->colors_l = ct->buttons_l = 0;
if (status_commands) {
uint32_t codepoint;
@@ -1151,11 +1193,11 @@ set_status(Bar *bar, char *text)
uint32_t x = 0;
size_t str_pos = 0;
- StatusButton *left_button = NULL;
- StatusButton *middle_button = NULL;
- StatusButton *right_button = NULL;
+ Button *left_button = NULL;
+ Button *middle_button = NULL;
+ Button *right_button = NULL;
- for (char *p = text; *p && str_pos < sizeof(bar->status) - 1; p++) {
+ for (char *p = text; *p && str_pos < sizeof(ct->text) - 1; p++) {
if (state == UTF8_ACCEPT && *p == '^') {
p++;
if (*p != '^') {
@@ -1166,29 +1208,29 @@ set_status(Bar *bar, char *text)
*end = '\0';
if (!strcmp(p, "bg")) {
- StatusColor *status_color;
- ARRAY_APPEND(bar->status_colors, bar->status_colors_l, bar->status_colors_c, status_color);
+ Color *color;
+ ARRAY_APPEND(ct->colors, ct->colors_l, ct->colors_c, color);
if (!*arg)
- status_color->color = inactive_bg_color;
+ color->color = inactive_bg_color;
else
- parse_color(arg, &status_color->color);
- status_color->bg = true;
- status_color->start = bar->status + str_pos;
+ parse_color(arg, &color->color);
+ color->bg = true;
+ color->start = ct->text + str_pos;
} else if (!strcmp(p, "fg")) {
- StatusColor *status_color;
- ARRAY_APPEND(bar->status_colors, bar->status_colors_l, bar->status_colors_c, status_color);
+ Color *color;
+ ARRAY_APPEND(ct->colors, ct->colors_l, ct->colors_c, color);
if (!*arg)
- status_color->color = inactive_fg_color;
+ color->color = inactive_fg_color;
else
- parse_color(arg, &status_color->color);
- status_color->bg = false;
- status_color->start = bar->status + str_pos;
+ parse_color(arg, &color->color);
+ color->bg = false;
+ color->start = ct->text + str_pos;
} else if (!strcmp(p, "lm")) {
if (left_button) {
left_button->x2 = x;
left_button = NULL;
} else if (*arg) {
- ARRAY_APPEND(bar->status_buttons, bar->status_buttons_l, bar->status_buttons_c, left_button);
+ ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, left_button);
left_button->btn = BTN_LEFT;
snprintf(left_button->command, sizeof left_button->command, "%s", arg);
left_button->x1 = x;
@@ -1198,7 +1240,7 @@ set_status(Bar *bar, char *text)
middle_button->x2 = x;
middle_button = NULL;
} else if (*arg) {
- ARRAY_APPEND(bar->status_buttons, bar->status_buttons_l, bar->status_buttons_c, middle_button);
+ ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, middle_button);
middle_button->btn = BTN_MIDDLE;
snprintf(middle_button->command, sizeof middle_button->command, "%s", arg);
middle_button->x1 = x;
@@ -1208,7 +1250,7 @@ set_status(Bar *bar, char *text)
right_button->x2 = x;
right_button = NULL;
} else if (*arg) {
- ARRAY_APPEND(bar->status_buttons, bar->status_buttons_l, bar->status_buttons_c, right_button);
+ ARRAY_APPEND(ct->buttons, ct->buttons_l, ct->buttons_c, right_button);
right_button->btn = BTN_RIGHT;
snprintf(right_button->command, sizeof right_button->command, "%s", arg);
right_button->x1 = x;
@@ -1223,7 +1265,7 @@ set_status(Bar *bar, char *text)
}
}
- bar->status[str_pos++] = *p;
+ ct->text[str_pos++] = *p;
if (utf8decode(&state, &codepoint, *p))
continue;
@@ -1247,9 +1289,28 @@ set_status(Bar *bar, char *text)
if (right_button)
right_button->x2 = x;
- bar->status[str_pos] = '\0';
+ ct->text[str_pos] = '\0';
} else {
- snprintf(bar->status, sizeof bar->status, "%s", text);
+ snprintf(ct->text, sizeof ct->text, "%s", text);
+ }
+}
+
+static void
+copy_customtext(CustomText *from, CustomText *to)
+{
+ snprintf(to->text, sizeof to->text, "%s", from->text);
+ to->colors_l = to->buttons_l = 0;
+ for (uint32_t i = 0; i < from->colors_l; i++) {
+ Color *color;
+ ARRAY_APPEND(to->colors, to->colors_l, to->colors_c, color);
+ color->color = from->colors[i].color;
+ color->bg = from->colors[i].bg;
+ color->start = from->colors[i].start - (char *)&from->text + (char *)&to->text;
+ }
+ for (uint32_t i = 0; i < from->buttons_l; i++) {
+ Button *button;
+ ARRAY_APPEND(to->buttons, to->buttons_l, to->buttons_c, button);
+ *button = from->buttons[i];
}
}
@@ -1305,29 +1366,33 @@ read_socket(void)
Bar *first = NULL;
wl_list_for_each(bar, &bar_list, link) {
if (first) {
- /* Copy over parsed status information to other bars */
- snprintf(bar->status, sizeof bar->status, "%s", first->status);
- bar->status_colors_l = bar->status_buttons_l = 0;
- for (uint32_t i = 0; i < first->status_colors_l; i++) {
- StatusColor *status_color;
- ARRAY_APPEND(bar->status_colors, bar->status_colors_l, bar->status_colors_c, status_color);
- status_color->color = first->status_colors[i].color;
- status_color->bg = first->status_colors[i].bg;
- status_color->start = first->status_colors[i].start - (char *)&first->status + (char *)&bar->status;
- }
- for (uint32_t i = 0; i < first->status_buttons_l; i++) {
- StatusButton *status_button;
- ARRAY_APPEND(bar->status_buttons, bar->status_buttons_l, bar->status_buttons_c, status_button);
- *status_button = first->status_buttons[i];
- }
+ copy_customtext(&first->status, &bar->status);
} else {
- set_status(bar, wordend);
+ parse_into_customtext(&bar->status, wordend);
first = bar;
}
bar->redraw = true;
}
} else {
- set_status(bar, wordend);
+ parse_into_customtext(&bar->status, wordend);
+ bar->redraw = true;
+ }
+ } else if (!strcmp(wordbeg, "title")) {
+ if (!custom_title || !*wordend)
+ return;
+ if (all) {
+ Bar *first = NULL;
+ wl_list_for_each(bar, &bar_list, link) {
+ if (first) {
+ copy_customtext(&first->title, &bar->title);
+ } else {
+ parse_into_customtext(&bar->title, wordend);
+ first = bar;
+ }
+ bar->redraw = true;
+ }
+ } else {
+ parse_into_customtext(&bar->title, wordend);
bar->redraw = true;
}
} else if (!strcmp(wordbeg, "show")) {
@@ -1507,6 +1572,11 @@ main(int argc, char **argv)
DIE("Option -status requires two arguments");
client_send_command(&sock_address, argv[i], "status", argv[i + 1]);
return 0;
+ } else if (!strcmp(argv[i], "-title")) {
+ if (++i + 1 >= argc)
+ DIE("Option -title requires two arguments");
+ client_send_command(&sock_address, argv[i], "title", argv[i + 1]);
+ return 0;
} else if (!strcmp(argv[i], "-show")) {
if (++i >= argc)
DIE("Option -show requires an argument");
@@ -1557,10 +1627,14 @@ main(int argc, char **argv)
status_commands = true;
} else if (!strcmp(argv[i], "-no-status-commands")) {
status_commands = false;
- } else if (!strcmp(argv[i], "-no-title")) {
- no_title = true;
- } else if (!strcmp(argv[i], "-no-no-title")) {
- no_title = false;
+ } else if (!strcmp(argv[i], "-center-title")) {
+ center_title = true;
+ } else if (!strcmp(argv[i], "-no-center-title")) {
+ center_title = false;
+ } else if (!strcmp(argv[i], "-custom-title")) {
+ custom_title = true;
+ } else if (!strcmp(argv[i], "-no-custom-title")) {
+ custom_title = false;
} else if (!strcmp(argv[i], "-font")) {
if (++i >= argc)
DIE("Option -font requires an argument");
@@ -1727,6 +1801,11 @@ main(int argc, char **argv)
free(tags[i]);
free(tags);
}
+ if (layouts) {
+ for (uint32_t i = 0; i < layouts_l; i++)
+ free(layouts[i]);
+ free(layouts);
+ }
wl_list_for_each_safe(bar, bar2, &bar_list, link)
teardown_bar(bar);