mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-06-06 03:44:22 +00:00
apprt: switch to reload_config action that calls update_config API
This commit is contained in:
18
src/App.zig
18
src/App.zig
@@ -12,7 +12,8 @@ const apprt = @import("apprt.zig");
|
||||
const Surface = @import("Surface.zig");
|
||||
const tracy = @import("tracy");
|
||||
const input = @import("input.zig");
|
||||
const Config = @import("config.zig").Config;
|
||||
const configpkg = @import("config.zig");
|
||||
const Config = configpkg.Config;
|
||||
const BlockingQueue = @import("datastruct/main.zig").BlockingQueue;
|
||||
const renderer = @import("renderer.zig");
|
||||
const font = @import("font/main.zig");
|
||||
@@ -239,7 +240,6 @@ fn drainMailbox(self: *App, rt_app: *apprt.App) !void {
|
||||
while (self.mailbox.pop()) |message| {
|
||||
log.debug("mailbox message={s}", .{@tagName(message)});
|
||||
switch (message) {
|
||||
.reload_config => try self.reloadConfig(rt_app),
|
||||
.open_config => try self.performAction(rt_app, .open_config),
|
||||
.new_window => |msg| try self.newWindow(rt_app, msg),
|
||||
.close => |surface| self.closeSurface(surface),
|
||||
@@ -260,14 +260,6 @@ fn drainMailbox(self: *App, rt_app: *apprt.App) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reloadConfig(self: *App, rt_app: *apprt.App) !void {
|
||||
log.debug("reloading configuration", .{});
|
||||
if (try rt_app.reloadConfig()) |new| {
|
||||
log.debug("new configuration received, applying", .{});
|
||||
try self.updateConfig(rt_app, new);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn closeSurface(self: *App, surface: *Surface) void {
|
||||
if (!self.hasSurface(surface)) return;
|
||||
surface.close();
|
||||
@@ -402,7 +394,7 @@ pub fn performAction(
|
||||
.quit => self.setQuit(),
|
||||
.new_window => try self.newWindow(rt_app, .{ .parent = null }),
|
||||
.open_config => try rt_app.performAction(.app, .open_config, {}),
|
||||
.reload_config => try self.reloadConfig(rt_app),
|
||||
.reload_config => try rt_app.performAction(.app, .reload_config, .{}),
|
||||
.close_all_windows => try rt_app.performAction(.app, .close_all_windows, {}),
|
||||
.toggle_quick_terminal => try rt_app.performAction(.app, .toggle_quick_terminal, {}),
|
||||
.toggle_visibility => try rt_app.performAction(.app, .toggle_visibility, {}),
|
||||
@@ -462,10 +454,6 @@ fn hasSurface(self: *const App, surface: *const Surface) bool {
|
||||
|
||||
/// The message types that can be sent to the app thread.
|
||||
pub const Message = union(enum) {
|
||||
/// Reload the configuration for the entire app and propagate it to
|
||||
/// all the active surfaces.
|
||||
reload_config: void,
|
||||
|
||||
// Open the configuration file
|
||||
open_config: void,
|
||||
|
||||
|
||||
@@ -1065,8 +1065,8 @@ fn updateRendererHealth(self: *Surface, health: renderer.Health) void {
|
||||
fn notifyConfigConditionalState(self: *Surface) void {
|
||||
self.rt_app.performAction(
|
||||
.{ .surface = self },
|
||||
.config_change_conditional_state,
|
||||
{},
|
||||
.reload_config,
|
||||
.{ .soft = true },
|
||||
) catch |err| {
|
||||
log.warn("failed to notify app of config state change err={}", .{err});
|
||||
};
|
||||
@@ -1077,8 +1077,22 @@ fn notifyConfigConditionalState(self: *Surface) void {
|
||||
/// or other surfaces.
|
||||
pub fn updateConfig(
|
||||
self: *Surface,
|
||||
config: *const configpkg.Config,
|
||||
original: *const configpkg.Config,
|
||||
) !void {
|
||||
// Apply our conditional state. If we fail to apply the conditional state
|
||||
// then we log and attempt to move forward with the old config.
|
||||
var config_: ?configpkg.Config = original.changeConditionalState(
|
||||
self.config_conditional_state,
|
||||
) catch |err| err: {
|
||||
log.warn("failed to apply conditional state to config err={}", .{err});
|
||||
break :err null;
|
||||
};
|
||||
defer if (config_) |*c| c.deinit();
|
||||
|
||||
// We want a config pointer for everything so we get that either
|
||||
// based on our conditional state or the original config.
|
||||
const config: *const configpkg.Config = if (config_) |*c| c else original;
|
||||
|
||||
// Update our new derived config immediately
|
||||
const derived = DerivedConfig.init(self.alloc, config) catch |err| {
|
||||
// If the derivation fails then we just log and return. We don't
|
||||
|
||||
@@ -201,6 +201,15 @@ pub const Action = union(Key) {
|
||||
/// on the app or surface.
|
||||
config_change_conditional_state,
|
||||
|
||||
/// A request to reload the configuration. The reload request can be
|
||||
/// from a user or for some internal reason. The reload request may
|
||||
/// request it is a soft reload or a full reload. See the struct for
|
||||
/// more documentation.
|
||||
///
|
||||
/// The configuration should be passed to updateConfig either at the
|
||||
/// app or surface level depending on the target.
|
||||
reload_config: ReloadConfig,
|
||||
|
||||
/// The configuration has changed. The value is a pointer to the new
|
||||
/// configuration. The pointer is only valid for the duration of the
|
||||
/// action and should not be stored.
|
||||
@@ -251,6 +260,7 @@ pub const Action = union(Key) {
|
||||
key_sequence,
|
||||
color_change,
|
||||
config_change_conditional_state,
|
||||
reload_config,
|
||||
config_change,
|
||||
};
|
||||
|
||||
@@ -514,6 +524,13 @@ pub const ColorKind = enum(c_int) {
|
||||
_,
|
||||
};
|
||||
|
||||
pub const ReloadConfig = extern struct {
|
||||
/// A soft reload means that the configuration doesn't need to be
|
||||
/// read off disk, but libghostty needs the full config again so call
|
||||
/// updateConfig with it.
|
||||
soft: bool = false,
|
||||
};
|
||||
|
||||
pub const ConfigChange = struct {
|
||||
config: *const configpkg.Config,
|
||||
|
||||
|
||||
@@ -47,11 +47,6 @@ pub const App = struct {
|
||||
/// Callback called to handle an action.
|
||||
action: *const fn (*App, apprt.Target.C, apprt.Action.C) callconv(.C) void,
|
||||
|
||||
/// Reload the configuration and return the new configuration.
|
||||
/// The old configuration can be freed immediately when this is
|
||||
/// called.
|
||||
reload_config: *const fn (AppUD) callconv(.C) ?*const Config,
|
||||
|
||||
/// Read the clipboard value. The return value must be preserved
|
||||
/// by the host until the next call. If there is no valid clipboard
|
||||
/// value then this should return null.
|
||||
@@ -375,16 +370,6 @@ pub const App = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reloadConfig(self: *App) !?*const Config {
|
||||
// Reload
|
||||
if (self.opts.reload_config(self.opts.userdata)) |new| {
|
||||
self.config = new;
|
||||
return self.config;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn wakeup(self: App) void {
|
||||
self.opts.wakeup(self.opts.userdata);
|
||||
}
|
||||
@@ -1374,10 +1359,14 @@ pub const CAPI = struct {
|
||||
};
|
||||
}
|
||||
|
||||
/// Reload the configuration.
|
||||
export fn ghostty_app_reload_config(v: *App) void {
|
||||
_ = v.core_app.reloadConfig(v) catch |err| {
|
||||
log.err("error reloading config err={}", .{err});
|
||||
/// Update the configuration to the provided config. This will propagate
|
||||
/// to all surfaces as well.
|
||||
export fn ghostty_app_update_config(
|
||||
v: *App,
|
||||
config: *const Config,
|
||||
) void {
|
||||
v.core_app.updateConfig(v, config) catch |err| {
|
||||
log.err("error updating config err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
@@ -1434,6 +1423,17 @@ pub const CAPI = struct {
|
||||
return surface.newSurfaceOptions();
|
||||
}
|
||||
|
||||
/// Update the configuration to the provided config for only this surface.
|
||||
export fn ghostty_surface_update_config(
|
||||
surface: *Surface,
|
||||
config: *const Config,
|
||||
) void {
|
||||
surface.core_surface.updateConfig(config) catch |err| {
|
||||
log.err("error updating config err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns true if the surface needs to confirm quitting.
|
||||
export fn ghostty_surface_needs_confirm_quit(surface: *Surface) bool {
|
||||
return surface.core_surface.needsConfirmQuit();
|
||||
|
||||
Reference in New Issue
Block a user