mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 00:36:07 +03:00
apprt/gtk: gotoSplit gets proper previous/next direction
This commit is contained in:
@ -193,89 +193,68 @@ pub const Side = enum { top_left, bottom_right };
|
|||||||
/// Returns the map that can be used to determine elements in various
|
/// Returns the map that can be used to determine elements in various
|
||||||
/// directions (primarily for gotoSplit).
|
/// directions (primarily for gotoSplit).
|
||||||
pub fn directionMap(self: *const Split, from: Side) DirectionMap {
|
pub fn directionMap(self: *const Split, from: Side) DirectionMap {
|
||||||
return switch (from) {
|
|
||||||
.top_left => self.directionMapFromTopLeft(),
|
|
||||||
.bottom_right => self.directionMapFromBottomRight(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn directionMapFromTopLeft(self: *const Split) DirectionMap {
|
|
||||||
var result = DirectionMap.initFull(null);
|
var result = DirectionMap.initFull(null);
|
||||||
|
|
||||||
if (self.container.split()) |parent_split| {
|
if (self.directionPrevious(from)) |prev| {
|
||||||
const deepest_br = parent_split.deepestSurface(.bottom_right);
|
result.put(.previous, prev);
|
||||||
result.put(.previous, deepest_br);
|
|
||||||
|
|
||||||
// This behavior matches the behavior of macOS at the time of writing
|
// This behavior matches the behavior of macOS at the time of writing
|
||||||
// this. There is an open issue (#524) to make this depend on the
|
// this. There is an open issue (#524) to make this depend on the
|
||||||
// actual physical location of the current split.
|
// actual physical location of the current split.
|
||||||
result.put(.top, deepest_br);
|
result.put(.top, prev);
|
||||||
result.put(.left, deepest_br);
|
result.put(.left, prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (self.bottom_right) {
|
if (self.directionNext(from)) |next| {
|
||||||
.surface => |s| {
|
result.put(.next, next);
|
||||||
result.put(.next, s);
|
result.put(.bottom, next);
|
||||||
result.put(.bottom, s);
|
result.put(.right, next);
|
||||||
result.put(.right, s);
|
|
||||||
},
|
|
||||||
|
|
||||||
.split => |s| {
|
|
||||||
const deepest_tl = s.deepestSurface(.top_left);
|
|
||||||
result.put(.next, deepest_tl);
|
|
||||||
result.put(.bottom, deepest_tl);
|
|
||||||
result.put(.right, deepest_tl);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn directionMapFromBottomRight(self: *const Split) DirectionMap {
|
fn directionPrevious(self: *const Split, from: Side) ?*Surface {
|
||||||
var result = DirectionMap.initFull(null);
|
switch (from) {
|
||||||
|
// From the bottom right, our previous is the deepest surface
|
||||||
|
// in the top-left of our own split.
|
||||||
|
.bottom_right => return self.top_left.deepestSurface(.bottom_right),
|
||||||
|
|
||||||
if (self.container.split()) |parent_split| {
|
// From the top left its more complicated. It is the de
|
||||||
const deepest_tl = parent_split.deepestSurface(.top_left);
|
.top_left => {
|
||||||
result.put(.next, deepest_tl);
|
// If we have no parent split then there can be no previous.
|
||||||
|
const parent = self.container.split() orelse return null;
|
||||||
|
const side = self.container.splitSide() orelse return null;
|
||||||
|
|
||||||
// This behavior matches the behavior of macOS at the time of writing
|
// The previous value is the previous of the side that we are.
|
||||||
// this. There is an open issue (#524) to make this depend on the
|
|
||||||
// actual physical location of the current split.
|
|
||||||
result.put(.top, deepest_tl);
|
|
||||||
result.put(.left, deepest_tl);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (self.top_left) {
|
|
||||||
.surface => |s| {
|
|
||||||
result.put(.previous, s);
|
|
||||||
result.put(.bottom, s);
|
|
||||||
result.put(.right, s);
|
|
||||||
},
|
|
||||||
|
|
||||||
.split => |s| {
|
|
||||||
const deepest_br = s.deepestSurface(.bottom_right);
|
|
||||||
result.put(.previous, deepest_br);
|
|
||||||
result.put(.bottom, deepest_br);
|
|
||||||
result.put(.right, deepest_br);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the most deeply nested surface for a given side.
|
|
||||||
fn deepestSurface(self: *const Split, side: Side) *Surface {
|
|
||||||
return switch (side) {
|
return switch (side) {
|
||||||
.bottom_right => switch (self.bottom_right) {
|
.top_left => parent.directionPrevious(.top_left),
|
||||||
.surface => |s| s,
|
.bottom_right => parent.directionPrevious(.bottom_right),
|
||||||
.split => |s| s.deepestSurface(.bottom_right),
|
|
||||||
},
|
|
||||||
|
|
||||||
.top_left => switch (self.top_left) {
|
|
||||||
.surface => |s| s,
|
|
||||||
.split => |s| s.deepestSurface(.top_left),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn directionNext(self: *const Split, from: Side) ?*Surface {
|
||||||
|
switch (from) {
|
||||||
|
// From the top left, our next is the earliest surface in the
|
||||||
|
// top-left direction of the bottom-right side of our split. Fun!
|
||||||
|
.top_left => return self.bottom_right.deepestSurface(.top_left),
|
||||||
|
|
||||||
|
// From the bottom right is more compliated. It is the deepest
|
||||||
|
// (last) surface in the
|
||||||
|
.bottom_right => {
|
||||||
|
// If we have no parent split then there can be no next.
|
||||||
|
const parent = self.container.split() orelse return null;
|
||||||
|
const side = self.container.splitSide() orelse return null;
|
||||||
|
|
||||||
|
// The previous value is the previous of the side that we are.
|
||||||
|
return switch (side) {
|
||||||
|
.top_left => parent.directionNext(.bottom_right),
|
||||||
|
.bottom_right => parent.directionNext(.bottom_right),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn removeChildren(self: *const Split) void {
|
fn removeChildren(self: *const Split) void {
|
||||||
|
@ -48,6 +48,9 @@ pub const Container = union(enum) {
|
|||||||
split_tl: *Elem,
|
split_tl: *Elem,
|
||||||
split_br: *Elem,
|
split_br: *Elem,
|
||||||
|
|
||||||
|
/// The side of the split.
|
||||||
|
pub const SplitSide = enum { top_left, bottom_right };
|
||||||
|
|
||||||
/// Elem is the possible element of any container. A container can
|
/// Elem is the possible element of any container. A container can
|
||||||
/// hold both a surface and a split. Any valid container should
|
/// hold both a surface and a split. Any valid container should
|
||||||
/// have an Elem value so that it can be properly used with
|
/// have an Elem value so that it can be properly used with
|
||||||
@ -92,6 +95,18 @@ pub const Container = union(enum) {
|
|||||||
.split => |s| s.grabFocus(),
|
.split => |s| s.grabFocus(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The last surface in this container in the direction specified.
|
||||||
|
/// Direction must be "top_left" or "bottom_right".
|
||||||
|
pub fn deepestSurface(self: Elem, side: SplitSide) ?*Surface {
|
||||||
|
return switch (self) {
|
||||||
|
.surface => |s| s,
|
||||||
|
.split => |s| (switch (side) {
|
||||||
|
.top_left => s.top_left,
|
||||||
|
.bottom_right => s.bottom_right,
|
||||||
|
}).deepestSurface(side),
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns the window that this surface is attached to.
|
/// Returns the window that this surface is attached to.
|
||||||
@ -127,6 +142,15 @@ pub const Container = union(enum) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The side that we are in the split.
|
||||||
|
pub fn splitSide(self: Container) ?SplitSide {
|
||||||
|
return switch (self) {
|
||||||
|
.none, .tab_ => null,
|
||||||
|
.split_tl => .top_left,
|
||||||
|
.split_br => .bottom_right,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Replace the container's element with this element. This is
|
/// Replace the container's element with this element. This is
|
||||||
/// used by children to modify their parents to for example change
|
/// used by children to modify their parents to for example change
|
||||||
/// from a surface to a split or a split back to a surface or
|
/// from a surface to a split or a split back to a surface or
|
||||||
|
Reference in New Issue
Block a user