~novakane/zelbar

27691564ea2ecdc135eb6af611b7dc06d02dc2f9 — Hugo Machet 1 year, 3 months ago d3335d1
code: Cleanup
5 files changed, 55 insertions(+), 100 deletions(-)

M CONTRIBUTING.md
M src/Backend.zig
M src/Tokenizer.zig
M src/data.zig
M src/main.zig
M CONTRIBUTING.md => CONTRIBUTING.md +7 -28
@@ 54,38 54,18 @@ Some things are not enforced by `zig fmt`, I do have an opinion on some of
these things though:

-   Use snake_case for function name, I know this is a pretty big difference
      from the official style guide but it makes code some much more readable.
      from the official style guide but it makes code so much more readable.
-   Wrap lines at 100 columns unless it helps readability.
-   Wrap comments at 80 columns.
-   Filename: use `Foo.zig` if you only export one struct, if there is
    more than one struct to export use `foo.zig`:
-   Use the struct name instead of Self.

    ```zig
    // Foo.zig
    const Foo = @This();

    field,
    field2,

    pub fn init() void {}

    fn function_foo() !void {}
    ```

    ```zig
    // foo.zig
    pub const Stuct1 = struct {
        field,
        field2,

        pub fn init() void {}
    };

    pub const Struct2 = struct {
        pub fn init() void {}

        fn function_foo() !void {}
    };
    // Do this
    pub fn init(foo: *Foo) void {}
    // instead of this
    pub fn init(self: *Foo) void {}
    ```

-   For import at the top of the file, I do it like this:


