Merge branch 'river-per-output'

This commit is contained in:
Daniel Eklöf 2021-08-09 19:56:57 +02:00
commit 315044d342
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
10 changed files with 82 additions and 12 deletions

View file

@ -17,6 +17,7 @@
individually. `border.width` is now a short-hand for setting all individually. `border.width` is now a short-hand for setting all
four borders to the same value four borders to the same value
(https://codeberg.org/dnkl/yambar/issues/77). (https://codeberg.org/dnkl/yambar/issues/77).
* river: `per-output: false|true`.
### Changed ### Changed

View file

@ -14,4 +14,5 @@ struct backend {
void (*commit)(const struct bar *bar); void (*commit)(const struct bar *bar);
void (*refresh)(const struct bar *bar); void (*refresh)(const struct bar *bar);
void (*set_cursor)(struct bar *bar, const char *cursor); void (*set_cursor)(struct bar *bar, const char *cursor);
const char *(*output_name)(const struct bar *bar);
}; };

View file

@ -162,6 +162,13 @@ set_cursor(struct bar *bar, const char *cursor)
b->backend.iface->set_cursor(bar, cursor); b->backend.iface->set_cursor(bar, cursor);
} }
static const char *
output_name(const struct bar *bar)
{
const struct private *b = bar->private;
return b->backend.iface->output_name(bar);
}
static void static void
on_mouse(struct bar *_bar, enum mouse_event event, enum mouse_button btn, on_mouse(struct bar *_bar, enum mouse_event event, enum mouse_button btn,
int x, int y) int x, int y)
@ -456,6 +463,7 @@ bar_new(const struct bar_config *config)
bar->destroy = &destroy; bar->destroy = &destroy;
bar->refresh = &refresh; bar->refresh = &refresh;
bar->set_cursor = &set_cursor; bar->set_cursor = &set_cursor;
bar->output_name = &output_name;
for (size_t i = 0; i < priv->left.count; i++) for (size_t i = 0; i < priv->left.count; i++)
priv->left.mods[i]->bar = bar; priv->left.mods[i]->bar = bar;

View file

@ -12,6 +12,8 @@ struct bar {
void (*refresh)(const struct bar *bar); void (*refresh)(const struct bar *bar);
void (*set_cursor)(struct bar *bar, const char *cursor); void (*set_cursor)(struct bar *bar, const char *cursor);
const char *(*output_name)(const struct bar *bar);
}; };
enum bar_location { BAR_TOP, BAR_BOTTOM }; enum bar_location { BAR_TOP, BAR_BOTTOM };

View file

@ -1308,6 +1308,15 @@ set_cursor(struct bar *_bar, const char *cursor)
update_cursor_surface(backend, seat); update_cursor_surface(backend, seat);
} }
static const char *
output_name(const struct bar *_bar)
{
const struct private *bar = _bar->private;
const struct wayland_backend *backend = bar->backend.data;
return backend->monitor != NULL ? backend->monitor->name : NULL;
}
const struct backend wayland_backend_iface = { const struct backend wayland_backend_iface = {
.setup = &setup, .setup = &setup,
.cleanup = &cleanup, .cleanup = &cleanup,
@ -1315,4 +1324,5 @@ const struct backend wayland_backend_iface = {
.commit = &commit, .commit = &commit,
.refresh = &refresh, .refresh = &refresh,
.set_cursor = &set_cursor, .set_cursor = &set_cursor,
.output_name = &output_name,
}; };

View file

@ -462,6 +462,13 @@ set_cursor(struct bar *_bar, const char *cursor)
backend->conn, backend->win, XCB_CW_CURSOR, &backend->cursor); backend->conn, backend->win, XCB_CW_CURSOR, &backend->cursor);
} }
static const char *
output_name(const struct bar *_bar)
{
/* Not implemented */
return NULL;
}
const struct backend xcb_backend_iface = { const struct backend xcb_backend_iface = {
.setup = &setup, .setup = &setup,
.cleanup = &cleanup, .cleanup = &cleanup,
@ -469,4 +476,5 @@ const struct backend xcb_backend_iface = {
.commit = &commit, .commit = &commit,
.refresh = &refresh, .refresh = &refresh,
.set_cursor = &set_cursor, .set_cursor = &set_cursor,
.output_name = &output_name,
}; };

View file

@ -50,6 +50,17 @@ conf_verify_int(keychain_t *chain, const struct yml_node *node)
return false; return false;
} }
bool
conf_verify_bool(keychain_t *chain, const struct yml_node *node)
{
if (yml_value_is_bool(node))
return true;
LOG_ERR("%s: value is not a boolean: '%s'",
conf_err_prefix(chain, node), yml_value_as_string(node));
return false;
}
bool bool
conf_verify_list(keychain_t *chain, const struct yml_node *node, conf_verify_list(keychain_t *chain, const struct yml_node *node,
bool (*verify)(keychain_t *chain, const struct yml_node *node)) bool (*verify)(keychain_t *chain, const struct yml_node *node))

