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;
|
self.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Focus on the Surface's gl_area in the given position.
|
/// Focus on first Surface that can be found in given position. If there's a
|
||||||
pub fn focusSurfaceInPosition(self: *Paned, position: Position) void {
|
/// Paned in the position, it will focus on the first surface in that position.
|
||||||
const surface: *Surface = self.surfaceInPosition(position) orelse return;
|
pub fn focusFirstSurfaceInPosition(self: *Paned, position: Position) void {
|
||||||
const widget = @as(*c.GtkWidget, @ptrCast(surface.gl_area));
|
const child = self.childInPosition(position);
|
||||||
surface.tab.focus_child = surface;
|
switch (child) {
|
||||||
_ = c.gtk_widget_grab_focus(widget);
|
.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.
|
/// 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);
|
c.gtk_paned_set_position(self.paned, parent_paned_position_before);
|
||||||
|
|
||||||
// Focus on new surface
|
// Focus on new surface
|
||||||
paned.focusSurfaceInPosition(.end);
|
paned.focusFirstSurfaceInPosition(.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace the existing .start or .end Child with the given new Child.
|
/// 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);
|
const parent_paned_position_before = c.gtk_paned_get_position(self.paned);
|
||||||
|
|
||||||
// Focus on the sibling, otherwise we'll get a GTK warning
|
// 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
|
// Now we can remove the other one
|
||||||
self.removeChildInPosition(position);
|
self.removeChildInPosition(position);
|
||||||
@ -193,13 +203,15 @@ fn addChild2(self: *Paned, child: Child) void {
|
|||||||
child.setParent(.{ .paned = .{ self, .end } });
|
child.setParent(.{ .paned = .{ self, .end } });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn surfaceInPosition(self: *Paned, position: Position) ?*Surface {
|
fn childInPosition(self: *Paned, position: Position) Child {
|
||||||
const child = switch (position) {
|
return switch (position) {
|
||||||
.start => self.child1,
|
.start => self.child1,
|
||||||
.end => self.child2,
|
.end => self.child2,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return switch (child) {
|
fn surfaceInPosition(self: *Paned, position: Position) ?*Surface {
|
||||||
|
return switch (self.childInPosition(position)) {
|
||||||
.surface => |surface| surface,
|
.surface => |surface| surface,
|
||||||
else => null,
|
else => null,
|
||||||
};
|
};
|
||||||
|
@ -188,7 +188,7 @@ pub fn splitSurface(self: *Tab, direction: input.SplitDirection) !void {
|
|||||||
self.setChild(.{ .paned = paned });
|
self.setChild(.{ .paned = paned });
|
||||||
|
|
||||||
// Focus on new surface
|
// Focus on new surface
|
||||||
paned.focusSurfaceInPosition(.end);
|
paned.focusFirstSurfaceInPosition(.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the current child from the Tab. Noop if no child set.
|
/// 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_child = sibling[0];
|
||||||
const sibling_widget = sibling[1];
|
const sibling_widget = sibling[1];
|
||||||
|
|
||||||
// Keep explicit reference to sibling's gl_area, so it's not
|
// Keep explicit reference to sibling's widget (gl_area, or Paned), so it's
|
||||||
// destroyed when we remove it from GtkPaned.
|
// not destroyed when we remove it from GtkPaned.
|
||||||
const sibling_object: *c.GObject = @ptrCast(sibling_widget);
|
const sibling_object: *c.GObject = @ptrCast(sibling_widget);
|
||||||
_ = c.g_object_ref(sibling_object);
|
_ = c.g_object_ref(sibling_object);
|
||||||
defer c.g_object_unref(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) {
|
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 => {},
|
else => {},
|
||||||
}
|
}
|
||||||
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.
|
||||||
|
Reference in New Issue
Block a user