river-layout: add user_command_tags event

It is not guaranteed that the next layout_demand event after a user_command
event has the same active tags (for example when there are no views visible).
As an example, a user could trigger a user_command while no views are visible,
then switch to a different tag set which has active views. The active tags of
the previous layout_demand may also be different.

Therefore it is impossible to correctly implement a layout generator which has
user commands apply only to the currently active tag set, which is solved by
this patch.
This commit is contained in:
Leon Henrik Plickat 2022-08-14 16:34:18 +02:00 committed by Isaac Freund
parent 416fdc8d06
commit 844ffce037
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
4 changed files with 22 additions and 3 deletions

View File

@ -111,7 +111,7 @@ pub fn build(b: *zbs.Builder) !void {
scanner.generate("zriver_control_v1", 1); scanner.generate("zriver_control_v1", 1);
scanner.generate("zriver_status_manager_v1", 3); scanner.generate("zriver_status_manager_v1", 3);
scanner.generate("river_layout_manager_v3", 1); scanner.generate("river_layout_manager_v3", 2);
scanner.generate("zwlr_layer_shell_v1", 4); scanner.generate("zwlr_layer_shell_v1", 4);
scanner.generate("zwlr_output_power_manager_v1", 1); scanner.generate("zwlr_output_power_manager_v1", 1);

View File

@ -38,7 +38,7 @@
can only be done by creating a new major version of the extension. can only be done by creating a new major version of the extension.
</description> </description>
<interface name="river_layout_manager_v3" version="1"> <interface name="river_layout_manager_v3" version="2">
<description summary="manage river layout objects"> <description summary="manage river layout objects">
A global factory for river_layout_v3 objects. A global factory for river_layout_v3 objects.
</description> </description>
@ -71,7 +71,7 @@
</request> </request>
</interface> </interface>
<interface name="river_layout_v3" version="1"> <interface name="river_layout_v3" version="2">
<description summary="receive and respond to layout demands"> <description summary="receive and respond to layout demands">
This interface allows clients to receive layout demands from the This interface allows clients to receive layout demands from the
compositor for a specific output and subsequently propose positions and compositor for a specific output and subsequently propose positions and
@ -174,8 +174,23 @@
A layout_demand will be sent after this event if the compositor is A layout_demand will be sent after this event if the compositor is
currently using this layout object to arrange the output. currently using this layout object to arrange the output.
If version 2 or higher of the river_layout_v3 object is bound, the
user_command_tags event is guaranteed to be sent directly before the
user_command event.
</description> </description>
<arg name="command" type="string"/> <arg name="command" type="string"/>
</event> </event>
<event name="user_command_tags" since="2">
<description summary="a command sent by the user">
If version 2 or higher of the river_layout_v3 object is bound, this
event will be sent directly before every user_command event. This allows
layout generators to be aware of the active tags when a user command is
sent. This is necessary for generators wanting to keep settings on a
per-tag basis.
</description>
<arg name="tags" type="uint" summary="tags of the output, 32-bit bitfield"/>
</event>
</interface> </interface>
</protocol> </protocol>

View File

@ -76,6 +76,9 @@ pub fn sendLayoutCmd(
if (mem.eql(u8, layout.namespace, target_namespace)) break layout; if (mem.eql(u8, layout.namespace, target_namespace)) break layout;
} else return; } else return;
if (layout.layout.getVersion() >= 2) {
layout.layout.sendUserCommandTags(output.pending.tags);
}
layout.layout.sendUserCommand(args[2]); layout.layout.sendUserCommand(args[2]);
if (layout == output.current.layout) output.arrangeViews(); if (layout == output.current.layout) output.arrangeViews();
} }

View File

@ -298,6 +298,7 @@ const Output = struct {
.bottom => layout.commit("rivertile - bottom", ev.serial), .bottom => layout.commit("rivertile - bottom", ev.serial),
} }
}, },
.user_command_tags => {},
} }
} }
}; };