apprt/gtk: handle syncing background opacity at the opengl level

This commit is contained in:
Adam Wolf
2025-02-27 23:19:45 -06:00
parent 049d86b9be
commit 56a4f57059
6 changed files with 51 additions and 11 deletions

View File

@ -1561,6 +1561,22 @@ pub fn setFontSize(self: *Surface, size: font.face.DesiredSize) !void {
self.queueRender() catch unreachable; self.queueRender() catch unreachable;
} }
/// Change the surface background opacity. This function may be reused anywhere that
/// might want to change the opacity of the surface.
///
/// This can only be called from the main thread.
pub fn setBackgroundOpacity(self: *Surface, opacity: f64) void {
log.debug("set background opacity={}", .{opacity});
// Notify our render thread of the new opacity.
_ = self.renderer_thread.mailbox.push(.{
.background_opacity = opacity,
}, .{ .forever = {} });
// Schedule render which also drains our mailbox
self.queueRender() catch unreachable;
}
/// This queues a render operation with the renderer thread. The render /// This queues a render operation with the renderer thread. The render
/// isn't guaranteed to happen immediately but it will happen as soon as /// isn't guaranteed to happen immediately but it will happen as soon as
/// practical. /// practical.

View File

@ -499,7 +499,7 @@ pub fn performAction(
.toggle_tab_overview => self.toggleTabOverview(target), .toggle_tab_overview => self.toggleTabOverview(target),
.toggle_split_zoom => self.toggleSplitZoom(target), .toggle_split_zoom => self.toggleSplitZoom(target),
.toggle_window_decorations => self.toggleWindowDecorations(target), .toggle_window_decorations => self.toggleWindowDecorations(target),
.toggle_background_opacity => self.toggleBackgroundOpacity(target), .toggle_background_opacity => try self.toggleBackgroundOpacity(target),
.quit_timer => self.quitTimer(value), .quit_timer => self.quitTimer(value),
.prompt_title => try self.promptTitle(target), .prompt_title => try self.promptTitle(target),
.toggle_quick_terminal => return try self.toggleQuickTerminal(), .toggle_quick_terminal => return try self.toggleQuickTerminal(),
@ -798,9 +798,9 @@ fn toggleQuickTerminal(self: *App) !bool {
} }
fn toggleBackgroundOpacity( fn toggleBackgroundOpacity(
_: *App, self: *App,
target: apprt.Target, target: apprt.Target,
) void { ) !void {
switch (target) { switch (target) {
.app => {}, .app => {},
.surface => |v| { .surface => |v| {
@ -811,7 +811,13 @@ fn toggleBackgroundOpacity(
); );
return; return;
}; };
window.toggleBackgroundOpacity();
const opacity = try window.toggleBackgroundOpacity();
// Cycle through all surfaces and set the background opacity so they stay in sync
for (self.core_app.surfaces.items) |surface| {
surface.core_surface.setBackgroundOpacity(opacity);
}
}, },
} }
} }

View File

@ -662,14 +662,13 @@ pub fn toggleWindowDecorations(self: *Window) void {
} }
/// Toggle the background opacity for this window. /// Toggle the background opacity for this window.
pub fn toggleBackgroundOpacity(self: *Window) void { pub fn toggleBackgroundOpacity(self: *Window) !f64 {
if (self.app.config.@"background-opacity" >= 1) return; if (self.app.config.@"background-opacity" >= 1) return self.app.config.@"background-opacity";
if (c.gtk_widget_has_css_class(@ptrCast(self.window), "background") == 1) { self.config.background_opacity = if (self.config.background_opacity == 1.0) self.app.config.@"background-opacity" else 1.0;
c.gtk_widget_remove_css_class(@ptrCast(self.window), "background"); try self.syncAppearance();
} else {
c.gtk_widget_add_css_class(@ptrCast(self.window), "background"); return self.config.background_opacity;
}
} }
/// Grabs focus on the currently selected tab. /// Grabs focus on the currently selected tab.

View File

@ -653,6 +653,17 @@ pub fn setVisible(self: *OpenGL, visible: bool) void {
_ = visible; _ = visible;
} }
/// Set the backgrond opacity in the config.
///
/// Must be called on the render thread.
pub fn setBackgroundOpacity(self: *OpenGL, opacity: f64) void {
if (single_threaded_draw) self.draw_mutex.lock();
defer if (single_threaded_draw) self.draw_mutex.unlock();
// We don't want to go below 0 or above 1
self.config.background_opacity = @max(0, @min(1, opacity));
}
/// Set the new font grid. /// Set the new font grid.
/// ///
/// Must be called on the render thread. /// Must be called on the render thread.

View File

@ -420,6 +420,11 @@ fn drainMailbox(self: *Thread) !void {
self.renderer.markDirty(); self.renderer.markDirty();
}, },
.background_opacity => |opacity| {
self.renderer.setBackgroundOpacity(opacity);
self.renderer.markDirty();
},
.cursor_color => |color| { .cursor_color => |color| {
self.renderer.cursor_color = color; self.renderer.cursor_color = color;
self.renderer.markDirty(); self.renderer.markDirty();

View File

@ -48,6 +48,9 @@ pub const Message = union(enum) {
/// Change the background color as set by an OSC 11 command, if any. /// Change the background color as set by an OSC 11 command, if any.
background_color: ?terminal.color.RGB, background_color: ?terminal.color.RGB,
/// Change the background opacity.
background_opacity: f64,
/// Change the cursor color. This can be done separately from changing the /// Change the cursor color. This can be done separately from changing the
/// config file in response to an OSC 12 command. /// config file in response to an OSC 12 command.
cursor_color: ?terminal.color.RGB, cursor_color: ?terminal.color.RGB,