macos: add `toggle_background_opacity` keybind action
parent
4883fd938e
commit
4c6d3f8ed2
|
|
@ -803,6 +803,7 @@ typedef enum {
|
||||||
GHOSTTY_ACTION_TOGGLE_QUICK_TERMINAL,
|
GHOSTTY_ACTION_TOGGLE_QUICK_TERMINAL,
|
||||||
GHOSTTY_ACTION_TOGGLE_COMMAND_PALETTE,
|
GHOSTTY_ACTION_TOGGLE_COMMAND_PALETTE,
|
||||||
GHOSTTY_ACTION_TOGGLE_VISIBILITY,
|
GHOSTTY_ACTION_TOGGLE_VISIBILITY,
|
||||||
|
GHOSTTY_ACTION_TOGGLE_BACKGROUND_OPACITY,
|
||||||
GHOSTTY_ACTION_MOVE_TAB,
|
GHOSTTY_ACTION_MOVE_TAB,
|
||||||
GHOSTTY_ACTION_GOTO_TAB,
|
GHOSTTY_ACTION_GOTO_TAB,
|
||||||
GHOSTTY_ACTION_GOTO_SPLIT,
|
GHOSTTY_ACTION_GOTO_SPLIT,
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,13 @@ class QuickTerminalController: BaseTerminalController {
|
||||||
animateOut()
|
animateOut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func toggleBackgroundOpacity() {
|
||||||
|
super.toggleBackgroundOpacity()
|
||||||
|
|
||||||
|
// Sync the window appearance with the new opacity state
|
||||||
|
syncAppearance()
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Methods
|
// MARK: Methods
|
||||||
|
|
||||||
func toggle() {
|
func toggle() {
|
||||||
|
|
@ -608,7 +615,8 @@ class QuickTerminalController: BaseTerminalController {
|
||||||
guard window.isVisible else { return }
|
guard window.isVisible else { return }
|
||||||
|
|
||||||
// If we have window transparency then set it transparent. Otherwise set it opaque.
|
// If we have window transparency then set it transparent. Otherwise set it opaque.
|
||||||
if (self.derivedConfig.backgroundOpacity < 1) {
|
// Also check if the user has overridden transparency to be fully opaque.
|
||||||
|
if !isBackgroundOpaque && self.derivedConfig.backgroundOpacity < 1 {
|
||||||
window.isOpaque = false
|
window.isOpaque = false
|
||||||
|
|
||||||
// This is weird, but we don't use ".clear" because this creates a look that
|
// This is weird, but we don't use ".clear" because this creates a look that
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@ class BaseTerminalController: NSWindowController,
|
||||||
/// The configuration derived from the Ghostty config so we don't need to rely on references.
|
/// The configuration derived from the Ghostty config so we don't need to rely on references.
|
||||||
private var derivedConfig: DerivedConfig
|
private var derivedConfig: DerivedConfig
|
||||||
|
|
||||||
|
/// Track whether background is forced opaque (true) or using config transparency (false)
|
||||||
|
var isBackgroundOpaque: Bool = false
|
||||||
|
|
||||||
/// The cancellables related to our focused surface.
|
/// The cancellables related to our focused surface.
|
||||||
private var focusedSurfaceCancellables: Set<AnyCancellable> = []
|
private var focusedSurfaceCancellables: Set<AnyCancellable> = []
|
||||||
|
|
||||||
|
|
@ -812,6 +815,22 @@ class BaseTerminalController: NSWindowController,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Background Opacity
|
||||||
|
|
||||||
|
/// Toggle the background opacity between transparent and opaque states.
|
||||||
|
/// If the configured background-opacity is already opaque (>= 1), this resets
|
||||||
|
/// the override flag to false so that future config changes take effect.
|
||||||
|
/// Subclasses should override this to sync their appearance after toggling.
|
||||||
|
func toggleBackgroundOpacity() {
|
||||||
|
// If config is already opaque, just ensure override is disabled
|
||||||
|
if ghostty.config.backgroundOpacity >= 1 {
|
||||||
|
isBackgroundOpaque = false
|
||||||
|
} else {
|
||||||
|
// Otherwise toggle between transparent and opaque
|
||||||
|
isBackgroundOpaque.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Fullscreen
|
// MARK: Fullscreen
|
||||||
|
|
||||||
/// Toggle fullscreen for the given mode.
|
/// Toggle fullscreen for the given mode.
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,14 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr
|
||||||
syncAppearance(focusedSurface.derivedConfig)
|
syncAppearance(focusedSurface.derivedConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func toggleBackgroundOpacity() {
|
||||||
|
super.toggleBackgroundOpacity()
|
||||||
|
|
||||||
|
// Sync the window appearance with the new opacity state
|
||||||
|
guard let focusedSurface else { return }
|
||||||
|
syncAppearance(focusedSurface.derivedConfig)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Terminal Creation
|
// MARK: Terminal Creation
|
||||||
|
|
||||||
/// Returns all the available terminal controllers present in the app currently.
|
/// Returns all the available terminal controllers present in the app currently.
|
||||||
|
|
|
||||||
|
|
@ -469,7 +469,10 @@ class TerminalWindow: NSWindow {
|
||||||
// Window transparency only takes effect if our window is not native fullscreen.
|
// Window transparency only takes effect if our window is not native fullscreen.
|
||||||
// In native fullscreen we disable transparency/opacity because the background
|
// In native fullscreen we disable transparency/opacity because the background
|
||||||
// becomes gray and widgets show through.
|
// becomes gray and widgets show through.
|
||||||
|
// Also check if the user has overridden transparency to be fully opaque.
|
||||||
|
let forceOpaque = terminalController?.isBackgroundOpaque ?? false
|
||||||
if !styleMask.contains(.fullScreen) &&
|
if !styleMask.contains(.fullScreen) &&
|
||||||
|
!forceOpaque &&
|
||||||
surfaceConfig.backgroundOpacity < 1
|
surfaceConfig.backgroundOpacity < 1
|
||||||
{
|
{
|
||||||
isOpaque = false
|
isOpaque = false
|
||||||
|
|
|
||||||
|
|
@ -573,6 +573,9 @@ extension Ghostty {
|
||||||
case GHOSTTY_ACTION_TOGGLE_VISIBILITY:
|
case GHOSTTY_ACTION_TOGGLE_VISIBILITY:
|
||||||
toggleVisibility(app, target: target)
|
toggleVisibility(app, target: target)
|
||||||
|
|
||||||
|
case GHOSTTY_ACTION_TOGGLE_BACKGROUND_OPACITY:
|
||||||
|
toggleBackgroundOpacity(app, target: target)
|
||||||
|
|
||||||
case GHOSTTY_ACTION_KEY_SEQUENCE:
|
case GHOSTTY_ACTION_KEY_SEQUENCE:
|
||||||
keySequence(app, target: target, v: action.action.key_sequence)
|
keySequence(app, target: target, v: action.action.key_sequence)
|
||||||
|
|
||||||
|
|
@ -1375,6 +1378,27 @@ extension Ghostty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func toggleBackgroundOpacity(
|
||||||
|
_ app: ghostty_app_t,
|
||||||
|
target: ghostty_target_s
|
||||||
|
) {
|
||||||
|
switch (target.tag) {
|
||||||
|
case GHOSTTY_TARGET_APP:
|
||||||
|
Ghostty.logger.warning("toggle background opacity does nothing with an app target")
|
||||||
|
return
|
||||||
|
|
||||||
|
case GHOSTTY_TARGET_SURFACE:
|
||||||
|
guard let surface = target.target.surface,
|
||||||
|
let surfaceView = self.surfaceView(from: surface),
|
||||||
|
let controller = surfaceView.window?.windowController as? BaseTerminalController else { return }
|
||||||
|
|
||||||
|
controller.toggleBackgroundOpacity()
|
||||||
|
|
||||||
|
default:
|
||||||
|
assertionFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static func toggleSecureInput(
|
private static func toggleSecureInput(
|
||||||
_ app: ghostty_app_t,
|
_ app: ghostty_app_t,
|
||||||
target: ghostty_target_s,
|
target: ghostty_target_s,
|
||||||
|
|
|
||||||
|
|
@ -5518,6 +5518,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
||||||
{},
|
{},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
.toggle_background_opacity => return try self.rt_app.performAction(
|
||||||
|
.{ .surface = self },
|
||||||
|
.toggle_background_opacity,
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
|
||||||
.show_on_screen_keyboard => return try self.rt_app.performAction(
|
.show_on_screen_keyboard => return try self.rt_app.performAction(
|
||||||
.{ .surface = self },
|
.{ .surface = self },
|
||||||
.show_on_screen_keyboard,
|
.show_on_screen_keyboard,
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,9 @@ pub const Action = union(Key) {
|
||||||
/// Toggle the visibility of all Ghostty terminal windows.
|
/// Toggle the visibility of all Ghostty terminal windows.
|
||||||
toggle_visibility,
|
toggle_visibility,
|
||||||
|
|
||||||
|
/// Toggle the window background opacity. This currently only works on macOS.
|
||||||
|
toggle_background_opacity,
|
||||||
|
|
||||||
/// Moves a tab by a relative offset.
|
/// Moves a tab by a relative offset.
|
||||||
///
|
///
|
||||||
/// Adjusts the tab position based on `offset` (e.g., -1 for left, +1
|
/// Adjusts the tab position based on `offset` (e.g., -1 for left, +1
|
||||||
|
|
@ -335,6 +338,7 @@ pub const Action = union(Key) {
|
||||||
toggle_quick_terminal,
|
toggle_quick_terminal,
|
||||||
toggle_command_palette,
|
toggle_command_palette,
|
||||||
toggle_visibility,
|
toggle_visibility,
|
||||||
|
toggle_background_opacity,
|
||||||
move_tab,
|
move_tab,
|
||||||
goto_tab,
|
goto_tab,
|
||||||
goto_split,
|
goto_split,
|
||||||
|
|
|
||||||
|
|
@ -755,6 +755,16 @@ pub const Action = union(enum) {
|
||||||
/// Only implemented on macOS.
|
/// Only implemented on macOS.
|
||||||
toggle_visibility,
|
toggle_visibility,
|
||||||
|
|
||||||
|
/// Toggle the window background opacity between transparent and opaque.
|
||||||
|
///
|
||||||
|
/// This does nothing when `background-opacity` is set to 1 or above.
|
||||||
|
///
|
||||||
|
/// When `background-opacity` is less than 1, this action will either make
|
||||||
|
/// the window transparent or not depending on its current transparency state.
|
||||||
|
///
|
||||||
|
/// Only implemented on macOS.
|
||||||
|
toggle_background_opacity,
|
||||||
|
|
||||||
/// Check for updates.
|
/// Check for updates.
|
||||||
///
|
///
|
||||||
/// Only implemented on macOS.
|
/// Only implemented on macOS.
|
||||||
|
|
@ -1240,6 +1250,7 @@ pub const Action = union(enum) {
|
||||||
.toggle_secure_input,
|
.toggle_secure_input,
|
||||||
.toggle_mouse_reporting,
|
.toggle_mouse_reporting,
|
||||||
.toggle_command_palette,
|
.toggle_command_palette,
|
||||||
|
.toggle_background_opacity,
|
||||||
.show_on_screen_keyboard,
|
.show_on_screen_keyboard,
|
||||||
.reset_window_size,
|
.reset_window_size,
|
||||||
.crash,
|
.crash,
|
||||||
|
|
|
||||||
|
|
@ -618,6 +618,12 @@ fn actionCommands(action: Action.Key) []const Command {
|
||||||
.description = "Toggle whether mouse events are reported to terminal applications.",
|
.description = "Toggle whether mouse events are reported to terminal applications.",
|
||||||
}},
|
}},
|
||||||
|
|
||||||
|
.toggle_background_opacity => comptime &.{.{
|
||||||
|
.action = .toggle_background_opacity,
|
||||||
|
.title = "Toggle Background Opacity",
|
||||||
|
.description = "Toggle the window background between transparent and opaque.",
|
||||||
|
}},
|
||||||
|
|
||||||
.check_for_updates => comptime &.{.{
|
.check_for_updates => comptime &.{.{
|
||||||
.action = .check_for_updates,
|
.action = .check_for_updates,
|
||||||
.title = "Check for Updates",
|
.title = "Check for Updates",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue