apprt/gtk: clean up gotoWindow
parent
bb246b2e0c
commit
dfb94cd55d
|
|
@ -2016,44 +2016,69 @@ const Action = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gotoWindow(
|
pub fn gotoWindow(direction: apprt.action.GotoWindow) bool {
|
||||||
direction: apprt.action.GotoWindow,
|
|
||||||
) bool {
|
|
||||||
const glist = gtk.Window.listToplevels();
|
const glist = gtk.Window.listToplevels();
|
||||||
defer glist.free();
|
defer glist.free();
|
||||||
|
|
||||||
const node = @as(?*glib.List, glist.findCustom(null, findActiveWindow));
|
// The window we're starting from is typically our active window.
|
||||||
|
const starting: *glib.List = @as(?*glib.List, glist.findCustom(
|
||||||
|
null,
|
||||||
|
findActiveWindow,
|
||||||
|
)) orelse glist;
|
||||||
|
|
||||||
const target_node = if (node) |n| switch (direction) {
|
// Go forward or backwards in the list until we find a valid
|
||||||
.next => n.f_next orelse glist,
|
// window that is visible.
|
||||||
.previous => n.f_prev orelse last: {
|
var current_: ?*glib.List = starting;
|
||||||
var current = glist;
|
while (current_) |node| : (current_ = switch (direction) {
|
||||||
while (current.f_next) |next| {
|
.next => node.f_next,
|
||||||
current = next;
|
.previous => node.f_prev,
|
||||||
}
|
}) {
|
||||||
break :last current;
|
const data = node.f_data orelse continue;
|
||||||
},
|
const gtk_window: *gtk.Window = @ptrCast(@alignCast(data));
|
||||||
} else glist;
|
if (gotoWindowMaybe(gtk_window)) return true;
|
||||||
|
}
|
||||||
const data = target_node.f_data orelse return false;
|
|
||||||
const gtk_window: *gtk.Window = @ptrCast(@alignCast(data));
|
// If we reached here, we didn't find a valid window to focus.
|
||||||
gtk.Window.present(gtk_window);
|
// Wrap around.
|
||||||
|
current_ = switch (direction) {
|
||||||
const ghostty_window = gobject.ext.cast(Window, gtk_window) orelse return false;
|
.next => glist,
|
||||||
|
.previous => last: {
|
||||||
var surface: ?*gobject.Object = null;
|
var end: *glib.List = glist;
|
||||||
ghostty_window.as(gobject.Object).get("active-surface", &surface, @as(?*anyopaque, null));
|
while (end.f_next) |next| end = next;
|
||||||
|
break :last end;
|
||||||
if (surface) |s| {
|
},
|
||||||
const surface_obj = gobject.ext.cast(Surface, s) orelse return false;
|
};
|
||||||
surface_obj.grabFocus();
|
while (current_) |node| : (current_ = switch (direction) {
|
||||||
return true;
|
.next => node.f_next,
|
||||||
|
.previous => node.f_prev,
|
||||||
|
}) {
|
||||||
|
if (current_ == starting) break;
|
||||||
|
const data = node.f_data orelse continue;
|
||||||
|
const gtk_window: *gtk.Window = @ptrCast(@alignCast(data));
|
||||||
|
if (gotoWindowMaybe(gtk_window)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.warn("window has no active surface, cannot grab focus", .{});
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gotoWindowMaybe(gtk_window: *gtk.Window) bool {
|
||||||
|
// If it is already active skip it.
|
||||||
|
if (gtk_window.isActive() != 0) return false;
|
||||||
|
// If it is hidden, skip it.
|
||||||
|
if (gtk_window.as(gtk.Widget).isVisible() == 0) return false;
|
||||||
|
// If it isn't a Ghostty window, skip it.
|
||||||
|
const window = gobject.ext.cast(
|
||||||
|
Window,
|
||||||
|
gtk_window,
|
||||||
|
) orelse return false;
|
||||||
|
|
||||||
|
// Focus our active surface
|
||||||
|
const surface = window.getActiveSurface() orelse return false;
|
||||||
|
gtk.Window.present(gtk_window);
|
||||||
|
surface.grabFocus();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn initialSize(
|
pub fn initialSize(
|
||||||
target: apprt.Target,
|
target: apprt.Target,
|
||||||
value: apprt.action.InitialSize,
|
value: apprt.action.InitialSize,
|
||||||
|
|
|
||||||
|
|
@ -793,7 +793,7 @@ pub const Window = extern struct {
|
||||||
|
|
||||||
/// Get the currently active surface. See the "active-surface" property.
|
/// Get the currently active surface. See the "active-surface" property.
|
||||||
/// This does not ref the value.
|
/// This does not ref the value.
|
||||||
fn getActiveSurface(self: *Self) ?*Surface {
|
pub fn getActiveSurface(self: *Self) ?*Surface {
|
||||||
const tab = self.getSelectedTab() orelse return null;
|
const tab = self.getSelectedTab() orelse return null;
|
||||||
return tab.getActiveSurface();
|
return tab.getActiveSurface();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue