river: add fullscreen rule

This commit adds a fullscreen rule for configuring
whether the view should be drawn fullscreen on start up.

The actions "fullscreen" and "no-fullscreen" map to the two
possible state of a view and semantically operate on the same
rule list. The behavior of adding, deleting and listing rules
follows that of float and ssd.
This commit is contained in:
polykernel 2023-11-06 10:53:44 -05:00
parent a0ea456ab2
commit 2b463c9e4d
No known key found for this signature in database
6 changed files with 34 additions and 9 deletions

View File

@ -1,6 +1,6 @@
function __riverctl_completion () function __riverctl_completion ()
{ {
local rule_actions="float no-float ssd csd tag output position dimensions" local rule_actions="float no-float ssd csd tag output position dimensions fullscreen no-fullscreen"
if [ "${COMP_CWORD}" -eq 1 ] if [ "${COMP_CWORD}" -eq 1 ]
then then
OPTS=" \ OPTS=" \
@ -66,7 +66,7 @@ function __riverctl_completion ()
"move"|"snap") OPTS="up down left right" ;; "move"|"snap") OPTS="up down left right" ;;
"resize") OPTS="horizontal vertical" ;; "resize") OPTS="horizontal vertical" ;;
"rule-add"|"rule-del") OPTS="-app-id -title $rule_actions" ;; "rule-add"|"rule-del") OPTS="-app-id -title $rule_actions" ;;
"list-rules") OPTS="float ssd tag output position dimensions" ;; "list-rules") OPTS="float ssd tag output position dimensions fullscreen" ;;
"map") OPTS="-release -repeat -layout" ;; "map") OPTS="-release -repeat -layout" ;;
"unmap") OPTS="-release" ;; "unmap") OPTS="-release" ;;
"attach-mode") OPTS="top bottom" ;; "attach-mode") OPTS="top bottom" ;;

View File

@ -88,10 +88,10 @@ complete -c riverctl -n '__fish_seen_subcommand_from unmap'
complete -c riverctl -n '__fish_seen_subcommand_from attach-mode' -n '__fish_riverctl_complete_arg 2' -a 'top bottom' complete -c riverctl -n '__fish_seen_subcommand_from attach-mode' -n '__fish_riverctl_complete_arg 2' -a 'top bottom'
complete -c riverctl -n '__fish_seen_subcommand_from focus-follows-cursor' -n '__fish_riverctl_complete_arg 2' -a 'disabled normal always' complete -c riverctl -n '__fish_seen_subcommand_from focus-follows-cursor' -n '__fish_riverctl_complete_arg 2' -a 'disabled normal always'
complete -c riverctl -n '__fish_seen_subcommand_from set-cursor-warp' -n '__fish_riverctl_complete_arg 2' -a 'disabled on-output-change on-focus-change' complete -c riverctl -n '__fish_seen_subcommand_from set-cursor-warp' -n '__fish_riverctl_complete_arg 2' -a 'disabled on-output-change on-focus-change'
complete -c riverctl -n '__fish_seen_subcommand_from list-rules' -n '__fish_riverctl_complete_arg 2' -a 'float ssd tag output position dimensions' complete -c riverctl -n '__fish_seen_subcommand_from list-rules' -n '__fish_riverctl_complete_arg 2' -a 'float ssd tag output position dimensions fullscreen'
# Options and subcommands for 'rule-add' and 'rule-del' # Options and subcommands for 'rule-add' and 'rule-del'
set -l rule_actions float no-float ssd csd tag output position dimensions set -l rule_actions float no-float ssd csd tag output position dimensions fullscreen no-fullscreen
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o app-id' -o 'app-id' -r complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o app-id' -o 'app-id' -r
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o title' -o 'title' -r complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'not __fish_seen_argument -o title' -o 'title' -r
complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'test (math (count (commandline -opc)) % 2) -eq 0' -a "$rule_actions" complete -c riverctl -n '__fish_seen_subcommand_from rule-add rule-del' -n "not __fish_seen_subcommand_from $rule_actions" -n 'test (math (count (commandline -opc)) % 2) -eq 0' -a "$rule_actions"

View File

@ -183,9 +183,9 @@ _riverctl()
# In case of a new rule added in river, we just need # In case of a new rule added in river, we just need
# to add it to the third option between '()', # to add it to the third option between '()',
# i.e (float no-float <new-option>) # i.e (float no-float <new-option>)
_arguments '1: :(-app-id -title)' '2: : ' ':: :(float no-float ssd csd tag output position dimensions)' _arguments '1: :(-app-id -title)' '2: : ' ':: :(float no-float ssd csd tag output position dimensions fullscreen no-fullscreen)'
;; ;;
list-rules) _alternative 'arguments:args:(float ssd tag output position dimensions)' ;; list-rules) _alternative 'arguments:args:(float ssd tag output position dimensions fullscreen)' ;;
*) return 0 ;; *) return 0 ;;
esac esac
;; ;;

View File