View file

@ -32,6 +32,7 @@ const char *conf_err_prefix(
bool conf_verify_string(keychain_t *chain, const struct yml_node *node); bool conf_verify_string(keychain_t *chain, const struct yml_node *node);
bool conf_verify_int(keychain_t *chain, const struct yml_node *node); bool conf_verify_int(keychain_t *chain, const struct yml_node *node);
bool conf_verify_bool(keychain_t *chain, const struct yml_node *node);
bool conf_verify_enum(keychain_t *chain, const struct yml_node *node, bool conf_verify_enum(keychain_t *chain, const struct yml_node *node,
const char *values[], size_t count); const char *values[], size_t count);

View file

@ -12,8 +12,8 @@ about the river tags.
It has an interface similar to the i3/sway module. It has an interface similar to the i3/sway module.
The configuration for the river module specifies one _title_ particle, The configuration for the river module specifies one _title_ particle,
which will be instantiated with tags representing the currently active which will be instantiated once for each seat, with tags representing
seat and the currently focused view's title. the seats' name and the title of the seats' currently focused view.
It also specifies a _content_ template particle, which is instantiated It also specifies a _content_ template particle, which is instantiated
once for all 32 river tags. This means you probably want to use a once for all 32 river tags. This means you probably want to use a
@ -41,10 +41,10 @@ once for all 32 river tags. This means you probably want to use a
: Set to *focused* if _focused_ is true, *unfocused* if _visible_ is true, but _focused_ is false, or *invisible* if the river tag is not visible on any monitors. : Set to *focused* if _focused_ is true, *unfocused* if _visible_ is true, but _focused_ is false, or *invisible* if the river tag is not visible on any monitors.
| seat | seat
: string : string
: The name of the currently active seat (*title* particle only, see CONFIGURATION) : The name of the seat (*title* particle only, see CONFIGURATION)
| title | title
: string : string
: The focused view's title (*title* particle only, see CONFIGURATION) : The seat's focused view's title (*title* particle only, see CONFIGURATION)
# CONFIGURATION # CONFIGURATION
@ -60,6 +60,12 @@ once for all 32 river tags. This means you probably want to use a
: particle : particle
: yes : yes
: Template particle that will be instantiated once for all of the 32 river tags. : Template particle that will be instantiated once for all of the 32 river tags.
| per-output
: bool
: no
: When set to false (the default), tags reflect the union of all
outputs. When set to true, tags reflect river tags and seats for
the output yambar is on only.
# EXAMPLES # EXAMPLES

View file

@ -48,6 +48,7 @@ struct private {
struct zriver_status_manager_v1 *status_manager; struct zriver_status_manager_v1 *status_manager;
struct particle *template; struct particle *template;
struct particle *title; struct particle *title;
bool per_output;
bool is_starting_up; bool is_starting_up;
tll(struct output) outputs; tll(struct output) outputs;
@ -76,6 +77,8 @@ content(struct module *mod)
{ {
const struct private *m = mod->private; const struct private *m = mod->private;
const char *output_bar_is_on = mod->bar->output_name(mod->bar);
mtx_lock(&m->mod->lock); mtx_lock(&m->mod->lock);
uint32_t output_focused = 0; uint32_t output_focused = 0;
@ -85,6 +88,13 @@ content(struct module *mod)
tll_foreach(m->outputs, it) { tll_foreach(m->outputs, it) {
const struct output *output = &it->item; const struct output *output = &it->item;
if (m->per_output &&
output_bar_is_on != NULL && output->name != NULL &&
strcmp(output->name, output_bar_is_on) != 0)
{
continue;
}
output_focused |= output->focused; output_focused |= output->focused;
occupied |= output->occupied; occupied |= output->occupied;
@ -348,7 +358,6 @@ unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1
mtx_lock(&mod->lock); mtx_lock(&mod->lock);
{ {
struct output *output = NULL; struct output *output = NULL;
tll_foreach(m->outputs, it) { tll_foreach(m->outputs, it) {
if (it->item.wl_output == wl_output) { if (it->item.wl_output == wl_output) {
@ -382,13 +391,21 @@ focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
LOG_DBG("seat: %s: focused view: %s", seat->name, title); LOG_DBG("seat: %s: focused view: %s", seat->name, title);
mtx_lock(&mod->lock); const char *output_bar_is_on = mod->bar->output_name(mod->bar);
if (!seat->m->per_output ||
(output_bar_is_on != NULL &&
seat->output != NULL && seat->output->name != NULL &&
strcmp(output_bar_is_on, seat->output->name) == 0))
{ {
free(seat->title); mtx_lock(&mod->lock);
seat->title = title != NULL ? strdup(title) : NULL; {
free(seat->title);
seat->title = title != NULL ? strdup(title) : NULL;
}
mtx_unlock(&mod->lock);
mod->bar->refresh(mod->bar);
} }
mtx_unlock(&mod->lock);
mod->bar->refresh(mod->bar);
} }
static const struct zriver_seat_status_v1_listener river_seat_status_listener = { static const struct zriver_seat_status_v1_listener river_seat_status_listener = {
@ -646,11 +663,12 @@ out:
} }
static struct module * static struct module *
river_new(struct particle *template, struct particle *title) river_new(struct particle *template, struct particle *title, bool per_output)
{ {
struct private *m = calloc(1, sizeof(*m)); struct private *m = calloc(1, sizeof(*m));
m->template = template; m->template = template;
m->title = title; m->title = title;
m->per_output = per_output;
m->is_starting_up = true; m->is_starting_up = true;
struct module *mod = module_common_new(); struct module *mod = module_common_new();
@ -668,9 +686,12 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
{ {
const struct yml_node *c = yml_get_value(node, "content"); const struct yml_node *c = yml_get_value(node, "content");
const struct yml_node *title = yml_get_value(node, "title"); const struct yml_node *title = yml_get_value(node, "title");
const struct yml_node *per_output = yml_get_value(node, "per-output");
return river_new( return river_new(
conf_to_particle(c, inherited), conf_to_particle(c, inherited),
title != NULL ? conf_to_particle(title, inherited) : NULL); title != NULL ? conf_to_particle(title, inherited) : NULL,
per_output != NULL ? yml_value_as_bool(per_output) : false);
} }
static bool static bool
@ -678,6 +699,7 @@ verify_conf(keychain_t *chain, const struct yml_node *node)
{ {
static const struct attr_info attrs[] = { static const struct attr_info attrs[] = {
{"title", false, &conf_verify_particle}, {"title", false, &conf_verify_particle},
{"per-output", false, &conf_verify_bool},
MODULE_COMMON_ATTRS, MODULE_COMMON_ATTRS,
}; };