Skip to content

API Enhancement #33

Description

@tokyob0t

Is your feature request related to a problem? Please describe.

As mentioned in #32 (comment), I'd like to follow aylur's suggestion of using GLib.Variant together with JSON serialization instead of the current custom ParameterFunc builders, as proposed here: Aylur#70 (comment).

While experimenting with the bindings, I also noticed that AstalNiri.msg does not appear to be introspectable. At least with Lua (LGI), attempting to access it results in:

lua: ...space/luawea/venv/share/lua/5.1/LuaGObject/class.lua:96: attempt to index field 'return_type' (a nil value)
stack traceback:
        ...space/luawea/venv/share/lua/5.1/LuaGObject/class.lua:96: in function 'find_constructor'
        ...space/luawea/venv/share/lua/5.1/LuaGObject/class.lua:276: in function 'load_class'
        ...e/luawea/venv/share/lua/5.1/LuaGObject/namespace.lua:50: in function 'loader'
        ...e/luawea/venv/share/lua/5.1/LuaGObject/namespace.lua:95: in function <...e/luawea/venv/share/lua/5.1/LuaGObject/namespace.lua:64>
        niri.lua:5: in main chunk
        [C]: ?

I'm not completely sure whether this is an issue in AstalNiri's introspection data or a bug in Lua LGI itself (I'll probably open an issue there as well), but it made me look more closely at the current API.

Another thing I noticed is that the public API could be made a bit more ergonomic. Many actions are exposed as individual helper methods that ultimately forward to the same send_act(...) implementation, for example:

public static bool focus_monitor_down() {
    return send_act("FocusMonitorDown");
}

public static bool focus_monitor_left() {
    return send_act("FocusMonitorLeft");
}

public static bool focus_window_down() {
    return send_act("FocusWindowDown");
}

public static bool focus_window_up() {
    return send_act("FocusWindowUp");
}

public static bool focus_window(int id) {
    return send_act("FocusWindow", serialize_fields({ int_member("id", id) }));
}

Likewise, the current JSON serialization helpers (ParameterFunc, *_member, *_value, etc.) require a considerable amount of boilerplate just to construct nested messages.

Describe the solution you'd like

I'd like to submit a PR with a few incremental improvements that all move in the same direction:

  • Make AstalNiri.msg introspectable (possibly renaming it to AstalNiri.Message).
  • Replace the custom JSON builder helpers with a GLib.Variant-based implementation using Json.gvariant_serialize().
  • Explore small improvements to the public API where they make the library easier to discover and use from GI bindings.

For example, constructing message payloads could become something like:

var action = serialized_json({
    kv_string("str", "string"),
    kv_bool("bool", false),
    kv_number("int", 0),
    kv_object("obj", {
        kv_string("nested", "string"),
    }),
});

instead of relying on the current ParameterFunc abstraction and dozens of helper methods.

I'm intentionally thinking of this as an incremental cleanup rather than a redesign of the IPC layer. The goal is to reduce boilerplate, improve maintainability, and make the API friendlier for bindings while keeping the underlying behavior unchanged.

Describe alternatives you've considered

  • Only making AstalNiri.msg introspectable.
  • Only replacing the serialization helpers with a GLib.Variant implementation.
  • Leaving the existing action helper API unchanged.

Those would all be reasonable on their own, but I think they fit naturally into the same cleanup PR.

Additional context

The initial scope would be intentionally small:

  • Make AstalNiri.msg introspectable (possibly as AstalNiri.Message).
  • Replace the ParameterFunc-based serialization with a GLib.Variant implementation.
  • Make small API improvements where they improve discoverability without significantly changing existing behavior.

If larger API changes seem worthwhile after that, they can be discussed separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions