mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-22 11:46:11 +03:00
gtk: refactor how Paned is created
This commit is contained in:

committed by
Mitchell Hashimoto

parent
19f7b37bb3
commit
142a2f4cb0
@ -15,6 +15,8 @@ const Parent = @import("relation.zig").Parent;
|
||||
const Child = @import("relation.zig").Child;
|
||||
const c = @import("c.zig");
|
||||
|
||||
const log = std.log.scoped(.gtk);
|
||||
|
||||
/// We'll need to keep a reference to the Window this belongs to for various reasons
|
||||
window: *Window,
|
||||
|
||||
@ -34,22 +36,28 @@ child2: Child,
|
||||
// maximize the parent pane, or close the tab.
|
||||
parent: Parent,
|
||||
|
||||
pub fn create(alloc: Allocator, window: *Window, direction: input.SplitDirection, label_text: *c.GtkWidget) !*Paned {
|
||||
pub fn create(alloc: Allocator, window: *Window, sibling: *Surface, direction: input.SplitDirection) !*Paned {
|
||||
var paned = try alloc.create(Paned);
|
||||
errdefer alloc.destroy(paned);
|
||||
try paned.init(window, direction, label_text);
|
||||
try paned.init(window, sibling, direction);
|
||||
return paned;
|
||||
}
|
||||
|
||||
pub fn init(self: *Paned, window: *Window, direction: input.SplitDirection, label_text: *c.GtkWidget) !void {
|
||||
pub fn init(self: *Paned, window: *Window, sibling: *Surface, direction: input.SplitDirection) !void {
|
||||
self.* = .{
|
||||
.window = window,
|
||||
.label_text = label_text,
|
||||
.label_text = undefined,
|
||||
.paned = undefined,
|
||||
.child1 = .none,
|
||||
.child2 = .none,
|
||||
.parent = undefined,
|
||||
};
|
||||
errdefer self.* = undefined;
|
||||
|
||||
self.label_text = sibling.getTitleLabel() orelse {
|
||||
log.warn("sibling surface has no title label", .{});
|
||||
return;
|
||||
};
|
||||
|
||||
const orientation: c_uint = switch (direction) {
|
||||
.right => c.GTK_ORIENTATION_HORIZONTAL,
|
||||
@ -57,10 +65,15 @@ pub fn init(self: *Paned, window: *Window, direction: input.SplitDirection, labe
|
||||
};
|
||||
|
||||
const paned = c.gtk_paned_new(orientation);
|
||||
errdefer c.gtk_widget_destroy(paned);
|
||||
errdefer c.g_object_unref(paned);
|
||||
|
||||
const gtk_paned: *c.GtkPaned = @ptrCast(paned);
|
||||
self.paned = gtk_paned;
|
||||
|
||||
const new_surface = try self.newSurface(sibling.tab, &sibling.core_surface);
|
||||
// This sets .parent on each surface
|
||||
self.addChild1Surface(sibling);
|
||||
self.addChild2Surface(new_surface);
|
||||
}
|
||||
|
||||
pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
|
||||
@ -98,16 +111,28 @@ pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
|
||||
return surface;
|
||||
}
|
||||
|
||||
pub fn focusSurfaceInPosition(self: *Paned, position: Position) void {
|
||||
const child = switch (position) {
|
||||
.start => self.child1,
|
||||
.end => self.child2,
|
||||
};
|
||||
|
||||
const surface = switch (child) {
|
||||
.surface => |surface| surface,
|
||||
else => return,
|
||||
};
|
||||
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(surface.gl_area));
|
||||
_ = c.gtk_widget_grab_focus(widget);
|
||||
}
|
||||
|
||||
pub fn setParent(self: *Paned, parent: Parent) void {
|
||||
self.parent = parent;
|
||||
}
|
||||
|
||||
pub fn removeChildren(self: *Paned) void {
|
||||
assert(self.child1 != .none);
|
||||
assert(self.child2 != .none);
|
||||
self.child1 = .none;
|
||||
self.child2 = .none;
|
||||
c.gtk_paned_set_start_child(@ptrCast(self.paned), null);
|
||||
c.gtk_paned_set_end_child(@ptrCast(self.paned), null);
|
||||
self.removeChildInPosition(.start);
|
||||
self.removeChildInPosition(.end);
|
||||
}
|
||||
|
||||
pub fn removeChildInPosition(self: *Paned, position: Position) void {
|
||||
@ -152,15 +177,3 @@ pub fn addChild2Paned(self: *Paned, paned: *Paned) void {
|
||||
paned.setParent(Parent{ .paned = .{ self, .end } });
|
||||
c.gtk_paned_set_end_child(@ptrCast(self.paned), @ptrCast(@alignCast(paned.paned)));
|
||||
}
|
||||
|
||||
pub fn splitStartPosition(self: *Paned, orientation: c.GtkOrientation) !void {
|
||||
_ = orientation;
|
||||
_ = self;
|
||||
// todo
|
||||
}
|
||||
|
||||
pub fn splitEndPosition(self: *Paned, orientation: c.GtkOrientation) !void {
|
||||
_ = orientation;
|
||||
_ = self;
|
||||
// todo
|
||||
}
|
||||
|
@ -345,22 +345,22 @@ pub fn toggleFullscreen(self: *Surface, mac_non_native: configpkg.NonNativeFulls
|
||||
self.window.toggleFullscreen(mac_non_native);
|
||||
}
|
||||
|
||||
pub fn getTitleLabel(self: *Surface) ?*c.GtkWidget {
|
||||
switch (self.title) {
|
||||
.none => return null,
|
||||
.label => |label| {
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(@alignCast(label)));
|
||||
return widget;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn newSplit(self: *Surface, direction: input.SplitDirection) !void {
|
||||
log.debug("new split, direction: {}", .{direction});
|
||||
|
||||
// TODO: Refactor all of this!
|
||||
|
||||
switch (self.parent) {
|
||||
.none => return,
|
||||
.paned => |parent_paned_tuple| {
|
||||
const label_text: *c.GtkWidget = switch (self.title) {
|
||||
.none => return,
|
||||
.label => |label| l: {
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(@alignCast(label)));
|
||||
break :l widget;
|
||||
},
|
||||
};
|
||||
|
||||
// Keep explicit reference to our gl_area before we remove ourselves.
|
||||
const sibling_object: *c.GObject = @ptrCast(self.gl_area);
|
||||
_ = c.g_object_ref(sibling_object);
|
||||
@ -374,12 +374,7 @@ pub fn newSplit(self: *Surface, direction: input.SplitDirection) !void {
|
||||
// Now remove ourselves from parent
|
||||
parent_paned.removeChildInPosition(parent_position);
|
||||
|
||||
// Create new sibling
|
||||
const paned = try Paned.create(self.app.core_app.alloc, self.window, direction, label_text);
|
||||
const new_surface = try paned.newSurface(self.tab, &self.core_surface);
|
||||
// This sets .parent on each surface
|
||||
paned.addChild1Surface(self);
|
||||
paned.addChild2Surface(new_surface);
|
||||
const paned = try Paned.create(self.app.core_app.alloc, self.window, self, direction);
|
||||
|
||||
// Add new split-paned
|
||||
switch (parent_position) {
|
||||
@ -389,31 +384,16 @@ pub fn newSplit(self: *Surface, direction: input.SplitDirection) !void {
|
||||
// Restore position
|
||||
c.gtk_paned_set_position(parent_paned.paned, parent_paned_position_before);
|
||||
// Focus on new surface
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(new_surface.gl_area));
|
||||
_ = c.gtk_widget_grab_focus(widget);
|
||||
paned.focusSurfaceInPosition(.end);
|
||||
},
|
||||
.tab => |tab| {
|
||||
const label_text: *c.GtkWidget = switch (self.title) {
|
||||
.none => return,
|
||||
.label => |label| l: {
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(@alignCast(label)));
|
||||
break :l widget;
|
||||
},
|
||||
};
|
||||
|
||||
tab.removeChild();
|
||||
|
||||
const paned = try Paned.create(self.app.core_app.alloc, self.window, direction, label_text);
|
||||
const new_surface = try paned.newSurface(tab, &self.core_surface);
|
||||
// This sets .parent on each surface
|
||||
paned.addChild1Surface(self);
|
||||
paned.addChild2Surface(new_surface);
|
||||
|
||||
const paned = try Paned.create(self.app.core_app.alloc, self.window, self, direction);
|
||||
tab.setChild(.{ .paned = paned });
|
||||
|
||||
// Focus on new surface
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(new_surface.gl_area));
|
||||
_ = c.gtk_widget_grab_focus(widget);
|
||||
paned.focusSurfaceInPosition(.end);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user