From 3689f1fe390ad14651d3cc96042339b7c47cd3cb Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 25 Mar 2023 16:36:12 -0700 Subject: [PATCH] apprt/gtk: only show exit confirmation if process is alive --- src/App.zig | 6 ++++-- src/Surface.zig | 12 +++++++++++- src/apprt/glfw.zig | 7 +++++-- src/apprt/gtk.zig | 13 ++++++------- src/apprt/surface.zig | 4 ++++ src/termio/Exec.zig | 2 +- 6 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/App.zig b/src/App.zig index f2d18a7fd..b5635c0da 100644 --- a/src/App.zig +++ b/src/App.zig @@ -74,7 +74,7 @@ pub fn tick(self: *App, rt_app: *apprt.App) !bool { while (i < self.surfaces.items.len) { const surface = self.surfaces.items[i]; if (surface.shouldClose()) { - rt_app.closeSurface(surface); + surface.close(false); continue; } @@ -143,8 +143,10 @@ fn reloadConfig(self: *App, rt_app: *apprt.App) !void { } fn closeSurface(self: *App, rt_app: *apprt.App, surface: *Surface) !void { + _ = rt_app; + if (!self.hasSurface(surface)) return; - rt_app.closeSurface(surface.rt_surface); + surface.close(); } fn redrawSurface(self: *App, rt_app: *apprt.App, surface: *apprt.Surface) !void { diff --git a/src/Surface.zig b/src/Surface.zig index 80fd87ac6..1b0a82cea 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -96,6 +96,10 @@ config: DerivedConfig, /// like such as "control-v" will write a "v" even if they're intercepted. ignore_char: bool = false, +/// This is set to true if our IO thread notifies us our child exited. +/// This is used to determine if we need to confirm, hold open, etc. +child_exited: bool = false, + /// Mouse state for the surface. const Mouse = struct { /// The last tracked mouse button state by button. @@ -522,7 +526,7 @@ pub fn deinit(self: *Surface) void { /// Close this surface. This will trigger the runtime to start the /// close process, which should ultimately deinitialize this surface. pub fn close(self: *Surface) void { - self.rt_surface.close(); + self.rt_surface.close(!self.child_exited); } /// Called from the app thread to handle mailbox messages to our specific @@ -553,6 +557,12 @@ pub fn handleMessage(self: *Surface, msg: Message) !void { }, .close => self.close(), + + // Close without confirmation. + .child_exited => { + self.child_exited = true; + self.close(); + }, } } diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index dfe758bf9..034ed31c1 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -409,8 +409,11 @@ pub const Surface = struct { } /// Close this surface. - pub fn close(self: *const Surface) void { - self.window.setShouldClose(true); + pub fn close(self: *Surface, processActive: bool) void { + _ = processActive; + self.setShouldClose(); + self.deinit(); + self.app.app.alloc.destroy(self); } /// Set the size limits of the window. diff --git a/src/apprt/gtk.zig b/src/apprt/gtk.zig index ce5e7d60f..2c1f653ab 100644 --- a/src/apprt/gtk.zig +++ b/src/apprt/gtk.zig @@ -171,11 +171,6 @@ pub const App = struct { } /// Close the given surface. - pub fn closeSurface(self: *App, surface: *Surface) void { - _ = self; - surface.close(); - } - pub fn redrawSurface(self: *App, surface: *Surface) void { _ = self; surface.invalidate(); @@ -635,7 +630,12 @@ pub const Surface = struct { } /// Close this surface. - pub fn close(self: *Surface) void { + pub fn close(self: *Surface, processActive: bool) void { + if (!processActive) { + self.window.closeSurface(self); + return; + } + // I'd like to make this prettier one day: // - Make the "Yes" button red // - Make the "No" button default @@ -658,7 +658,6 @@ pub const Surface = struct { _ = c.g_signal_connect_data(alert, "response", c.G_CALLBACK(>kCloseConfirmation), self, null, G_CONNECT_DEFAULT); c.gtk_widget_show(alert); - //self.window.closeSurface(self); } pub fn newTab(self: *Surface) !void { diff --git a/src/apprt/surface.zig b/src/apprt/surface.zig index d5ebc0083..859d694d5 100644 --- a/src/apprt/surface.zig +++ b/src/apprt/surface.zig @@ -33,6 +33,10 @@ pub const Message = union(enum) { /// Close the surface. This will only close the current surface that /// receives this, not the full application. close: void, + + /// The child process running in the surface has exited. This may trigger + /// a surface close, it may not. + child_exited: void, }; /// A surface mailbox. diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index a9632d799..4e908f72a 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -401,7 +401,7 @@ fn processExit( // Notify our surface we want to close _ = ev.surface_mailbox.push(.{ - .close = {}, + .child_exited = {}, }, .{ .forever = {} }); return .disarm;