gtk: Remove window reference from jump commands

Removes redundant implementations that is already present in the core
application to work with surfaces.
This commit is contained in:
Tommy Brunn
2026-01-03 22:15:23 +01:00
parent 8754c53e0e
commit d3aa684139
4 changed files with 16 additions and 160 deletions

View File

@@ -1176,36 +1176,6 @@ pub const Application = extern struct {
return self.private().config.ref();
}
/// Collect all surfaces from all windows in the application.
/// The caller must unref each surface and window and deinit the list.
pub fn collectAllSurfaces(
self: *Self,
alloc: Allocator,
) !std.ArrayList(Window.SurfaceInfo) {
var all_surfaces: std.ArrayList(Window.SurfaceInfo) = .{};
errdefer {
for (all_surfaces.items) |info| {
info.surface.unref();
info.window.unref();
}
all_surfaces.deinit(alloc);
}
const windows = self.as(gtk.Application).getWindows();
var it: ?*glib.List = windows;
while (it) |node| : (it = node.f_next) {
const window_widget = @as(*gtk.Window, @ptrCast(@alignCast(node.f_data)));
const window = gobject.ext.cast(Window, window_widget) orelse continue;
var window_surfaces = try window.collectSurfaces(alloc);
defer window_surfaces.deinit(alloc);
try all_surfaces.appendSlice(alloc, window_surfaces.items);
}
return all_surfaces;
}
/// Set the configuration for this application. The reference count
/// is increased on the new configuration and the old one is
/// unreferenced.

View File

