aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/terminal/ScreenSet.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/terminal/ScreenSet.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (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.zig107
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);
+}