mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
core: many more actions
This commit is contained in:
101
src/Surface.zig
101
src/Surface.zig
@ -841,7 +841,7 @@ fn passwordInput(self: *Surface, v: bool) !void {
|
|||||||
self.rt_app.performAction(
|
self.rt_app.performAction(
|
||||||
.{ .surface = self },
|
.{ .surface = self },
|
||||||
.secure_input,
|
.secure_input,
|
||||||
v,
|
if (v) .on else .off,
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
// We ignore this error because we don't want to fail this
|
// We ignore this error because we don't want to fail this
|
||||||
// entire operation just because the apprt failed to set
|
// entire operation just because the apprt failed to set
|
||||||
@ -3685,44 +3685,55 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
.new_split => |direction| {
|
.new_split => |direction| try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "newSplit")) {
|
.{ .surface = self },
|
||||||
try self.rt_surface.newSplit(switch (direction) {
|
.new_split,
|
||||||
.right => .right,
|
switch (direction) {
|
||||||
.down => .down,
|
.right => .right,
|
||||||
.auto => if (self.screen_size.width > self.screen_size.height)
|
.down => .down,
|
||||||
.right
|
.auto => if (self.screen_size.width > self.screen_size.height)
|
||||||
else
|
.right
|
||||||
.down,
|
else
|
||||||
});
|
.down,
|
||||||
} else log.warn("runtime doesn't implement newSplit", .{});
|
},
|
||||||
},
|
),
|
||||||
|
|
||||||
.goto_split => |direction| {
|
.goto_split => |direction| try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "gotoSplit")) {
|
.{ .surface = self },
|
||||||
self.rt_surface.gotoSplit(direction);
|
.goto_split,
|
||||||
} else log.warn("runtime doesn't implement gotoSplit", .{});
|
switch (direction) {
|
||||||
},
|
inline else => |tag| @field(
|
||||||
|
apprt.action.GotoSplit,
|
||||||
|
@tagName(tag),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
.resize_split => |param| {
|
.resize_split => |value| try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "resizeSplit")) {
|
.{ .surface = self },
|
||||||
const direction = param[0];
|
.resize_split,
|
||||||
const amount = param[1];
|
.{
|
||||||
self.rt_surface.resizeSplit(direction, amount);
|
.amount = value[1],
|
||||||
} else log.warn("runtime doesn't implement resizeSplit", .{});
|
.direction = switch (value[0]) {
|
||||||
},
|
inline else => |tag| @field(
|
||||||
|
apprt.action.ResizeSplit.Direction,
|
||||||
|
@tagName(tag),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
.equalize_splits => {
|
.equalize_splits => try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "equalizeSplits")) {
|
.{ .surface = self },
|
||||||
self.rt_surface.equalizeSplits();
|
.equalize_splits,
|
||||||
} else log.warn("runtime doesn't implement equalizeSplits", .{});
|
{},
|
||||||
},
|
),
|
||||||
|
|
||||||
.toggle_split_zoom => {
|
.toggle_split_zoom => try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "toggleSplitZoom")) {
|
.{ .surface = self },
|
||||||
self.rt_surface.toggleSplitZoom();
|
.toggle_split_zoom,
|
||||||
} else log.warn("runtime doesn't implement toggleSplitZoom", .{});
|
{},
|
||||||
},
|
),
|
||||||
|
|
||||||
.toggle_fullscreen => {
|
.toggle_fullscreen => {
|
||||||
if (@hasDecl(apprt.Surface, "toggleFullscreen")) {
|
if (@hasDecl(apprt.Surface, "toggleFullscreen")) {
|
||||||
@ -3730,17 +3741,17 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
} else log.warn("runtime doesn't implement toggleFullscreen", .{});
|
} else log.warn("runtime doesn't implement toggleFullscreen", .{});
|
||||||
},
|
},
|
||||||
|
|
||||||
.toggle_window_decorations => {
|
.toggle_window_decorations => try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "toggleWindowDecorations")) {
|
.{ .surface = self },
|
||||||
self.rt_surface.toggleWindowDecorations();
|
.toggle_window_decorations,
|
||||||
} else log.warn("runtime doesn't implement toggleWindowDecorations", .{});
|
{},
|
||||||
},
|
),
|
||||||
|
|
||||||
.toggle_secure_input => {
|
.toggle_secure_input => try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "toggleSecureInput")) {
|
.{ .surface = self },
|
||||||
self.rt_surface.toggleSecureInput();
|
.secure_input,
|
||||||
} else log.warn("runtime doesn't implement toggleSecureInput", .{});
|
.toggle,
|
||||||
},
|
),
|
||||||
|
|
||||||
.select_all => {
|
.select_all => {
|
||||||
const sel = self.io.terminal.screen.selectAll();
|
const sel = self.io.terminal.screen.selectAll();
|
||||||
|
@ -32,10 +32,8 @@ pub const ClipboardRequestType = structs.ClipboardRequestType;
|
|||||||
pub const ColorScheme = structs.ColorScheme;
|
pub const ColorScheme = structs.ColorScheme;
|
||||||
pub const CursorPos = structs.CursorPos;
|
pub const CursorPos = structs.CursorPos;
|
||||||
pub const DesktopNotification = structs.DesktopNotification;
|
pub const DesktopNotification = structs.DesktopNotification;
|
||||||
pub const GotoTab = structs.GotoTab;
|
|
||||||
pub const IMEPos = structs.IMEPos;
|
pub const IMEPos = structs.IMEPos;
|
||||||
pub const Selection = structs.Selection;
|
pub const Selection = structs.Selection;
|
||||||
pub const SplitDirection = structs.SplitDirection;
|
|
||||||
pub const SurfaceSize = structs.SurfaceSize;
|
pub const SurfaceSize = structs.SurfaceSize;
|
||||||
|
|
||||||
/// The implementation to use for the app runtime. This is comptime chosen
|
/// The implementation to use for the app runtime. This is comptime chosen
|
||||||
|
@ -21,12 +21,32 @@ pub const Action = union(enum) {
|
|||||||
/// the tab should be opened in a new window.
|
/// the tab should be opened in a new window.
|
||||||
new_tab,
|
new_tab,
|
||||||
|
|
||||||
|
/// Create a new split. The value determines the location of the split
|
||||||
|
/// relative to the target.
|
||||||
|
new_split: SplitDirection,
|
||||||
|
|
||||||
|
/// Close all open windows.
|
||||||
|
close_all_windows,
|
||||||
|
|
||||||
|
/// Toggle whether window directions are shown.
|
||||||
|
toggle_window_decorations,
|
||||||
|
|
||||||
/// Jump to a specific tab. Must handle the scenario that the tab
|
/// Jump to a specific tab. Must handle the scenario that the tab
|
||||||
/// value is invalid.
|
/// value is invalid.
|
||||||
goto_tab: GotoTab,
|
goto_tab: GotoTab,
|
||||||
|
|
||||||
/// Close all open windows.
|
/// Jump to a specific split.
|
||||||
close_all_windows,
|
goto_split: GotoSplit,
|
||||||
|
|
||||||
|
/// Resize the split in the given direction.
|
||||||
|
resize_split: ResizeSplit,
|
||||||
|
|
||||||
|
/// Equalize all the splits in the target window.
|
||||||
|
equalize_splits,
|
||||||
|
|
||||||
|
/// Toggle whether a split is zoomed or not. A zoomed split is resized
|
||||||
|
/// to take up the entire window.
|
||||||
|
toggle_split_zoom,
|
||||||
|
|
||||||
/// Open the Ghostty configuration. This is platform-specific about
|
/// Open the Ghostty configuration. This is platform-specific about
|
||||||
/// what it means; it can mean opening a dedicated UI or just opening
|
/// what it means; it can mean opening a dedicated UI or just opening
|
||||||
@ -44,7 +64,7 @@ pub const Action = union(enum) {
|
|||||||
/// entering a password or other sensitive information. This can be used
|
/// entering a password or other sensitive information. This can be used
|
||||||
/// by the app runtime to change the appearance of the cursor, setup
|
/// by the app runtime to change the appearance of the cursor, setup
|
||||||
/// system APIs to not log the input, etc.
|
/// system APIs to not log the input, etc.
|
||||||
secure_input: bool,
|
secure_input: SecureInput,
|
||||||
|
|
||||||
/// The enum of keys in the tagged union.
|
/// The enum of keys in the tagged union.
|
||||||
pub const Key = @typeInfo(Action).Union.tag_type.?;
|
pub const Key = @typeInfo(Action).Union.tag_type.?;
|
||||||
@ -68,6 +88,38 @@ pub const Target = union(enum) {
|
|||||||
surface: *CoreSurface,
|
surface: *CoreSurface,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is made extern (c_int) to make interop easier with our embedded
|
||||||
|
// runtime. The small size cost doesn't make a difference in our union.
|
||||||
|
pub const SplitDirection = enum(c_int) {
|
||||||
|
right,
|
||||||
|
down,
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is made extern (c_int) to make interop easier with our embedded
|
||||||
|
// runtime. The small size cost doesn't make a difference in our union.
|
||||||
|
pub const GotoSplit = enum(c_int) {
|
||||||
|
previous,
|
||||||
|
next,
|
||||||
|
|
||||||
|
top,
|
||||||
|
left,
|
||||||
|
bottom,
|
||||||
|
right,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The amount to resize the split by and the direction to resize it in.
|
||||||
|
pub const ResizeSplit = struct {
|
||||||
|
amount: u16,
|
||||||
|
direction: Direction,
|
||||||
|
|
||||||
|
pub const Direction = enum(c_int) {
|
||||||
|
up,
|
||||||
|
down,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/// The tab to jump to. This is non-exhaustive so that integer values represent
|
/// The tab to jump to. This is non-exhaustive so that integer values represent
|
||||||
/// the index (zero-based) of the tab to jump to. Negative values are special
|
/// the index (zero-based) of the tab to jump to. Negative values are special
|
||||||
/// values.
|
/// values.
|
||||||
@ -77,3 +129,9 @@ pub const GotoTab = enum(c_int) {
|
|||||||
last = -3,
|
last = -3,
|
||||||
_,
|
_,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const SecureInput = enum(c_int) {
|
||||||
|
on,
|
||||||
|
off,
|
||||||
|
toggle,
|
||||||
|
};
|
||||||
|
@ -81,7 +81,7 @@ pub const App = struct {
|
|||||||
|
|
||||||
/// Create a new split view. If the embedder doesn't support split
|
/// Create a new split view. If the embedder doesn't support split
|
||||||
/// views then this can be null.
|
/// views then this can be null.
|
||||||
new_split: ?*const fn (SurfaceUD, apprt.SplitDirection, apprt.Surface.Options) callconv(.C) void = null,
|
new_split: ?*const fn (SurfaceUD, apprt.action.SplitDirection, apprt.Surface.Options) callconv(.C) void = null,
|
||||||
|
|
||||||
/// New tab with options. The surface may be null if there is no target
|
/// New tab with options. The surface may be null if there is no target
|
||||||
/// surface in which case the apprt is expected to create a new window.
|
/// surface in which case the apprt is expected to create a new window.
|
||||||
@ -98,10 +98,10 @@ pub const App = struct {
|
|||||||
close_surface: ?*const fn (SurfaceUD, bool) callconv(.C) void = null,
|
close_surface: ?*const fn (SurfaceUD, bool) callconv(.C) void = null,
|
||||||
|
|
||||||
/// Focus the previous/next split (if any).
|
/// Focus the previous/next split (if any).
|
||||||
focus_split: ?*const fn (SurfaceUD, input.SplitFocusDirection) callconv(.C) void = null,
|
focus_split: ?*const fn (SurfaceUD, apprt.action.GotoSplit) callconv(.C) void = null,
|
||||||
|
|
||||||
/// Resize the current split.
|
/// Resize the current split.
|
||||||
resize_split: ?*const fn (SurfaceUD, input.SplitResizeDirection, u16) callconv(.C) void = null,
|
resize_split: ?*const fn (SurfaceUD, apprt.action.ResizeSplit.Direction, u16) callconv(.C) void = null,
|
||||||
|
|
||||||
/// Equalize all splits in the current window
|
/// Equalize all splits in the current window
|
||||||
equalize_splits: ?*const fn (SurfaceUD) callconv(.C) void = null,
|
equalize_splits: ?*const fn (SurfaceUD) callconv(.C) void = null,
|
||||||
@ -534,16 +534,113 @@ pub const App = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setPasswordInput(self: *App, target: apprt.Target, v: bool) void {
|
fn newSplit(
|
||||||
const func = self.opts.set_password_input orelse {
|
self: *const App,
|
||||||
log.info("runtime embedder does not support set_password_input", .{});
|
target: apprt.Target,
|
||||||
|
direction: apprt.action.SplitDirection,
|
||||||
|
) void {
|
||||||
|
const func = self.opts.new_split orelse {
|
||||||
|
log.info("runtime embedder does not support splits", .{});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
func(switch (target) {
|
switch (target) {
|
||||||
.app => null,
|
.app => func(null, direction, .{}),
|
||||||
.surface => |surface| surface.rt_surface.userdata,
|
.surface => |v| func(
|
||||||
}, v);
|
v.rt_surface.userdata,
|
||||||
|
direction,
|
||||||
|
v.rt_surface.newSurfaceOptions(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gotoSplit(
|
||||||
|
self: *const App,
|
||||||
|
target: apprt.Target,
|
||||||
|
direction: apprt.action.GotoSplit,
|
||||||
|
) void {
|
||||||
|
const func = self.opts.focus_split orelse {
|
||||||
|
log.info("runtime embedder does not support focus split", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (target) {
|
||||||
|
.app => {},
|
||||||
|
.surface => |v| func(v.rt_surface.userdata, direction),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resizeSplit(
|
||||||
|
self: *const App,
|
||||||
|
target: apprt.Target,
|
||||||
|
resize: apprt.action.ResizeSplit,
|
||||||
|
) void {
|
||||||
|
const func = self.opts.resize_split orelse {
|
||||||
|
log.info("runtime embedder does not support resize split", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (target) {
|
||||||
|
.app => {},
|
||||||
|
.surface => |v| func(
|
||||||
|
v.rt_surface.userdata,
|
||||||
|
resize.direction,
|
||||||
|
resize.amount,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn equalizeSplits(self: *const App, target: apprt.Target) void {
|
||||||
|
const func = self.opts.equalize_splits orelse {
|
||||||
|
log.info("runtime embedder does not support equalize splits", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (target) {
|
||||||
|
.app => func(null),
|
||||||
|
.surface => |v| func(v.rt_surface.userdata),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toggleSplitZoom(self: *const App, target: apprt.Target) void {
|
||||||
|
const func = self.opts.toggle_split_zoom orelse {
|
||||||
|
log.info("runtime embedder does not support split zoom", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (target) {
|
||||||
|
.app => func(null),
|
||||||
|
.surface => |v| func(v.rt_surface.userdata),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setPasswordInput(self: *App, target: apprt.Target, v: apprt.action.SecureInput) void {
|
||||||
|
switch (v) {
|
||||||
|
inline .on, .off => |tag| {
|
||||||
|
const func = self.opts.set_password_input orelse {
|
||||||
|
log.info("runtime embedder does not support set_password_input", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
func(switch (target) {
|
||||||
|
.app => null,
|
||||||
|
.surface => |surface| surface.rt_surface.userdata,
|
||||||
|
}, switch (tag) {
|
||||||
|
.on => true,
|
||||||
|
.off => false,
|
||||||
|
else => comptime unreachable,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
.toggle => {
|
||||||
|
const func = self.opts.toggle_secure_input orelse {
|
||||||
|
log.info("runtime embedder does not support toggle_secure_input", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
func();
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a given action.
|
/// Perform a given action.
|
||||||
@ -561,11 +658,17 @@ pub const App = struct {
|
|||||||
|
|
||||||
.new_tab => self.newTab(target),
|
.new_tab => self.newTab(target),
|
||||||
.goto_tab => self.gotoTab(target, value),
|
.goto_tab => self.gotoTab(target, value),
|
||||||
|
.new_split => self.newSplit(target, value),
|
||||||
|
.resize_split => self.resizeSplit(target, value),
|
||||||
|
.equalize_splits => self.equalizeSplits(target),
|
||||||
|
.toggle_split_zoom => self.toggleSplitZoom(target),
|
||||||
|
.goto_split => self.gotoSplit(target, value),
|
||||||
.open_config => try configpkg.edit.open(self.core_app.alloc),
|
.open_config => try configpkg.edit.open(self.core_app.alloc),
|
||||||
.secure_input => self.setPasswordInput(target, value),
|
.secure_input => self.setPasswordInput(target, value),
|
||||||
|
|
||||||
// Unimplemented
|
// Unimplemented
|
||||||
.close_all_windows,
|
.close_all_windows,
|
||||||
|
.toggle_window_decorations,
|
||||||
.quit_timer,
|
.quit_timer,
|
||||||
=> log.warn("unimplemented action={}", .{action}),
|
=> log.warn("unimplemented action={}", .{action}),
|
||||||
}
|
}
|
||||||
@ -795,16 +898,6 @@ pub const Surface = struct {
|
|||||||
func(self.userdata, mode);
|
func(self.userdata, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newSplit(self: *const Surface, direction: apprt.SplitDirection) !void {
|
|
||||||
const func = self.app.opts.new_split orelse {
|
|
||||||
log.info("runtime embedder does not support splits", .{});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = self.newSurfaceOptions();
|
|
||||||
func(self.userdata, direction, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn close(self: *const Surface, process_alive: bool) void {
|
pub fn close(self: *const Surface, process_alive: bool) void {
|
||||||
const func = self.app.opts.close_surface orelse {
|
const func = self.app.opts.close_surface orelse {
|
||||||
log.info("runtime embedder does not support closing a surface", .{});
|
log.info("runtime embedder does not support closing a surface", .{});
|
||||||
@ -814,42 +907,6 @@ pub const Surface = struct {
|
|||||||
func(self.userdata, process_alive);
|
func(self.userdata, process_alive);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gotoSplit(self: *const Surface, direction: input.SplitFocusDirection) void {
|
|
||||||
const func = self.app.opts.focus_split orelse {
|
|
||||||
log.info("runtime embedder does not support focus split", .{});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
func(self.userdata, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resizeSplit(self: *const Surface, direction: input.SplitResizeDirection, amount: u16) void {
|
|
||||||
const func = self.app.opts.resize_split orelse {
|
|
||||||
log.info("runtime embedder does not support resize split", .{});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
func(self.userdata, direction, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn equalizeSplits(self: *const Surface) void {
|
|
||||||
const func = self.app.opts.equalize_splits orelse {
|
|
||||||
log.info("runtime embedder does not support equalize splits", .{});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
func(self.userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn getContentScale(self: *const Surface) !apprt.ContentScale {
|
pub fn getContentScale(self: *const Surface) !apprt.ContentScale {
|
||||||
return self.content_scale;
|
return self.content_scale;
|
||||||
}
|
}
|
||||||
@ -1137,15 +1194,6 @@ pub const Surface = struct {
|
|||||||
func(self.userdata, nonNativeFullscreen);
|
func(self.userdata, nonNativeFullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggleSecureInput(self: *Surface) void {
|
|
||||||
const func = self.app.opts.toggle_secure_input orelse {
|
|
||||||
log.info("runtime embedder does not toggle_secure_input", .{});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn newWindow(self: *const Surface) !void {
|
fn newWindow(self: *const Surface) !void {
|
||||||
const func = self.app.opts.new_window orelse {
|
const func = self.app.opts.new_window orelse {
|
||||||
log.info("runtime embedder does not support new_window", .{});
|
log.info("runtime embedder does not support new_window", .{});
|
||||||
@ -1899,26 +1947,61 @@ pub const CAPI = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Request that the surface split in the given direction.
|
/// Request that the surface split in the given direction.
|
||||||
export fn ghostty_surface_split(ptr: *Surface, direction: apprt.SplitDirection) void {
|
export fn ghostty_surface_split(ptr: *Surface, direction: apprt.action.SplitDirection) void {
|
||||||
ptr.newSplit(direction) catch {};
|
ptr.app.performAction(
|
||||||
|
.{ .surface = &ptr.core_surface },
|
||||||
|
.new_split,
|
||||||
|
direction,
|
||||||
|
) catch |err| {
|
||||||
|
log.err("error creating new split err={}", .{err});
|
||||||
|
return;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Focus on the next split (if any).
|
/// Focus on the next split (if any).
|
||||||
export fn ghostty_surface_split_focus(ptr: *Surface, direction: input.SplitFocusDirection) void {
|
export fn ghostty_surface_split_focus(
|
||||||
ptr.gotoSplit(direction);
|
ptr: *Surface,
|
||||||
|
direction: apprt.action.GotoSplit,
|
||||||
|
) void {
|
||||||
|
ptr.app.performAction(
|
||||||
|
.{ .surface = &ptr.core_surface },
|
||||||
|
.goto_split,
|
||||||
|
direction,
|
||||||
|
) catch |err| {
|
||||||
|
log.err("error creating new split err={}", .{err});
|
||||||
|
return;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize the current split by moving the split divider in the given
|
/// Resize the current split by moving the split divider in the given
|
||||||
/// direction. `direction` specifies which direction the split divider will
|
/// direction. `direction` specifies which direction the split divider will
|
||||||
/// move relative to the focused split. `amount` is a fractional value
|
/// move relative to the focused split. `amount` is a fractional value
|
||||||
/// between 0 and 1 that specifies by how much the divider will move.
|
/// between 0 and 1 that specifies by how much the divider will move.
|
||||||
export fn ghostty_surface_split_resize(ptr: *Surface, direction: input.SplitResizeDirection, amount: u16) void {
|
export fn ghostty_surface_split_resize(
|
||||||
ptr.resizeSplit(direction, amount);
|
ptr: *Surface,
|
||||||
|
direction: apprt.action.ResizeSplit.Direction,
|
||||||
|
amount: u16,
|
||||||
|
) void {
|
||||||
|
ptr.app.performAction(
|
||||||
|
.{ .surface = &ptr.core_surface },
|
||||||
|
.resize_split,
|
||||||
|
.{ .direction = direction, .amount = amount },
|
||||||
|
) catch |err| {
|
||||||
|
log.err("error resizing split err={}", .{err});
|
||||||
|
return;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Equalize the size of all splits in the current window.
|
/// Equalize the size of all splits in the current window.
|
||||||
export fn ghostty_surface_split_equalize(ptr: *Surface) void {
|
export fn ghostty_surface_split_equalize(ptr: *Surface) void {
|
||||||
ptr.equalizeSplits();
|
ptr.app.performAction(
|
||||||
|
.{ .surface = &ptr.core_surface },
|
||||||
|
.equalize_splits,
|
||||||
|
{},
|
||||||
|
) catch |err| {
|
||||||
|
log.err("error equalizing splits err={}", .{err});
|
||||||
|
return;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invoke an action on the surface.
|
/// Invoke an action on the surface.
|
||||||
|
@ -150,7 +150,13 @@ pub const App = struct {
|
|||||||
.open_config => try configpkg.edit.open(self.app.alloc),
|
.open_config => try configpkg.edit.open(self.app.alloc),
|
||||||
|
|
||||||
// Unimplemented
|
// Unimplemented
|
||||||
|
.new_split,
|
||||||
|
.goto_split,
|
||||||
|
.resize_split,
|
||||||
|
.equalize_splits,
|
||||||
|
.toggle_split_zoom,
|
||||||
.close_all_windows,
|
.close_all_windows,
|
||||||
|
.toggle_window_decorations,
|
||||||
.goto_tab,
|
.goto_tab,
|
||||||
.quit_timer,
|
.quit_timer,
|
||||||
.secure_input,
|
.secure_input,
|
||||||
|
@ -62,13 +62,6 @@ pub const DesktopNotification = struct {
|
|||||||
body: []const u8,
|
body: []const u8,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is made extern (c_int) to make interop easier with our embedded
|
|
||||||
// runtime. The small size cost doesn't make a difference in our union.
|
|
||||||
pub const SplitDirection = enum(c_int) {
|
|
||||||
right,
|
|
||||||
down,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The color scheme in use (light vs dark).
|
/// The color scheme in use (light vs dark).
|
||||||
pub const ColorScheme = enum(u2) {
|
pub const ColorScheme = enum(u2) {
|
||||||
light = 0,
|
light = 0,
|
||||||
|
@ -410,8 +410,7 @@ pub const Action = union(enum) {
|
|||||||
// Note: we don't support top or left yet
|
// Note: we don't support top or left yet
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extern because it is used in the embedded runtime ABI.
|
pub const SplitFocusDirection = enum {
|
||||||
pub const SplitFocusDirection = enum(c_int) {
|
|
||||||
previous,
|
previous,
|
||||||
next,
|
next,
|
||||||
|
|
||||||
@ -421,8 +420,7 @@ pub const Action = union(enum) {
|
|||||||
right,
|
right,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extern because it is used in the embedded runtime ABI.
|
pub const SplitResizeDirection = enum {
|
||||||
pub const SplitResizeDirection = enum(c_int) {
|
|
||||||
up,
|
up,
|
||||||
down,
|
down,
|
||||||
left,
|
left,
|
||||||
|
Reference in New Issue
Block a user