@@ -192,10 +192,14 @@ pub const CommandPalette = extern struct {
// for GTK.
if (!isActionSupportedOnGtk(command.action)) continue;
const cmd = Command.new(config, command);
const cmd = Command.new(config, command) catch |err| {
log.warn("failed to create command: {}", .{err});
continue;
};
errdefer cmd.unref();
commands.append(alloc, cmd) catch |err| {
log.warn("failed to add command to list: {}", .{err});
cmd.unref();
continue;
};
}
@@ -227,21 +231,11 @@ pub const CommandPalette = extern struct {
const app = Application.default();
const alloc = app.allocator();
// Collect all surfaces from all windows
var surfaces = app.collectAllSurfaces(alloc) catch |err| {
log.warn("failed to collect surfaces for jump commands: {}", .{err});
return;
};
defer {
for (surfaces.items) |info| {
info.surface.unref();
info.window.unref();
}
surfaces.deinit(alloc);
}
for (surfaces.items) |info| {
const cmd = Command.newJump(config, info.surface, info.window);
// Get all surfaces from the core app
const core_app = app.core();
for (core_app.surfaces.items) |apprt_surface| {
const surface = apprt_surface.gobj();
const cmd = Command.newJump(config, surface);
errdefer cmd.unref();
try commands.append(alloc, cmd);
}
@@ -361,8 +355,7 @@ pub const CommandPalette = extern struct {
// Handle jump commands differently
if (cmd.isJump()) {
const surface = cmd.getJumpSurface() orelse return;
const window = cmd.getJumpWindow() orelse return;
focusSurface(surface, window);
surface.present();
return;
}
@@ -565,23 +558,20 @@ const Command = extern struct {
pub const JumpData = struct {
surface: *Surface,
window: *Window,
title: ?[:0]const u8 = null,
description: ?[:0]const u8 = null,
sort_key: usize,
};
};
pub fn new(config: *Config, command: input.Command) *Self {
pub fn new(config: *Config, command: input.Command) Allocator.Error!*Self {
const self = gobject.ext.newInstance(Self, .{
.config = config,
});
errdefer self.unref();
const priv = self.private();
const cloned = command.clone(priv.arena.allocator()) catch {
self.unref();
return undefined;
};
const cloned = try command.clone(priv.arena.allocator());
priv.data = .{
.regular = .{
@@ -593,7 +583,7 @@ const Command = extern struct {
}
/// Create a new jump command that focuses a specific surface.
pub fn newJump(config: *Config, surface: *Surface, window: *Window) *Self {
pub fn newJump(config: *Config, surface: *Surface) *Self {
const self = gobject.ext.newInstance(Self, .{
.config = config,
});
@@ -602,7 +592,6 @@ const Command = extern struct {
priv.data = .{
.jump = .{
.surface = surface.ref(),
.window = window.ref(),
.sort_key = @intFromPtr(surface),
},
};
@@ -631,7 +620,6 @@ const Command = extern struct {
.regular => {},
.jump => |*j| {
j.surface.unref();
j.window.unref();
},
}
@@ -774,15 +762,6 @@ const Command = extern struct {
};
}
/// Get the jump window.
pub fn getJumpWindow(self: *Self) ?*Window {
const priv = self.private();
return switch (priv.data) {
.regular => null,
.jump => |*j| j.window,
};
}
//---------------------------------------------------------------
const C = Common(Self, Private);
@@ -810,43 +789,3 @@ const Command = extern struct {
}
};
};
/// Focus a surface in a window, bringing the window to front and switching
/// to the appropriate tab if needed.
fn focusSurface(surface: *Surface, window: *Window) void {
window.as(gtk.Window).present();
// Find the tab containing this surface
const tab_view = window.getTabView();
const n = tab_view.getNPages();
if (n < 0) return;
for (0..@intCast(n)) |i| {
const page = tab_view.getNthPage(@intCast(i));
const child = page.getChild();
const tab = gobject.ext.cast(Tab, child) orelse continue;
// Check if this tab contains the surface
const tree = tab.getSurfaceTree() orelse continue;
var it = tree.iterator();
var found = false;
while (it.next()) |entry| {
if (entry.view == surface) {
found = true;
break;
}
}
if (found) {
// Switch to this tab
tab_view.setSelectedPage(page);
// Look up the split tree and update last focused surface
const split_tree = tab.getSplitTree();
split_tree.setLastFocusedSurface(surface);
surface.grabFocus();
break;
}
}
}

View File

@@ -478,12 +478,6 @@ pub const SplitTree = extern struct {
return surface;
}
/// Sets the last focused surface in the tree. This is used to track
/// which surface should be considered "active" for the split tree.
pub fn setLastFocusedSurface(self: *Self, surface: ?*Surface) void {
self.private().last_focused.set(surface);
}
/// Returns whether any of the surfaces in the tree have a parent.
/// This is important because we can only rebuild the widget tree
/// when every surface has no parent.

View File

@@ -804,53 +804,6 @@ pub const Window = extern struct {
return self.private().config;
}
/// Information about a surface in a window.
pub const SurfaceInfo = struct {
surface: *Surface,
window: *Window,
};
/// Collect all surfaces from all tabs in this window.
/// The caller must unref each surface and window when done.
pub fn collectSurfaces(
self: *Self,
alloc: std.mem.Allocator,
) !std.ArrayList(SurfaceInfo) {
var surfaces: std.ArrayList(SurfaceInfo) = .{};
errdefer {
for (surfaces.items) |info| {
info.surface.unref();
info.window.unref();
}
surfaces.deinit(alloc);
}
const priv = self.private();
const n = priv.tab_view.getNPages();
if (n < 0) return surfaces;
for (0..@intCast(n)) |i| {
const page = priv.tab_view.getNthPage(@intCast(i));
const child = page.getChild();
const tab = gobject.ext.cast(Tab, child) orelse {
log.warn("unexpected non-Tab child in tab view", .{});
continue;
};
const tree = tab.getSurfaceTree() orelse continue;
var it = tree.iterator();
while (it.next()) |entry| {
try surfaces.append(alloc, .{
.surface = entry.view.ref(),
.window = self.ref(),
});
}
}
return surfaces;
}
/// Get the tab view for this window.
pub fn getTabView(self: *Self) *adw.TabView {
return self.private().tab_view;