module/river: add support for the ‘mode’ event

Seat status v3 adds a new ‘mode’ event, that informs us of the current
mode (as set by e.g. ‘riverctl enter-mode passthrough’)

The mode is exposed as a tag (named “mode”) on river’s “title”
particle:

  - river:
      title:
        map:
          default: {empty: {}}
          conditions:
            mode == passthrough:
              string: {text: " {mode} ", deco: {background: {color: ff0000ff}}}
This commit is contained in:
Daniel Eklöf 2022-06-02 17:24:42 +02:00
parent a3a0334069
commit c738f1c63d
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 60 additions and 7 deletions

View file

@ -19,6 +19,10 @@
* font-shaping: new inheritable configuration option, allowing you to
configure whether strings should be _shaped_ using HarfBuzz, or not
([#159][159]).
* river: support for the new “mode” event present in version 3 of the
river status manager protocol, in the form of a new tag, _”mode”_,
in the `title` particle.
[153]: https://codeberg.org/dnkl/yambar/issues/153
[159]: https://codeberg.org/dnkl/yambar/issues/159

View file

@ -13,13 +13,14 @@ It has an interface similar to the i3/sway module.
The configuration for the river module specifies one _title_ particle,
which will be instantiated once for each seat, with tags representing
the seats' name and the title of the seats' currently focused view.
the seats' name, the title of the seats' currently focused view, and
its current river "mode".
It also specifies a _content_ template particle, which is instantiated
once for all 32 river tags. This means you probably want to use a
*map* particle to hide unused river tags.
# TAGS
# TAGS (for the "content" particle)
[[ *Name*
:[ *Type*
@ -42,12 +43,23 @@ once for all 32 river tags. This means you probably want to use a
| state
: string
: Set to *urgent* if _urgent_ is true, *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.
# TAGS (for the "title" particle)
[[ *Name*
:[ *Type*
:[ *Description*
| seat
: string
: The name of the seat (*title* particle only, see CONFIGURATION)
| title
: string
: The seat's focused view's title (*title* particle only, see CONFIGURATION)
| mode
: string
: The seat's current mode (entered with e.g. *riverctl enter-mode foobar*)
# CONFIGURATION
@ -76,7 +88,7 @@ once for all 32 river tags. This means you probably want to use a
bar:
left:
- river:
title: {string: { text: "{seat} - {title}" }}
title: {string: { text: "{seat} - {title} ({mode})" }}
content:
map:
conditions:

View file

@ -16,7 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
</copyright>
<interface name="zriver_status_manager_v1" version="2">
<interface name="zriver_status_manager_v1" version="3">
<description summary="manage river status objects">
A global factory for objects that receive status information specific
to river. It could be used to implement, for example, a status bar.
@ -85,7 +85,7 @@
</event>
</interface>
<interface name="zriver_seat_status_v1" version="1">
<interface name="zriver_seat_status_v1" version="3">
<description summary="track seat focus">
This interface allows clients to receive information about the current
focus of a seat. Note that (un)focused_output events will only be sent
@ -121,5 +121,13 @@
</description>
<arg name="title" type="string" summary="title of the focused view"/>
</event>
<event name="mode" since="3">
<description summary="the active mode changed">
Sent once on binding the interface and again whenever a new mode
is entered (e.g. with riverctl enter-mode foobar).
</description>
<arg name="name" type="string" summary="name of the mode"/>
</event>
</interface>
</protocol>

View file

@ -16,6 +16,8 @@
#include "river-status-unstable-v1.h"
#include "xdg-output-unstable-v1.h"
#define min(x, y) ((x) < (y) ? (x) : (y))
struct private;
struct output {
@ -39,6 +41,7 @@ struct seat {
uint32_t wl_name;
char *name;
char *mode;
char *title;
struct output *output;
};
@ -158,8 +161,9 @@ content(struct module *mod)
.tags = (struct tag *[]){
tag_new_string(mod, "seat", seat->name),
tag_new_string(mod, "title", seat->title),
tag_new_string(mod, "mode", seat->mode),
},
.count = 2,
.count = 3,
};
tag_parts[i++] = m->title->instantiate(m->title, &tags);
@ -199,6 +203,7 @@ seat_destroy(struct seat *seat)
{
free(seat->title);
free(seat->name);
free(seat->mode);
if (seat->status != NULL)
zriver_seat_status_v1_destroy(seat->status);
if (seat->wl_seat != NULL)
@ -435,10 +440,34 @@ focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
}
}
#if defined(ZRIVER_SEAT_STATUS_V1_MODE_SINCE_VERSION)
static void
mode(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
const char *name)
{
struct seat *seat = data;
struct module *mod = seat->m->mod;
mtx_lock(&mod->lock);
{
free(seat->mode);
seat->mode = strdup(name);
mtx_unlock(&mod->lock);
}
mod->bar->refresh(mod->bar);
LOG_DBG("seat: %s, current mode: %s", seat->name, seat->mode);
}
#endif
static const struct zriver_seat_status_v1_listener river_seat_status_listener = {
.focused_output = &focused_output,
.unfocused_output = &unfocused_output,
.focused_view = &focused_view,
#if defined(ZRIVER_SEAT_STATUS_V1_MODE_SINCE_VERSION)
.mode = &mode,
#endif
};
static void
@ -557,7 +586,7 @@ handle_global(void *data, struct wl_registry *registry,
return;
m->status_manager = wl_registry_bind(
registry, name, &zriver_status_manager_v1_interface, required);
registry, name, &zriver_status_manager_v1_interface, min(version, 3));
mtx_lock(&m->mod->lock);
tll_foreach(m->outputs, it)