mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
gtk: find first surface to focus on if sibling is Paned
This commit is contained in:

committed by
Mitchell Hashimoto

parent
f1e81563d9
commit
b1e3685664
@ -82,12 +82,22 @@ pub fn setParent(self: *Paned, parent: Parent) void {
|
||||
self.parent = parent;
|
||||
}
|
||||
|
||||
/// Focus on the Surface's gl_area in the given position.
|
||||
pub fn focusSurfaceInPosition(self: *Paned, position: Position) void {
|
||||
const surface: *Surface = self.surfaceInPosition(position) orelse return;
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(surface.gl_area));
|
||||
surface.tab.focus_child = surface;
|
||||
/// Focus on first Surface that can be found in given position. If there's a
|
||||
/// Paned in the position, it will focus on the first surface in that position.
|
||||
pub fn focusFirstSurfaceInPosition(self: *Paned, position: Position) void {
|
||||
const child = self.childInPosition(position);
|
||||
switch (child) {
|
||||
.surface => |s| {
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(s.gl_area));
|
||||
s.tab.focus_child = s;
|
||||
_ = c.gtk_widget_grab_focus(widget);
|
||||
},
|
||||
.paned => |p| p.focusFirstSurfaceInPosition(position),
|
||||
.none => {
|
||||
log.warn("attempted to focus on first surface, found none", .{});
|
||||
return;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Split the Surface in the given position into a Paned with two surfaces.
|
||||
@ -116,7 +126,7 @@ pub fn splitSurfaceInPosition(self: *Paned, position: Position, direction: input
|
||||
c.gtk_paned_set_position(self.paned, parent_paned_position_before);
|
||||
|
||||
// Focus on new surface
|
||||
paned.focusSurfaceInPosition(.end);
|
||||
paned.focusFirstSurfaceInPosition(.end);
|
||||
}
|
||||
|
||||
/// Replace the existing .start or .end Child with the given new Child.
|
||||
@ -125,7 +135,7 @@ pub fn replaceChildInPosition(self: *Paned, child: Child, position: Position) vo
|
||||
const parent_paned_position_before = c.gtk_paned_get_position(self.paned);
|
||||
|
||||
// Focus on the sibling, otherwise we'll get a GTK warning
|
||||
self.focusSurfaceInPosition(if (position == .start) .end else .start);
|
||||
self.focusFirstSurfaceInPosition(if (position == .start) .end else .start);
|
||||
|
||||
// Now we can remove the other one
|
||||
self.removeChildInPosition(position);
|
||||
@ -193,13 +203,15 @@ fn addChild2(self: *Paned, child: Child) void {
|
||||
child.setParent(.{ .paned = .{ self, .end } });
|
||||
}
|
||||
|
||||
fn surfaceInPosition(self: *Paned, position: Position) ?*Surface {
|
||||
const child = switch (position) {
|
||||
fn childInPosition(self: *Paned, position: Position) Child {
|
||||
return switch (position) {
|
||||
.start => self.child1,
|
||||
.end => self.child2,
|
||||
};
|
||||
}
|
||||
|
||||
return switch (child) {
|
||||
fn surfaceInPosition(self: *Paned, position: Position) ?*Surface {
|
||||
return switch (self.childInPosition(position)) {
|
||||
.surface => |surface| surface,
|
||||
else => null,
|
||||
};
|
||||
|
@ -188,7 +188,7 @@ pub fn splitSurface(self: *Tab, direction: input.SplitDirection) !void {
|
||||
self.setChild(.{ .paned = paned });
|
||||
|
||||
// Focus on new surface
|
||||
paned.focusSurfaceInPosition(.end);
|
||||
paned.focusFirstSurfaceInPosition(.end);
|
||||
}
|
||||
|
||||
/// Remove the current child from the Tab. Noop if no child set.
|
||||
|
@ -283,8 +283,8 @@ fn closeSurfaceInPaned(self: *Window, surface: *Surface, paned: *Paned, position
|
||||
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.
|
||||
// Keep explicit reference to sibling's widget (gl_area, or Paned), 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);
|
||||
@ -314,11 +314,17 @@ fn closeSurfaceInPaned(self: *Window, surface: *Surface, paned: *Paned, position
|
||||
}
|
||||
|
||||
switch (sibling_child) {
|
||||
.surface => |s| s.tab.focus_child = s,
|
||||
.surface => |s| {
|
||||
s.tab.focus_child = s;
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(s.gl_area));
|
||||
_ = c.gtk_widget_grab_focus(widget);
|
||||
},
|
||||
.paned => |p| {
|
||||
// Focus on first surface in sibling Paned
|
||||
p.focusFirstSurfaceInPosition(position);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
const widget = @as(*c.GtkWidget, @ptrCast(sibling_widget));
|
||||
_ = c.gtk_widget_grab_focus(widget);
|
||||
}
|
||||
|
||||
/// Returns true if this window has any tabs.
|
||||
|
Reference in New Issue
Block a user