diff --git a/src/apprt/gtk-ng/class/application.zig b/src/apprt/gtk-ng/class/application.zig index becfac14a..d8b795f4d 100644 --- a/src/apprt/gtk-ng/class/application.zig +++ b/src/apprt/gtk-ng/class/application.zig @@ -886,10 +886,10 @@ pub const Application = extern struct { self.syncActionAccelerator("win.reset", .{ .reset = {} }); self.syncActionAccelerator("win.clear", .{ .clear_screen = {} }); self.syncActionAccelerator("win.prompt-title", .{ .prompt_surface_title = {} }); - self.syncActionAccelerator("split-tree.new-left", .{ .new_split = .left }); - self.syncActionAccelerator("split-tree.new-right", .{ .new_split = .right }); - self.syncActionAccelerator("split-tree.new-up", .{ .new_split = .up }); - self.syncActionAccelerator("split-tree.new-down", .{ .new_split = .down }); + self.syncActionAccelerator("split-tree.new-split::left", .{ .new_split = .left }); + self.syncActionAccelerator("split-tree.new-split::right", .{ .new_split = .right }); + self.syncActionAccelerator("split-tree.new-split::up", .{ .new_split = .up }); + self.syncActionAccelerator("split-tree.new-split::down", .{ .new_split = .down }); } fn syncActionAccelerator( @@ -1814,12 +1814,12 @@ const Action = struct { .surface => |core| { const surface = core.rt_surface.surface; - return surface.as(gtk.Widget).activateAction(switch (direction) { - .right => "split-tree.new-right", - .left => "split-tree.new-left", - .down => "split-tree.new-down", - .up => "split-tree.new-up", - }, null) != 0; + + return surface.as(gtk.Widget).activateAction( + "split-tree.new-split", + "&s", + @tagName(direction).ptr, + ) != 0; }, } } diff --git a/src/apprt/gtk-ng/class/split_tree.zig b/src/apprt/gtk-ng/class/split_tree.zig index 1da0896a2..a5e823158 100644 --- a/src/apprt/gtk-ng/class/split_tree.zig +++ b/src/apprt/gtk-ng/class/split_tree.zig @@ -175,16 +175,16 @@ pub const SplitTree = extern struct { // // For action names: // https://docs.gtk.org/gio/type_func.Action.name_is_valid.html - const actions = .{ + const actions: []const struct { + [:0]const u8, + *const fn (*gio.SimpleAction, ?*glib.Variant, *Self) callconv(.c) void, + ?*glib.VariantType, + } = &.{ // All of these will eventually take a target surface parameter. // For now all our targets originate from the focused surface. - .{ "new-left", actionNewLeft, null }, - .{ "new-right", actionNewRight, null }, - .{ "new-up", actionNewUp, null }, - .{ "new-down", actionNewDown, null }, - - .{ "equalize", actionEqualize, null }, - .{ "zoom", actionZoom, null }, + .{ "new-split", &actionNewSplit, glib.ext.VariantType.newFor([:0]const u8) }, + .{ "equalize", &actionEqualize, null }, + .{ "zoom", &actionZoom, null }, }; // We need to collect our actions into a group since we're just @@ -192,12 +192,16 @@ pub const SplitTree = extern struct { const group = gio.SimpleActionGroup.new(); errdefer group.unref(); const map = group.as(gio.ActionMap); - inline for (actions) |entry| { + for (actions) |entry| { const action = gio.SimpleAction.new( entry[0], entry[2], ); - defer action.unref(); + defer { + action.unref(); + if (entry[2]) |ptype| ptype.free(); + } + _ = gio.SimpleAction.signals.activate.connect( action, *Self, @@ -567,56 +571,30 @@ pub const SplitTree = extern struct { //--------------------------------------------------------------- // Signal handlers - pub fn actionNewLeft( + pub fn actionNewSplit( _: *gio.SimpleAction, - parameter_: ?*glib.Variant, + args_: ?*glib.Variant, self: *Self, ) callconv(.c) void { - _ = parameter_; - self.newSplit( - .left, - self.getActiveSurface(), - ) catch |err| { - log.warn("new split failed error={}", .{err}); + const args = args_ orelse { + log.warn("split-tree.new-split called without a parameter", .{}); + return; }; - } - pub fn actionNewRight( - _: *gio.SimpleAction, - parameter_: ?*glib.Variant, - self: *Self, - ) callconv(.c) void { - _ = parameter_; - self.newSplit( - .right, - self.getActiveSurface(), - ) catch |err| { - log.warn("new split failed error={}", .{err}); + var dir: ?[*:0]const u8 = null; + args.get("&s", &dir); + + const direction = std.meta.stringToEnum( + Surface.Tree.Split.Direction, + std.mem.span(dir) orelse return, + ) orelse { + // Need to be defensive here since actions can be triggered externally. + log.warn("invalid split direction for split-tree.new-split: {s}", .{dir.?}); + return; }; - } - pub fn actionNewUp( - _: *gio.SimpleAction, - parameter_: ?*glib.Variant, - self: *Self, - ) callconv(.c) void { - _ = parameter_; self.newSplit( - .up, - self.getActiveSurface(), - ) catch |err| { - log.warn("new split failed error={}", .{err}); - }; - } - - pub fn actionNewDown( - _: *gio.SimpleAction, - parameter_: ?*glib.Variant, - self: *Self, - ) callconv(.c) void { - _ = parameter_; - self.newSplit( - .down, + direction, self.getActiveSurface(), ) catch |err| { log.warn("new split failed error={}", .{err}); diff --git a/src/apprt/gtk-ng/ui/1.2/surface.blp b/src/apprt/gtk-ng/ui/1.2/surface.blp index 97fc7483b..98f4f5dd2 100644 --- a/src/apprt/gtk-ng/ui/1.2/surface.blp +++ b/src/apprt/gtk-ng/ui/1.2/surface.blp @@ -194,22 +194,26 @@ menu context_menu_model { item { label: _("Split Up"); - action: "split-tree.new-up"; + action: "split-tree.new-split"; + target: "up"; } item { label: _("Split Down"); - action: "split-tree.new-down"; + action: "split-tree.new-split"; + target: "down"; } item { label: _("Split Left"); - action: "split-tree.new-left"; + action: "split-tree.new-split"; + target: "left"; } item { label: _("Split Right"); - action: "split-tree.new-right"; + action: "split-tree.new-split"; + target: "right"; } }