mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
gtk: refactor code and add comments to Paned
This commit is contained in:

committed by
Mitchell Hashimoto

parent
fde6289880
commit
eed2bb3078
@ -75,7 +75,7 @@ pub fn init(self: *Paned, window: *Window, sibling: *Surface, direction: input.S
|
|||||||
self.addChild2(.{ .surface = surface });
|
self.addChild2(.{ .surface = surface });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
|
fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
|
||||||
// Grab a surface allocation we'll need it later.
|
// Grab a surface allocation we'll need it later.
|
||||||
var surface = try self.window.app.core_app.alloc.create(Surface);
|
var surface = try self.window.app.core_app.alloc.create(Surface);
|
||||||
errdefer self.window.app.core_app.alloc.destroy(surface);
|
errdefer self.window.app.core_app.alloc.destroy(surface);
|
||||||
@ -110,16 +110,19 @@ pub fn newSurface(self: *Paned, tab: *Tab, parent_: ?*CoreSurface) !*Surface {
|
|||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the parent of Paned.
|
||||||
pub fn setParent(self: *Paned, parent: Parent) void {
|
pub fn setParent(self: *Paned, parent: Parent) void {
|
||||||
self.parent = parent;
|
self.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Focus on the Surface's gl_area in the given position.
|
||||||
pub fn focusSurfaceInPosition(self: *Paned, position: Position) void {
|
pub fn focusSurfaceInPosition(self: *Paned, position: Position) void {
|
||||||
const surface: *Surface = self.surfaceInPosition(position) orelse return;
|
const surface: *Surface = self.surfaceInPosition(position) orelse return;
|
||||||
const widget = @as(*c.GtkWidget, @ptrCast(surface.gl_area));
|
const widget = @as(*c.GtkWidget, @ptrCast(surface.gl_area));
|
||||||
_ = c.gtk_widget_grab_focus(widget);
|
_ = c.gtk_widget_grab_focus(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Split the Surface in the given position into a Paned with two surfaces.
|
||||||
pub fn splitSurfaceInPosition(self: *Paned, position: Position, direction: input.SplitDirection) !void {
|
pub fn splitSurfaceInPosition(self: *Paned, position: Position, direction: input.SplitDirection) !void {
|
||||||
const surface: *Surface = self.surfaceInPosition(position) orelse return;
|
const surface: *Surface = self.surfaceInPosition(position) orelse return;
|
||||||
|
|
||||||
@ -148,6 +151,7 @@ pub fn splitSurfaceInPosition(self: *Paned, position: Position, direction: input
|
|||||||
paned.focusSurfaceInPosition(.end);
|
paned.focusSurfaceInPosition(.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Replace the existing .start or .end Child with the given new Child.
|
||||||
pub fn replaceChildInPosition(self: *Paned, child: Child, position: Position) void {
|
pub fn replaceChildInPosition(self: *Paned, child: Child, position: Position) void {
|
||||||
// Keep position of divider
|
// Keep position of divider
|
||||||
const parent_paned_position_before = c.gtk_paned_get_position(self.paned);
|
const parent_paned_position_before = c.gtk_paned_get_position(self.paned);
|
||||||
@ -167,11 +171,25 @@ pub fn replaceChildInPosition(self: *Paned, child: Child, position: Position) vo
|
|||||||
c.gtk_paned_set_position(self.paned, parent_paned_position_before);
|
c.gtk_paned_set_position(self.paned, parent_paned_position_before);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove both children, setting *c.GtkPaned start/end children to null.
|
||||||
pub fn removeChildren(self: *Paned) void {
|
pub fn removeChildren(self: *Paned) void {
|
||||||
self.removeChildInPosition(.start);
|
self.removeChildInPosition(.start);
|
||||||
self.removeChildInPosition(.end);
|
self.removeChildInPosition(.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Deinit the Paned by deiniting its child Paneds, if they exist.
|
||||||
|
pub fn deinit(self: *Paned, alloc: Allocator) void {
|
||||||
|
for ([_]Child{ self.child1, self.child2 }) |child| {
|
||||||
|
switch (child) {
|
||||||
|
.none, .surface => continue,
|
||||||
|
.paned => |paned| {
|
||||||
|
paned.deinit(alloc);
|
||||||
|
alloc.destroy(paned);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn removeChildInPosition(self: *Paned, position: Position) void {
|
fn removeChildInPosition(self: *Paned, position: Position) void {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
.start => {
|
.start => {
|
||||||
@ -218,15 +236,3 @@ fn surfaceInPosition(self: *Paned, position: Position) ?*Surface {
|
|||||||
else => null,
|
else => null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Paned, alloc: Allocator) void {
|
|
||||||
for ([_]Child{ self.child1, self.child2 }) |child| {
|
|
||||||
switch (child) {
|
|
||||||
.none, .surface => continue,
|
|
||||||
.paned => |paned| {
|
|
||||||
paned.deinit(alloc);
|
|
||||||
alloc.destroy(paned);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -158,12 +158,6 @@ pub fn setChild(self: *Tab, child: Child) void {
|
|||||||
self.child = child;
|
self.child = child;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gtkTabCloseClick(_: *c.GtkButton, ud: ?*anyopaque) callconv(.C) void {
|
|
||||||
const tab: *Tab = @ptrCast(@alignCast(ud));
|
|
||||||
const window = tab.window;
|
|
||||||
window.closeTab(tab);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *Tab) void {
|
pub fn deinit(self: *Tab) void {
|
||||||
switch (self.child) {
|
switch (self.child) {
|
||||||
.none, .surface => return,
|
.none, .surface => return,
|
||||||
@ -173,3 +167,9 @@ pub fn deinit(self: *Tab) void {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gtkTabCloseClick(_: *c.GtkButton, ud: ?*anyopaque) callconv(.C) void {
|
||||||
|
const tab: *Tab = @ptrCast(@alignCast(ud));
|
||||||
|
const window = tab.window;
|
||||||
|
window.closeTab(tab);
|
||||||
|
}
|
||||||
|
@ -15,6 +15,7 @@ const App = @import("App.zig");
|
|||||||
const Paned = @import("Paned.zig");
|
const Paned = @import("Paned.zig");
|
||||||
const Surface = @import("Surface.zig");
|
const Surface = @import("Surface.zig");
|
||||||
const Tab = @import("Tab.zig");
|
const Tab = @import("Tab.zig");
|
||||||
|
const Position = @import("relation.zig").Position;
|
||||||
const icon = @import("icon.zig");
|
const icon = @import("icon.zig");
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
|
|
||||||
@ -213,7 +214,6 @@ pub fn removeTab(self: *Window, tab: *Tab) !void {
|
|||||||
if (t == tab) break i;
|
if (t == tab) break i;
|
||||||
} else null;
|
} else null;
|
||||||
|
|
||||||
// TODO: Shrink capacity?
|
|
||||||
if (tab_idx) |idx| _ = self.tabs.orderedRemove(idx) else return error.TabNotFound;
|
if (tab_idx) |idx| _ = self.tabs.orderedRemove(idx) else return error.TabNotFound;
|
||||||
|
|
||||||
// Deallocate the tab
|
// Deallocate the tab
|
||||||
@ -256,8 +256,6 @@ pub fn closeTab(self: *Window, tab: *Tab) void {
|
|||||||
pub fn closeSurface(self: *Window, surface: *Surface) void {
|
pub fn closeSurface(self: *Window, surface: *Surface) void {
|
||||||
assert(surface.window == self);
|
assert(surface.window == self);
|
||||||
|
|
||||||
const alloc = self.app.core_app.alloc;
|
|
||||||
|
|
||||||
switch (surface.parent) {
|
switch (surface.parent) {
|
||||||
.none => unreachable,
|
.none => unreachable,
|
||||||
.tab => |tab| self.closeTab(tab),
|
.tab => |tab| self.closeTab(tab),
|
||||||
@ -265,56 +263,60 @@ pub fn closeSurface(self: *Window, surface: *Surface) void {
|
|||||||
const paned = paned_tuple[0];
|
const paned = paned_tuple[0];
|
||||||
const position = paned_tuple[1];
|
const position = paned_tuple[1];
|
||||||
|
|
||||||
const sibling = switch (position) {
|
self.closeSurfaceInPaned(surface, paned, position);
|
||||||
.start => .{
|
|
||||||
paned.child2,
|
|
||||||
c.gtk_paned_get_end_child(paned.paned),
|
|
||||||
},
|
|
||||||
.end => .{
|
|
||||||
paned.child1,
|
|
||||||
c.gtk_paned_get_start_child(paned.paned),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// TODO: Use destructuring syntax once it doesn't break ZLS
|
|
||||||
const sibling_child = sibling[0];
|
|
||||||
const sibling_widget = sibling[1];
|
|
||||||
|
|
||||||
// Keep explicit reference to sibling's gl_area, so it's not
|
|
||||||
// destroyed when we remove it from GtkPaned.
|
|
||||||
const sibling_object: *c.GObject = @ptrCast(sibling_widget);
|
|
||||||
_ = c.g_object_ref(sibling_object);
|
|
||||||
defer c.g_object_unref(sibling_object);
|
|
||||||
|
|
||||||
// Remove reference on the surface we're closing
|
|
||||||
surface.setParent(.none);
|
|
||||||
|
|
||||||
// Remove children.
|
|
||||||
paned.removeChildren();
|
|
||||||
// Don't need to call paned.deinit, because we already removed children.
|
|
||||||
defer alloc.destroy(paned);
|
|
||||||
|
|
||||||
switch (paned.parent) {
|
|
||||||
.none => unreachable,
|
|
||||||
.tab => |tab| {
|
|
||||||
// If parent of Paned we belong to is a tab, we can
|
|
||||||
// replace the child with the other surface
|
|
||||||
tab.removeChild();
|
|
||||||
tab.setChild(sibling_child);
|
|
||||||
},
|
|
||||||
.paned => |parent_paned_tuple| {
|
|
||||||
const parent_paned = parent_paned_tuple[0];
|
|
||||||
const parent_paned_position = parent_paned_tuple[1];
|
|
||||||
|
|
||||||
parent_paned.replaceChildInPosition(sibling_child, parent_paned_position);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const widget = @as(*c.GtkWidget, @ptrCast(sibling_widget));
|
|
||||||
_ = c.gtk_widget_grab_focus(widget);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn closeSurfaceInPaned(self: *Window, surface: *Surface, paned: *Paned, position: Position) void {
|
||||||
|
const sibling = switch (position) {
|
||||||
|
.start => .{
|
||||||
|
paned.child2,
|
||||||
|
c.gtk_paned_get_end_child(paned.paned),
|
||||||
|
},
|
||||||
|
.end => .{
|
||||||
|
paned.child1,
|
||||||
|
c.gtk_paned_get_start_child(paned.paned),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// TODO: Use destructuring syntax once it doesn't break ZLS
|
||||||
|
const sibling_child = sibling[0];
|
||||||
|
const sibling_widget = sibling[1];
|
||||||
|
|
||||||
|
// Keep explicit reference to sibling's gl_area, so it's not
|
||||||
|
// destroyed when we remove it from GtkPaned.
|
||||||
|
const sibling_object: *c.GObject = @ptrCast(sibling_widget);
|
||||||
|
_ = c.g_object_ref(sibling_object);
|
||||||
|
defer c.g_object_unref(sibling_object);
|
||||||
|
|
||||||
|
// Remove reference on the surface we're closing
|
||||||
|
surface.setParent(.none);
|
||||||
|
|
||||||
|
// Remove children.
|
||||||
|
paned.removeChildren();
|
||||||
|
// Don't need to call paned.deinit, because we already removed children.
|
||||||
|
defer self.app.core_app.alloc.destroy(paned);
|
||||||
|
|
||||||
|
switch (paned.parent) {
|
||||||
|
.none => unreachable,
|
||||||
|
.tab => |tab| {
|
||||||
|
// If parent of Paned we belong to is a tab, we can
|
||||||
|
// replace the child with the other surface
|
||||||
|
tab.removeChild();
|
||||||
|
tab.setChild(sibling_child);
|
||||||
|
},
|
||||||
|
.paned => |parent_paned_tuple| {
|
||||||
|
const parent_paned = parent_paned_tuple[0];
|
||||||
|
const parent_paned_position = parent_paned_tuple[1];
|
||||||
|
|
||||||
|
parent_paned.replaceChildInPosition(sibling_child, parent_paned_position);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const widget = @as(*c.GtkWidget, @ptrCast(sibling_widget));
|
||||||
|
_ = c.gtk_widget_grab_focus(widget);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if this window has any tabs.
|
/// Returns true if this window has any tabs.
|
||||||
pub fn hasTabs(self: *const Window) bool {
|
pub fn hasTabs(self: *const Window) bool {
|
||||||
return c.gtk_notebook_get_n_pages(self.notebook) > 1;
|
return c.gtk_notebook_get_n_pages(self.notebook) > 1;
|
||||||
|
Reference in New Issue
Block a user