diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-04 19:22:04 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 01:23:06 +0300 |
| commit | 41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch) | |
| tree | 3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/terminal/ScreenSet.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/terminal/ScreenSet.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/terminal/ScreenSet.zig | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/terminal/ScreenSet.zig b/vendor/libghostty-vt/src/terminal/ScreenSet.zig new file mode 100644 index 00000000..d0856da5 --- /dev/null +++ b/vendor/libghostty-vt/src/terminal/ScreenSet.zig @@ -0,0 +1,107 @@ +/// A ScreenSet holds multiple terminal screens. This is initially created +/// to handle simple primary vs alternate screens, but could be extended +/// in the future to handle N screens. +/// +/// One of the goals of this is to allow lazy initialization of screens +/// as needed. The primary screen is always initialized, but the alternate +/// screen may not be until first used. +const ScreenSet = @This(); + +const std = @import("std"); +const assert = @import("../quirks.zig").inlineAssert; +const lib = @import("lib.zig"); +const testing = std.testing; +const Allocator = std.mem.Allocator; +const Screen = @import("Screen.zig"); + +/// The possible keys for screens in the screen set. +pub const Key = lib.Enum(lib.target, &.{ + "primary", + "alternate", +}); + +/// The key value of the currently active screen. Useful for simple +/// comparisons, e.g. "is this screen the primary screen". +active_key: Key, + +/// The active screen pointer. +active: *Screen, + +/// All screens that are initialized. +all: std.EnumMap(Key, *Screen), + +pub fn init( + alloc: Allocator, + opts: Screen.Options, +) Allocator.Error!ScreenSet { + // We need to initialize our initial primary screen + const screen = try alloc.create(Screen); + errdefer alloc.destroy(screen); + screen.* = try .init(alloc, opts); + return .{ + .active_key = .primary, + .active = screen, + .all = .init(.{ .primary = screen }), + }; +} + +pub fn deinit(self: *ScreenSet, alloc: Allocator) void { + // Destroy all initialized screens + var it = self.all.iterator(); + while (it.next()) |entry| { + entry.value.*.deinit(); + alloc.destroy(entry.value.*); + } +} + +/// Get the screen for the given key, if it is initialized. +pub fn get(self: *const ScreenSet, key: Key) ?*Screen { + return self.all.get(key); +} + +/// Get the screen for the given key, initializing it if necessary. +pub fn getInit( + self: *ScreenSet, + alloc: Allocator, + key: Key, + opts: Screen.Options, +) Allocator.Error!*Screen { + if (self.get(key)) |screen| return screen; + const screen = try alloc.create(Screen); + errdefer alloc.destroy(screen); + screen.* = try .init(alloc, opts); + self.all.put(key, screen); + return screen; +} + +/// Remove a key from the set. The primary screen cannot be removed (asserted). +pub fn remove( + self: *ScreenSet, + alloc: Allocator, + key: Key, +) void { + assert(key != .primary); + if (self.all.fetchRemove(key)) |screen| { + screen.deinit(); + alloc.destroy(screen); + } +} + +/// Switch the active screen to the given key. Requires that the +/// screen is initialized. +pub fn switchTo(self: *ScreenSet, key: Key) void { + self.active_key = key; + self.active = self.all.get(key).?; +} + +test ScreenSet { + const alloc = testing.allocator; + var set: ScreenSet = try .init(alloc, .default); + defer set.deinit(alloc); + try testing.expectEqual(.primary, set.active_key); + + // Initialize a secondary screen + _ = try set.getInit(alloc, .alternate, .default); + set.switchTo(.alternate); + try testing.expectEqual(.alternate, set.active_key); +} |
