diff --git a/include/ghostty.h b/include/ghostty.h index 95de1339e..f5e4da8d9 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -262,7 +262,7 @@ typedef void (*ghostty_runtime_new_tab_cb)(void *, ghostty_surface_config_s); typedef void (*ghostty_runtime_new_window_cb)(void *, ghostty_surface_config_s); typedef void (*ghostty_runtime_close_surface_cb)(void *, bool); typedef void (*ghostty_runtime_focus_split_cb)(void *, ghostty_split_focus_direction_e); -typedef void (*ghostty_runtime_zoom_split_cb)(void *); +typedef void (*ghostty_runtime_zoom_split_cb)(void *, bool); typedef void (*ghostty_runtime_goto_tab_cb)(void *, int32_t); typedef void (*ghostty_runtime_toggle_fullscreen_cb)(void *, ghostty_non_native_fullscreen_e); diff --git a/src/Surface.zig b/src/Surface.zig index cbbf4c5f0..7633fd52e 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -2119,9 +2119,14 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void }, .zoom_split => { - log.warn("ZOOM ZOOM", .{}); if (@hasDecl(apprt.Surface, "zoomSplit")) { - self.rt_surface.zoomSplit(); + self.rt_surface.zoomSplit(true); + } else log.warn("runtime doesn't implement zoomSplit", .{}); + }, + + .unzoom_split => { + if (@hasDecl(apprt.Surface, "zoomSplit")) { + self.rt_surface.zoomSplit(false); } else log.warn("runtime doesn't implement zoomSplit", .{}); }, diff --git a/src/apprt/embedded.zig b/src/apprt/embedded.zig index 59d934eb1..60e88c638 100644 --- a/src/apprt/embedded.zig +++ b/src/apprt/embedded.zig @@ -73,7 +73,7 @@ pub const App = struct { focus_split: ?*const fn (SurfaceUD, input.SplitFocusDirection) callconv(.C) void = null, /// Zoom the current split. - zoom_split: ?*const fn (SurfaceUD) callconv(.C) void = null, + zoom_split: ?*const fn (SurfaceUD, bool) callconv(.C) void = null, /// Goto tab goto_tab: ?*const fn (SurfaceUD, usize) callconv(.C) void = null, @@ -273,13 +273,13 @@ pub const Surface = struct { func(self.opts.userdata, direction); } - pub fn zoomSplit(self: *const Surface) void { + pub fn zoomSplit(self: *const Surface, zoom: bool) void { const func = self.app.opts.zoom_split orelse { log.info("runtime embedder does not support zoom split", .{}); return; }; - func(self.opts.userdata); + func(self.opts.userdata, zoom); } pub fn getContentScale(self: *const Surface) !apprt.ContentScale { diff --git a/src/config.zig b/src/config.zig index c73b288ca..c99845ef8 100644 --- a/src/config.zig +++ b/src/config.zig @@ -688,6 +688,11 @@ pub const Config = struct { .{ .key = .equal, .mods = .{ .super = true, .shift = true } }, .{ .zoom_split = {} }, ); + try result.keybind.set.put( + alloc, + .{ .key = .minus, .mods = .{ .super = true, .shift = true } }, + .{ .unzoom_split = {} }, + ); } return result; diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 7324748be..d146d7b52 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -160,6 +160,7 @@ pub const Action = union(enum) { /// Zoom and unzoom the current split. zoom_split: void, + unzoom_split: void, /// Reload the configuration. The exact meaning depends on the app runtime /// in use but this usually involves re-reading the configuration file