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.
|
// 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
|
// It is up to the apprt if there is a quit timer at all and if it
|
||||||
// should be canceled.
|
// 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
|
/// 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
|
// If we have no surfaces, we can start the quit timer. It is up to the
|
||||||
// apprt to determine if this is necessary.
|
// apprt to determine if this is necessary.
|
||||||
if (@hasDecl(apprt.App, "startQuitTimer") and
|
if (self.surfaces.items.len == 0) rt_surface.app.performAction(
|
||||||
self.surfaces.items.len == 0) rt_surface.app.startQuitTimer();
|
.{ .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
|
/// 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)});
|
log.debug("mailbox message={s}", .{@tagName(message)});
|
||||||
switch (message) {
|
switch (message) {
|
||||||
.reload_config => try self.reloadConfig(rt_app),
|
.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),
|
.new_window => |msg| try self.newWindow(rt_app, msg),
|
||||||
.close => |surface| try self.closeSurface(surface),
|
.close => |surface| try self.closeSurface(surface),
|
||||||
.quit => try self.setQuit(),
|
.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 {
|
pub fn reloadConfig(self: *App, rt_app: *apprt.App) !void {
|
||||||
log.debug("reloading configuration", .{});
|
log.debug("reloading configuration", .{});
|
||||||
if (try rt_app.reloadConfig()) |new| {
|
if (try rt_app.reloadConfig()) |new| {
|
||||||
@ -316,13 +321,9 @@ pub fn performAction(
|
|||||||
.ignore => {},
|
.ignore => {},
|
||||||
.quit => try self.setQuit(),
|
.quit => try self.setQuit(),
|
||||||
.new_window => try self.newWindow(rt_app, .{ .parent = null }),
|
.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),
|
.reload_config => try self.reloadConfig(rt_app),
|
||||||
.close_all_windows => {
|
.close_all_windows => try rt_app.performAction(.app, .close_all_windows, {}),
|
||||||
if (@hasDecl(apprt.App, "closeAllWindows")) {
|
|
||||||
rt_app.closeAllWindows();
|
|
||||||
} else log.warn("runtime doesn't implement closeAllWindows", .{});
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,34 @@ const std = @import("std");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const CoreSurface = @import("../Surface.zig");
|
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) {
|
pub const Action = union(enum) {
|
||||||
|
/// Open a new window. The target determines whether properties such
|
||||||
|
/// as font size should be inherited.
|
||||||
new_window,
|
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.
|
/// The enum of keys in the tagged union.
|
||||||
pub const Key = @typeInfo(Action).Union.tag_type.?;
|
pub const Key = @typeInfo(Action).Union.tag_type.?;
|
||||||
|
|
||||||
|
@ -141,12 +141,14 @@ pub const App = struct {
|
|||||||
.app => null,
|
.app => null,
|
||||||
.surface => |v| v,
|
.surface => |v| v,
|
||||||
}),
|
}),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Open the configuration in the system editor.
|
.open_config => try configpkg.edit.open(self.app.alloc),
|
||||||
pub fn openConfig(self: *App) !void {
|
|
||||||
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.
|
/// Reload the configuration. This should return the new configuration.
|
||||||
|
Reference in New Issue
Block a user