diff --git a/src/Surface.zig b/src/Surface.zig index 6e58ab5a5..af0a742c6 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -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; diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index a3a6ec411..8987d3504 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -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), } } diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index f8d6dd5da..5d835b4b3 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -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; }