bar: allow user to specify _which_ monitor to place the bar on

If not specified, the primary monitor will be used.
This commit is contained in:
Daniel Eklöf 2019-01-20 22:05:12 +01:00
parent ef04097bef
commit f26892d938
5 changed files with 35 additions and 5 deletions

View file

@ -42,7 +42,7 @@
**f00bar** is a light-weight and configurable status panel (_bar_, for
short) for X.
It has a number of _modules_ that provides information in the form of
It has a number of _modules_ that provide information in the form of
_tags_. For example, the _clock_ module has a _date_ tag that contains
the current date.
@ -161,6 +161,8 @@ There are a couple types used that are specific to f00bar.
be self-explanatory.
- `background` (_color_, **required**): background color, in
_rgba_. Thus, in the example above, the background is set to _black_
- `monitor` (_string_): monitor to place the bar. If not specified,
the primary monitor will be used.
- `left-spacing` (_int_): space, in pixels, added **before** each module
- `right-spacing` (_int_): space, in pixels, added **after** each module
- `spacing` (_int_): short-hand for setting both `left-spacing` and

29
bar.c
View file

@ -30,6 +30,7 @@
struct private {
/* From bar_config */
char *monitor;
enum bar_location location;
int height;
int left_spacing, right_spacing;
@ -339,11 +340,18 @@ run(struct bar *_bar)
bar->conn,
xcb_randr_get_monitors(bar->conn, screen->root, 0),
&e);
assert(e == NULL);
if (e != NULL) {
LOG_ERR("failed to get monitor list: %s", xcb_error(e));
free(e);
/* TODO: cleanup (disconnect) */
return 1;
}
bar->height_with_border = bar->height + 2 * bar->border.width;
/* Find monitor coordinates and width/height */
bool found_monitor = false;
for (xcb_randr_monitor_info_iterator_t it =
xcb_randr_get_monitors_monitors_iterator(monitors);
it.rem > 0;
@ -356,20 +364,31 @@ run(struct bar *_bar)
mon->width, mon->height, mon->x, mon->y,
mon->width_in_millimeters, mon->height_in_millimeters);
free(name);
if (!mon->primary)
if (!((bar->monitor == NULL && mon->primary) ||
(bar->monitor != NULL && strcmp(bar->monitor, name) == 0)))
{
free(name);
continue;
}
free(name);
bar->x = mon->x;
bar->y = mon->y;
bar->width = mon->width;
bar->y += bar->location == BAR_TOP ? 0
: screen->height_in_pixels - bar->height_with_border;
found_monitor = true;
break;
}
free(monitors);
if (!found_monitor) {
LOG_ERR("no matching monitor");
/* TODO: cleanup */
return 1;
}
uint8_t depth = 0;
xcb_visualtype_t *vis = xcb_aux_find_visual_by_attrs(screen, -1, 32);
@ -690,6 +709,7 @@ destroy(struct bar *bar)
free(b->center.exps);
free(b->right.mods);
free(b->right.exps);
free(b->monitor);
free(bar->private);
free(bar);
@ -699,6 +719,7 @@ struct bar *
bar_new(const struct bar_config *config)
{
struct private *priv = malloc(sizeof(*priv));
priv->monitor = config->monitor != NULL ? strdup(config->monitor) : NULL;
priv->location = config->location;
priv->height = config->height;
priv->background = config->background;

1
bar.h
View file

@ -17,6 +17,7 @@ struct bar {
enum bar_location { BAR_TOP, BAR_BOTTOM };
struct bar_config {
const char *monitor;
enum bar_location location;
int height;
int left_spacing, right_spacing;

View file

@ -359,6 +359,8 @@ conf_verify_bar(const struct yml_node *bar)
{"location", true, &verify_bar_location},
{"background", true, &conf_verify_color},
{"monitor", false, &conf_verify_string},
{"spacing", false, &conf_verify_int},
{"left-spacing", false, &conf_verify_int},
{"right-spacing", false, &conf_verify_int},

View file

@ -194,6 +194,10 @@ conf_to_bar(const struct yml_node *bar)
* Optional attributes
*/
const struct yml_node *monitor = yml_get_value(bar, "monitor");
if (monitor != NULL)
conf.monitor = yml_value_as_string(monitor);
const struct yml_node *spacing = yml_get_value(bar, "spacing");
if (spacing != NULL)
conf.left_spacing = conf.right_spacing = yml_value_as_int(spacing);