~novakane/public-inbox

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
4 3

[PATCH rivercarro] Implement per-tag-cfg

Iskren Chernev <me@iskren.info>
Details
Message ID
<20240330195100.3414-1-me@iskren.info>
DKIM signature
pass
Download raw message
Patch: +73 -47
It is sometimes useful to remember the configuration for every tag,
instead of having a single configuration for all tags. Add a command
line option to pick per-tags-config, Then keep the available
configuration in a HashMap and pick the right one for user_command and
layout.
---
 src/main.zig | 120 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 73 insertions(+), 47 deletions(-)

diff --git a/src/main.zig b/src/main.zig
index f0298c7..f13c49d 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -40,6 +40,7 @@ const usage =
    \\  -h              Print this help message and exit.
    \\  -version        Print the version number and exit.
    \\  -no-smart-gaps  Disable smart gaps
    \\  -per-tag-cfg    Remember configuration per tag
    \\
    \\  The following commands may also be sent to rivercarro at runtime:
    \\
@@ -86,6 +87,7 @@ const Config = struct {
    main_count: u31 = 1,
    main_ratio: f64 = 0.6,
    width_ratio: f64 = 1.0,
    per_tag_config: bool = false,
};

const Context = struct {
@@ -101,10 +103,25 @@ const Output = struct {
    wl_output: *wl.Output,
    name: u32,

    cfg: Config,
    cfgs: std.AutoHashMap(u32, Config),
    user_command_tags: u32 = 0,

    layout: *river.LayoutV3 = undefined,

    fn get_cfg(output: *Output, tags: u32) *Config {
        var default_cfg = output.cfgs.getPtr(0) orelse unreachable;
        if (!cfg.per_tag_config) {
            return default_cfg;
        }
        // default to global config
        var entry = output.cfgs.getOrPutValue(tags, default_cfg.*) catch {
            // 0 always has a value
            log.err("out of memory, reverting to default cfg", .{});
            return default_cfg;
        };
        return entry.value_ptr;
    }

    fn get_layout(output: *Output) !void {
        output.layout = try ctx.layout_manager.?.getLayout(output.wl_output, "rivercarro");
        output.layout.setListener(*Output, layout_listener, output);
@@ -116,6 +133,7 @@ const Output = struct {

            .user_command => |ev| {
                var it = mem.tokenize(u8, mem.span(ev.command), " ");
                const active_cfg = output.get_cfg(output.user_command_tags);
                const raw_cmd = it.next() orelse {
                    log.err("not enough arguments", .{});
                    return;
@@ -139,12 +157,12 @@ const Output = struct {
                            return;
                        };
                        switch (raw_arg[0]) {
                            '+' => output.cfg.inner_gaps +|= @intCast(arg),
                            '+' => active_cfg.inner_gaps +|= @intCast(arg),
                            '-' => {
                                const res = output.cfg.inner_gaps +| arg;
                                if (res >= 0) output.cfg.inner_gaps = @intCast(res);
                                const res = active_cfg.inner_gaps +| arg;
                                if (res >= 0) active_cfg.*.inner_gaps = @intCast(res);
                            },
                            else => output.cfg.inner_gaps = @intCast(arg),
                            else => active_cfg.*.inner_gaps = @intCast(arg),
                        }
                    },
                    .@"outer-gaps" => {
@@ -153,12 +171,12 @@ const Output = struct {
                            return;
                        };
                        switch (raw_arg[0]) {
                            '+' => output.cfg.outer_gaps +|= @intCast(arg),
                            '+' => active_cfg.*.outer_gaps +|= @intCast(arg),
                            '-' => {
                                const res = output.cfg.outer_gaps +| arg;
                                if (res >= 0) output.cfg.outer_gaps = @intCast(res);
                                const res = active_cfg.outer_gaps +| arg;
                                if (res >= 0) active_cfg.*.outer_gaps = @intCast(res);
                            },
                            else => output.cfg.outer_gaps = @intCast(arg),
                            else => active_cfg.*.outer_gaps = @intCast(arg),
                        }
                    },
                    .gaps => {
@@ -168,23 +186,23 @@ const Output = struct {
                        };
                        switch (raw_arg[0]) {
                            '+' => {
                                output.cfg.inner_gaps +|= @intCast(arg);
                                output.cfg.outer_gaps +|= @intCast(arg);
                                active_cfg.*.inner_gaps +|= @intCast(arg);
                                active_cfg.*.outer_gaps +|= @intCast(arg);
                            },
                            '-' => {
                                const o = output.cfg.outer_gaps +| arg;
                                const i = output.cfg.inner_gaps +| arg;
                                if (i >= 0) output.cfg.inner_gaps = @intCast(i);
                                if (o >= 0) output.cfg.outer_gaps = @intCast(o);
                                const o = active_cfg.outer_gaps +| arg;
                                const i = active_cfg.inner_gaps +| arg;
                                if (i >= 0) active_cfg.*.inner_gaps = @intCast(i);
                                if (o >= 0) active_cfg.*.outer_gaps = @intCast(o);
                            },
                            else => {
                                output.cfg.inner_gaps = @intCast(arg);
                                output.cfg.outer_gaps = @intCast(arg);
                                active_cfg.*.inner_gaps = @intCast(arg);
                                active_cfg.*.outer_gaps = @intCast(arg);
                            },
                        }
                    },
                    .@"main-location" => {
                        output.cfg.main_location = std.meta.stringToEnum(Location, raw_arg) orelse {
                        active_cfg.*.main_location = std.meta.stringToEnum(Location, raw_arg) orelse {
                            log.err("unknown location: {s}", .{raw_arg});
                            return;
                        };
@@ -203,11 +221,11 @@ const Output = struct {
                                picked = current;
                                if (pick_next) break;
                            }
                            if (current == output.cfg.main_location) {
                            if (current == active_cfg.main_location) {
                                pick_next = true;
                            }
                        }
                        output.cfg.main_location = picked.?;
                        active_cfg.*.main_location = picked.?;
                    },
                    .@"main-count" => {
                        const arg = fmt.parseInt(i32, raw_arg, 10) catch |err| {
@@ -215,13 +233,13 @@ const Output = struct {
                            return;
                        };
                        switch (raw_arg[0]) {
                            '+' => output.cfg.main_count +|= @intCast(arg),
                            '+' => active_cfg.*.main_count +|= @intCast(arg),
                            '-' => {
                                const res = output.cfg.main_count +| arg;
                                if (res >= 1) output.cfg.main_count = @intCast(res);
                                const res = active_cfg.main_count +| arg;
                                if (res >= 1) active_cfg.*.main_count = @intCast(res);
                            },
                            else => {
                                if (arg >= 1) output.cfg.main_count = @intCast(arg);
                                if (arg >= 1) active_cfg.*.main_count = @intCast(arg);
                            },
                        }
                    },
@@ -232,9 +250,9 @@ const Output = struct {
                        };
                        switch (raw_arg[0]) {
                            '+', '-' => {
                                output.cfg.main_ratio = math.clamp(output.cfg.main_ratio + arg, 0.1, 0.9);
                                active_cfg.*.main_ratio = math.clamp(active_cfg.main_ratio + arg, 0.1, 0.9);
                            },
                            else => output.cfg.main_ratio = math.clamp(arg, 0.1, 0.9),
                            else => active_cfg.*.main_ratio = math.clamp(arg, 0.1, 0.9),
                        }
                    },
                    .@"width-ratio" => {
@@ -244,44 +262,47 @@ const Output = struct {
                        };
                        switch (raw_arg[0]) {
                            '+', '-' => {
                                output.cfg.width_ratio = math.clamp(output.cfg.width_ratio + arg, 0.1, 1.0);
                                active_cfg.*.width_ratio = math.clamp(active_cfg.width_ratio + arg, 0.1, 1.0);
                            },
                            else => output.cfg.width_ratio = math.clamp(arg, 0.1, 1.0),
                            else => active_cfg.*.width_ratio = math.clamp(arg, 0.1, 1.0),
                        }
                    },
                }
            },
            .user_command_tags => {},
            .user_command_tags => |ev| {
                output.user_command_tags = ev.tags;
            },

            .layout_demand => |ev| {
                assert(ev.view_count > 0);

                const main_count = @min(output.cfg.main_count, @as(u31, @truncate(ev.view_count)));
                const active_cfg = output.get_cfg(ev.tags);
                const main_count = @min(active_cfg.main_count, @as(u31, @truncate(ev.view_count)));
                const sec_count = @as(u31, @truncate(ev.view_count)) -| main_count;

                const only_one_view = ev.view_count == 1 or output.cfg.main_location == .monocle;
                const only_one_view = ev.view_count == 1 or active_cfg.main_location == .monocle;

                // Don't add gaps if there is only one view.
                if (only_one_view and cfg.smart_gaps) {
                    cfg.outer_gaps = 0;
                    cfg.inner_gaps = 0;
                } else {
                    cfg.outer_gaps = output.cfg.outer_gaps;
                    cfg.inner_gaps = output.cfg.inner_gaps;
                    cfg.outer_gaps = active_cfg.outer_gaps;
                    cfg.inner_gaps = active_cfg.inner_gaps;
                }

                const usable_w = switch (output.cfg.main_location) {
                const usable_w = switch (active_cfg.main_location) {
                    .left, .right, .monocle => @as(
                        u31,
                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * output.cfg.width_ratio),
                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * active_cfg.width_ratio),
                    ) -| (2 *| cfg.outer_gaps),
                    .top, .bottom => @as(u31, @truncate(ev.usable_height)) -| (2 *| cfg.outer_gaps),
                };
                const usable_h = switch (output.cfg.main_location) {
                const usable_h = switch (active_cfg.main_location) {
                    .left, .right, .monocle => @as(u31, @truncate(ev.usable_height)) -| (2 *| cfg.outer_gaps),
                    .top, .bottom => @as(
                        u31,
                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * output.cfg.width_ratio),
                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * active_cfg.width_ratio),
                    ) -| (2 *| cfg.outer_gaps),
                };

@@ -295,7 +316,7 @@ const Output = struct {
                var sec_h: u31 = undefined;
                var sec_h_rem: u31 = undefined;

                if (output.cfg.main_location == .monocle) {
                if (active_cfg.main_location == .monocle) {
                    main_w = usable_w;
                    main_h = usable_h;

@@ -303,7 +324,7 @@ const Output = struct {
                    sec_h = usable_h;
                } else {
                    if (sec_count > 0) {
                        main_w = @as(u31, @intFromFloat(output.cfg.main_ratio * @as(f64, @floatFromInt(usable_w))));
                        main_w = @as(u31, @intFromFloat(active_cfg.main_ratio * @as(f64, @floatFromInt(usable_w))));
                        main_h = usable_h / main_count;
                        main_h_rem = usable_h % main_count;

@@ -324,7 +345,7 @@ const Output = struct {
                    var width: u31 = undefined;
                    var height: u31 = undefined;

                    if (output.cfg.main_location == .monocle) {
                    if (active_cfg.main_location == .monocle) {
                        x = 0;
                        y = 0;
                        width = main_w;
@@ -346,7 +367,7 @@ const Output = struct {
                        }
                    }

                    switch (output.cfg.main_location) {
                    switch (active_cfg.main_location) {
                        .left => layout.pushViewDimensions(
                            x +| cfg.outer_gaps,
                            y +| cfg.outer_gaps,
@@ -385,7 +406,7 @@ const Output = struct {
                    }
                }

                switch (output.cfg.main_location) {
                switch (active_cfg.main_location) {
                    .left => layout.commit("left", ev.serial),
                    .right => layout.commit("right", ev.serial),
                    .top => layout.commit("top", ev.serial),
@@ -408,6 +429,7 @@ pub fn main() !void {
        .{ .name = "main-count", .kind = .arg },
        .{ .name = "main-ratio", .kind = .arg },
        .{ .name = "width-ratio", .kind = .arg },
        .{ .name = "per-tag-cfg", .kind = .boolean },
    }).parse(os.argv[1..]) catch {
        try std.io.getStdErr().writeAll(usage);
        os.exit(1);
@@ -457,6 +479,9 @@ pub fn main() !void {
            fatal_usage("Invalid value '{s}' provided to -width-ratio", .{raw});
        }
    }
    if (res.flags.@"per-tag-cfg") {
        cfg.per_tag_config = true;
    }

    const display = wl.Display.connect(null) catch {
        fatal("unable to connect to wayland compositor", .{});
@@ -513,11 +538,11 @@ fn registry_event(context: *Context, registry: *wl.Registry, event: wl.Registry.
                const node = try gpa.create(std.SinglyLinkedList(Output).Node);
                errdefer gpa.destroy(node);

                node.data = .{
                    .wl_output = wl_output,
                    .name = ev.name,
                    .cfg = cfg,
                };
                node.data = .{ .wl_output = wl_output, .name = ev.name, .cfgs = blk: {
                    var cfgs = std.AutoHashMap(u32, Config).init(gpa);
                    try cfgs.put(0, cfg);
                    break :blk cfgs;
                } };

                if (ctx.initialized) try node.data.get_layout();
                context.outputs.prepend(node);
@@ -529,6 +554,7 @@ fn registry_event(context: *Context, registry: *wl.Registry, event: wl.Registry.
                if (node.data.name == ev.name) {
                    node.data.wl_output.release();
                    node.data.layout.destroy();
                    node.data.cfgs.deinit();
                    context.outputs.remove(node);
                    gpa.destroy(node);
                    break;
-- 
2.44.0

[rivercarro/patches/.build.yml] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<D07CIBW3H4BE.3F71I7C4RUQ9C@fra01>
In-Reply-To
<20240330195100.3414-1-me@iskren.info> (view parent)
DKIM signature
missing
Download raw message
rivercarro/patches/.build.yml: SUCCESS in 1m3s

[Implement per-tag-cfg][0] from [Iskren Chernev][1]

[0]: https://lists.sr.ht/~novakane/public-inbox/patches/50615
[1]: me@iskren.info

✓ #1182928 SUCCESS rivercarro/patches/.build.yml https://builds.sr.ht/~novakane/job/1182928
Iskren Chernev <me@iskren.info>
Details
Message ID
<6570849d-e99e-4cfd-8e7e-7aad94040f8d@iskren.info>
In-Reply-To
<20240330195100.3414-1-me@iskren.info> (view parent)
DKIM signature
pass
Download raw message
Sorry for posting the patch again, I though the old one got lost.

This one adds deinit, and cleans up the init (in a labeled block). 
Ideally there should be an Output init/deinit which captures the logic, 
I can do that as well, but it's a bit offtopic, so decided against it.

On 3/30/24 9:51 PM, Iskren Chernev wrote:
> It is sometimes useful to remember the configuration for every tag,
> instead of having a single configuration for all tags. Add a command
> line option to pick per-tags-config, Then keep the available
> configuration in a HashMap and pick the right one for user_command and
> layout.
> ---
>   src/main.zig | 120 +++++++++++++++++++++++++++++++--------------------
>   1 file changed, 73 insertions(+), 47 deletions(-)
> 
> diff --git a/src/main.zig b/src/main.zig
> index f0298c7..f13c49d 100644
> --- a/src/main.zig
> +++ b/src/main.zig
> @@ -40,6 +40,7 @@ const usage =
>       \\  -h              Print this help message and exit.
>       \\  -version        Print the version number and exit.
>       \\  -no-smart-gaps  Disable smart gaps
> +    \\  -per-tag-cfg    Remember configuration per tag
>       \\
>       \\  The following commands may also be sent to rivercarro at runtime:
>       \\
> @@ -86,6 +87,7 @@ const Config = struct {
>       main_count: u31 = 1,
>       main_ratio: f64 = 0.6,
>       width_ratio: f64 = 1.0,
> +    per_tag_config: bool = false,
>   };
>   
>   const Context = struct {
> @@ -101,10 +103,25 @@ const Output = struct {
>       wl_output: *wl.Output,
>       name: u32,
>   
> -    cfg: Config,
> +    cfgs: std.AutoHashMap(u32, Config),
> +    user_command_tags: u32 = 0,
>   
>       layout: *river.LayoutV3 = undefined,
>   
> +    fn get_cfg(output: *Output, tags: u32) *Config {
> +        var default_cfg = output.cfgs.getPtr(0) orelse unreachable;
> +        if (!cfg.per_tag_config) {
> +            return default_cfg;
> +        }
> +        // default to global config
> +        var entry = output.cfgs.getOrPutValue(tags, default_cfg.*) catch {
> +            // 0 always has a value
> +            log.err("out of memory, reverting to default cfg", .{});
> +            return default_cfg;
> +        };
> +        return entry.value_ptr;
> +    }
> +
>       fn get_layout(output: *Output) !void {
>           output.layout = try ctx.layout_manager.?.getLayout(output.wl_output, "rivercarro");
>           output.layout.setListener(*Output, layout_listener, output);
> @@ -116,6 +133,7 @@ const Output = struct {
>   
>               .user_command => |ev| {
>                   var it = mem.tokenize(u8, mem.span(ev.command), " ");
> +                const active_cfg = output.get_cfg(output.user_command_tags);
>                   const raw_cmd = it.next() orelse {
>                       log.err("not enough arguments", .{});
>                       return;
> @@ -139,12 +157,12 @@ const Output = struct {
>                               return;
>                           };
>                           switch (raw_arg[0]) {
> -                            '+' => output.cfg.inner_gaps +|= @intCast(arg),
> +                            '+' => active_cfg.inner_gaps +|= @intCast(arg),
>                               '-' => {
> -                                const res = output.cfg.inner_gaps +| arg;
> -                                if (res >= 0) output.cfg.inner_gaps = @intCast(res);
> +                                const res = active_cfg.inner_gaps +| arg;
> +                                if (res >= 0) active_cfg.*.inner_gaps = @intCast(res);
>                               },
> -                            else => output.cfg.inner_gaps = @intCast(arg),
> +                            else => active_cfg.*.inner_gaps = @intCast(arg),
>                           }
>                       },
>                       .@"outer-gaps" => {
> @@ -153,12 +171,12 @@ const Output = struct {
>                               return;
>                           };
>                           switch (raw_arg[0]) {
> -                            '+' => output.cfg.outer_gaps +|= @intCast(arg),
> +                            '+' => active_cfg.*.outer_gaps +|= @intCast(arg),
>                               '-' => {
> -                                const res = output.cfg.outer_gaps +| arg;
> -                                if (res >= 0) output.cfg.outer_gaps = @intCast(res);
> +                                const res = active_cfg.outer_gaps +| arg;
> +                                if (res >= 0) active_cfg.*.outer_gaps = @intCast(res);
>                               },
> -                            else => output.cfg.outer_gaps = @intCast(arg),
> +                            else => active_cfg.*.outer_gaps = @intCast(arg),
>                           }
>                       },
>                       .gaps => {
> @@ -168,23 +186,23 @@ const Output = struct {
>                           };
>                           switch (raw_arg[0]) {
>                               '+' => {
> -                                output.cfg.inner_gaps +|= @intCast(arg);
> -                                output.cfg.outer_gaps +|= @intCast(arg);
> +                                active_cfg.*.inner_gaps +|= @intCast(arg);
> +                                active_cfg.*.outer_gaps +|= @intCast(arg);
>                               },
>                               '-' => {
> -                                const o = output.cfg.outer_gaps +| arg;
> -                                const i = output.cfg.inner_gaps +| arg;
> -                                if (i >= 0) output.cfg.inner_gaps = @intCast(i);
> -                                if (o >= 0) output.cfg.outer_gaps = @intCast(o);
> +                                const o = active_cfg.outer_gaps +| arg;
> +                                const i = active_cfg.inner_gaps +| arg;
> +                                if (i >= 0) active_cfg.*.inner_gaps = @intCast(i);
> +                                if (o >= 0) active_cfg.*.outer_gaps = @intCast(o);
>                               },
>                               else => {
> -                                output.cfg.inner_gaps = @intCast(arg);
> -                                output.cfg.outer_gaps = @intCast(arg);
> +                                active_cfg.*.inner_gaps = @intCast(arg);
> +                                active_cfg.*.outer_gaps = @intCast(arg);
>                               },
>                           }
>                       },
>                       .@"main-location" => {
> -                        output.cfg.main_location = std.meta.stringToEnum(Location, raw_arg) orelse {
> +                        active_cfg.*.main_location = std.meta.stringToEnum(Location, raw_arg) orelse {
>                               log.err("unknown location: {s}", .{raw_arg});
>                               return;
>                           };
> @@ -203,11 +221,11 @@ const Output = struct {
>                                   picked = current;
>                                   if (pick_next) break;
>                               }
> -                            if (current == output.cfg.main_location) {
> +                            if (current == active_cfg.main_location) {
>                                   pick_next = true;
>                               }
>                           }
> -                        output.cfg.main_location = picked.?;
> +                        active_cfg.*.main_location = picked.?;
>                       },
>                       .@"main-count" => {
>                           const arg = fmt.parseInt(i32, raw_arg, 10) catch |err| {
> @@ -215,13 +233,13 @@ const Output = struct {
>                               return;
>                           };
>                           switch (raw_arg[0]) {
> -                            '+' => output.cfg.main_count +|= @intCast(arg),
> +                            '+' => active_cfg.*.main_count +|= @intCast(arg),
>                               '-' => {
> -                                const res = output.cfg.main_count +| arg;
> -                                if (res >= 1) output.cfg.main_count = @intCast(res);
> +                                const res = active_cfg.main_count +| arg;
> +                                if (res >= 1) active_cfg.*.main_count = @intCast(res);
>                               },
>                               else => {
> -                                if (arg >= 1) output.cfg.main_count = @intCast(arg);
> +                                if (arg >= 1) active_cfg.*.main_count = @intCast(arg);
>                               },
>                           }
>                       },
> @@ -232,9 +250,9 @@ const Output = struct {
>                           };
>                           switch (raw_arg[0]) {
>                               '+', '-' => {
> -                                output.cfg.main_ratio = math.clamp(output.cfg.main_ratio + arg, 0.1, 0.9);
> +                                active_cfg.*.main_ratio = math.clamp(active_cfg.main_ratio + arg, 0.1, 0.9);
>                               },
> -                            else => output.cfg.main_ratio = math.clamp(arg, 0.1, 0.9),
> +                            else => active_cfg.*.main_ratio = math.clamp(arg, 0.1, 0.9),
>                           }
>                       },
>                       .@"width-ratio" => {
> @@ -244,44 +262,47 @@ const Output = struct {
>                           };
>                           switch (raw_arg[0]) {
>                               '+', '-' => {
> -                                output.cfg.width_ratio = math.clamp(output.cfg.width_ratio + arg, 0.1, 1.0);
> +                                active_cfg.*.width_ratio = math.clamp(active_cfg.width_ratio + arg, 0.1, 1.0);
>                               },
> -                            else => output.cfg.width_ratio = math.clamp(arg, 0.1, 1.0),
> +                            else => active_cfg.*.width_ratio = math.clamp(arg, 0.1, 1.0),
>                           }
>                       },
>                   }
>               },
> -            .user_command_tags => {},
> +            .user_command_tags => |ev| {
> +                output.user_command_tags = ev.tags;
> +            },
>   
>               .layout_demand => |ev| {
>                   assert(ev.view_count > 0);
>   
> -                const main_count = @min(output.cfg.main_count, @as(u31, @truncate(ev.view_count)));
> +                const active_cfg = output.get_cfg(ev.tags);
> +                const main_count = @min(active_cfg.main_count, @as(u31, @truncate(ev.view_count)));
>                   const sec_count = @as(u31, @truncate(ev.view_count)) -| main_count;
>   
> -                const only_one_view = ev.view_count == 1 or output.cfg.main_location == .monocle;
> +                const only_one_view = ev.view_count == 1 or active_cfg.main_location == .monocle;
>   
>                   // Don't add gaps if there is only one view.
>                   if (only_one_view and cfg.smart_gaps) {
>                       cfg.outer_gaps = 0;
>                       cfg.inner_gaps = 0;
>                   } else {
> -                    cfg.outer_gaps = output.cfg.outer_gaps;
> -                    cfg.inner_gaps = output.cfg.inner_gaps;
> +                    cfg.outer_gaps = active_cfg.outer_gaps;
> +                    cfg.inner_gaps = active_cfg.inner_gaps;
>                   }
>   
> -                const usable_w = switch (output.cfg.main_location) {
> +                const usable_w = switch (active_cfg.main_location) {
>                       .left, .right, .monocle => @as(
>                           u31,
> -                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * output.cfg.width_ratio),
> +                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * active_cfg.width_ratio),
>                       ) -| (2 *| cfg.outer_gaps),
>                       .top, .bottom => @as(u31, @truncate(ev.usable_height)) -| (2 *| cfg.outer_gaps),
>                   };
> -                const usable_h = switch (output.cfg.main_location) {
> +                const usable_h = switch (active_cfg.main_location) {
>                       .left, .right, .monocle => @as(u31, @truncate(ev.usable_height)) -| (2 *| cfg.outer_gaps),
>                       .top, .bottom => @as(
>                           u31,
> -                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * output.cfg.width_ratio),
> +                        @intFromFloat(@as(f64, @floatFromInt(ev.usable_width)) * active_cfg.width_ratio),
>                       ) -| (2 *| cfg.outer_gaps),
>                   };
>   
> @@ -295,7 +316,7 @@ const Output = struct {
>                   var sec_h: u31 = undefined;
>                   var sec_h_rem: u31 = undefined;
>   
> -                if (output.cfg.main_location == .monocle) {
> +                if (active_cfg.main_location == .monocle) {
>                       main_w = usable_w;
>                       main_h = usable_h;
>   
> @@ -303,7 +324,7 @@ const Output = struct {
>                       sec_h = usable_h;
>                   } else {
>                       if (sec_count > 0) {
> -                        main_w = @as(u31, @intFromFloat(output.cfg.main_ratio * @as(f64, @floatFromInt(usable_w))));
> +                        main_w = @as(u31, @intFromFloat(active_cfg.main_ratio * @as(f64, @floatFromInt(usable_w))));
>                           main_h = usable_h / main_count;
>                           main_h_rem = usable_h % main_count;
>   
> @@ -324,7 +345,7 @@ const Output = struct {
>                       var width: u31 = undefined;
>                       var height: u31 = undefined;
>   
> -                    if (output.cfg.main_location == .monocle) {
> +                    if (active_cfg.main_location == .monocle) {
>                           x = 0;
>                           y = 0;
>                           width = main_w;
> @@ -346,7 +367,7 @@ const Output = struct {
>                           }
>                       }
>   
> -                    switch (output.cfg.main_location) {
> +                    switch (active_cfg.main_location) {
>                           .left => layout.pushViewDimensions(
>                               x +| cfg.outer_gaps,
>                               y +| cfg.outer_gaps,
> @@ -385,7 +406,7 @@ const Output = struct {
>                       }
>                   }
>   
> -                switch (output.cfg.main_location) {
> +                switch (active_cfg.main_location) {
>                       .left => layout.commit("left", ev.serial),
>                       .right => layout.commit("right", ev.serial),
>                       .top => layout.commit("top", ev.serial),
> @@ -408,6 +429,7 @@ pub fn main() !void {
>           .{ .name = "main-count", .kind = .arg },
>           .{ .name = "main-ratio", .kind = .arg },
>           .{ .name = "width-ratio", .kind = .arg },
> +        .{ .name = "per-tag-cfg", .kind = .boolean },
>       }).parse(os.argv[1..]) catch {
>           try std.io.getStdErr().writeAll(usage);
>           os.exit(1);
> @@ -457,6 +479,9 @@ pub fn main() !void {
>               fatal_usage("Invalid value '{s}' provided to -width-ratio", .{raw});
>           }
>       }
> +    if (res.flags.@"per-tag-cfg") {
> +        cfg.per_tag_config = true;
> +    }
>   
>       const display = wl.Display.connect(null) catch {
>           fatal("unable to connect to wayland compositor", .{});
> @@ -513,11 +538,11 @@ fn registry_event(context: *Context, registry: *wl.Registry, event: wl.Registry.
>                   const node = try gpa.create(std.SinglyLinkedList(Output).Node);
>                   errdefer gpa.destroy(node);
>   
> -                node.data = .{
> -                    .wl_output = wl_output,
> -                    .name = ev.name,
> -                    .cfg = cfg,
> -                };
> +                node.data = .{ .wl_output = wl_output, .name = ev.name, .cfgs = blk: {
> +                    var cfgs = std.AutoHashMap(u32, Config).init(gpa);
> +                    try cfgs.put(0, cfg);
> +                    break :blk cfgs;
> +                } };
>   
>                   if (ctx.initialized) try node.data.get_layout();
>                   context.outputs.prepend(node);
> @@ -529,6 +554,7 @@ fn registry_event(context: *Context, registry: *wl.Registry, event: wl.Registry.
>                   if (node.data.name == ev.name) {
>                       node.data.wl_output.release();
>                       node.data.layout.destroy();
> +                    node.data.cfgs.deinit();
>                       context.outputs.remove(node);
>                       gpa.destroy(node);
>                       break;
Details
Message ID
<d876a800ee047c9ee9eef642f7ae77ae0ea43249@hmachet.com>
In-Reply-To
<6570849d-e99e-4cfd-8e7e-7aad94040f8d@iskren.info> (view parent)
DKIM signature
pass
Download raw message
March 30, 2024 at 8:56 PM, "Iskren Chernev" <me@iskren.info> wrote:



> 
> Sorry for posting the patch again, I though the old one got lost.
> 
> This one adds deinit, and cleans up the init (in a labeled block). Ideally there should be an Output init/deinit which captures the logic, I can do that as well, but it's a bit offtopic, so decided against it.
> 

It is not lost, I just didn't have the time to look at it, I'll try to
do this this week if I can.

Something I can already say tough, is that everywhere you use
`active_cfg.*.` this is not needed, e.g.

`active_cfg.*.outer_gaps` can become `active_cfg.outer_gaps`
Details
Message ID
<51b1c0bff36feeb4d556e6ff34c75fe5ff90b582@hmachet.com>
In-Reply-To
<20240330195100.3414-1-me@iskren.info> (view parent)
DKIM signature
pass
Download raw message
A few nitpicks but other than that it seems to works well, I'll test it
a bit more in the next few days, and see if I can think of improvements
for the implementation, but that seems fine for now.


> @@ -40,6 +40,7 @@ const usage =
> 
>  \\ -h Print this help message and exit.
> 
>  \\ -version Print the version number and exit.
> 
>  \\ -no-smart-gaps Disable smart gaps
> 
> + \\ -per-tag-cfg Remember configuration per tag
> 

I prefer just `per-tag`


> @@ -86,6 +87,7 @@ const Config = struct {
> 
>  main_count: u31 = 1,
> 
>  main_ratio: f64 = 0.6,
> 
>  width_ratio: f64 = 1.0,
> 
> + per_tag_config: bool = false,
> 
>  };

same, just `per_tag`

> 
> - cfg: Config,
> 
> + cfgs: std.AutoHashMap(u32, Config),

Could you use std.AutoHashMapUnmanaged instead

> 
> - const res = output.cfg.inner_gaps +| arg;
> 
> - if (res >= 0) output.cfg.inner_gaps = @intCast(res);
> 
> + const res = active_cfg.inner_gaps +| arg;
> 
> + if (res >= 0) active_cfg.*.inner_gaps = @intCast(res);
> 
>  },

`active_cfg.inner_gaps`

as said in the previous mail `.*` is not needed, you can
remove it everywhere
Reply to thread Export thread (mbox)