diff --git a/src/config/Config.zig b/src/config/Config.zig index 0deada505..543792225 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -609,22 +609,30 @@ keybind: Keybinds = .{}, /// On Linux, this requires OpenGL 4.2. Ghostty typically only requires /// OpenGL 3.3, but custom shaders push that requirement up to 4.2. /// -/// The shader API is identical to the ShaderToy API: you specify a `mainImage` -/// function and the available uniforms match ShaderToy. The iChannel0 uniform +/// The shader API is identical to the Shadertoy API: you specify a `mainImage` +/// function and the available uniforms match Shadertoy. The iChannel0 uniform /// is a texture containing the rendered terminal screen. /// /// If the shader fails to compile, the shader will be ignored. Any errors /// related to shader compilation will not show up as configuration errors /// and only show up in the log, since shader compilation happens after -/// configuration loading on the dedicated render thread. If your shader is -/// not working, another way to debug is to run the `ghostty -/// +custom-shader-compile` command which will compile the shader and show any -/// errors. For interactive development, use ShaderToy.com. +/// configuration loading on the dedicated render thread. For interactive +/// development, use Shadertoy.com. /// /// This can be repeated multiple times to load multiple shaders. The shaders /// will be run in the order they are specified. @"custom-shader": RepeatablePath = .{}, +/// If true (default), the focused terminal surface will run an animation +/// loop when custom shaders are used. This uses slightly more CPU (generally +/// less than 10%) but allows the shader to animate. This only runs if there +/// are custom shaders. +/// +/// If this is set to false, the terminal and custom shader will only render +/// when the terminal is updated. This is more efficient but the shader will +/// not animate. +@"custom-shader-animation": bool = true, + /// If anything other than false, fullscreen mode on macOS will not use the /// native fullscreen, but make the window fullscreen without animations and /// using a new space. It's faster than the native fullscreen mode since it diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index e26019a9a..1012d6bea 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -152,6 +152,7 @@ pub const DerivedConfig = struct { selection_foreground: ?terminal.color.RGB, invert_selection_fg_bg: bool, custom_shaders: std.ArrayListUnmanaged([]const u8), + custom_shader_animation: bool, pub fn init( alloc_gpa: Allocator, @@ -206,6 +207,7 @@ pub const DerivedConfig = struct { null, .custom_shaders = custom_shaders, + .custom_shader_animation = config.@"custom-shader-animation", .arena = arena, }; @@ -471,7 +473,8 @@ pub fn threadExit(self: *const Metal) void { /// True if our renderer has animations so that a higher frequency /// timer is used. pub fn hasAnimations(self: *const Metal) bool { - return self.custom_shader_state != null; + return self.custom_shader_state != null and + self.config.custom_shader_animation; } /// Returns the grid size for a given screen size. This is safe to call diff --git a/src/renderer/OpenGL.zig b/src/renderer/OpenGL.zig index 62232a2de..3d7031c8d 100644 --- a/src/renderer/OpenGL.zig +++ b/src/renderer/OpenGL.zig @@ -200,6 +200,7 @@ pub const DerivedConfig = struct { selection_foreground: ?terminal.color.RGB, invert_selection_fg_bg: bool, custom_shaders: std.ArrayListUnmanaged([]const u8), + custom_shader_animation: bool, pub fn init( alloc_gpa: Allocator, @@ -254,6 +255,7 @@ pub const DerivedConfig = struct { null, .custom_shaders = custom_shaders, + .custom_shader_animation = config.@"custom-shader-animation", .arena = arena, }; @@ -479,7 +481,7 @@ pub fn threadExit(self: *const OpenGL) void { /// timer is used. pub fn hasAnimations(self: *const OpenGL) bool { const state = self.gl_state orelse return false; - return state.custom != null; + return state.custom != null and self.config.custom_shader_animation; } /// Callback when the focus changes for the terminal this is rendering.