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", .{}); log.warn("abnormal process exit detected, showing error message", .{});
// Update our terminal to note the abnormal exit. In the future we // Try and show a GUI message. If it returns true, don't do anything else.
// may want the apprt to handle this to show some native GUI element. if (self.rt_app.performAction(
self.childExitedAbnormally(info) catch |err| {
log.err("error handling abnormal child exit err={}", .{err});
return;
};
_ = self.rt_app.performAction(
.{ .surface = self }, .{ .surface = self },
.show_child_exited, .show_child_exited,
info, info,
) catch |err| { ) catch |err| gui: {
log.err("error trying to show native child exited GUI err={}", .{err}); 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; 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 // surface then they will see this message and know the process has
// completed. // completed.
terminal: { 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(); self.renderer_state.mutex.lock();
defer self.renderer_state.mutex.unlock(); defer self.renderer_state.mutex.unlock();
const t: *terminal.Terminal = self.renderer_state.terminal; 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, .{}); 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 // 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. // state is updated, and now its up to the user to decide what to do.
if (self.config.wait_after_command) return; if (self.config.wait_after_command) return;

View File

@ -521,7 +521,7 @@ pub fn performAction(
.ring_bell => try self.ringBell(target), .ring_bell => try self.ringBell(target),
.toggle_command_palette => try self.toggleCommandPalette(target), .toggle_command_palette => try self.toggleCommandPalette(target),
.open_url => self.openUrl(value), .open_url => self.openUrl(value),
.show_child_exited => try self.showChildExited(target, value), .show_child_exited => return try self.showChildExited(target, value),
// Unimplemented // Unimplemented
.close_all_windows, .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) { switch (target) {
.app => {}, .app => return false,
.surface => |surface| try surface.rt_surface.showChildExited(value), .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(); media_file.unref();
} }
pub fn showChildExited(self: *Surface, info: apprt.surface.Message.ChildExited) (error{})!void { pub fn showChildExited(self: *Surface, info: apprt.surface.Message.ChildExited) (error{})!bool {
if (!adw_version.supportsBanner()) return; if (!adw_version.supportsBanner()) return false;
const warning_box = gtk.Box.new(.vertical, 0); 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); warning_box.append(banner_widget);
self.overlay.addOverlay(warning_box.as(gtk.Widget)); self.overlay.addOverlay(warning_box.as(gtk.Widget));
return true;
} }