mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
plumb the linux cgroup through to termio
This commit is contained in:
@ -404,6 +404,16 @@ pub fn init(
|
||||
.renderer_wakeup = render_thread.wakeup,
|
||||
.renderer_mailbox = render_thread.mailbox,
|
||||
.surface_mailbox = .{ .surface = self, .app = app_mailbox },
|
||||
|
||||
// Get the cgroup if we're on linux and have the decl. I'd love
|
||||
// to change this from a decl to a surface options struct because
|
||||
// then we can do memory management better (don't need to retain
|
||||
// the string around).
|
||||
.linux_cgroup = if (comptime builtin.os.tag == .linux and
|
||||
@hasDecl(apprt.runtime.Surface, "cgroup"))
|
||||
rt_surface.cgroup()
|
||||
else
|
||||
termio.Options.linux_cgroup_default,
|
||||
});
|
||||
errdefer io.deinit();
|
||||
|
||||
|
@ -11,6 +11,7 @@ const font = @import("../../font/main.zig");
|
||||
const input = @import("../../input.zig");
|
||||
const terminal = @import("../../terminal/main.zig");
|
||||
const CoreSurface = @import("../../Surface.zig");
|
||||
const internal_os = @import("../../os/main.zig");
|
||||
|
||||
const App = @import("App.zig");
|
||||
const Split = @import("Split.zig");
|
||||
@ -255,6 +256,10 @@ im_commit_buffered: bool = false,
|
||||
im_buf: [128]u8 = undefined,
|
||||
im_len: u7 = 0,
|
||||
|
||||
/// The surface-specific cgroup path. See App.transient_cgroup_path for
|
||||
/// details on what this is.
|
||||
cgroup_path: ?[]const u8 = null,
|
||||
|
||||
pub fn create(alloc: Allocator, app: *App, opts: Options) !*Surface {
|
||||
var surface = try alloc.create(Surface);
|
||||
errdefer alloc.destroy(surface);
|
||||
@ -342,6 +347,36 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
||||
break :font_size parent.font_size;
|
||||
};
|
||||
|
||||
// If the parent has a transient cgroup, then we're creating cgroups
|
||||
// for each surface if we can. We need to create a child cgroup.
|
||||
const cgroup_path: ?[]const u8 = cgroup: {
|
||||
const base = app.transient_cgroup_base orelse break :cgroup null;
|
||||
|
||||
// For the unique group name we use the self pointer. This may
|
||||
// not be a good idea for security reasons but not sure yet. We
|
||||
// may want to change this to something else eventually to be safe.
|
||||
var buf: [256]u8 = undefined;
|
||||
const name = std.fmt.bufPrint(
|
||||
&buf,
|
||||
"surface({X}).scope",
|
||||
.{@intFromPtr(self)},
|
||||
) catch unreachable;
|
||||
|
||||
// Create the cgroup. If it fails, no big deal... just ignore.
|
||||
internal_os.cgroup.create(base, name, null) catch |err| {
|
||||
log.err("failed to create surface cgroup err={}", .{err});
|
||||
break :cgroup null;
|
||||
};
|
||||
|
||||
// Success, save the cgroup path.
|
||||
break :cgroup std.fmt.allocPrint(
|
||||
app.core_app.alloc,
|
||||
"{s}/{s}",
|
||||
.{ base, name },
|
||||
) catch null;
|
||||
};
|
||||
errdefer if (cgroup_path) |path| app.core_app.alloc.free(path);
|
||||
|
||||
// Build our result
|
||||
self.* = .{
|
||||
.app = app,
|
||||
@ -354,6 +389,7 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
||||
.size = .{ .width = 800, .height = 600 },
|
||||
.cursor_pos = .{ .x = 0, .y = 0 },
|
||||
.im_context = im_context,
|
||||
.cgroup_path = cgroup_path,
|
||||
};
|
||||
errdefer self.* = undefined;
|
||||
|
||||
@ -442,9 +478,10 @@ pub fn deinit(self: *Surface) void {
|
||||
self.core_surface.deinit();
|
||||
self.core_surface = undefined;
|
||||
|
||||
if (self.cgroup_path) |path| self.app.core_app.alloc.free(path);
|
||||
|
||||
// Free all our GTK stuff
|
||||
c.g_object_unref(self.im_context);
|
||||
|
||||
if (self.cursor) |cursor| c.g_object_unref(cursor);
|
||||
}
|
||||
|
||||
@ -463,6 +500,11 @@ fn render(self: *Surface) !void {
|
||||
try self.core_surface.renderer.drawFrame(self);
|
||||
}
|
||||
|
||||
/// Called by core surface to get the cgroup.
|
||||
pub fn cgroup(self: *const Surface) ?[]const u8 {
|
||||
return self.cgroup_path;
|
||||
}
|
||||
|
||||
/// Queue the inspector to render if we have one.
|
||||
pub fn queueInspectorRender(self: *Surface) void {
|
||||
if (self.inspector) |v| v.queueRender();
|
||||
|
@ -179,7 +179,14 @@ pub fn init(alloc: Allocator, opts: termio.Options) !Exec {
|
||||
term.width_px = subprocess.screen_size.width;
|
||||
term.height_px = subprocess.screen_size.height;
|
||||
|
||||
return Exec{
|
||||
// TODO: make work
|
||||
if (comptime builtin.os.tag == .linux) {
|
||||
if (opts.linux_cgroup) |cgroup| {
|
||||
log.warn("DESIRED cgroup={s}", .{cgroup});
|
||||
}
|
||||
}
|
||||
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
.terminal = term,
|
||||
.subprocess = subprocess,
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! The options that are used to configure a terminal IO implementation.
|
||||
|
||||
const builtin = @import("builtin");
|
||||
const xev = @import("xev");
|
||||
const apprt = @import("../apprt.zig");
|
||||
const renderer = @import("../renderer.zig");
|
||||
@ -41,3 +42,10 @@ renderer_mailbox: *renderer.Thread.Mailbox,
|
||||
|
||||
/// The mailbox for sending the surface messages.
|
||||
surface_mailbox: apprt.surface.Mailbox,
|
||||
|
||||
/// The cgroup to apply to the started termio process, if able by
|
||||
/// the termio implementation. This only applies to Linux.
|
||||
linux_cgroup: LinuxCgroup = linux_cgroup_default,
|
||||
|
||||
pub const LinuxCgroup = if (builtin.os.tag == .linux) ?[]const u8 else void;
|
||||
pub const linux_cgroup_default = if (LinuxCgroup == void) {} else null;
|
||||
|
Reference in New Issue
Block a user