Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/ghostty.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,12 @@ typedef struct {

// Config types

// config.Path
typedef struct {
const char* path;
bool optional;
} ghostty_config_path_s;

// config.Color
typedef struct {
uint8_t r;
Expand Down
8 changes: 8 additions & 0 deletions macos/Sources/App/macOS/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,14 @@ class AppDelegate: NSObject,
NSSound.beep()
}

if ghostty.config.bellFeatures.contains(.audio) {
if let configPath = ghostty.config.bellAudioPath,
let sound = NSSound(contentsOfFile: configPath.path, byReference: false) {
sound.volume = ghostty.config.bellAudioVolume
sound.play()
}
}

if ghostty.config.bellFeatures.contains(.attention) {
// Bounce the dock icon if we're not focused.
NSApp.requestUserAttention(.informationalRequest)
Expand Down
17 changes: 17 additions & 0 deletions macos/Sources/Ghostty/Ghostty.Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,23 @@ extension Ghostty {
return .init(rawValue: v)
}

var bellAudioPath: ConfigPath? {
guard let config = self.config else { return nil }
var v = ghostty_config_path_s()
let key = "bell-audio-path"
guard ghostty_config_get(config, &v, key, UInt(key.lengthOfBytes(using: .utf8))) else { return nil }
let path = String(cString: v.path)
return path.isEmpty ? nil : ConfigPath(path: path, optional: v.optional)
}

var bellAudioVolume: Float {
guard let config = self.config else { return 0.5 }
var v: Double = 0.5
let key = "bell-audio-volume"
_ = ghostty_config_get(config, &v, key, UInt(key.lengthOfBytes(using: .utf8)))
return Float(v)
}

var notifyOnCommandFinish: NotifyOnCommandFinish {
guard let config = self.config else { return .never }
var v: UnsafePointer<Int8>?
Expand Down
6 changes: 6 additions & 0 deletions macos/Sources/Ghostty/Ghostty.ConfigTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
// can get typed information without depending on all the dependencies of GhosttyKit.

extension Ghostty {
/// A configuration path value that may be optional or required.
struct ConfigPath: Sendable {
let path: String
let optional: Bool
}

/// macos-icon
enum MacOSIcon: String, Sendable {
case official
Expand Down
3 changes: 1 addition & 2 deletions src/config/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3087,15 +3087,14 @@ keybind: Keybinds = .{},
/// the path is not absolute, it is considered relative to the directory of the
/// configuration file that it is referenced from, or from the current working
/// directory if this is used as a CLI flag. The path may be prefixed with `~/`
/// to reference the user's home directory. (GTK only)
/// to reference the user's home directory.
///
/// Available since: 1.2.0
@"bell-audio-path": ?Path = null,

/// If `audio` is an enabled bell feature, this is the volume to play the audio
/// file at (relative to the system volume). This is a floating point number
/// ranging from 0.0 (silence) to 1.0 (as loud as possible). The default is 0.5.
/// (GTK only)
///
/// Available since: 1.2.0
@"bell-audio-volume": f64 = 0.5,
Expand Down
14 changes: 14 additions & 0 deletions src/config/path.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ pub const Path = union(enum) {
return std.meta.eql(self, other);
}

/// ghostty_config_path_s
pub const C = extern struct {
path: [*:0]const u8,
optional: bool,
};

/// Returns the path as a C-compatible struct.
pub fn cval(self: Path) C {
return switch (self) {
.optional => |path| .{ .path = path.ptr, .optional = true },
.required => |path| .{ .path = path.ptr, .optional = false },
};
}

/// Parse the input and return a Path. A leading `?` indicates that the path
/// is _optional_ and an error should not be logged or displayed to the user
/// if that path does not exist. Otherwise the path is required and an error
Expand Down
Loading