mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
apprt: transition all hasDecls in App.zig to use the new action dispatch
This commit is contained in:
33
src/App.zig
33
src/App.zig
@ -138,7 +138,13 @@ pub fn addSurface(self: *App, rt_surface: *apprt.Surface) !void {
|
||||
// Since we have non-zero surfaces, we can cancel the quit timer.
|
||||
// It is up to the apprt if there is a quit timer at all and if it
|
||||
// should be canceled.
|
||||
if (@hasDecl(apprt.App, "cancelQuitTimer")) rt_surface.app.cancelQuitTimer();
|
||||
rt_surface.app.performAction(
|
||||
.{ .surface = &rt_surface.core_surface },
|
||||
.quit_timer,
|
||||
.stop,
|
||||
) catch |err| {
|
||||
log.warn("error stopping quit timer err={}", .{err});
|
||||
};
|
||||
}
|
||||
|
||||
/// Delete the surface from the known surface list. This will NOT call the
|
||||
@ -166,8 +172,13 @@ pub fn deleteSurface(self: *App, rt_surface: *apprt.Surface) void {
|
||||
|
||||
// If we have no surfaces, we can start the quit timer. It is up to the
|
||||
// apprt to determine if this is necessary.
|
||||
if (@hasDecl(apprt.App, "startQuitTimer") and
|
||||
self.surfaces.items.len == 0) rt_surface.app.startQuitTimer();
|
||||
if (self.surfaces.items.len == 0) rt_surface.app.performAction(
|
||||
.{ .surface = &rt_surface.core_surface },
|
||||
.quit_timer,
|
||||
.start,
|
||||
) catch |err| {
|
||||
log.warn("error starting quit timer err={}", .{err});
|
||||
};
|
||||
}
|
||||
|
||||
/// The last focused surface. This is only valid while on the main thread
|
||||
@ -194,7 +205,7 @@ fn drainMailbox(self: *App, rt_app: *apprt.App) !void {
|
||||
log.debug("mailbox message={s}", .{@tagName(message)});
|
||||
switch (message) {
|
||||
.reload_config => try self.reloadConfig(rt_app),
|
||||
.open_config => try self.openConfig(rt_app),
|
||||
.open_config => try self.performAction(rt_app, .open_config),
|
||||
.new_window => |msg| try self.newWindow(rt_app, msg),
|
||||
.close => |surface| try self.closeSurface(surface),
|
||||
.quit => try self.setQuit(),
|
||||
@ -205,12 +216,6 @@ fn drainMailbox(self: *App, rt_app: *apprt.App) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn openConfig(self: *App, rt_app: *apprt.App) !void {
|
||||
_ = self;
|
||||
log.debug("opening configuration", .{});
|
||||
try rt_app.openConfig();
|
||||
}
|
||||
|
||||
pub fn reloadConfig(self: *App, rt_app: *apprt.App) !void {
|
||||
log.debug("reloading configuration", .{});
|
||||
if (try rt_app.reloadConfig()) |new| {
|
||||
@ -316,13 +321,9 @@ pub fn performAction(
|
||||
.ignore => {},
|
||||
.quit => try self.setQuit(),
|
||||
.new_window => try self.newWindow(rt_app, .{ .parent = null }),
|
||||
.open_config => try self.openConfig(rt_app),
|
||||
.open_config => try rt_app.performAction(.app, .open_config, {}),
|
||||
.reload_config => try self.reloadConfig(rt_app),
|
||||
.close_all_windows => {
|
||||
if (@hasDecl(apprt.App, "closeAllWindows")) {
|
||||
rt_app.closeAllWindows();
|
||||
} else log.warn("runtime doesn't implement closeAllWindows", .{});
|
||||
},
|
||||
.close_all_windows => try rt_app.performAction(.app, .close_all_windows, {}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,34 @@ const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const CoreSurface = @import("../Surface.zig");
|
||||
|
||||
/// The possible actions an apprt has to react to.
|
||||
/// The possible actions an apprt has to react to. Actions are one-way
|
||||
/// messages that are sent to the app runtime to trigger some behavior.
|
||||
///
|
||||
/// Actions are very often key binding actions but can also be triggered
|
||||
/// by lifecycle events. For example, the `quit_timer` action is not bindable.
|
||||
///
|
||||
/// Importantly, actions are generally OPTIONAL to implement by an apprt.
|
||||
/// Required functionality is called directly on the runtime structure so
|
||||
/// there is a compiler error if an action is not implemented.
|
||||
pub const Action = union(enum) {
|
||||
/// Open a new window. The target determines whether properties such
|
||||
/// as font size should be inherited.
|
||||
new_window,
|
||||
|
||||
/// Close all open windows.
|
||||
close_all_windows,
|
||||
|
||||
/// Open the Ghostty configuration. This is platform-specific about
|
||||
/// what it means; it can mean opening a dedicated UI or just opening
|
||||
/// a file in a text editor.
|
||||
open_config,
|
||||
|
||||
/// Called when there are no more surfaces and the app should quit
|
||||
/// after the configured delay. This can be cancelled by sending
|
||||
/// another quit_timer action with "stop". Multiple "starts" shouldn't
|
||||
/// happen and can be ignored or cause a restart it isn't that important.
|
||||
quit_timer: enum { start, stop },
|
||||
|
||||
/// The enum of keys in the tagged union.
|
||||
pub const Key = @typeInfo(Action).Union.tag_type.?;
|
||||
|
||||
|
@ -141,12 +141,14 @@ pub const App = struct {
|
||||
.app => null,
|
||||
.surface => |v| v,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Open the configuration in the system editor.
|
||||
pub fn openConfig(self: *App) !void {
|
||||
try configpkg.edit.open(self.app.alloc);
|
||||
.open_config => try configpkg.edit.open(self.app.alloc),
|
||||
|
||||
// Unimplemented
|
||||
.close_all_windows,
|
||||
.quit_timer,
|
||||
=> log.warn("unimplemented action={}", .{action}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reload the configuration. This should return the new configuration.
|
||||
|
Reference in New Issue
Block a user