mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
gtk: implement custom audio for bell
This commit is contained in:
@ -28,6 +28,9 @@
|
||||
pkgs.glib
|
||||
pkgs.gobject-introspection
|
||||
pkgs.gsettings-desktop-schemas
|
||||
pkgs.gst_all_1.gst-plugins-base
|
||||
pkgs.gst_all_1.gst-plugins-good
|
||||
pkgs.gst_all_1.gstreamer
|
||||
pkgs.gtk4
|
||||
pkgs.libadwaita
|
||||
]
|
||||
|
@ -35,6 +35,7 @@
|
||||
gtk4,
|
||||
gtk4-layer-shell,
|
||||
gobject-introspection,
|
||||
gst_all_1,
|
||||
libadwaita,
|
||||
blueprint-compiler,
|
||||
gettext,
|
||||
@ -166,6 +167,9 @@ in
|
||||
wayland
|
||||
wayland-scanner
|
||||
wayland-protocols
|
||||
gst_all_1.gstreamer
|
||||
gst_all_1.gst-plugins-base
|
||||
gst_all_1.gst-plugins-good
|
||||
];
|
||||
|
||||
# This should be set onto the rpath of the ghostty binary if you want
|
||||
|
@ -127,6 +127,10 @@ in
|
||||
mv $out/share/vim/vimfiles "$vim"
|
||||
ln -sf "$vim" "$out/share/vim/vimfiles"
|
||||
echo "$vim" >> "$out/nix-support/propagated-user-env-packages"
|
||||
|
||||
echo "gst_all_1.gstreamer" >> "$out/nix-support/propagated-user-env-packages"
|
||||
echo "gst_all_1.gst-plugins-base" >> "$out/nix-support/propagated-user-env-packages"
|
||||
echo "gst_all_1.gst-plugins-good" >> "$out/nix-support/propagated-user-env-packages"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
|
@ -2405,6 +2405,47 @@ pub fn ringBell(self: *Surface) !void {
|
||||
surface.beep();
|
||||
}
|
||||
|
||||
if (features.audio) audio: {
|
||||
// Play a user-specified audio file.
|
||||
|
||||
const pathname, const optional = switch (self.app.config.@"bell-audio-path" orelse break :audio) {
|
||||
.optional => |path| .{ path, true },
|
||||
.required => |path| .{ path, false },
|
||||
};
|
||||
|
||||
const volume: f64 = @min(
|
||||
@max(
|
||||
0.0,
|
||||
self.app.config.@"bell-audio-volume",
|
||||
),
|
||||
1.0,
|
||||
);
|
||||
|
||||
std.debug.assert(std.fs.path.isAbsolute(pathname));
|
||||
const media_file = gtk.MediaFile.newForFilename(pathname);
|
||||
|
||||
if (!optional) {
|
||||
_ = gobject.Object.signals.notify.connect(
|
||||
media_file,
|
||||
?*anyopaque,
|
||||
gtkStreamError,
|
||||
null,
|
||||
.{ .detail = "error" },
|
||||
);
|
||||
}
|
||||
_ = gobject.Object.signals.notify.connect(
|
||||
media_file,
|
||||
?*anyopaque,
|
||||
gtkStreamEnded,
|
||||
null,
|
||||
.{ .detail = "ended" },
|
||||
);
|
||||
|
||||
const media_stream = media_file.as(gtk.MediaStream);
|
||||
media_stream.setVolume(volume);
|
||||
media_stream.play();
|
||||
}
|
||||
|
||||
// Mark tab as needing attention
|
||||
if (self.container.tab()) |tab| tab: {
|
||||
const page = window.notebook.getTabPage(tab) orelse break :tab;
|
||||
@ -2413,3 +2454,27 @@ pub fn ringBell(self: *Surface) !void {
|
||||
if (page.getSelected() == 0) page.setNeedsAttention(@intFromBool(true));
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle a stream that is in an error state.
|
||||
fn gtkStreamError(media_file: *gtk.MediaFile, _: *gobject.ParamSpec, _: ?*anyopaque) callconv(.c) void {
|
||||
const path = path: {
|
||||
const file = media_file.getFile() orelse break :path null;
|
||||
break :path file.getPath();
|
||||
};
|
||||
defer if (path) |p| glib.free(p);
|
||||
|
||||
const media_stream = media_file.as(gtk.MediaStream);
|
||||
const err = media_stream.getError() orelse return;
|
||||
|
||||
log.warn("error playing bell from {s}: {s} {d} {s}", .{
|
||||
path orelse "<<unknown>>",
|
||||
glib.quarkToString(err.f_domain),
|
||||
err.f_code,
|
||||
err.f_message orelse "",
|
||||
});
|
||||
}
|
||||
|
||||
/// Stream is finished, release the memory.
|
||||
fn gtkStreamEnded(media_file: *gtk.MediaFile, _: *gobject.ParamSpec, _: ?*anyopaque) callconv(.c) void {
|
||||
media_file.unref();
|
||||
}
|
||||
|
@ -1890,8 +1890,10 @@ keybind: Keybinds = .{},
|
||||
/// open terminals.
|
||||
@"custom-shader-animation": CustomShaderAnimation = .true,
|
||||
|
||||
/// The list of enabled features that are activated after encountering
|
||||
/// a bell character.
|
||||
/// Bell features to enable if bell support is available in your runtime. Not
|
||||
/// all features are available on all runtimes. The format of this is a list of
|
||||
/// features to enable separated by commas. If you prefix a feature with `no-`
|
||||
/// then it is disabled. If you omit a feature, its default value is used.
|
||||
///
|
||||
/// Valid values are:
|
||||
///
|
||||
@ -1901,17 +1903,36 @@ keybind: Keybinds = .{},
|
||||
/// This could result in an audiovisual effect, a notification, or something
|
||||
/// else entirely. Changing these effects require altering system settings:
|
||||
/// for instance under the "Sound > Alert Sound" setting in GNOME,
|
||||
/// or the "Accessibility > System Bell" settings in KDE Plasma.
|
||||
/// or the "Accessibility > System Bell" settings in KDE Plasma. (GTK only)
|
||||
///
|
||||
/// On macOS this has no affect.
|
||||
/// * `audio`
|
||||
///
|
||||
/// Play a custom sound. (GTK only)
|
||||
///
|
||||
/// Example: `audio`, `no-audio`, `system`, `no-system`:
|
||||
///
|
||||
/// On macOS, if the app is unfocused, it will bounce the app icon in the dock
|
||||
/// once. Additionally, the title of the window with the alerted terminal
|
||||
/// surface will contain a bell emoji (🔔) until the terminal is focused
|
||||
/// or a key is pressed. These are not currently configurable since they're
|
||||
/// considered unobtrusive.
|
||||
///
|
||||
/// By default, no bell features are enabled.
|
||||
@"bell-features": BellFeatures = .{},
|
||||
|
||||
/// If `audio` is an enabled bell feature, this is a path to an audio file. If
|
||||
/// 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)
|
||||
@"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)
|
||||
@"bell-audio-volume": f64 = 0.5,
|
||||
|
||||
/// Control the in-app notifications that Ghostty shows.
|
||||
///
|
||||
/// On Linux (GTK), in-app notifications show up as toasts. Toasts appear
|
||||
@ -5765,6 +5786,7 @@ pub const AppNotifications = packed struct {
|
||||
/// See bell-features
|
||||
pub const BellFeatures = packed struct {
|
||||
system: bool = false,
|
||||
audio: bool = false,
|
||||
};
|
||||
|
||||
/// See mouse-shift-capture
|
||||
|
Reference in New Issue
Block a user