@ -311,7 +311,7 @@ matches everything while _\*\*_ and the empty string are invalid.
Both *float* and *no-float* rules are added to the same list, Both *float* and *no-float* rules are added to the same list,
which means that adding a *no-float* rule with the same arguments which means that adding a *no-float* rule with the same arguments
as a *float* rule will overwrite it. The same holds for *ssd* and as a *float* rule will overwrite it. The same holds for *ssd* and
*csd* rules. *csd*, *fullscreen* and *no-fullscreen* rules.
If multiple rules in a list match a given view the most specific If multiple rules in a list match a given view the most specific
rule will be applied. For example with the following rules rule will be applied. For example with the following rules
@ -339,7 +339,7 @@ matches everything while _\*\*_ and the empty string are invalid.
*rule-del* [*-app-id* _glob_|*-title* _glob_] _action_ *rule-del* [*-app-id* _glob_|*-title* _glob_] _action_
Delete a rule created using *rule-add* with the given arguments. Delete a rule created using *rule-add* with the given arguments.
*list-rules* *float*|*ssd*|*tag*|*position*|*dimensions* *list-rules* *float*|*ssd*|*tag*|*position*|*dimensions*|*fullscreen*
Print the specified rule list. The output is ordered from most specific Print the specified rule list. The output is ordered from most specific
to least specific, the same order in which views are checked against to least specific, the same order in which views are checked against
when searching for a match. Only the first matching rule in the list when searching for a match. Only the first matching rule in the list

View File

@ -488,6 +488,9 @@ pub fn map(view: *Self) !void {
if (server.config.float_rules.match(view)) |float| { if (server.config.float_rules.match(view)) |float| {
view.pending.float = float; view.pending.float = float;
} }
if (server.config.fullscreen_rules.match(view)) |fullscreen| {
view.pending.fullscreen = fullscreen;
}
if (server.config.ssd_rules.match(view)) |ssd| { if (server.config.ssd_rules.match(view)) |ssd| {
view.pending.ssd = ssd; view.pending.ssd = ssd;
} }

View File

@ -36,6 +36,8 @@ const Action = enum {
output, output,
position, position,
dimensions, dimensions,
fullscreen,
@"no-fullscreen",
}; };
pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void { pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void {
@ -51,7 +53,7 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
const action = std.meta.stringToEnum(Action, result.args[0]) orelse return Error.UnknownOption; const action = std.meta.stringToEnum(Action, result.args[0]) orelse return Error.UnknownOption;
const positional_arguments_count: u8 = switch (action) { const positional_arguments_count: u8 = switch (action) {
.float, .@"no-float", .ssd, .csd => 1, .float, .@"no-float", .ssd, .csd, .fullscreen, .@"no-fullscreen" => 1,
.tag, .output => 2, .tag, .output => 2,
.position, .dimensions => 3, .position, .dimensions => 3,
}; };
@ -122,6 +124,13 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
}, },
}); });
}, },
.fullscreen, .@"no-fullscreen" => {
try server.config.fullscreen_rules.add(.{
.app_id_glob = app_id_glob,
.title_glob = title_glob,
.value = (action == .fullscreen),
});
},
} }
} }
@ -165,6 +174,9 @@ pub fn ruleDel(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
.dimensions => { .dimensions => {
_ = server.config.dimensions_rules.del(rule); _ = server.config.dimensions_rules.del(rule);
}, },
.fullscreen, .@"no-fullscreen" => {
_ = server.config.fullscreen_rules.del(rule);
},
} }
} }
@ -188,6 +200,7 @@ pub fn listRules(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!
output, output,
position, position,
dimensions, dimensions,
fullscreen,
}, args[1]) orelse return Error.UnknownOption; }, args[1]) orelse return Error.UnknownOption;
const max_glob_len = switch (list) { const max_glob_len = switch (list) {
.float => server.config.float_rules.getMaxGlobLen(), .float => server.config.float_rules.getMaxGlobLen(),
@ -196,6 +209,7 @@ pub fn listRules(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!
.output => server.config.output_rules.getMaxGlobLen(), .output => server.config.output_rules.getMaxGlobLen(),
.position => server.config.position_rules.getMaxGlobLen(), .position => server.config.position_rules.getMaxGlobLen(),
.dimensions => server.config.dimensions_rules.getMaxGlobLen(), .dimensions => server.config.dimensions_rules.getMaxGlobLen(),
.fullscreen => server.config.fullscreen_rules.getMaxGlobLen(),
}; };
const app_id_column_max = 2 + @max("app-id".len, max_glob_len.app_id); const app_id_column_max = 2 + @max("app-id".len, max_glob_len.app_id);
const title_column_max = 2 + @max("title".len, max_glob_len.title); const title_column_max = 2 + @max("title".len, max_glob_len.title);
@ -256,6 +270,14 @@ pub fn listRules(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!
try writer.print("{d}x{d}\n", .{ rule.value.width, rule.value.height }); try writer.print("{d}x{d}\n", .{ rule.value.width, rule.value.height });
} }
}, },
.fullscreen => {
const rules = server.config.fullscreen_rules.rules.items;
for (rules) |rule| {
try fmt.formatBuf(rule.title_glob, .{ .width = title_column_max, .alignment = .left }, writer);
try fmt.formatBuf(rule.app_id_glob, .{ .width = app_id_column_max, .alignment = .left }, writer);
try writer.print("{s}\n", .{if (rule.value) "fullscreen" else "no-fullscreen"});
}
},
} }
out.* = try buffer.toOwnedSlice(); out.* = try buffer.toOwnedSlice();