refactoring, remove uthash dependency, add -not-title option

This commit is contained in:
kolunmi 2023-03-14 12:07:21 -07:00
parent fbb2b67ba2
commit c91e728fd6
4 changed files with 227 additions and 243 deletions

View File

@ -18,43 +18,27 @@ WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner) WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
xdg-shell-protocol.h: xdg-shell-protocol.h:
$(WAYLAND_SCANNER) client-header \ $(WAYLAND_SCANNER) client-header $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
xdg-shell-protocol.c: xdg-shell-protocol.c:
$(WAYLAND_SCANNER) private-code \ $(WAYLAND_SCANNER) private-code $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
xdg-shell-protocol.o: xdg-shell-protocol.h xdg-shell-protocol.o: xdg-shell-protocol.h
xdg-output-unstable-v1-protocol.h: xdg-output-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) client-header \ $(WAYLAND_SCANNER) client-header $(WAYLAND_PROTOCOLS)/unstable/xdg-output/xdg-output-unstable-v1.xml $@
$(WAYLAND_PROTOCOLS)/unstable/xdg-output/xdg-output-unstable-v1.xml $@
xdg-output-unstable-v1-protocol.c: xdg-output-unstable-v1-protocol.c:
$(WAYLAND_SCANNER) private-code \ $(WAYLAND_SCANNER) private-code $(WAYLAND_PROTOCOLS)/unstable/xdg-output/xdg-output-unstable-v1.xml $@
$(WAYLAND_PROTOCOLS)/unstable/xdg-output/xdg-output-unstable-v1.xml $@
xdg-output-unstable-v1-protocol.o: xdg-output-unstable-v1-protocol.h xdg-output-unstable-v1-protocol.o: xdg-output-unstable-v1-protocol.h
wlr-layer-shell-unstable-v1-protocol.h: wlr-layer-shell-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) client-header \ $(WAYLAND_SCANNER) client-header protocols/wlr-layer-shell-unstable-v1.xml $@
protocols/wlr-layer-shell-unstable-v1.xml $@
wlr-layer-shell-unstable-v1-protocol.c: wlr-layer-shell-unstable-v1-protocol.c:
$(WAYLAND_SCANNER) private-code \ $(WAYLAND_SCANNER) private-code protocols/wlr-layer-shell-unstable-v1.xml $@
protocols/wlr-layer-shell-unstable-v1.xml $@
wlr-layer-shell-unstable-v1-protocol.o: wlr-layer-shell-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.o: wlr-layer-shell-unstable-v1-protocol.h
net-tapesoftware-dwl-wm-unstable-v1-protocol.h: net-tapesoftware-dwl-wm-unstable-v1-protocol.h:
$(WAYLAND_SCANNER) client-header \ $(WAYLAND_SCANNER) client-header protocols/net-tapesoftware-dwl-wm-unstable-v1.xml $@
protocols/net-tapesoftware-dwl-wm-unstable-v1.xml $@
net-tapesoftware-dwl-wm-unstable-v1-protocol.c: net-tapesoftware-dwl-wm-unstable-v1-protocol.c:
$(WAYLAND_SCANNER) private-code \ $(WAYLAND_SCANNER) private-code protocols/net-tapesoftware-dwl-wm-unstable-v1.xml $@
protocols/net-tapesoftware-dwl-wm-unstable-v1.xml $@
net-tapesoftware-dwl-wm-unstable-v1-protocol.o: net-tapesoftware-dwl-wm-unstable-v1-protocol.h net-tapesoftware-dwl-wm-unstable-v1-protocol.o: net-tapesoftware-dwl-wm-unstable-v1-protocol.h
dwlb.o: utf8.h config.h xdg-shell-protocol.h xdg-output-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h net-tapesoftware-dwl-wm-unstable-v1-protocol.o dwlb.o: utf8.h config.h xdg-shell-protocol.h xdg-output-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h net-tapesoftware-dwl-wm-unstable-v1-protocol.o

View File

