diff --git a/dam.c b/dam.c index a39613b..5a50e10 100644 --- a/dam.c +++ b/dam.c @@ -173,28 +173,6 @@ spawn(const Arg *arg) command_run(); } -static void -bar_hide(Bar *bar) -{ - zwlr_layer_surface_v1_destroy(bar->layer_surface); - wl_surface_destroy(bar->surface); - bar->configured = false; -} - -static void -bar_destroy(Bar *bar) -{ - wl_list_remove(&bar->link); - bufpool_cleanup(&bar->pool); - free(bar->layout); - free(bar->title); - drwl_setimage(bar->drw, NULL); - drwl_destroy(bar->drw); - zriver_output_status_v1_destroy(bar->output_status); - bar_hide(bar); - wl_output_destroy(bar->wl_output); -} - static void bar_load_fonts(Bar *bar) { @@ -206,6 +184,11 @@ bar_load_fonts(Bar *bar) die("failed to load fonts"); bar->lrpad = bar->drw->font->height; bar->height = bar->drw->font->height + 2; + + if (bar->layer_surface) { + zwlr_layer_surface_v1_set_size(bar->layer_surface, 0, bar->height / bar->scale); + zwlr_layer_surface_v1_set_exclusive_zone(bar->layer_surface, bar->height / bar->scale); + } } static void @@ -220,6 +203,7 @@ bar_draw(Bar *bar) if (!bar->configured) return; + errno = 0; if (!(buf = bufpool_getbuf(&bar->pool, shm, bar->width, bar->height))) die(errno ? "bufpool_getbuf:" : "no buffer available"); drwl_setimage(bar->drw, buf->image); @@ -280,80 +264,6 @@ bars_draw() bar_draw(bar); } -static void -layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, - uint32_t serial, uint32_t width, uint32_t height) -{ - Bar *bar = data; - - if (bar->configured) - return; - bar->width = width * bar->scale; - bar->height = height * bar->scale; - bar->configured = true; - zwlr_layer_surface_v1_ack_configure(bar->layer_surface, serial); - bar_draw(bar); -} - -static void -layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *layer_surface) -{ - Bar *bar = data; - bar_destroy(bar); -} - -static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { - .configure = layer_surface_configure, - .closed = layer_surface_closed, -}; - -static void -surface_handle_preferred_scale(void *data, - struct wl_surface *wl_surface, int32_t scale) -{ - Bar *bar = data; - bar->scale = scale; - bar_load_fonts(bar); - zwlr_layer_surface_v1_set_size(bar->layer_surface, 0, bar->height / bar->scale); -} - -static const struct wl_surface_listener surface_listener = { - .enter = noop, - .leave = noop, - .preferred_buffer_scale = surface_handle_preferred_scale, - .preferred_buffer_transform = noop, -}; - -static void -bar_show(Bar *bar) -{ - bar->surface = wl_compositor_create_surface(compositor); - wl_surface_add_listener(bar->surface, &surface_listener, NULL); - - bar->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - layer_shell, bar->surface, bar->wl_output, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "bar"); - zwlr_layer_surface_v1_add_listener( - bar->layer_surface, &layer_surface_listener, bar); - zwlr_layer_surface_v1_set_size(bar->layer_surface, 0, bar->height); - zwlr_layer_surface_v1_set_exclusive_zone(bar->layer_surface, bar->height); - zwlr_layer_surface_v1_set_anchor(bar->layer_surface, - (topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) - | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); - wl_surface_commit(bar->surface); -} - -static void -bars_toggle_selected() -{ - Bar *bar; - - wl_list_for_each(bar, &bars, link) { - if (bar == selbar && bar->configured) - bar_hide(bar); - else if (bar == selbar) - bar_show(bar); - } -} static void output_status_handle_focused_tags(void *data, @@ -429,6 +339,125 @@ static const struct zriver_output_status_v1_listener output_status_listener = { .layout_name_clear = output_status_handle_layout_name_clear }; +static void +bar_hide(Bar *bar) +{ + zwlr_layer_surface_v1_destroy(bar->layer_surface); + wl_surface_destroy(bar->surface); + bar->configured = false; +} + +static void +bar_destroy(Bar *bar) +{ + wl_list_remove(&bar->link); + bufpool_cleanup(&bar->pool); + free(bar->layout); + free(bar->title); + drwl_setimage(bar->drw, NULL); + drwl_destroy(bar->drw); + zriver_output_status_v1_destroy(bar->output_status); + bar_hide(bar); + wl_output_destroy(bar->wl_output); +} + +static void +layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, + uint32_t serial, uint32_t width, uint32_t height) +{ + Bar *bar = data; + + if (bar->width / bar->scale == width && bar->height / bar->scale == height) + return; + + bar->width = width * bar->scale; + bar->height = height * bar->scale; + bar->configured = true; + zwlr_layer_surface_v1_ack_configure(bar->layer_surface, serial); + bar_draw(bar); +} + +static void +layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *layer_surface) +{ + Bar *bar = data; + bar_destroy(bar); +} + +static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .configure = layer_surface_configure, + .closed = layer_surface_closed, +}; + +static void +bar_show(Bar *bar) +{ + bar->surface = wl_compositor_create_surface(compositor); + + bar->layer_surface = zwlr_layer_shell_v1_get_layer_surface( + layer_shell, bar->surface, bar->wl_output, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "bar"); + zwlr_layer_surface_v1_add_listener( + bar->layer_surface, &layer_surface_listener, bar); + zwlr_layer_surface_v1_set_size(bar->layer_surface, 0, bar->height / bar->scale); + zwlr_layer_surface_v1_set_exclusive_zone(bar->layer_surface, bar->height / bar->scale); + zwlr_layer_surface_v1_set_anchor(bar->layer_surface, + (topbar ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM) + | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT); + wl_surface_commit(bar->surface); +} + +static void +bars_toggle_selected() +{ + Bar *bar; + + wl_list_for_each(bar, &bars, link) { + if (bar == selbar && bar->configured) + bar_hide(bar); + else if (bar == selbar) + bar_show(bar); + } +} + +static void +output_handle_done(void *data, struct wl_output *wl_output) +{ + Bar *bar = data; + + if (bar->drw) + return; + + if (!(bar->drw = drwl_create())) + die("failed to create drwl context"); + bar_load_fonts(bar); + + bar->output_status = zriver_status_manager_v1_get_river_output_status( + status_manager, bar->wl_output); + zriver_output_status_v1_add_listener(bar->output_status, + &output_status_listener, bar); + + if (showbar) + bar_show(bar); +} + +static void +output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) +{ + Bar *bar = data; + + bar->scale = factor; + if (bar->drw) + bar_load_fonts(bar); +} + +static const struct wl_output_listener output_listener = { + .geometry = noop, + .mode = noop, + .done = output_handle_done, + .scale = output_handle_scale, + .name = noop, + .description = noop, +}; static void seat_status_handle_focused_output(void *data, @@ -493,9 +522,12 @@ static void pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - pointer.x = wl_fixed_to_int(surface_x); - pointer.y = wl_fixed_to_int(surface_y); pointer.button = 0; + if (!selbar) + return; + + pointer.x = wl_fixed_to_int(surface_x) * selbar->scale; + pointer.y = wl_fixed_to_int(surface_y) * selbar->scale; } static void @@ -506,7 +538,7 @@ pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) unsigned int i = 0, x = 0; unsigned int tag, click; - if (!pointer.button || !selbar) + if (!pointer.button) return; lw = TEXTW(selbar, selbar->layout); @@ -581,9 +613,9 @@ registry_handle_global(void *data, struct wl_registry *wl_registry, else if (!strcmp(interface, wl_shm_interface.name)) shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); else if (!strcmp(interface, zwlr_layer_shell_v1_interface.name)) - layer_shell = wl_registry_bind(wl_registry, name, &zwlr_layer_shell_v1_interface, 2); + layer_shell = wl_registry_bind(wl_registry, name, &zwlr_layer_shell_v1_interface, 3); else if (!strcmp(interface, wl_seat_interface.name)) { - seat = wl_registry_bind(registry, name, &wl_seat_interface, 5); + seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); wl_seat_add_listener(seat, &seat_listener, NULL); } else if (!strcmp(interface, zriver_control_v1_interface.name)) control = wl_registry_bind(registry, name, &zriver_control_v1_interface, 1); @@ -594,6 +626,7 @@ registry_handle_global(void *data, struct wl_registry *wl_registry, bar->scale = 1; bar->wl_name = name; bar->wl_output = wl_registry_bind(registry, name, &wl_output_interface, 2); + wl_output_add_listener(bar->wl_output, &output_listener, bar); wl_list_insert(&bars, &bar->link); } } @@ -634,7 +667,6 @@ static void setup(void) { sigset_t mask; - Bar *bar; if (!(display = wl_display_connect(NULL))) die("failed to connect to wayland"); @@ -663,20 +695,6 @@ setup(void) status_manager, seat); zriver_seat_status_v1_add_listener(seat_status, &seat_status_listener, NULL); - - wl_list_for_each(bar, &bars, link) { - if (!(bar->drw = drwl_create())) - die("failed to create drwl context"); - bar_load_fonts(bar); - - bar->output_status = zriver_status_manager_v1_get_river_output_status( - status_manager, bar->wl_output); - zriver_output_status_v1_add_listener(bar->output_status, - &output_status_listener, bar); - - if (showbar) - bar_show(bar); - } } static void