mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
core: more actions
This commit is contained in:
@ -3663,35 +3663,27 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||
v,
|
||||
),
|
||||
|
||||
.new_tab => {
|
||||
if (@hasDecl(apprt.Surface, "newTab")) {
|
||||
try self.rt_surface.newTab();
|
||||
} else log.warn("runtime doesn't implement newTab", .{});
|
||||
},
|
||||
.new_tab => try self.rt_app.performAction(
|
||||
.{ .surface = self },
|
||||
.new_tab,
|
||||
{},
|
||||
),
|
||||
|
||||
.previous_tab => {
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(.previous);
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
},
|
||||
|
||||
.next_tab => {
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(.next);
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
},
|
||||
|
||||
.last_tab => {
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(.last);
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
},
|
||||
|
||||
.goto_tab => |n| {
|
||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
||||
self.rt_surface.gotoTab(@enumFromInt(n));
|
||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
||||
inline .previous_tab,
|
||||
.next_tab,
|
||||
.last_tab,
|
||||
.goto_tab,
|
||||
=> |v, tag| try self.rt_app.performAction(
|
||||
.{ .surface = self },
|
||||
.goto_tab,
|
||||
switch (tag) {
|
||||
.previous_tab => .previous,
|
||||
.next_tab => .next,
|
||||
.last_tab => .last,
|
||||
.goto_tab => @enumFromInt(v),
|
||||
else => comptime unreachable,
|
||||
},
|
||||
),
|
||||
|
||||
.new_split => |direction| {
|
||||
if (@hasDecl(apprt.Surface, "newSplit")) {
|
||||
|
@ -12,9 +12,9 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const build_config = @import("build_config.zig");
|
||||
|
||||
const action = @import("apprt/action.zig");
|
||||
const structs = @import("apprt/structs.zig");
|
||||
|
||||
pub const action = @import("apprt/action.zig");
|
||||
pub const glfw = @import("apprt/glfw.zig");
|
||||
pub const gtk = @import("apprt/gtk.zig");
|
||||
pub const none = @import("apprt/none.zig");
|
||||
|
@ -16,6 +16,15 @@ pub const Action = union(enum) {
|
||||
/// as font size should be inherited.
|
||||
new_window,
|
||||
|
||||
/// Open a new tab. If the target is a surface it should be opened in
|
||||
/// the same window as the surface. If the target is the app then
|
||||
/// the tab should be opened in a new window.
|
||||
new_tab,
|
||||
|
||||
/// Jump to a specific tab. Must handle the scenario that the tab
|
||||
/// value is invalid.
|
||||
goto_tab: GotoTab,
|
||||
|
||||
/// Close all open windows.
|
||||
close_all_windows,
|
||||
|
||||
@ -58,3 +67,13 @@ pub const Target = union(enum) {
|
||||
app,
|
||||
surface: *CoreSurface,
|
||||
};
|
||||
|
||||
/// 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
|
||||
/// values.
|
||||
pub const GotoTab = enum(c_int) {
|
||||
previous = -1,
|
||||
next = -2,
|
||||
last = -3,
|
||||
_,
|
||||
};
|
||||
|
@ -83,7 +83,8 @@ pub const App = struct {
|
||||
/// views then this can be null.
|
||||
new_split: ?*const fn (SurfaceUD, apprt.SplitDirection, apprt.Surface.Options) callconv(.C) void = null,
|
||||
|
||||
/// New tab with options.
|
||||
/// 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.
|
||||
new_tab: ?*const fn (SurfaceUD, apprt.Surface.Options) callconv(.C) void = null,
|
||||
|
||||
/// New window with options. The surface may be null if there is no
|
||||
@ -109,7 +110,7 @@ pub const App = struct {
|
||||
toggle_split_zoom: ?*const fn (SurfaceUD) callconv(.C) void = null,
|
||||
|
||||
/// Goto tab
|
||||
goto_tab: ?*const fn (SurfaceUD, apprt.GotoTab) callconv(.C) void = null,
|
||||
goto_tab: ?*const fn (SurfaceUD, apprt.action.GotoTab) callconv(.C) void = null,
|
||||
|
||||
/// Toggle fullscreen for current window.
|
||||
toggle_fullscreen: ?*const fn (SurfaceUD, configpkg.NonNativeFullscreen) callconv(.C) void = null,
|
||||
@ -506,9 +507,36 @@ pub const App = struct {
|
||||
func(null, .{});
|
||||
}
|
||||
|
||||
fn newTab(self: *const App, target: apprt.Target) void {
|
||||
const func = self.opts.new_tab orelse {
|
||||
log.info("runtime embedder does not support new_tab", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
switch (target) {
|
||||
.app => func(null, .{}),
|
||||
.surface => |v| func(
|
||||
v.rt_surface.userdata,
|
||||
v.rt_surface.newSurfaceOptions(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn gotoTab(self: *App, target: apprt.Target, tab: apprt.action.GotoTab) void {
|
||||
const func = self.opts.goto_tab orelse {
|
||||
log.info("runtime embedder does not support goto_tab", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
switch (target) {
|
||||
.app => {},
|
||||
.surface => |v| func(v.rt_surface.userdata, tab),
|
||||
}
|
||||
}
|
||||
|
||||
fn setPasswordInput(self: *App, target: apprt.Target, v: bool) void {
|
||||
const func = self.opts.set_password_input orelse {
|
||||
log.info("runtime embedder does not set_password_input", .{});
|
||||
log.info("runtime embedder does not support set_password_input", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
@ -531,8 +559,9 @@ pub const App = struct {
|
||||
.surface => |v| v,
|
||||
}),
|
||||
|
||||
.new_tab => self.newTab(target),
|
||||
.goto_tab => self.gotoTab(target, value),
|
||||
.open_config => try configpkg.edit.open(self.core_app.alloc),
|
||||
|
||||
.secure_input => self.setPasswordInput(target, value),
|
||||
|
||||
// Unimplemented
|
||||
@ -1099,15 +1128,6 @@ pub const Surface = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn gotoTab(self: *Surface, tab: apprt.GotoTab) void {
|
||||
const func = self.app.opts.goto_tab orelse {
|
||||
log.info("runtime embedder does not goto_tab", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
func(self.userdata, tab);
|
||||
}
|
||||
|
||||
pub fn toggleFullscreen(self: *Surface, nonNativeFullscreen: configpkg.NonNativeFullscreen) void {
|
||||
const func = self.app.opts.toggle_fullscreen orelse {
|
||||
log.info("runtime embedder does not toggle_fullscreen", .{});
|
||||
@ -1126,16 +1146,6 @@ pub const Surface = struct {
|
||||
func();
|
||||
}
|
||||
|
||||
pub fn newTab(self: *const Surface) !void {
|
||||
const func = self.app.opts.new_tab orelse {
|
||||
log.info("runtime embedder does not support new_tab", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
const options = self.newSurfaceOptions();
|
||||
func(self.userdata, options);
|
||||
}
|
||||
|
||||
fn newWindow(self: *const Surface) !void {
|
||||
const func = self.app.opts.new_window orelse {
|
||||
log.info("runtime embedder does not support new_window", .{});
|
||||
|
@ -142,10 +142,16 @@ pub const App = struct {
|
||||
.surface => |v| v,
|
||||
}),
|
||||
|
||||
.new_tab => try self.newTab(switch (target) {
|
||||
.app => null,
|
||||
.surface => |v| v,
|
||||
}),
|
||||
|
||||
.open_config => try configpkg.edit.open(self.app.alloc),
|
||||
|
||||
// Unimplemented
|
||||
.close_all_windows,
|
||||
.goto_tab,
|
||||
.quit_timer,
|
||||
.secure_input,
|
||||
=> log.info("unimplemented action={}", .{action}),
|
||||
@ -216,12 +222,17 @@ pub const App = struct {
|
||||
}
|
||||
|
||||
/// Create a new tab in the parent surface.
|
||||
fn newTab(self: *App, parent: *CoreSurface) !void {
|
||||
fn newTab(self: *App, parent_: ?*CoreSurface) !void {
|
||||
if (!Darwin.enabled) {
|
||||
log.warn("tabbing is not supported on this platform", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
const parent = parent_ orelse {
|
||||
_ = try self.newSurface(null);
|
||||
return;
|
||||
};
|
||||
|
||||
// Create the new window
|
||||
const window = try self.newSurface(parent);
|
||||
|
||||
@ -540,11 +551,6 @@ pub const Surface = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new tab in the window containing this surface.
|
||||
pub fn newTab(self: *Surface) !void {
|
||||
try self.app.newTab(&self.core_surface);
|
||||
}
|
||||
|
||||
/// Checks if the glfw window is in fullscreen.
|
||||
pub fn isFullscreen(self: *Surface) bool {
|
||||
return self.window.getMonitor() != null;
|
||||
|
@ -62,16 +62,6 @@ pub const DesktopNotification = struct {
|
||||
body: []const u8,
|
||||
};
|
||||
|
||||
/// 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
|
||||
/// values.
|
||||
pub const GotoTab = enum(c_int) {
|
||||
previous = -1,
|
||||
next = -2,
|
||||
last = -3,
|
||||
_,
|
||||
};
|
||||
|
||||
// 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) {
|
||||
|
Reference in New Issue
Block a user