@ -12,7 +12,6 @@ A fast, feature-complete bar for [dwl](https://github.com/djpohly/dwl).
* libwayland-cursor * libwayland-cursor
* pixman * pixman
* fcft * fcft
* uthash
## Installation ## Installation
```bash ```bash
@ -32,7 +31,7 @@ dwl -s 'dwlb -font "monospace:size=16"'
If dwl is [patched](https://lists.sr.ht/~raphi/public-inbox/patches/39166) appropriately, dwlb is capable of communicating directly with dwl. When ipc is enabled with `-ipc`, dwlb does not read from stdin, and clicking tags functions as you would expect. Ipc can be disabled with `-no-ipc`. If dwl is [patched](https://lists.sr.ht/~raphi/public-inbox/patches/39166) appropriately, dwlb is capable of communicating directly with dwl. When ipc is enabled with `-ipc`, dwlb does not read from stdin, and clicking tags functions as you would expect. Ipc can be disabled with `-no-ipc`.
## Commands ## Commands
Command options send instructions to existing instances of dwlb. All commands take at least one argument to specify a bar on which to operate. This may be zxdg_output_v1 name, "all" to affect all outputs, "selected" for the current output, or "first" for the first output in the internal list. Command options send instructions to existing instances of dwlb. All commands take at least one argument to specify a bar on which to operate. This may be zxdg_output_v1 name, "all" to affect all outputs, or "selected" for the current output.
### Status Text ### Status Text
The `-status` command is used to write status text. The text may contain in-line commands in the following format: `^cmd(argument)`. The `-status` command is used to write status text. The text may contain in-line commands in the following format: `^cmd(argument)`.

View File

@ -7,7 +7,7 @@ static bool bottom = false;
static bool hide_vacant = false; static bool hide_vacant = false;
// font // font
static char *fontstr = "monospace:size=10"; static char *fontstr = "monospace:size=16";
// tag names if ipc is disabled // tag names if ipc is disabled
static char *tags_noipc[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static char *tags_noipc[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
@ -27,3 +27,6 @@ static uint32_t vertical_padding = 1;
// allow in-line color commands in status text // allow in-line color commands in status text
static bool status_commands = true; static bool status_commands = true;
// do not display current window title
static bool no_title = false;

430
dwlb.c
View File

@ -17,9 +17,9 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include <utlist.h>
#include <wayland-client.h> #include <wayland-client.h>
#include <wayland-cursor.h> #include <wayland-cursor.h>
#include <wayland-util.h>
#include "utf8.h" #include "utf8.h"
#include "xdg-shell-protocol.h" #include "xdg-shell-protocol.h"
@ -65,7 +65,7 @@
} while (0) } while (0)
#define PROGRAM "dwlb" #define PROGRAM "dwlb"
#define VERSION "0.1" #define VERSION "0.2"
#define USAGE \ #define USAGE \
"usage: dwlb [OPTIONS]\n" \ "usage: dwlb [OPTIONS]\n" \
"Ipc\n" \ "Ipc\n" \
@ -80,6 +80,8 @@
" -no-hide-vacant-tags display empty and inactive tags\n" \ " -no-hide-vacant-tags display empty and inactive tags\n" \
" -status-commands enable in-line commands in status text\n" \ " -status-commands enable in-line commands in status text\n" \
" -no-status-commands disable 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" \
" -font [FONT] specify a font\n" \ " -font [FONT] specify a font\n" \
" -tags [NUMBER] [FIRST]...[LAST] if ipc is disabled, specify custom tag names\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" \ " -vertical-padding [PIXELS] specify vertical pixel padding above and below text\n" \
@ -114,61 +116,48 @@ typedef struct {
char command[128]; char command[128];
} StatusButton; } StatusButton;
typedef struct Bar Bar; typedef struct {
struct Bar {
struct zxdg_output_v1 *xdg_output;
struct wl_output *wl_output; struct wl_output *wl_output;
struct wl_surface *wl_surface; struct wl_surface *wl_surface;
struct zwlr_layer_surface_v1 *layer_surface; struct zwlr_layer_surface_v1 *layer_surface;
struct zxdg_output_v1 *xdg_output;
struct znet_tapesoftware_dwl_wm_monitor_v1 *dwl_wm_monitor; struct znet_tapesoftware_dwl_wm_monitor_v1 *dwl_wm_monitor;
uint32_t registry_name; uint32_t registry_name;
char *xdg_output_name; char *xdg_output_name;
bool configured; bool configured;
uint32_t width; uint32_t width, height;
uint32_t height;
uint32_t textpadding; uint32_t textpadding;
uint32_t stride; uint32_t stride, bufsize;
uint32_t bufsize;
uint32_t mtags; uint32_t mtags, ctags, urg, sel;
uint32_t ctags;
uint32_t urg;
uint32_t selmon;
char layout[32]; char layout[32];
uint32_t layout_idx; uint32_t layout_idx, last_layout_idx;
uint32_t last_layout_idx; char title[1024], status[1024];
char title[1024];
char status[1024];
StatusColor *status_colors; StatusColor *status_colors;
uint32_t status_colors_l, status_colors_c; uint32_t status_colors_l, status_colors_c;
StatusButton *status_buttons; StatusButton *status_buttons;
uint32_t status_buttons_l, status_buttons_c; uint32_t status_buttons_l, status_buttons_c;
bool hidden; bool hidden, bottom;
bool bottom;
bool redraw; bool redraw;
Bar *prev, *next; struct wl_list link;
}; } Bar;
typedef struct Seat Seat; typedef struct {
struct Seat {
struct wl_seat *wl_seat; struct wl_seat *wl_seat;
struct wl_pointer *wl_pointer; struct wl_pointer *wl_pointer;
uint32_t registry_name; uint32_t registry_name;
Bar *bar; Bar *bar;
uint32_t pointer_x; uint32_t pointer_x, pointer_y;
uint32_t pointer_y;
uint32_t pointer_button; uint32_t pointer_button;
Seat *prev, *next; struct wl_list link;
}; } Seat;
static int sock_fd; static int sock_fd;
static char socketdir[256]; static char socketdir[256];
@ -183,24 +172,21 @@ static struct wl_compositor *compositor;
static struct wl_shm *shm; static struct wl_shm *shm;
static struct zwlr_layer_shell_v1 *layer_shell; static struct zwlr_layer_shell_v1 *layer_shell;
static struct zxdg_output_manager_v1 *output_manager; static struct zxdg_output_manager_v1 *output_manager;
static struct znet_tapesoftware_dwl_wm_v1 *dwl_wm;
static struct wl_cursor_image *cursor_image; static struct wl_cursor_image *cursor_image;
static struct wl_surface *cursor_surface; static struct wl_surface *cursor_surface;
static struct znet_tapesoftware_dwl_wm_v1 *dwl_wm;
static struct wl_list bar_list, seat_list;
static char **tags; static char **tags;
static uint32_t tags_l, tags_c; static uint32_t tags_l, tags_c;
static char **layouts; static char **layouts;
static uint32_t layouts_l, layouts_c; static uint32_t layouts_l, layouts_c;
static Bar *bar_list;
static Seat *seat_list;
static struct fcft_font *font; static struct fcft_font *font;
static uint32_t height; static uint32_t height, textpadding;
static uint32_t textpadding;
static bool run_display = true; static bool run_display;
static bool ready = false;
#include "config.h" #include "config.h"
@ -220,13 +206,13 @@ static int
allocate_shm_file(size_t size) allocate_shm_file(size_t size)
{ {
int fd = memfd_create("surface", MFD_CLOEXEC); int fd = memfd_create("surface", MFD_CLOEXEC);
if (fd < 0) if (fd == -1)
return -1; return -1;
int ret; int ret;
do { do {
ret = ftruncate(fd, size); ret = ftruncate(fd, size);
} while (ret < 0 && errno == EINTR); } while (ret == -1 && errno == EINTR);
if (ret < 0) { if (ret == -1) {
close(fd); close(fd);
return -1; return -1;
} }
@ -247,11 +233,10 @@ draw_text(char *text,
StatusColor *colors, StatusColor *colors,
uint32_t colors_l) uint32_t colors_l)
{ {
if (!*text || !max_x) if (!text || !*text || !max_x)
return x; return x;
uint32_t ix = x; uint32_t ix = x, nx;
uint32_t nx;
if ((nx = x + padding) + padding >= max_x) if ((nx = x + padding) + padding >= max_x)
return x; return x;
@ -267,11 +252,7 @@ draw_text(char *text,
if (draw_bg) if (draw_bg)
cur_bg_color = bg_color; cur_bg_color = bg_color;
uint32_t color_ind = 0; uint32_t color_ind = 0, codepoint, state = UTF8_ACCEPT, last_cp = 0;
uint32_t codepoint;
uint32_t state = UTF8_ACCEPT;
uint32_t last_cp = 0;
for (char *p = text; *p; p++) { for (char *p = text; *p; p++) {
/* Check for new colors */ /* Check for new colors */
if (state == UTF8_ACCEPT && colors && (draw_fg || draw_bg)) { if (state == UTF8_ACCEPT && colors && (draw_fg || draw_bg)) {
@ -325,12 +306,13 @@ draw_text(char *text,
} }
} }
if (draw_bg) if (draw_bg) {
pixman_image_fill_boxes(PIXMAN_OP_OVER, background, pixman_image_fill_boxes(PIXMAN_OP_OVER, background,
cur_bg_color, 1, &(pixman_box32_t){ cur_bg_color, 1, &(pixman_box32_t){
.x1 = x, .x2 = nx, .x1 = x, .x2 = nx,
.y1 = 0, .y2 = buf_height .y1 = 0, .y2 = buf_height
}); });
}
/* increment pen position */ /* increment pen position */
x = nx; x = nx;
@ -396,9 +378,10 @@ draw_frame(Bar *bar)
uint32_t boxw = font->height / 6 + 2; uint32_t boxw = font->height / 6 + 2;
for (uint32_t i = 0; i < tags_l; i++) { for (uint32_t i = 0; i < tags_l; i++) {
bool active = bar->mtags & 1 << i; const bool active = bar->mtags & 1 << i;
bool occupied = bar->ctags & 1 << i; const bool occupied = bar->ctags & 1 << i;
bool urgent = bar->urg & 1 << i; const bool urgent = bar->urg & 1 << i;
if (hide_vacant && !active && !occupied && !urgent) if (hide_vacant && !active && !occupied && !urgent)
continue; continue;
@ -411,7 +394,7 @@ draw_frame(Bar *bar)
.x1 = x + boxs, .x2 = x + boxs + boxw, .x1 = x + boxs, .x2 = x + boxs + boxw,
.y1 = boxs, .y2 = boxs + boxw .y1 = boxs, .y2 = boxs + boxw
}); });
if ((!bar->selmon || !active) && boxw >= 3) { if ((!bar->sel || !active) && boxw >= 3) {
/* Make box hollow */ /* Make box hollow */
pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground, pixman_image_fill_boxes(PIXMAN_OP_SRC, foreground,
&(pixman_color_t){ 0 }, &(pixman_color_t){ 0 },
@ -436,14 +419,16 @@ draw_frame(Bar *bar)
bar->width, bar->height, bar->textpadding, bar->width, bar->height, bar->textpadding,
bar->status_colors, bar->status_colors_l); bar->status_colors, bar->status_colors_l);
x = draw_text(bar->title, x, y, foreground, background, if (!no_title) {
bar->selmon ? &active_fg_color : &inactive_fg_color, x = draw_text(bar->title, x, y, foreground, background,
bar->selmon ? &active_bg_color : &inactive_bg_color, bar->sel ? &active_fg_color : &inactive_fg_color,
bar->width - status_width, bar->height, bar->textpadding, bar->sel ? &active_bg_color : &inactive_bg_color,
NULL, 0); bar->width - status_width, bar->height, bar->textpadding,
NULL, 0);
}
pixman_image_fill_boxes(PIXMAN_OP_SRC, background, pixman_image_fill_boxes(PIXMAN_OP_SRC, background,
bar->selmon ? &active_bg_color : &inactive_bg_color, 1, bar->sel ? &active_bg_color : &inactive_bg_color, 1,
&(pixman_box32_t){ &(pixman_box32_t){
.x1 = x, .x2 = bar->width - status_width, .x1 = x, .x2 = bar->width - status_width,
.y1 = 0, .y2 = bar->height .y1 = 0, .y2 = bar->height
@ -564,11 +549,14 @@ pointer_enter(void *data, struct wl_pointer *pointer,
{ {
Seat *seat = (Seat *)data; Seat *seat = (Seat *)data;
seat->bar = NULL;
Bar *bar; Bar *bar;
DL_FOREACH(bar_list, bar) wl_list_for_each(bar, &bar_list, link) {
if (bar->wl_surface == surface) if (bar->wl_surface == surface) {
seat->bar = bar;
break; break;
seat->bar = bar; }
}
if (!cursor_image) { if (!cursor_image) {
struct wl_cursor_theme *cursor_theme = wl_cursor_theme_load(NULL, 24, shm); struct wl_cursor_theme *cursor_theme = wl_cursor_theme_load(NULL, 24, shm);
@ -605,7 +593,7 @@ pointer_motion(void *data, struct wl_pointer *pointer, uint32_t time,
wl_fixed_t surface_x, wl_fixed_t surface_y) wl_fixed_t surface_x, wl_fixed_t surface_y)
{ {
Seat *seat = (Seat *)data; Seat *seat = (Seat *)data;
seat->pointer_x = wl_fixed_to_int(surface_x); seat->pointer_x = wl_fixed_to_int(surface_x);
seat->pointer_y = wl_fixed_to_int(surface_y); seat->pointer_y = wl_fixed_to_int(surface_y);
} }
@ -618,13 +606,12 @@ pointer_frame(void *data, struct wl_pointer *pointer)
if (!seat->pointer_button || !seat->bar) if (!seat->pointer_button || !seat->bar)
return; return;
uint32_t x = 0; uint32_t x = 0, i = 0;
uint32_t i = 0;
do { do {
if (hide_vacant) { if (hide_vacant) {
bool active = seat->bar->mtags & 1 << i; const bool active = seat->bar->mtags & 1 << i;
bool occupied = seat->bar->ctags & 1 << i; const bool occupied = seat->bar->ctags & 1 << i;
bool urgent = seat->bar->urg & 1 << i; const bool urgent = seat->bar->urg & 1 << i;
if (!active && !occupied && !urgent) if (!active && !occupied && !urgent)
continue; continue;
} }
@ -768,8 +755,8 @@ dwl_wm_monitor_selected(void *data, struct znet_tapesoftware_dwl_wm_monitor_v1 *
{ {
Bar *bar = (Bar *)data; Bar *bar = (Bar *)data;
if (selected != bar->selmon) { if (selected != bar->sel) {
bar->selmon = selected; bar->sel = selected;
bar->redraw = true; bar->redraw = true;
} }
} }
@ -819,6 +806,9 @@ static void
dwl_wm_monitor_title(void *data, struct znet_tapesoftware_dwl_wm_monitor_v1 *dwl_wm_monitor, dwl_wm_monitor_title(void *data, struct znet_tapesoftware_dwl_wm_monitor_v1 *dwl_wm_monitor,
const char *title) const char *title)
{ {
if (no_title)
return;
Bar *bar = (Bar *)data; Bar *bar = (Bar *)data;
if (strcmp(bar->title, title) != 0) { if (strcmp(bar->title, title) != 0) {
@ -901,12 +891,6 @@ setup_bar(Bar *bar)
show_bar(bar); show_bar(bar);
} }
static void
setup_seat(Seat *seat)
{
wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
}
static void static void
handle_global(void *data, struct wl_registry *registry, handle_global(void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version) uint32_t name, const char *interface, uint32_t version)
@ -925,35 +909,28 @@ handle_global(void *data, struct wl_registry *registry,
znet_tapesoftware_dwl_wm_v1_add_listener(dwl_wm, &dwl_wm_listener, NULL); znet_tapesoftware_dwl_wm_v1_add_listener(dwl_wm, &dwl_wm_listener, NULL);
} }
} else if (!strcmp(interface, wl_output_interface.name)) { } else if (!strcmp(interface, wl_output_interface.name)) {
Bar *bar = malloc(sizeof(Bar)); Bar *bar = calloc(1, sizeof(Bar));
if (!bar) if (!bar)
EDIE("malloc"); EDIE("calloc");
memset(bar, 0, sizeof(Bar));
bar->registry_name = name; bar->registry_name = name;
bar->wl_output = wl_registry_bind(registry, name, &wl_output_interface, 1); bar->wl_output = wl_registry_bind(registry, name, &wl_output_interface, 1);
DL_APPEND(bar_list, bar); if (run_display)
if (ready)
setup_bar(bar); setup_bar(bar);
wl_list_insert(&bar_list, &bar->link);
} else if (!strcmp(interface, wl_seat_interface.name)) { } else if (!strcmp(interface, wl_seat_interface.name)) {
Seat *seat = malloc(sizeof(Seat)); Seat *seat = calloc(1, sizeof(Seat));
if (!seat) if (!seat)
EDIE("malloc"); EDIE("calloc");
memset(seat, 0, sizeof(Seat));
seat->registry_name = name; seat->registry_name = name;
seat->wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 7); seat->wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 7);
DL_APPEND(seat_list, seat); wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
setup_seat(seat); wl_list_insert(&seat_list, &seat->link);
} }
} }
static void static void
teardown_bar(Bar *bar) teardown_bar(Bar *bar)
{ {
zxdg_output_v1_destroy(bar->xdg_output);
if (!bar->hidden) {
zwlr_layer_surface_v1_destroy(bar->layer_surface);
wl_surface_destroy(bar->wl_surface);
}
if (ipc) if (ipc)
znet_tapesoftware_dwl_wm_monitor_v1_destroy(bar->dwl_wm_monitor); znet_tapesoftware_dwl_wm_monitor_v1_destroy(bar->dwl_wm_monitor);
if (bar->xdg_output_name) if (bar->xdg_output_name)
@ -962,15 +939,21 @@ teardown_bar(Bar *bar)
free(bar->status_colors); free(bar->status_colors);
if (bar->status_buttons) if (bar->status_buttons)
free(bar->status_buttons); free(bar->status_buttons);
if (!bar->hidden) {
zwlr_layer_surface_v1_destroy(bar->layer_surface);
wl_surface_destroy(bar->wl_surface);
}
zxdg_output_v1_destroy(bar->xdg_output);
wl_output_destroy(bar->wl_output);
free(bar); free(bar);
} }
static void static void
teardown_seat(Seat *seat) teardown_seat(Seat *seat)
{ {
wl_seat_destroy(seat->wl_seat);
if (seat->wl_pointer) if (seat->wl_pointer)
wl_pointer_destroy(seat->wl_pointer); wl_pointer_destroy(seat->wl_pointer);
wl_seat_destroy(seat->wl_seat);
free(seat); free(seat);
} }
@ -978,22 +961,21 @@ static void
handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
{ {
Bar *bar; Bar *bar;
DL_FOREACH(bar_list, bar)
if (bar->registry_name == name)
break;
if (bar) {
DL_DELETE(bar_list, bar);
teardown_bar(bar);
return;
}
Seat *seat; Seat *seat;
DL_FOREACH(seat_list, seat)
if (seat->registry_name == name) wl_list_for_each(bar, &bar_list, link) {
break; if (bar->registry_name == name) {
if (seat) { wl_list_remove(&bar->link);
DL_DELETE(seat_list, seat); teardown_bar(bar);
teardown_seat(seat); return;
}
}
wl_list_for_each(seat, &seat_list, link) {
if (seat->registry_name == name) {
wl_list_remove(&seat->link);
teardown_seat(seat);
return;
}
} }
} }
@ -1017,7 +999,7 @@ advance_word(char **beg, char **end)
#define ADVANCE() advance_word(&wordbeg, &wordend) #define ADVANCE() advance_word(&wordbeg, &wordend)
#define ADVANCE_IF_LAST_CONT() if (ADVANCE() == -1) continue #define ADVANCE_IF_LAST_CONT() if (ADVANCE() == -1) continue
#define ADVANCE_IF_LAST_BREAK() if (ADVANCE() == -1) break #define ADVANCE_IF_LAST_RET() if (ADVANCE() == -1) return
static void static void
read_stdin(void) read_stdin(void)
@ -1051,11 +1033,13 @@ read_stdin(void)
ADVANCE_IF_LAST_CONT(); ADVANCE_IF_LAST_CONT();
Bar *bar; Bar *it, *bar = NULL;
DL_FOREACH(bar_list, bar) wl_list_for_each(it, &bar_list, link) {
if (bar->xdg_output_name) if (it->xdg_output_name && !strcmp(wordbeg, it->xdg_output_name)) {
if (!strcmp(wordbeg, bar->xdg_output_name)) bar = it;
break; break;
}
}
if (!bar) if (!bar)
continue; continue;
@ -1092,8 +1076,8 @@ read_stdin(void)
} }
} else if (!strcmp(wordbeg, "selmon")) { } else if (!strcmp(wordbeg, "selmon")) {
ADVANCE(); ADVANCE();
if ((val = atoi(wordbeg)) != bar->selmon) { if ((val = atoi(wordbeg)) != bar->sel) {
bar->selmon = val; bar->sel = val;
bar->redraw = true; bar->redraw = true;
} }
} }
@ -1283,132 +1267,134 @@ read_socket(void)
return; return;
sockbuf[len] = '\0'; sockbuf[len] = '\0';
do { char *wordbeg, *wordend;
char *wordbeg, *wordend; wordend = (char *)&sockbuf;
wordend = (char *)&sockbuf;
ADVANCE_IF_LAST_BREAK(); ADVANCE_IF_LAST_RET();
Bar *bar; Bar *bar = NULL, *it;
bool all = false; bool all = false;
if (!strcmp(wordbeg, "all")) { if (!strcmp(wordbeg, "all")) {
all = true; all = true;
} else if (!strcmp(wordbeg, "selected")) { } else if (!strcmp(wordbeg, "selected")) {
DL_FOREACH(bar_list, bar) wl_list_for_each(it, &bar_list, link) {
if (bar->selmon) if (it->sel) {
break; bar = it;
} else if (!strcmp(wordbeg, "first")) {
bar = bar_list;
} else {
DL_FOREACH(bar_list, bar)
if (bar->xdg_output_name)
if (!strcmp(wordbeg, bar->xdg_output_name))
break;
}
if (!all && !bar)
break;
ADVANCE();
if (!strcmp(wordbeg, "status")) {
if (!wordend)
break; break;
if (all) { }
if (!bar_list) }
break; } else {
set_status(bar_list, wordend); wl_list_for_each(it, &bar_list, link) {
bar_list->redraw = true; if (it->xdg_output_name && !strcmp(wordbeg, it->xdg_output_name)) {
bar = it;
break;
}
}
}
if (!all && !bar)
return;
ADVANCE();
/* Copy over parsed status information to other bars */ if (!strcmp(wordbeg, "status")) {
DL_FOREACH(bar_list->next, bar) { if (!*wordend)
snprintf(bar->status, sizeof bar->status, "%s", bar_list->status); return;
if (all) {
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; bar->status_colors_l = bar->status_buttons_l = 0;
for (uint32_t i = 0; i < bar_list->status_colors_l; i++) { for (uint32_t i = 0; i < first->status_colors_l; i++) {
StatusColor *status_color; StatusColor *status_color;
ARRAY_APPEND(bar->status_colors, bar->status_colors_l, bar->status_colors_c, status_color); ARRAY_APPEND(bar->status_colors, bar->status_colors_l, bar->status_colors_c, status_color);
status_color->color = bar_list->status_colors[i].color; status_color->color = first->status_colors[i].color;
status_color->bg = bar_list->status_colors[i].bg; status_color->bg = first->status_colors[i].bg;
status_color->start = bar_list->status_colors[i].start - (char *)&bar_list->status + (char *)&bar->status; status_color->start = first->status_colors[i].start - (char *)&first->status + (char *)&bar->status;
} }
for (uint32_t i = 0; i < bar_list->status_buttons_l; i++) { for (uint32_t i = 0; i < first->status_buttons_l; i++) {
StatusButton *status_button; StatusButton *status_button;
ARRAY_APPEND(bar->status_buttons, bar->status_buttons_l, bar->status_buttons_c, status_button); ARRAY_APPEND(bar->status_buttons, bar->status_buttons_l, bar->status_buttons_c, status_button);
*status_button = bar_list->status_buttons[i]; *status_button = first->status_buttons[i];
} }
bar->redraw = true; } else {
set_status(bar, wordend);
first = bar;
} }
} else {
set_status(bar, wordend);
bar->redraw = true; bar->redraw = true;
} }
} else if (!strcmp(wordbeg, "show")) { } else {
if (all) { set_status(bar, wordend);
DL_FOREACH(bar_list, bar) bar->redraw = true;
if (bar->hidden) }
show_bar(bar); } else if (!strcmp(wordbeg, "show")) {
} else { if (all) {
wl_list_for_each(bar, &bar_list, link)
if (bar->hidden) if (bar->hidden)
show_bar(bar); show_bar(bar);
} } else {
} else if (!strcmp(wordbeg, "hide")) { if (bar->hidden)
if (all) { show_bar(bar);
DL_FOREACH(bar_list, bar) }
if (!bar->hidden) } else if (!strcmp(wordbeg, "hide")) {
hide_bar(bar); if (all) {
} else { wl_list_for_each(bar, &bar_list, link)
if (!bar->hidden) if (!bar->hidden)
hide_bar(bar); hide_bar(bar);
} } else {
} else if (!strcmp(wordbeg, "toggle-visibility")) { if (!bar->hidden)
if (all) { hide_bar(bar);
DL_FOREACH(bar_list, bar) }
if (bar->hidden) } else if (!strcmp(wordbeg, "toggle-visibility")) {
show_bar(bar); if (all) {
else wl_list_for_each(bar, &bar_list, link)
hide_bar(bar);
} else {
if (bar->hidden) if (bar->hidden)
show_bar(bar); show_bar(bar);
else else
hide_bar(bar); hide_bar(bar);
} } else {
} else if (!strcmp(wordbeg, "set-top")) { if (bar->hidden)
if (all) { show_bar(bar);
DL_FOREACH(bar_list, bar) else
if (bar->bottom) hide_bar(bar);
set_top(bar); }
} else if (!strcmp(wordbeg, "set-top")) {
} else { if (all) {
wl_list_for_each(bar, &bar_list, link)
if (bar->bottom) if (bar->bottom)
set_top(bar); set_top(bar);
}
} else if (!strcmp(wordbeg, "set-bottom")) {
if (all) {
DL_FOREACH(bar_list, bar)
if (!bar->bottom)
set_bottom(bar);
} else { } else {
if (bar->bottom)
set_top(bar);
}
} else if (!strcmp(wordbeg, "set-bottom")) {
if (all) {
wl_list_for_each(bar, &bar_list, link)
if (!bar->bottom) if (!bar->bottom)
set_bottom(bar); set_bottom(bar);
}
} else if (!strcmp(wordbeg, "toggle-location")) { } else {
if (all) { if (!bar->bottom)
DL_FOREACH(bar_list, bar) set_bottom(bar);
if (bar->bottom) }
set_top(bar); } else if (!strcmp(wordbeg, "toggle-location")) {
else if (all) {
set_bottom(bar); wl_list_for_each(bar, &bar_list, link)
} else {
if (bar->bottom) if (bar->bottom)
set_top(bar); set_top(bar);
else else
set_bottom(bar); set_bottom(bar);
} } else {
if (bar->bottom)
set_top(bar);
else
set_bottom(bar);
} }
} while (0); }
} }
static void static void
@ -1442,7 +1428,7 @@ event_loop(void)
read_stdin(); read_stdin();
Bar *bar; Bar *bar;
DL_FOREACH(bar_list, bar) { wl_list_for_each(bar, &bar_list, link) {
if (bar->redraw) { if (bar->redraw) {
if (!bar->hidden) if (!bar->hidden)
draw_frame(bar); draw_frame(bar);
@ -1571,6 +1557,10 @@ main(int argc, char **argv)
status_commands = true; status_commands = true;
} else if (!strcmp(argv[i], "-no-status-commands")) { } else if (!strcmp(argv[i], "-no-status-commands")) {
status_commands = false; 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], "-font")) { } else if (!strcmp(argv[i], "-font")) {
if (++i >= argc) if (++i >= argc)
DIE("Option -font requires an argument"); DIE("Option -font requires an argument");
@ -1643,6 +1633,9 @@ main(int argc, char **argv)
if (!display) if (!display)
DIE("Failed to create display"); DIE("Failed to create display");
wl_list_init(&bar_list);
wl_list_init(&seat_list);
struct wl_registry *registry = wl_display_get_registry(display); struct wl_registry *registry = wl_display_get_registry(display);
wl_registry_add_listener(registry, &registry_listener, NULL); wl_registry_add_listener(registry, &registry_listener, NULL);
wl_display_roundtrip(display); wl_display_roundtrip(display);
@ -1674,7 +1667,7 @@ main(int argc, char **argv)
} }
/* Setup bars */ /* Setup bars */
DL_FOREACH(bar_list, bar) wl_list_for_each(bar, &bar_list, link)
setup_bar(bar); setup_bar(bar);
wl_display_roundtrip(display); wl_display_roundtrip(display);
@ -1688,16 +1681,21 @@ main(int argc, char **argv)
EDIE("malloc"); EDIE("malloc");
stdinbuf_cap = 1024; stdinbuf_cap = 1024;
} }
/* Set up socket */ /* Set up socket */
for (uint32_t i = 0;; i++) { bool found = false;
for (uint32_t i = 0; i < 50; i++) {
if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 1)) == -1) if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 1)) == -1)
DIE("socket"); DIE("socket");
snprintf(sock_address.sun_path, sizeof sock_address.sun_path, "%s/dwlb-%i", socketdir, i); snprintf(sock_address.sun_path, sizeof sock_address.sun_path, "%s/dwlb-%i", socketdir, i);
if (connect(sock_fd, (struct sockaddr *)&sock_address, sizeof sock_address) == -1) if (connect(sock_fd, (struct sockaddr *)&sock_address, sizeof sock_address) == -1) {
found = true;
break; break;
}
close(sock_fd); close(sock_fd);
} }
if (!found)
DIE("Could not secure a socket path");
socketpath = (char *)&sock_address.sun_path; socketpath = (char *)&sock_address.sun_path;
unlink(socketpath); unlink(socketpath);
@ -1714,7 +1712,7 @@ main(int argc, char **argv)
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, SIG_IGN);
/* Run */ /* Run */
ready = true; run_display = true;
event_loop(); event_loop();
/* Clean everything up */ /* Clean everything up */
@ -1730,9 +1728,9 @@ main(int argc, char **argv)
free(tags); free(tags);
} }
DL_FOREACH_SAFE(bar_list, bar, bar2) wl_list_for_each_safe(bar, bar2, &bar_list, link)
teardown_bar(bar); teardown_bar(bar);
DL_FOREACH_SAFE(seat_list, seat, seat2) wl_list_for_each_safe(seat, seat2, &seat_list, link)
teardown_seat(seat); teardown_seat(seat);
zwlr_layer_shell_v1_destroy(layer_shell); zwlr_layer_shell_v1_destroy(layer_shell);