From 0060d89b5be3a8b07d43599ea88fc7c5893bf36e Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Wed, 5 Aug 2026 13:35:30 -0400 Subject: [PATCH] core: fix encoded key request cleanup Encoded key requests are owned by the caller until they are added to a key sequence or queued for IO. The child_exited path and failed queue append returned without freeing the allocated request. The existing errdefer was also too broad: after queueIo took ownership, a later setSelection or queueRender error could free the queued request. We now free requests in the return paths that still own them, and the errdefer has been removed. Also, activate a sequence only after encoding and queue append succeed so failure preserves the previous sequence state. --- src/Surface.zig | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index 1a890d9b8..b063e7a6c 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -858,7 +858,7 @@ inline fn surfaceMailbox(self: *Surface) Mailbox { }; } -/// Queue a message for the IO thread. +/// Queue a message for the IO thread, taking ownership of `msg`. /// /// We centralize all our logic into this spot so we can intercept /// messages for example in readonly mode. @@ -2824,11 +2824,11 @@ pub fn keyCallback( // an encoded value, we close the surface. We want to eventually // move this behavior to the apprt probably. if (self.child_exited) { + write_req.deinit(); self.close(); return .closed; } - errdefer write_req.deinit(); self.queueIo(switch (write_req) { .small => |v| .{ .write_small = v }, .stable => |v| .{ .write_stable = v }, @@ -2946,16 +2946,19 @@ fn maybeHandleBinding( // Determine if this entry has an action or if its a leader key. const leaf: input.Binding.Set.GenericLeaf = switch (entry.value_ptr.*) { .leader => |set| { - // Setup the next set we'll look at. - self.keyboard.sequence_set = set; - // Store this event so that we can drain and encode on invalid. // We don't need to cap this because it is naturally capped by // the config validation. if (try self.encodeKey(event, insp_ev)) |req| { - try self.keyboard.sequence_queued.append(self.alloc, req); + self.keyboard.sequence_queued.append(self.alloc, req) catch |err| { + req.deinit(); + return err; + }; } + // Setup the next set we'll look at only after all fallible work. + self.keyboard.sequence_set = set; + // Start or continue our key sequence _ = self.rt_app.performAction( .{ .surface = self },