From 4570356e577995578a7120c01837c24d918cf96c Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 2 Sep 2023 16:03:51 -0700 Subject: [PATCH] turn zoom into a toggle rather than an explicit zoom/unzoom --- include/ghostty.h | 4 ++-- macos/Sources/Ghostty/AppState.swift | 11 +++-------- macos/Sources/Ghostty/Ghostty.SplitView.swift | 8 ++------ macos/Sources/Ghostty/Package.swift | 7 ++----- src/Surface.zig | 14 ++++---------- src/apprt/embedded.zig | 10 +++++----- src/config.zig | 18 +++++++----------- src/input/Binding.zig | 5 ++--- 8 files changed, 27 insertions(+), 50 deletions(-) diff --git a/include/ghostty.h b/include/ghostty.h index f5e4da8d9..8d5c8cf8c 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 *, bool); +typedef void (*ghostty_runtime_toggle_split_zoom_cb)(void *); typedef void (*ghostty_runtime_goto_tab_cb)(void *, int32_t); typedef void (*ghostty_runtime_toggle_fullscreen_cb)(void *, ghostty_non_native_fullscreen_e); @@ -279,7 +279,7 @@ typedef struct { ghostty_runtime_new_window_cb new_window_cb; ghostty_runtime_close_surface_cb close_surface_cb; ghostty_runtime_focus_split_cb focus_split_cb; - ghostty_runtime_zoom_split_cb zoom_split_cb; + ghostty_runtime_toggle_split_zoom_cb toggle_split_zoom_cb; ghostty_runtime_goto_tab_cb goto_tab_cb; ghostty_runtime_toggle_fullscreen_cb toggle_fullscreen_cb; } ghostty_runtime_config_s; diff --git a/macos/Sources/Ghostty/AppState.swift b/macos/Sources/Ghostty/AppState.swift index e55031bc3..2eccd3c2a 100644 --- a/macos/Sources/Ghostty/AppState.swift +++ b/macos/Sources/Ghostty/AppState.swift @@ -73,7 +73,7 @@ extension Ghostty { new_window_cb: { userdata, surfaceConfig in AppState.newWindow(userdata, config: surfaceConfig) }, close_surface_cb: { userdata, processAlive in AppState.closeSurface(userdata, processAlive: processAlive) }, focus_split_cb: { userdata, direction in AppState.focusSplit(userdata, direction: direction) }, - zoom_split_cb: { userdata, zoom in AppState.zoomSplit(userdata, zoom: zoom) }, + toggle_split_zoom_cb: { userdata in AppState.toggleSplitZoom(userdata) }, goto_tab_cb: { userdata, n in AppState.gotoTab(userdata, n: n) }, toggle_fullscreen_cb: { userdata, nonNativeFullscreen in AppState.toggleFullscreen(userdata, nonNativeFullscreen: nonNativeFullscreen) } ) @@ -206,16 +206,11 @@ extension Ghostty { ) } - static func zoomSplit(_ userdata: UnsafeMutableRawPointer?, zoom: Bool) { + static func toggleSplitZoom(_ userdata: UnsafeMutableRawPointer?) { guard let surface = self.surfaceUserdata(from: userdata) else { return } - var name = Notification.didZoomSplit - if (!zoom) { - name = Notification.didZoomResetSplit - } - NotificationCenter.default.post( - name: name, + name: Notification.didToggleSplitZoom, object: surface ) } diff --git a/macos/Sources/Ghostty/Ghostty.SplitView.swift b/macos/Sources/Ghostty/Ghostty.SplitView.swift index 0af024dda..4dc9c24df 100644 --- a/macos/Sources/Ghostty/Ghostty.SplitView.swift +++ b/macos/Sources/Ghostty/Ghostty.SplitView.swift @@ -199,14 +199,13 @@ extension Ghostty { var body: some View { let center = NotificationCenter.default + let pubZoom = center.publisher(for: Notification.didToggleSplitZoom) // If we're zoomed, we don't render anything, we are transparent. This // ensures that the View stays around so we don't lose our state, but // also that the zoomed view on top can see through if background transparency // is enabled. if (zoomedSurface == nil) { - let pubZoom = center.publisher(for: Notification.didZoomSplit) - ZStack { switch (node) { case .noSplit(let leaf): @@ -248,11 +247,8 @@ extension Ghostty { } .navigationTitle(surfaceTitle ?? "Ghostty") } else { - // If we're zoomed, we want to listen for zoom resets. - let pubZoomReset = center.publisher(for: Notification.didZoomResetSplit) - ZStack {} - .onReceive(pubZoomReset) { onZoomReset(notification: $0) } + .onReceive(pubZoom) { onZoomReset(notification: $0) } } } diff --git a/macos/Sources/Ghostty/Package.swift b/macos/Sources/Ghostty/Package.swift index 35b0dca89..81404fbfb 100644 --- a/macos/Sources/Ghostty/Package.swift +++ b/macos/Sources/Ghostty/Package.swift @@ -96,11 +96,8 @@ extension Ghostty.Notification { /// work around bugs. macOS 13+ should use the ".focused()" attribute. static let didBecomeFocusedSurface = Notification.Name("com.mitchellh.ghostty.didBecomeFocusedSurface") - /// Notification that a surface is being zoomed or unzoomed. Note that these are sent - /// regardless of if the surface is part of a split or not. It is up to the receiver to validate - /// this. - static let didZoomSplit = Notification.Name("com.mitchellh.ghostty.didZoomSplit") - static let didZoomResetSplit = Notification.Name("com.mitchellh.ghostty.didZoomResetSplit") + /// Notification sent to toggle split maximize/unmaximize. + static let didToggleSplitZoom = Notification.Name("com.mitchellh.ghostty.didToggleSplitZoom") } // Make the input enum hashable. diff --git a/src/Surface.zig b/src/Surface.zig index 7633fd52e..5531ac986 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -2118,16 +2118,10 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void } else log.warn("runtime doesn't implement gotoSplit", .{}); }, - .zoom_split => { - if (@hasDecl(apprt.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", .{}); + .toggle_split_zoom => { + if (@hasDecl(apprt.Surface, "toggleSplitZoom")) { + self.rt_surface.toggleSplitZoom(); + } else log.warn("runtime doesn't implement toggleSplitZoom", .{}); }, .toggle_fullscreen => { diff --git a/src/apprt/embedded.zig b/src/apprt/embedded.zig index 60e88c638..7d246c940 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, bool) callconv(.C) void = null, + toggle_split_zoom: ?*const fn (SurfaceUD) 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, zoom: bool) void { - const func = self.app.opts.zoom_split orelse { - log.info("runtime embedder does not support zoom split", .{}); + pub fn toggleSplitZoom(self: *const Surface) void { + const func = self.app.opts.toggle_split_zoom orelse { + log.info("runtime embedder does not support split zoom", .{}); return; }; - func(self.opts.userdata, zoom); + func(self.opts.userdata); } pub fn getContentScale(self: *const Surface) !apprt.ContentScale { diff --git a/src/config.zig b/src/config.zig index c99845ef8..7c111ca90 100644 --- a/src/config.zig +++ b/src/config.zig @@ -563,6 +563,13 @@ pub const Config = struct { .{ .toggle_fullscreen = {} }, ); + // Toggle zoom a split + try result.keybind.set.put( + alloc, + .{ .key = .enter, .mods = ctrlOrSuper(.{ .shift = true }) }, + .{ .toggle_split_zoom = {} }, + ); + // Mac-specific keyboard bindings. if (comptime builtin.target.isDarwin()) { try result.keybind.set.put( @@ -682,17 +689,6 @@ pub const Config = struct { .{ .key = .right, .mods = .{ .super = true, .alt = true } }, .{ .goto_split = .right }, ); - - try result.keybind.set.put( - alloc, - .{ .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 d146d7b52..9cbd2f1c4 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -158,9 +158,8 @@ pub const Action = union(enum) { /// Focus on a split in a given direction. goto_split: SplitFocusDirection, - /// Zoom and unzoom the current split. - zoom_split: void, - unzoom_split: void, + /// zoom/unzoom the current split. + toggle_split_zoom: void, /// Reload the configuration. The exact meaning depends on the app runtime /// in use but this usually involves re-reading the configuration file