apprt/gtk-ng: win.ring-bell

Co-authored-by: Jeffrey C. Ollie <jcollie@dmacc.edu>
pull/8221/head
Mitchell Hashimoto 2025-08-13 08:53:13 -07:00
parent 408ec24165
commit d37e3828a2
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
2 changed files with 35 additions and 0 deletions

View File

@ -274,6 +274,8 @@ pub const Surface = extern struct {
/// ///
/// The surface view handles the audio bell feature but none of the /// The surface view handles the audio bell feature but none of the
/// others so it is up to the embedding widget to react to this. /// others so it is up to the embedding widget to react to this.
///
/// Bell ringing will also emit the win.ring-bell action.
pub const bell = struct { pub const bell = struct {
pub const name = "bell"; pub const name = "bell";
pub const connect = impl.connect; pub const connect = impl.connect;
@ -546,12 +548,16 @@ pub const Surface = extern struct {
// Enable our bell ringing state // Enable our bell ringing state
self.setBellRinging(true); self.setBellRinging(true);
// Emit our direct signal for anyone who cares
signals.bell.impl.emit( signals.bell.impl.emit(
self, self,
null, null,
.{}, .{},
null, null,
); );
// Activate a window action if it exists
_ = self.as(gtk.Widget).activateAction("win.ring-bell", null);
} }
pub fn toggleFullscreen(self: *Self) void { pub fn toggleFullscreen(self: *Self) void {

View File

@ -336,6 +336,7 @@ pub const Window = extern struct {
.{ "close-tab", actionCloseTab, null }, .{ "close-tab", actionCloseTab, null },
.{ "new-tab", actionNewTab, null }, .{ "new-tab", actionNewTab, null },
.{ "new-window", actionNewWindow, null }, .{ "new-window", actionNewWindow, null },
.{ "ring-bell", actionRingBell, null },
.{ "split-right", actionSplitRight, null }, .{ "split-right", actionSplitRight, null },
.{ "split-left", actionSplitLeft, null }, .{ "split-left", actionSplitLeft, null },
.{ "split-up", actionSplitUp, null }, .{ "split-up", actionSplitUp, null },
@ -1317,6 +1318,10 @@ pub const Window = extern struct {
// Setup our binding group. This ensures things like the title // Setup our binding group. This ensures things like the title
// are synced from the active tab. // are synced from the active tab.
priv.tab_bindings.setSource(child.as(gobject.Object)); priv.tab_bindings.setSource(child.as(gobject.Object));
// If the tab was previously marked as needing attention
// (e.g. due to a bell character), we now unmark that
page.setNeedsAttention(@intFromBool(false));
} }
fn tabViewPageAttached( fn tabViewPageAttached(
@ -1729,6 +1734,30 @@ pub const Window = extern struct {
self.performBindingAction(.clear_screen); self.performBindingAction(.clear_screen);
} }
fn actionRingBell(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Window,
) callconv(.c) void {
const priv = self.private();
const config = if (priv.config) |v| v.get() else return;
if (config.@"bell-features".system) system: {
const native = self.as(gtk.Native).getSurface() orelse {
log.warn("unable to get native surface from window", .{});
break :system;
};
native.beep();
}
if (config.@"bell-features".attention) {
// Request user attention
self.winproto().setUrgent(true) catch |err| {
log.warn("failed to request user attention={}", .{err});
};
}
}
/// Toggle the command palette. /// Toggle the command palette.
/// ///
/// TODO: accept the surface that toggled the command palette as a parameter /// TODO: accept the surface that toggled the command palette as a parameter