show child exited: return a boolean if native GUI is shown

If a native GUI is shown by the runtime when a child exits, use the
returned boolean to determine if text should be show in the terminal to
avoid duplicating information.
This commit is contained in:
Jeffrey C. Ollie
2025-07-06 16:48:15 -05:00
parent 103772ee8f
commit 5219bc51e5
3 changed files with 31 additions and 23 deletions

View File

@ -1011,19 +1011,21 @@ fn childExited(self: *Surface, info: apprt.surface.Message.ChildExited) void {
log.warn("abnormal process exit detected, showing error message", .{});
// Update our terminal to note the abnormal exit. In the future we
// may want the apprt to handle this to show some native GUI element.
self.childExitedAbnormally(info) catch |err| {
log.err("error handling abnormal child exit err={}", .{err});
return;
};
_ = self.rt_app.performAction(
// Try and show a GUI message. If it returns true, don't do anything else.
if (self.rt_app.performAction(
.{ .surface = self },
.show_child_exited,
info,
) catch |err| {
) catch |err| gui: {
log.err("error trying to show native child exited GUI err={}", .{err});
break :gui false;
}) return;
// If a native GUI notification was not showm. update our terminal to
// note the abnormal exit.
self.childExitedAbnormally(info) catch |err| {
log.err("error handling abnormal child exit err={}", .{err});
return;
};
return;
@ -1036,6 +1038,18 @@ fn childExited(self: *Surface, info: apprt.surface.Message.ChildExited) void {
// surface then they will see this message and know the process has
// completed.
terminal: {
// First try and show a native GUI message.
if (self.rt_app.performAction(
.{ .surface = self },
.show_child_exited,
info,
) catch |err| gui: {
log.err("error trying to show native child exited GUI err={}", .{err});
break :gui false;
}) break :terminal;
// If the native GUI can't be shown, display a text message in the
// terminal.
self.renderer_state.mutex.lock();
defer self.renderer_state.mutex.unlock();
const t: *terminal.Terminal = self.renderer_state.terminal;
@ -1052,14 +1066,6 @@ fn childExited(self: *Surface, info: apprt.surface.Message.ChildExited) void {
t.screen.kitty_keyboard.set(.set, .{});
}
_ = self.rt_app.performAction(
.{ .surface = self },
.show_child_exited,
info,
) catch |err| {
log.err("error trying to show native child exited GUI err={}", .{err});
};
// Waiting after command we stop here. The terminal is updated, our
// state is updated, and now its up to the user to decide what to do.
if (self.config.wait_after_command) return;

View File

@ -521,7 +521,7 @@ pub fn performAction(
.ring_bell => try self.ringBell(target),
.toggle_command_palette => try self.toggleCommandPalette(target),
.open_url => self.openUrl(value),
.show_child_exited => try self.showChildExited(target, value),
.show_child_exited => return try self.showChildExited(target, value),
// Unimplemented
.close_all_windows,
@ -847,10 +847,10 @@ fn toggleCommandPalette(_: *App, target: apprt.Target) !void {
}
}
fn showChildExited(_: *App, target: apprt.Target, value: apprt.surface.Message.ChildExited) !void {
fn showChildExited(_: *App, target: apprt.Target, value: apprt.surface.Message.ChildExited) (error{})!bool {
switch (target) {
.app => {},
.surface => |surface| try surface.rt_surface.showChildExited(value),
.app => return false,
.surface => |surface| return try surface.rt_surface.showChildExited(value),
}
}

View File

@ -2504,8 +2504,8 @@ fn gtkStreamEnded(media_file: *gtk.MediaFile, _: *gobject.ParamSpec, _: ?*anyopa
media_file.unref();
}
pub fn showChildExited(self: *Surface, info: apprt.surface.Message.ChildExited) (error{})!void {
if (!adw_version.supportsBanner()) return;
pub fn showChildExited(self: *Surface, info: apprt.surface.Message.ChildExited) (error{})!bool {
if (!adw_version.supportsBanner()) return false;
const warning_box = gtk.Box.new(.vertical, 0);
@ -2528,4 +2528,6 @@ pub fn showChildExited(self: *Surface, info: apprt.surface.Message.ChildExited)
warning_box.append(banner_widget);
self.overlay.addOverlay(warning_box.as(gtk.Widget));
return true;
}