mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
termio: move renderer message sending out to separate func
This commit is contained in:
@ -144,6 +144,38 @@ pub const StreamHandler = struct {
|
|||||||
self.termio_messaged = true;
|
self.termio_messaged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send a renderer message and unlock the renderer state mutex
|
||||||
|
/// if necessary to ensure we don't deadlock.
|
||||||
|
///
|
||||||
|
/// This assumes the renderer state mutex is locked.
|
||||||
|
inline fn rendererMessageWriter(
|
||||||
|
self: *StreamHandler,
|
||||||
|
msg: renderer.Message,
|
||||||
|
) void {
|
||||||
|
// See termio.Mailbox.send for more details on how this works.
|
||||||
|
|
||||||
|
// Try instant first. If it works then we can return.
|
||||||
|
if (self.renderer_mailbox.push(msg, .{ .instant = {} }) > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instant would have blocked. Release the renderer mutex,
|
||||||
|
// wake up the renderer to allow it to process the message,
|
||||||
|
// and then try again.
|
||||||
|
self.renderer_state.mutex.unlock();
|
||||||
|
defer self.renderer_state.mutex.lock();
|
||||||
|
self.renderer_wakeup.notify() catch |err| {
|
||||||
|
// This is an EXTREMELY unlikely case. We still don't return
|
||||||
|
// and attempt to send the message because its most likely
|
||||||
|
// that everything is fine, but log in case a freeze happens.
|
||||||
|
log.warn(
|
||||||
|
"failed to notify renderer, may deadlock err={}",
|
||||||
|
.{err},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
_ = self.renderer_mailbox.push(msg, .{ .forever = {} });
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dcsHook(self: *StreamHandler, dcs: terminal.DCS) !void {
|
pub fn dcsHook(self: *StreamHandler, dcs: terminal.DCS) !void {
|
||||||
var cmd = self.dcs.hook(self.alloc, dcs) orelse return;
|
var cmd = self.dcs.hook(self.alloc, dcs) orelse return;
|
||||||
defer cmd.deinit();
|
defer cmd.deinit();
|
||||||
@ -1279,7 +1311,7 @@ pub const StreamHandler = struct {
|
|||||||
for (request.list.items) |item| {
|
for (request.list.items) |item| {
|
||||||
switch (item) {
|
switch (item) {
|
||||||
.query => |key| {
|
.query => |key| {
|
||||||
const color = switch (key) {
|
const color: terminal.color.RGB = switch (key) {
|
||||||
.foreground => self.foreground_color,
|
.foreground => self.foreground_color,
|
||||||
.background => self.background_color,
|
.background => self.background_color,
|
||||||
.cursor => self.cursor_color,
|
.cursor => self.cursor_color,
|
||||||
@ -1305,42 +1337,27 @@ pub const StreamHandler = struct {
|
|||||||
|
|
||||||
// See messageWriter which has similar logic and
|
// See messageWriter which has similar logic and
|
||||||
// explains why we may have to do this.
|
// explains why we may have to do this.
|
||||||
const msg: renderer.Message = .{
|
self.rendererMessageWriter(.{
|
||||||
.foreground_color = v.color,
|
.foreground_color = v.color,
|
||||||
};
|
});
|
||||||
if (self.renderer_mailbox.push(msg, .{ .instant = {} }) == 0) {
|
|
||||||
self.renderer_state.mutex.unlock();
|
|
||||||
defer self.renderer_state.mutex.lock();
|
|
||||||
_ = self.renderer_mailbox.push(msg, .{ .forever = {} });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.background => {
|
.background => {
|
||||||
self.background_color = v.color;
|
self.background_color = v.color;
|
||||||
|
|
||||||
// See messageWriter which has similar logic and
|
// See messageWriter which has similar logic and
|
||||||
// explains why we may have to do this.
|
// explains why we may have to do this.
|
||||||
const msg: renderer.Message = .{
|
self.rendererMessageWriter(.{
|
||||||
.background_color = v.color,
|
.background_color = v.color,
|
||||||
};
|
});
|
||||||
if (self.renderer_mailbox.push(msg, .{ .instant = {} }) == 0) {
|
|
||||||
self.renderer_state.mutex.unlock();
|
|
||||||
defer self.renderer_state.mutex.lock();
|
|
||||||
_ = self.renderer_mailbox.push(msg, .{ .forever = {} });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.cursor => {
|
.cursor => {
|
||||||
self.cursor_color = v.color;
|
self.cursor_color = v.color;
|
||||||
|
|
||||||
// See messageWriter which has similar logic and
|
// See messageWriter which has similar logic and
|
||||||
// explains why we may have to do this.
|
// explains why we may have to do this.
|
||||||
const msg: renderer.Message = .{
|
self.rendererMessageWriter(.{
|
||||||
.cursor_color = v.color,
|
.cursor_color = v.color,
|
||||||
};
|
});
|
||||||
if (self.renderer_mailbox.push(msg, .{ .instant = {} }) == 0) {
|
|
||||||
self.renderer_state.mutex.unlock();
|
|
||||||
defer self.renderer_state.mutex.lock();
|
|
||||||
_ = self.renderer_mailbox.push(msg, .{ .forever = {} });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
else => if (v.key.palette()) |i| {
|
else => if (v.key.palette()) |i| {
|
||||||
@ -1361,42 +1378,27 @@ pub const StreamHandler = struct {
|
|||||||
|
|
||||||
// See messageWriter which has similar logic and
|
// See messageWriter which has similar logic and
|
||||||
// explains why we may have to do this.
|
// explains why we may have to do this.
|
||||||
const msg: renderer.Message = .{
|
self.rendererMessageWriter(.{
|
||||||
.foreground_color = self.default_foreground_color,
|
.foreground_color = self.default_foreground_color,
|
||||||
};
|
});
|
||||||
if (self.renderer_mailbox.push(msg, .{ .instant = {} }) == 0) {
|
|
||||||
self.renderer_state.mutex.unlock();
|
|
||||||
defer self.renderer_state.mutex.lock();
|
|
||||||
_ = self.renderer_mailbox.push(msg, .{ .forever = {} });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.background => {
|
.background => {
|
||||||
self.background_color = self.default_background_color;
|
self.background_color = self.default_background_color;
|
||||||
|
|
||||||
// See messageWriter which has similar logic and
|
// See messageWriter which has similar logic and
|
||||||
// explains why we may have to do this.
|
// explains why we may have to do this.
|
||||||
const msg: renderer.Message = .{
|
self.rendererMessageWriter(.{
|
||||||
.background_color = self.default_background_color,
|
.background_color = self.default_background_color,
|
||||||
};
|
});
|
||||||
if (self.renderer_mailbox.push(msg, .{ .instant = {} }) == 0) {
|
|
||||||
self.renderer_state.mutex.unlock();
|
|
||||||
defer self.renderer_state.mutex.lock();
|
|
||||||
_ = self.renderer_mailbox.push(msg, .{ .forever = {} });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
.cursor => {
|
.cursor => {
|
||||||
self.cursor_color = self.default_cursor_color;
|
self.cursor_color = self.default_cursor_color;
|
||||||
|
|
||||||
// See messageWriter which has similar logic and
|
// See messageWriter which has similar logic and
|
||||||
// explains why we may have to do this.
|
// explains why we may have to do this.
|
||||||
const msg: renderer.Message = .{
|
self.rendererMessageWriter(.{
|
||||||
.cursor_color = self.default_cursor_color,
|
.cursor_color = self.default_cursor_color,
|
||||||
};
|
});
|
||||||
if (self.renderer_mailbox.push(msg, .{ .instant = {} }) == 0) {
|
|
||||||
self.renderer_state.mutex.unlock();
|
|
||||||
defer self.renderer_state.mutex.lock();
|
|
||||||
_ = self.renderer_mailbox.push(msg, .{ .forever = {} });
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
else => if (key.palette()) |i| {
|
else => if (key.palette()) |i| {
|
||||||
@ -1422,5 +1424,9 @@ pub const StreamHandler = struct {
|
|||||||
.data = try buf.toOwnedSlice(),
|
.data = try buf.toOwnedSlice(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Note: we don't have to do a queueRender here because every
|
||||||
|
// processed stream will queue a render once it is done processing
|
||||||
|
// the read() syscall.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user