river: add tags rule
This commit is contained in:
parent
a98de941d0
commit
0b142bd16b
@ -62,8 +62,8 @@ function __riverctl_completion ()
|
|||||||
"focus-output"|"focus-view"|"send-to-output"|"swap") OPTS="next previous" ;;
|
"focus-output"|"focus-view"|"send-to-output"|"swap") OPTS="next previous" ;;
|
||||||
"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="float no-float ssd csd" ;;
|
"rule-add"|"rule-del") OPTS="float no-float ssd csd tag" ;;
|
||||||
"list-rules") OPTS="float ssd" ;;
|
"list-rules") OPTS="float ssd tag" ;;
|
||||||
"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" ;;
|
||||||
|
@ -83,9 +83,9 @@ complete -c riverctl -x -n '__fish_seen_subcommand_from unmap' -a
|
|||||||
complete -c riverctl -x -n '__fish_seen_subcommand_from attach-mode' -a 'top bottom'
|
complete -c riverctl -x -n '__fish_seen_subcommand_from attach-mode' -a 'top bottom'
|
||||||
complete -c riverctl -x -n '__fish_seen_subcommand_from focus-follows-cursor' -a 'disabled normal always'
|
complete -c riverctl -x -n '__fish_seen_subcommand_from focus-follows-cursor' -a 'disabled normal always'
|
||||||
complete -c riverctl -x -n '__fish_seen_subcommand_from set-cursor-warp' -a 'disabled on-output-change on-focus-change'
|
complete -c riverctl -x -n '__fish_seen_subcommand_from set-cursor-warp' -a 'disabled on-output-change on-focus-change'
|
||||||
complete -c riverctl -x -n '__fish_seen_subcommand_from rule-add' -a 'float no-float ssd csd'
|
complete -c riverctl -x -n '__fish_seen_subcommand_from rule-add' -a 'float no-float ssd csd tag'
|
||||||
complete -c riverctl -x -n '__fish_seen_subcommand_from rule-del' -a 'float no-float ssd csd'
|
complete -c riverctl -x -n '__fish_seen_subcommand_from rule-del' -a 'float no-float ssd csd tag'
|
||||||
complete -c riverctl -x -n '__fish_seen_subcommand_from list-rules' -a 'float ssd'
|
complete -c riverctl -x -n '__fish_seen_subcommand_from list-rules' -a 'float ssd tag'
|
||||||
|
|
||||||
# Subcommands for 'input'
|
# Subcommands for 'input'
|
||||||
complete -c riverctl -x -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 2' -a "(__riverctl_list_input_devices)"
|
complete -c riverctl -x -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 2' -a "(__riverctl_list_input_devices)"
|
||||||
|
@ -183,9 +183,9 @@ _riverctl()
|
|||||||
focus-follows-cursor) _alternative 'arguments:args:(disabled normal always)' ;;
|
focus-follows-cursor) _alternative 'arguments:args:(disabled normal always)' ;;
|
||||||
set-cursor-warp) _alternative 'arguments:args:(disabled on-output-change on-focus-change)' ;;
|
set-cursor-warp) _alternative 'arguments:args:(disabled on-output-change on-focus-change)' ;;
|
||||||
hide-cursor) _riverctl_hide_cursor ;;
|
hide-cursor) _riverctl_hide_cursor ;;
|
||||||
rule-add) _alternative 'arguments:args:(float no-float ssd csd)' ;;
|
rule-add) _alternative 'arguments:args:(float no-float ssd csd tag)' ;;
|
||||||
rule-del) _alternative 'arguments:args:(float no-float ssd csd)' ;;
|
rule-del) _alternative 'arguments:args:(float no-float ssd csd tag)' ;;
|
||||||
list-rules) _alternative 'arguments:args:(float ssd)' ;;
|
list-rules) _alternative 'arguments:args:(float ssd tag)' ;;
|
||||||
*) return 0 ;;
|
*) return 0 ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
@ -258,10 +258,11 @@ For example, _abc_ is matched by _a\*_, _\*a\*_, _\*b\*_, _\*c_, _abc_, and
|
|||||||
_\*_ but not matched by _\*a_, _b\*_, _\*b_, _c\*_, or _ab_. Note that _\*_
|
_\*_ but not matched by _\*a_, _b\*_, _\*b_, _c\*_, or _ab_. Note that _\*_
|
||||||
matches everything while _\*\*_ and the empty string are invalid.
|
matches everything while _\*\*_ and the empty string are invalid.
|
||||||
|
|
||||||
*rule-add* _action_ [*-app-id* _glob_|*-title* _glob_]
|
*rule-add* _action_ [*-app-id* _glob_|*-title* _glob_] [_argument_]
|
||||||
Add a rule that applies an _action_ to views with *app-id* and *title*
|
Add a rule that applies an _action_ to views with *app-id* and *title*
|
||||||
matched by the respective _glob_. Omitting *-app-id* or *-title*
|
matched by the respective _glob_. Omitting *-app-id* or *-title*
|
||||||
is equivalent to passing *-app-id* _\*_ or *-title* _\*_.
|
is equivalent to passing *-app-id* _\*_ or *-title* _\*_.
|
||||||
|
Some actions require an _argument_.
|
||||||
|
|
||||||
The supported _action_ types are:
|
The supported _action_ types are:
|
||||||
|
|
||||||
@ -272,6 +273,8 @@ matches everything while _\*\*_ and the empty string are invalid.
|
|||||||
and existing views.
|
and existing views.
|
||||||
- *csd*: Use client-side decorations for the view. Applies to new
|
- *csd*: Use client-side decorations for the view. Applies to new
|
||||||
and existing views.
|
and existing views.
|
||||||
|
- *tag*: Set the initial tags of the view. Requires the tags as
|
||||||
|
an argument. Applies only to new views.
|
||||||
|
|
||||||
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
|
||||||
@ -300,7 +303,7 @@ matches everything while _\*\*_ and the empty string are invalid.
|
|||||||
*rule-del* _action_ [*-app-id* _glob_|*-title* _glob_]
|
*rule-del* _action_ [*-app-id* _glob_|*-title* _glob_]
|
||||||
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*
|
*list-rules* *float*|*ssd*|*tag*
|
||||||
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
|
||||||
|
@ -75,6 +75,7 @@ modes: std.ArrayListUnmanaged(Mode),
|
|||||||
|
|
||||||
float_rules: RuleList(bool) = .{},
|
float_rules: RuleList(bool) = .{},
|
||||||
ssd_rules: RuleList(bool) = .{},
|
ssd_rules: RuleList(bool) = .{},
|
||||||
|
tag_rules: RuleList(u32) = .{},
|
||||||
|
|
||||||
/// The selected focus_follows_cursor mode
|
/// The selected focus_follows_cursor mode
|
||||||
focus_follows_cursor: FocusFollowsCursorMode = .disabled,
|
focus_follows_cursor: FocusFollowsCursorMode = .disabled,
|
||||||
@ -150,6 +151,7 @@ pub fn deinit(self: *Self) void {
|
|||||||
|
|
||||||
self.float_rules.deinit();
|
self.float_rules.deinit();
|
||||||
self.ssd_rules.deinit();
|
self.ssd_rules.deinit();
|
||||||
|
self.tag_rules.deinit();
|
||||||
|
|
||||||
util.gpa.free(self.default_layout_namespace);
|
util.gpa.free(self.default_layout_namespace);
|
||||||
|
|
||||||
|
@ -508,6 +508,7 @@ pub fn map(view: *Self) !void {
|
|||||||
view.pending.box.y = @divTrunc(math.max(0, output.usable_box.height - view.pending.box.height), 2);
|
view.pending.box.y = @divTrunc(math.max(0, output.usable_box.height - view.pending.box.height), 2);
|
||||||
|
|
||||||
view.pending.tags = blk: {
|
view.pending.tags = blk: {
|
||||||
|
if (server.config.tag_rules.match(view)) |tags| break :blk tags;
|
||||||
const tags = output.pending.tags & server.config.spawn_tagmask;
|
const tags = output.pending.tags & server.config.spawn_tagmask;
|
||||||
break :blk if (tags != 0) tags else output.pending.tags;
|
break :blk if (tags != 0) tags else output.pending.tags;
|
||||||
};
|
};
|
||||||
|
@ -32,6 +32,7 @@ const Action = enum {
|
|||||||
@"no-float",
|
@"no-float",
|
||||||
ssd,
|
ssd,
|
||||||
csd,
|
csd,
|
||||||
|
tag,
|
||||||
};
|
};
|
||||||
|
|
||||||
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 {
|
||||||
@ -44,9 +45,14 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
return error.InvalidValue;
|
return error.InvalidValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (result.args.len > 0) return Error.TooManyArguments;
|
|
||||||
|
|
||||||
const action = std.meta.stringToEnum(Action, args[1]) orelse return Error.UnknownOption;
|
const action = std.meta.stringToEnum(Action, args[1]) orelse return Error.UnknownOption;
|
||||||
|
|
||||||
|
const positional_arguments_count: u8 = switch (action) {
|
||||||
|
.float, .@"no-float", .ssd, .csd => 0,
|
||||||
|
.tag => 1,
|
||||||
|
};
|
||||||
|
if (result.args.len > positional_arguments_count) return Error.TooManyArguments;
|
||||||
|
|
||||||
const app_id_glob = result.flags.@"app-id" orelse "*";
|
const app_id_glob = result.flags.@"app-id" orelse "*";
|
||||||
const title_glob = result.flags.title orelse "*";
|
const title_glob = result.flags.title orelse "*";
|
||||||
|
|
||||||
@ -70,6 +76,14 @@ pub fn ruleAdd(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
apply_ssd_rules();
|
apply_ssd_rules();
|
||||||
server.root.applyPending();
|
server.root.applyPending();
|
||||||
},
|
},
|
||||||
|
.tag => {
|
||||||
|
const tag = try fmt.parseInt(u32, result.args[0], 10);
|
||||||
|
try server.config.tag_rules.add(.{
|
||||||
|
.app_id_glob = app_id_glob,
|
||||||
|
.title_glob = title_glob,
|
||||||
|
.value = tag,
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +118,12 @@ pub fn ruleDel(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
|
|||||||
apply_ssd_rules();
|
apply_ssd_rules();
|
||||||
server.root.applyPending();
|
server.root.applyPending();
|
||||||
},
|
},
|
||||||
|
.tag => {
|
||||||
|
server.config.tag_rules.del(.{
|
||||||
|
.app_id_glob = app_id_glob,
|
||||||
|
.title_glob = title_glob,
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +140,15 @@ pub fn listRules(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!
|
|||||||
if (args.len < 2) return error.NotEnoughArguments;
|
if (args.len < 2) return error.NotEnoughArguments;
|
||||||
if (args.len > 2) return error.TooManyArguments;
|
if (args.len > 2) return error.TooManyArguments;
|
||||||
|
|
||||||
const list = std.meta.stringToEnum(enum { float, ssd }, args[1]) orelse return Error.UnknownOption;
|
const list = std.meta.stringToEnum(enum {
|
||||||
|
float,
|
||||||
|
ssd,
|
||||||
|
tag,
|
||||||
|
}, 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(),
|
||||||
.ssd => server.config.ssd_rules.getMaxGlobLen(),
|
.ssd => server.config.ssd_rules.getMaxGlobLen(),
|
||||||
|
.tag => server.config.tag_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);
|
||||||
@ -140,6 +165,7 @@ pub fn listRules(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!
|
|||||||
const rules = switch (list) {
|
const rules = switch (list) {
|
||||||
.float => server.config.float_rules.rules.items,
|
.float => server.config.float_rules.rules.items,
|
||||||
.ssd => server.config.ssd_rules.rules.items,
|
.ssd => server.config.ssd_rules.rules.items,
|
||||||
|
else => unreachable,
|
||||||
};
|
};
|
||||||
for (rules) |rule| {
|
for (rules) |rule| {
|
||||||
try fmt.formatBuf(rule.title_glob, .{ .width = title_column_max, .alignment = .Left }, writer);
|
try fmt.formatBuf(rule.title_glob, .{ .width = title_column_max, .alignment = .Left }, writer);
|
||||||
@ -147,9 +173,18 @@ pub fn listRules(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!
|
|||||||
try writer.print("{s}\n", .{switch (list) {
|
try writer.print("{s}\n", .{switch (list) {
|
||||||
.float => if (rule.value) "float" else "no-float",
|
.float => if (rule.value) "float" else "no-float",
|
||||||
.ssd => if (rule.value) "ssd" else "csd",
|
.ssd => if (rule.value) "ssd" else "csd",
|
||||||
|
else => unreachable,
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.tag => {
|
||||||
|
const rules = server.config.tag_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("{b}\n", .{rule.value});
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
out.* = buffer.toOwnedSlice();
|
out.* = buffer.toOwnedSlice();
|
||||||
|
Loading…
Reference in New Issue
Block a user