From d83bf5aeb4b10bf4ac7cb0ca3c3447e041c31446 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 18 Mar 2023 19:21:28 -0700 Subject: [PATCH] termio: close surface on process exit --- src/Surface.zig | 16 +++++++++++----- src/apprt/surface.zig | 4 ++++ src/termio/Exec.zig | 17 ++++++++++++----- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index 26903eeed..9d2ee7f62 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -479,6 +479,14 @@ pub fn deinit(self: *Surface) void { log.info("surface closed addr={x}", .{@ptrToInt(self)}); } +/// 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 { + if (@hasDecl(apprt.Surface, "closeSurface")) { + try self.rt_surface.closeSurface(); + } else log.warn("runtime doesn't implement closeSurface", .{}); +} + /// Called from the app thread to handle mailbox messages to our specific /// surface. pub fn handleMessage(self: *Surface, msg: Message) !void { @@ -503,6 +511,8 @@ pub fn handleMessage(self: *Surface, msg: Message) !void { try self.clipboardWrite(v.data); }, }, + + .close => self.close(), } } @@ -953,11 +963,7 @@ pub fn keyCallback( } else log.warn("runtime doesn't implement gotoSplit", .{}); }, - .close_surface => { - if (@hasDecl(apprt.Surface, "closeSurface")) { - try self.rt_surface.closeSurface(); - } else log.warn("runtime doesn't implement closeSurface", .{}); - }, + .close_surface => self.close(), .close_window => { _ = self.app_mailbox.push(.{ .close = self }, .{ .instant = {} }); diff --git a/src/apprt/surface.zig b/src/apprt/surface.zig index 0e6439a41..3f409efb7 100644 --- a/src/apprt/surface.zig +++ b/src/apprt/surface.zig @@ -23,6 +23,10 @@ pub const Message = union(enum) { /// Write the clipboard contents. clipboard_write: WriteReq, + + /// Close the surface. This will only close the current surface that + /// receives this, not the full application. + close: void, }; /// A surface mailbox. diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index 9a2fc7459..9078d77de 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -130,6 +130,7 @@ pub fn threadEnter(self: *Exec, thread: *termio.Thread) !ThreadData { ev_data_ptr.* = .{ .writer_mailbox = thread.mailbox, .writer_wakeup = thread.wakeup, + .surface_mailbox = self.surface_mailbox, .renderer_state = self.renderer_state, .renderer_wakeup = self.renderer_wakeup, .renderer_mailbox = self.renderer_mailbox, @@ -142,7 +143,6 @@ pub fn threadEnter(self: *Exec, thread: *termio.Thread) !ThreadData { .ev = ev_data_ptr, .terminal = &self.terminal, .grid_size = &self.grid_size, - .surface_mailbox = self.surface_mailbox, }, }, }; @@ -277,6 +277,9 @@ const EventData = struct { writer_mailbox: *termio.Mailbox, writer_wakeup: xev.Async, + /// Mailbox for the surface. + surface_mailbox: apprt.surface.Mailbox, + /// The stream parser. This parses the stream of escape codes and so on /// from the child process and calls callbacks in the stream handler. terminal_stream: terminal.Stream(StreamHandler), @@ -354,6 +357,11 @@ fn processExit( ev.process_exited = true; ev.data_stream.close(loop, completion, EventData, ev, ttyClose); + // Notify our surface we want to close + _ = ev.surface_mailbox.push(.{ + .close = {}, + }, .{ .forever = {} }); + return .disarm; } @@ -820,7 +828,6 @@ const StreamHandler = struct { alloc: Allocator, grid_size: *renderer.GridSize, terminal: *terminal.Terminal, - surface_mailbox: apprt.surface.Mailbox, /// This is set to true when a message was written to the writer /// mailbox. This can be used by callers to determine if they need @@ -1167,7 +1174,7 @@ const StreamHandler = struct { std.mem.copy(u8, &buf, title); buf[title.len] = 0; - _ = self.surface_mailbox.push(.{ + _ = self.ev.surface_mailbox.push(.{ .set_title = buf, }, .{ .forever = {} }); } @@ -1179,14 +1186,14 @@ const StreamHandler = struct { // Get clipboard contents if (data.len == 1 and data[0] == '?') { - _ = self.surface_mailbox.push(.{ + _ = self.ev.surface_mailbox.push(.{ .clipboard_read = kind, }, .{ .forever = {} }); return; } // Write clipboard contents - _ = self.surface_mailbox.push(.{ + _ = self.ev.surface_mailbox.push(.{ .clipboard_write = try apprt.surface.Message.WriteReq.init( self.alloc, data,