feat(ipc): add per-client tag event to zdwl_ipc_output_v2 v3

Adds `client` event reporting appid/title/tagmask once per managed
client per output during state-update batches. Closes the gap where
consumers could see per-tag client counts but not per-tag client
identities.

Bumps zdwl_ipc_output_v2 interface to v3 and zdwl_ipc_manager_v2
global advertisement to v3. Implementation localized to
dwl_ipc_output_printstatus_to in src/ext-protocol/dwl-ipc.h.
This commit is contained in:
dashdashRod 2026-05-01 14:28:50 -03:00
parent b9c6a2c196
commit 33eda01a07
3 changed files with 30 additions and 3 deletions

View file

@ -19,7 +19,7 @@ I would probably just submit raphi's patchset but I don't think that would be po
reset.
</description>
<interface name="zdwl_ipc_manager_v2" version="2">
<interface name="zdwl_ipc_manager_v2" version="3">
<description summary="manage dwl state">
This interface is exposed as a global in wl_registry.
@ -60,7 +60,7 @@ I would probably just submit raphi's patchset but I don't think that would be po
</event>
</interface>
<interface name="zdwl_ipc_output_v2" version="2">
<interface name="zdwl_ipc_output_v2" version="3">
<description summary="control dwl output">
Observe and control a dwl output.
@ -128,6 +128,17 @@ I would probably just submit raphi's patchset but I don't think that would be po
<arg name="appid" type="string" summary="The new appid."/>
</event>
<event name="client" since="3">
<description summary="Reports a client and its tag mask.">
Reports a single managed client on this output, with its appid, title,
and tag bitmask. Fired once per client per state-update batch, after
all tag events and before frame.
</description>
<arg name="appid" type="string" summary="The client's appid."/>
<arg name="title" type="string" summary="The client's title."/>
<arg name="tagmask" type="uint" summary="Bitmask of tags this client occupies."/>
</event>
<event name="layout_symbol" since="1">
<description summary="Update the current layout symbol">
Indicates the layout has changed. Since layout symbols are dynamic.

View file

@ -212,6 +212,21 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) {
}
zdwl_ipc_output_v2_send_frame(ipc_output->resource);
//recently added
if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_CLIENT_SINCE_VERSION) {
const char *c_appid, *c_title;
wl_list_for_each(c, &clients, link) {
if (c->mon != monitor)
continue;
c_appid = client_get_appid(c);
c_title = client_get_title(c);
zdwl_ipc_output_v2_send_client(ipc_output->resource,
c_appid ? c_appid : broken,
c_title ? c_title : broken,
c->tags);
}
}
}
void dwl_ipc_output_set_client_tags(struct wl_client *client,

View file

@ -5802,7 +5802,8 @@ void setup(void) {
wlr_log(WLR_INFO, "VR will not be available.");
}
wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL,
wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 3, NULL,
dwl_ipc_manager_bind);
// 创建顶层管理句柄