@@ 108,8 88,7 @@ these things though:

    const Buffer = @import("shm.zig").Buffer;
    const BufferStack = @import("shm.zig").BufferStack;
    const ctx = &@import("Client.zig").ctx;
    const renderer = @import("renderer.zig");
    const ctx = &@import("main.zig").context;
    const Surface = @import("Surface.zig");
    const Output = @This();
    ```

M src/Backend.zig => src/Backend.zig +32 -43
@@ 75,8 75,7 @@ const Output = struct {
    }
};

// Most code for pointers have been taken and adapted from https://git.sr.ht/~leon_plickat/wayprompt
// same license.
// Taken and adapted from https://git.sr.ht/~leon_plickat/wayprompt, same license.
const HotSpot = struct {
    action: []const u8,
    x: u31,


@@ 89,6 88,7 @@ const HotSpot = struct {
            y >= hotspot.y and y <= hotspot.y +| hotspot.height;
    }

    /// Write action in STDOUT.
    fn act(hotspot: HotSpot) !void {
        var bw = io.bufferedWriter(io.getStdOut().writer());
        const writer = bw.writer();


@@ 98,6 98,8 @@ const HotSpot = struct {
    }
};

// Pointers event code have been taken and adapted from
// https://git.sr.ht/~leon_plickat/wayprompt, same license.
const Seat = struct {
    const CursorShape = enum { none, arrow, hand };



@@ 186,7 188,7 @@ const Seat = struct {
                    .released => {
                        if (seat.press_hotspot == null) return;
                        if (ctx.backend.surface.?.hotspot_from_point(seat.pointer_x, seat.pointer_y)) |hs| {
                            if (hs == seat.press_hotspot.?) hs.act() catch return;
                            if (hs == seat.press_hotspot.?) hs.act() catch {};
                        }
                        seat.press_hotspot = null;
                    },


@@ 241,7 243,7 @@ const Seat = struct {

        // These just point back to the CursorTheme, no need to keep them.
        const wl_cursor = seat.cursor_theme.?.getCursor(name) orelse return error.NoCursor;
        const cursor_image = wl_cursor.images[0]; // TODO Is this nullable? Not in the bindings, but they may be wrong.
        const cursor_image = wl_cursor.images[0];
        const wl_buffer = try cursor_image.getBuffer();

        if (seat.cursor_surface == null) {


@@ 260,15 262,15 @@ const Seat = struct {
        seat.wl_pointer.?.setCursor(
            seat.last_enter_serial,
            seat.cursor_surface.?,
            @intCast(i32, @divFloor(cursor_image.hotspot_x, @intCast(u32, ctx.backend.scale))),
            @intCast(i32, @divFloor(cursor_image.hotspot_y, @intCast(u32, ctx.backend.scale))),
            @divFloor(@intCast(i32, cursor_image.hotspot_x), ctx.backend.scale),
            @divFloor(@intCast(i32, cursor_image.hotspot_y), ctx.backend.scale),
        );
    }
};

const Surface = struct {
    wl_surface: ?*wl.Surface = null,
    layer_surface: ?*zwlr.LayerSurfaceV1 = null,
    wl_surface: *wl.Surface = undefined,
    layer_surface: *zwlr.LayerSurfaceV1 = undefined,

    hotspots: std.ArrayListUnmanaged(HotSpot) = .{},



@@ 293,22 295,18 @@ const Surface = struct {
        };

        // Configure the layer_surface.
        if (surface.layer_surface) |ls| {
            ls.setListener(*Surface, layer_surface_listener, surface);
            configure_layer(ls, 0, ctx.bar.config.height, ctx.backend.scale);
        }
        surface.layer_surface.setListener(*Surface, layer_surface_listener, surface);
        configure_layer(surface.layer_surface, 0, ctx.bar.config.height, ctx.backend.scale);

        // We need to commit the empty surface first so we can receive a configure
        // event with width and height requested for our surface.
        surface.wl_surface.?.commit();
        surface.wl_surface.commit();
    }

    fn deinit(surface: *Surface) void {
        surface.hotspots.deinit(ctx.gpa);
        if (surface.layer_surface) |layer_surface| layer_surface.destroy();
        if (surface.wl_surface) |wl_surface| wl_surface.destroy();
        surface.layer_surface = null;
        surface.wl_surface = null;
        surface.layer_surface.destroy();
        surface.wl_surface.destroy();
    }

    fn hotspot_from_point(surface: *Surface, x: u31, y: u31) ?*HotSpot {


@@ 354,13 352,13 @@ const Surface = struct {
        switch (event) {
            .configure => |ev| {
                surface.configured = true;
                surface.layer_surface.?.ackConfigure(ev.serial);
                surface.layer_surface.ackConfigure(ev.serial);

                const w = @truncate(u31, ev.width);
                const h = @truncate(u31, ev.height);

                if (surface.configured and ctx.backend.width != w or ctx.backend.height != h) {
                    configure_layer(surface.layer_surface.?, w, h, ctx.backend.scale);
                    configure_layer(surface.layer_surface, w, h, ctx.backend.scale);

                    ctx.backend.width = w * @intCast(u31, ctx.backend.scale);
                    ctx.backend.height = h * @intCast(u31, ctx.backend.scale);


@@ 435,7 433,7 @@ const Buffer = struct {

    fn deinit(buffer: Buffer) void {
        if (buffer.pixman_image) |pix| _ = pix.unref();
        if (buffer.wl_buffer) |wl_buffer| wl_buffer.destroy();
        if (buffer.wl_buffer) |wlb| wlb.destroy();
        if (buffer.data) |data| os.munmap(data);
    }



@@ 487,7 485,7 @@ scale: i32 = 1,

seats: std.SinglyLinkedList(Seat) = .{},

surface: ?*Surface = null,
surface: ?Surface = null,

pool: std.AutoHashMapUnmanaged(u32, Buffer) = .{},
next_buffer: ?*Buffer = null,


@@ 517,8 515,7 @@ pub fn init(backend: *Backend, cfg: Bar.Config) !bool {
    // Roundtrip to get all outputs/seats infos.
    _ = backend.display.roundtrip();

    // Get the output requested by the user or use the first one in the outputs
    // list.
    // Get the output requested by the user or use the first one in the outputs list.
    if (cfg.output_name) |name| {
        var it = backend.outputs.first;
        while (it) |node| : (it = node.next) {


@@ 542,9 539,8 @@ pub fn init(backend: *Backend, cfg: Bar.Config) !bool {

    ctx.bar = try Bar.new(cfg);

    // Create the surface after the bar so we have all infos needed from the
    // bar config.
    backend.surface = try ctx.gpa.create(Surface);
    // Create the surface after the bar so we have all infos needed from the bar config.
    backend.surface = Surface{};
    try backend.surface.?.init();

    try backend.init_pool_buffer(2);


@@ 554,20 550,17 @@ pub fn init(backend: *Backend, cfg: Bar.Config) !bool {

pub fn deinit(backend: *Backend) void {
    var it = backend.pool.valueIterator();
    while (it.next()) |buf| {
        buf.deinit();
    }
    while (it.next()) |buf| buf.deinit();
    backend.pool.deinit(ctx.gpa);

    if (backend.surface) |surface| {
        surface.deinit();
        ctx.gpa.destroy(surface);
    if (backend.surface) |*s| {
        s.deinit();
        backend.surface = null;
    }

    if (backend.compositor) |compositor| compositor.destroy();
    if (backend.compositor) |cmp| cmp.destroy();
    if (backend.shm) |shm| shm.destroy();
    if (backend.layer_shell) |layer_shell| layer_shell.destroy();
    if (backend.layer_shell) |ls| ls.destroy();

    while (backend.outputs.popFirst()) |node| {
        node.data.deinit();


@@ 593,12 586,10 @@ pub fn schedule_and_commit(backend: *Backend) !void {

    if (backend.next_buffer) |pending| {
        if (ctx.bar.render_scheduled) {
            if (surface.wl_surface) |wl_surface| {
                wl_surface.setBufferScale(backend.scale);
                wl_surface.attach(pending.wl_buffer, 0, 0);
                wl_surface.damageBuffer(0, 0, pending.width, pending.height);
                wl_surface.commit();
            }
            surface.wl_surface.setBufferScale(backend.scale);
            surface.wl_surface.attach(pending.wl_buffer, 0, 0);
            surface.wl_surface.damageBuffer(0, 0, pending.width, pending.height);
            surface.wl_surface.commit();

            ctx.bar.render_scheduled = false;



@@ 644,9 635,7 @@ fn get_next_buffer(backend: Backend, shm: *wl.Shm, width: u31, height: u31) !?*B
    var it = backend.pool.valueIterator();
    while (it.next()) |buf| {
        if (buf.busy) continue;
        if (buf.wl_buffer == null) {
            try buf.init(shm, width, height);
        }
        if (buf.wl_buffer == null) try buf.init(shm, width, height);

        if (buf.width != width or buf.height != height) {
            buf.deinit();

M src/Tokenizer.zig => src/Tokenizer.zig +6 -2
@@ 65,7 65,7 @@ pub const Tag = enum {
    /// %{X:size}
    attr_offset,

    /// Actions on mouse click
    /// Action on mouse click
    /// %{A:action}
    attr_action,



@@ 384,7 384,7 @@ test "attributes block tokenizer (good input)" {
test "tokenizer (good input)" {
    const testing = @import("std").testing;

    const buf: []const u8 = "%{l}TEXT%{c}%{R}TEXT%TEXT%{B:0x000000}TEXT% TEXT%%{U:0x000000ff:4}TEXT%%%\n";
    const buf: []const u8 = "%{l}%{A:ran-dom cmd}TEXT%{c}%{R}TEXT%TEXT%{B:0x000000}TEXT% TEXT%%{U:0x000000ff:4}TEXT%%%\n";
    var tokenizer = Tokenizer.init(buf);

    var tok = tokenizer.next();


@@ 392,6 392,10 @@ test "tokenizer (good input)" {
    try testing.expectEqualStrings(tok.bytes, "l");

    tok = tokenizer.next();
    try testing.expect(tok.tag == .attr_action);
    try testing.expectEqualStrings(tok.bytes, "A:ran-dom cmd");

    tok = tokenizer.next();
    try testing.expect(tok.tag == .text);
    try testing.expectEqualStrings(tok.bytes, "TEXT");


M src/data.zig => src/data.zig +6 -17
@@ 60,17 60,10 @@ pub fn expose(input: []const u8, bar_x: u16, bar_w: u16) !void {
        index -= 1;

        var e = entries.list.get(index);

        switch (e.alignment) {
            .left => {
                entries_x[L] -= try e.render(@ptrCast(*i16, &entries_x[L]), entry_h);
            },
            .center => {
                entries_x[C] -= try e.render(@ptrCast(*i16, &entries_x[C]), entry_h);
            },
            .right => {
                entries_x[R] -= try e.render(@ptrCast(*i16, &entries_x[R]), entry_h);
            },
            .left => entries_x[L] -= try e.render(@ptrCast(*i16, &entries_x[L]), entry_h),
            .center => entries_x[C] -= try e.render(@ptrCast(*i16, &entries_x[C]), entry_h),
            .right => entries_x[R] -= try e.render(@ptrCast(*i16, &entries_x[R]), entry_h),
        }
    }



@@ 119,9 112,7 @@ fn parse_input(input: []const u8, height: u16) !Entries {

                try entries.list.append(ally, entry);

                if (tokenizer.index < input.len - 1) {
                    entry = Entry.new();
                }
                if (tokenizer.index < input.len - 1) entry = Entry.new();
            },

            .attr_align_l => entry.alignment = .left,


@@ 149,16 140,14 @@ fn parse_input(input: []const u8, height: u16) !Entries {
                try entry.lines.putNoClobber(ally, .under, line);
            },

            .attr_offset => {
                entry.offset = try fmt.parseUnsigned(u15, token.bytes[2..], 10);
            },
            .attr_offset => entry.offset = try fmt.parseUnsigned(u15, token.bytes[2..], 10),

            .attr_action => entry.action = token.bytes[2..],

            .eol => return entries,

            .invalid => {
                ctx.fatal(.renderer, "{s} column: {d}\n\t{s}", .{
                ctx.fatal(.data, "{s} column: {d}\n\t{s}", .{
                    @tagName(tokenizer.err),
                    tokenizer.column,
                    input[tokenizer.index..],

M src/main.zig => src/main.zig +4 -10
@@ 63,7 63,7 @@ const Context = struct {

    initialized: bool = false,

    pub fn deinit(ctx: *Context) void {
    fn deinit(ctx: *Context) void {
        ctx.bar.deinit();
        ctx.backend.deinit();
    }


@@ 130,12 130,8 @@ pub fn main() anyerror!void {
        try io.getStdOut().writeAll(build_options.version ++ "\n");
        os.exit(0);
    }
    if (result.argFlag("-o")) |raw| {
        default_cfg.output_name = raw;
    }
    if (result.boolFlag("-btm")) {
        default_cfg.location = .bottom;
    }
    if (result.argFlag("-o")) |raw| default_cfg.output_name = raw;
    if (result.boolFlag("-btm")) default_cfg.location = .bottom;
    if (result.argFlag("-L")) |raw| {
        const n = try fmt.parseUnsigned(u16, raw, 10);
        switch (n) {


@@ 172,9 168,7 @@ pub fn main() anyerror!void {
            .left = arr[3],
        };
    }
    if (result.argFlag("-fn")) |raw| {
        default_cfg.fonts_name = raw;
    }
    if (result.argFlag("-fn")) |raw| default_cfg.fonts_name = raw;
    if (result.argFlag("-B")) |raw| {
        decorations.check_rgba(.main, raw);
        try default_cfg.colors.put(context.gpa, .bg, raw);