apprt/gtk: only show exit confirmation if process is alive

This commit is contained in:
Mitchell Hashimoto
2023-03-25 16:36:12 -07:00
parent 2c0dbab7ba
commit 3689f1fe39
6 changed files with 31 additions and 13 deletions

View File

@ -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 {

View File

@ -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();
},
}
}

View File

@ -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.

View File

@ -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(&gtkCloseConfirmation), self, null, G_CONNECT_DEFAULT);
c.gtk_widget_show(alert);
//self.window.closeSurface(self);
}
pub fn newTab(self: *Surface) !void {

View File

@ -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.

View File

@ -401,7 +401,7 @@ fn processExit(
// Notify our surface we want to close
_ = ev.surface_mailbox.push(.{
.close = {},
.child_exited = {},
}, .{ .forever = {} });
return .disarm;