mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +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,
|
v,
|
||||||
),
|
),
|
||||||
|
|
||||||
.new_tab => {
|
.new_tab => try self.rt_app.performAction(
|
||||||
if (@hasDecl(apprt.Surface, "newTab")) {
|
.{ .surface = self },
|
||||||
try self.rt_surface.newTab();
|
.new_tab,
|
||||||
} else log.warn("runtime doesn't implement newTab", .{});
|
{},
|
||||||
},
|
),
|
||||||
|
|
||||||
.previous_tab => {
|
inline .previous_tab,
|
||||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
.next_tab,
|
||||||
self.rt_surface.gotoTab(.previous);
|
.last_tab,
|
||||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
.goto_tab,
|
||||||
},
|
=> |v, tag| try self.rt_app.performAction(
|
||||||
|
.{ .surface = self },
|
||||||
.next_tab => {
|
.goto_tab,
|
||||||
if (@hasDecl(apprt.Surface, "gotoTab")) {
|
switch (tag) {
|
||||||
self.rt_surface.gotoTab(.next);
|
.previous_tab => .previous,
|
||||||
} else log.warn("runtime doesn't implement gotoTab", .{});
|
.next_tab => .next,
|
||||||
},
|
.last_tab => .last,
|
||||||
|
.goto_tab => @enumFromInt(v),
|
||||||
.last_tab => {
|
else => comptime unreachable,
|
||||||
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", .{});
|
|
||||||
},
|
},
|
||||||
|
),
|
||||||
|
|
||||||
.new_split => |direction| {
|
.new_split => |direction| {
|
||||||
if (@hasDecl(apprt.Surface, "newSplit")) {
|
if (@hasDecl(apprt.Surface, "newSplit")) {
|
||||||
|
@ -12,9 +12,9 @@ const std = @import("std");
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const build_config = @import("build_config.zig");
|
const build_config = @import("build_config.zig");
|
||||||
|
|
||||||
const action = @import("apprt/action.zig");
|
|
||||||
const structs = @import("apprt/structs.zig");
|
const structs = @import("apprt/structs.zig");
|
||||||
|
|
||||||
|
pub const action = @import("apprt/action.zig");
|
||||||
pub const glfw = @import("apprt/glfw.zig");
|
pub const glfw = @import("apprt/glfw.zig");
|
||||||
pub const gtk = @import("apprt/gtk.zig");
|
pub const gtk = @import("apprt/gtk.zig");
|
||||||
pub const none = @import("apprt/none.zig");
|
pub const none = @import("apprt/none.zig");
|
||||||
|
@ -16,6 +16,15 @@ pub const Action = union(enum) {
|
|||||||
/// as font size should be inherited.
|
/// as font size should be inherited.
|
||||||
new_window,
|
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 open windows.
|
||||||
close_all_windows,
|
close_all_windows,
|
||||||
|
|
||||||
@ -58,3 +67,13 @@ pub const Target = union(enum) {
|
|||||||
app,
|
app,
|
||||||
surface: *CoreSurface,
|
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.
|
/// 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.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_tab: ?*const fn (SurfaceUD, apprt.Surface.Options) callconv(.C) void = null,
|
||||||
|
|
||||||
/// New window with options. The surface may be null if there is no
|
/// 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,
|
toggle_split_zoom: ?*const fn (SurfaceUD) callconv(.C) void = null,
|
||||||
|
|
||||||
/// Goto tab
|
/// 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 for current window.
|
||||||
toggle_fullscreen: ?*const fn (SurfaceUD, configpkg.NonNativeFullscreen) callconv(.C) void = null,
|
toggle_fullscreen: ?*const fn (SurfaceUD, configpkg.NonNativeFullscreen) callconv(.C) void = null,
|
||||||
@ -506,9 +507,36 @@ pub const App = struct {
|
|||||||
func(null, .{});
|
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 {
|
fn setPasswordInput(self: *App, target: apprt.Target, v: bool) void {
|
||||||
const func = self.opts.set_password_input orelse {
|
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;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -531,8 +559,9 @@ pub const App = struct {
|
|||||||
.surface => |v| v,
|
.surface => |v| v,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
.new_tab => self.newTab(target),
|
||||||
|
.goto_tab => self.gotoTab(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
|
||||||
@ -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 {
|
pub fn toggleFullscreen(self: *Surface, nonNativeFullscreen: configpkg.NonNativeFullscreen) void {
|
||||||
const func = self.app.opts.toggle_fullscreen orelse {
|
const func = self.app.opts.toggle_fullscreen orelse {
|
||||||
log.info("runtime embedder does not toggle_fullscreen", .{});
|
log.info("runtime embedder does not toggle_fullscreen", .{});
|
||||||
@ -1126,16 +1146,6 @@ pub const Surface = struct {
|
|||||||
func();
|
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 {
|
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", .{});
|
||||||
|
@ -142,10 +142,16 @@ pub const App = struct {
|
|||||||
.surface => |v| v,
|
.surface => |v| v,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
.new_tab => try self.newTab(switch (target) {
|
||||||
|
.app => null,
|
||||||
|
.surface => |v| v,
|
||||||
|
}),
|
||||||
|
|
||||||
.open_config => try configpkg.edit.open(self.app.alloc),
|
.open_config => try configpkg.edit.open(self.app.alloc),
|
||||||
|
|
||||||
// Unimplemented
|
// Unimplemented
|
||||||
.close_all_windows,
|
.close_all_windows,
|
||||||
|
.goto_tab,
|
||||||
.quit_timer,
|
.quit_timer,
|
||||||
.secure_input,
|
.secure_input,
|
||||||
=> log.info("unimplemented action={}", .{action}),
|
=> log.info("unimplemented action={}", .{action}),
|
||||||
@ -216,12 +222,17 @@ pub const App = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new tab in the parent surface.
|
/// 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) {
|
if (!Darwin.enabled) {
|
||||||
log.warn("tabbing is not supported on this platform", .{});
|
log.warn("tabbing is not supported on this platform", .{});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const parent = parent_ orelse {
|
||||||
|
_ = try self.newSurface(null);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
// Create the new window
|
// Create the new window
|
||||||
const window = try self.newSurface(parent);
|
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.
|
/// Checks if the glfw window is in fullscreen.
|
||||||
pub fn isFullscreen(self: *Surface) bool {
|
pub fn isFullscreen(self: *Surface) bool {
|
||||||
return self.window.getMonitor() != null;
|
return self.window.getMonitor() != null;
|
||||||
|
@ -62,16 +62,6 @@ pub const DesktopNotification = struct {
|
|||||||
body: []const u8,
|
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
|
// 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.
|
// runtime. The small size cost doesn't make a difference in our union.
|
||||||
pub const SplitDirection = enum(c_int) {
|
pub const SplitDirection = enum(c_int) {
|
||||||
|
Reference in New Issue
Block a user