hyprland: preserve tab group restore order
This commit is contained in:
@@ -22,6 +22,7 @@ local layout_names = {
|
|||||||
[monocle_layout] = "Monocle",
|
[monocle_layout] = "Monocle",
|
||||||
}
|
}
|
||||||
local minimized_workspace = "special:minimized"
|
local minimized_workspace = "special:minimized"
|
||||||
|
local tabbed_group_restore_workspace_prefix = "special:tabbed-monocle-restore-"
|
||||||
local current_layout = columns_layout
|
local current_layout = columns_layout
|
||||||
local enable_nstack = true
|
local enable_nstack = true
|
||||||
local enable_hyprexpo = true
|
local enable_hyprexpo = true
|
||||||
@@ -413,10 +414,30 @@ local function window_address_set(windows)
|
|||||||
return addresses
|
return addresses
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function window_address_list(windows)
|
||||||
|
local addresses = {}
|
||||||
|
for _, window in ipairs(windows) do
|
||||||
|
if window and window.address then
|
||||||
|
addresses[#addresses + 1] = window.address
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return addresses
|
||||||
|
end
|
||||||
|
|
||||||
local function window_address_in_set(window, addresses)
|
local function window_address_in_set(window, addresses)
|
||||||
return window and window.address and addresses[window.address] or false
|
return window and window.address and addresses[window.address] or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function windows_by_address()
|
||||||
|
local windows = {}
|
||||||
|
for _, window in ipairs(hl.get_windows()) do
|
||||||
|
if window and window.address then
|
||||||
|
windows[window.address] = window
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return windows
|
||||||
|
end
|
||||||
|
|
||||||
local function numeric_component(value, key, index)
|
local function numeric_component(value, key, index)
|
||||||
if type(value) ~= "table" then
|
if type(value) ~= "table" then
|
||||||
return 0
|
return 0
|
||||||
@@ -755,10 +776,56 @@ local function find_tabbed_group_anchor(state)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function ordered_windows_for_tabbed_group_restore(state, workspace_id)
|
||||||
|
local ordered = {}
|
||||||
|
local seen = {}
|
||||||
|
local live_windows = windows_by_address()
|
||||||
|
local workspace = workspace_id and hl.get_workspace(tostring(workspace_id)) or active_workspace()
|
||||||
|
|
||||||
|
if state and state.order then
|
||||||
|
for _, address in ipairs(state.order) do
|
||||||
|
local window = live_windows[address]
|
||||||
|
if window and not window.floating and not window.hidden and (not workspace or same_workspace(window.workspace, workspace)) then
|
||||||
|
ordered[#ordered + 1] = window
|
||||||
|
seen[address] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if workspace then
|
||||||
|
for _, window in ipairs(tiled_windows(workspace)) do
|
||||||
|
if window and window.address and not seen[window.address] then
|
||||||
|
ordered[#ordered + 1] = window
|
||||||
|
seen[window.address] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ordered
|
||||||
|
end
|
||||||
|
|
||||||
|
local function restore_tabbed_group_window_order(state, workspace_id)
|
||||||
|
local ordered = ordered_windows_for_tabbed_group_restore(state, workspace_id)
|
||||||
|
if #ordered <= 1 or not workspace_id then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local restore_workspace = tabbed_group_restore_workspace_prefix .. tostring(workspace_id)
|
||||||
|
for _, window in ipairs(ordered) do
|
||||||
|
move_window_to_workspace(restore_workspace, false, window)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, window in ipairs(ordered) do
|
||||||
|
move_window_to_workspace(workspace_id, false, window)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function restore_workspace_tabbed_group()
|
local function restore_workspace_tabbed_group()
|
||||||
local key = workspace_key()
|
local key = workspace_key()
|
||||||
local anchor = find_tabbed_group_anchor(tabbed_workspace_groups[key])
|
local state = tabbed_workspace_groups[key]
|
||||||
|
local anchor = find_tabbed_group_anchor(state)
|
||||||
local anchor_selector = window_selector(anchor)
|
local anchor_selector = window_selector(anchor)
|
||||||
|
local target_workspace_id = anchor and anchor.workspace and anchor.workspace.id
|
||||||
|
|
||||||
if not anchor_selector then
|
if not anchor_selector then
|
||||||
tabbed_workspace_groups[key] = nil
|
tabbed_workspace_groups[key] = nil
|
||||||
@@ -771,6 +838,8 @@ local function restore_workspace_tabbed_group()
|
|||||||
hl.dsp.group.toggle({ window = anchor_selector })()
|
hl.dsp.group.toggle({ window = anchor_selector })()
|
||||||
tabbed_workspace_groups[key] = nil
|
tabbed_workspace_groups[key] = nil
|
||||||
set_layout(columns_layout)
|
set_layout(columns_layout)
|
||||||
|
restore_tabbed_group_window_order(state, target_workspace_id)
|
||||||
|
hl.dsp.focus({ window = anchor_selector })()
|
||||||
schedule_nstack_count_update()
|
schedule_nstack_count_update()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -786,6 +855,7 @@ local function gather_workspace_into_tabbed_group()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local original_order = window_address_list(tiled_windows(workspace))
|
||||||
local candidates = active_workspace_tiled_group_candidates(workspace)
|
local candidates = active_workspace_tiled_group_candidates(workspace)
|
||||||
if #candidates <= 1 then
|
if #candidates <= 1 then
|
||||||
set_layout(columns_layout)
|
set_layout(columns_layout)
|
||||||
@@ -849,6 +919,7 @@ local function gather_workspace_into_tabbed_group()
|
|||||||
|
|
||||||
tabbed_workspace_groups[key] = {
|
tabbed_workspace_groups[key] = {
|
||||||
anchor = anchor.address,
|
anchor = anchor.address,
|
||||||
|
order = original_order,
|
||||||
windows = candidate_addresses,
|
windows = candidate_addresses,
|
||||||
}
|
}
|
||||||
hl.dsp.focus({ window = anchor_selector })()
|
hl.dsp.focus({ window = anchor_selector })()
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
# Use the flake source for enumeration (pure), but point links at the worktree.
|
# Use the flake source for enumeration (pure), but point links at the worktree.
|
||||||
srcDotfiles = ../dotfiles;
|
srcDotfiles = ../dotfiles;
|
||||||
|
srcConfig = srcDotfiles + "/config";
|
||||||
|
|
||||||
excludedTop = [
|
excludedTop = [
|
||||||
# Managed by nix-shared/home-manager/codex-generated-skills.nix so
|
# Managed by nix-shared/home-manager/codex-generated-skills.nix so
|
||||||
@@ -57,6 +58,22 @@
|
|||||||
lib.nameValuePair ".${rel}" {
|
lib.nameValuePair ".${rel}" {
|
||||||
source = oos "${worktreeDotfiles}/${rel}";
|
source = oos "${worktreeDotfiles}/${rel}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
configEntries = builtins.readDir srcConfig;
|
||||||
|
configDirExclusions = [
|
||||||
|
# Home Manager writes generated fontconfig fragments under this tree.
|
||||||
|
"fontconfig"
|
||||||
|
# Home Manager's gtk module writes settings.ini and gtk.css here.
|
||||||
|
"gtk-3.0"
|
||||||
|
];
|
||||||
|
configDirNames =
|
||||||
|
lib.filter
|
||||||
|
(name: configEntries.${name} == "directory" && !(lib.elem name configDirExclusions))
|
||||||
|
(builtins.attrNames configEntries);
|
||||||
|
mkConfigDir = name:
|
||||||
|
lib.nameValuePair name {
|
||||||
|
source = oos "${worktreeDotfiles}/config/${name}";
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
../nix-shared/home-manager/codex-generated-skills.nix
|
../nix-shared/home-manager/codex-generated-skills.nix
|
||||||
@@ -65,6 +82,9 @@ in {
|
|||||||
home.file =
|
home.file =
|
||||||
builtins.listToAttrs (map mkManaged managedRelFiles);
|
builtins.listToAttrs (map mkManaged managedRelFiles);
|
||||||
|
|
||||||
|
xdg.configFile =
|
||||||
|
builtins.listToAttrs (map mkConfigDir configDirNames);
|
||||||
|
|
||||||
myModules.codexGeneratedSkills.enable = true;
|
myModules.codexGeneratedSkills.enable = true;
|
||||||
|
|
||||||
# Home Manager directory links for .emacs.d resolve through the store on this
|
# Home Manager directory links for .emacs.d resolve through the store on this
|
||||||
|
|||||||
@@ -204,10 +204,6 @@ in {
|
|||||||
xdg.configFile."qt5ct/qt5ct.conf".text = qtctConfig;
|
xdg.configFile."qt5ct/qt5ct.conf".text = qtctConfig;
|
||||||
xdg.configFile."qt6ct/qt6ct.conf".text = qtctConfig;
|
xdg.configFile."qt6ct/qt6ct.conf".text = qtctConfig;
|
||||||
|
|
||||||
xdg.configFile."zellij/config.kdl".source =
|
|
||||||
config.lib.file.mkOutOfStoreSymlink
|
|
||||||
"${config.home.homeDirectory}/dotfiles/dotfiles/config/zellij/config.kdl";
|
|
||||||
|
|
||||||
xdg.configFile."menus/applications.menu" = lib.mkIf nixos.config.myModules.desktop.enable {
|
xdg.configFile."menus/applications.menu" = lib.mkIf nixos.config.myModules.desktop.enable {
|
||||||
source = "${pkgs.kdePackages.plasma-workspace}/etc/xdg/menus/plasma-applications.menu";
|
source = "${pkgs.kdePackages.plasma-workspace}/etc/xdg/menus/plasma-applications.menu";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -189,11 +189,7 @@
|
|||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: let
|
}: {
|
||||||
hyprConfigDir =
|
|
||||||
config.lib.file.mkOutOfStoreSymlink
|
|
||||||
"${config.home.homeDirectory}/dotfiles/dotfiles/config/hypr";
|
|
||||||
in {
|
|
||||||
services.kanshi = {
|
services.kanshi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
systemdTarget = "graphical-session.target";
|
systemdTarget = "graphical-session.target";
|
||||||
@@ -247,8 +243,6 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg.configFile."hypr".source = hyprConfigDir;
|
|
||||||
|
|
||||||
xdg.configFile."systemd/user/wayland-wm@hyprland.desktop.service.d/10-cleanup-stale-session.conf".text = ''
|
xdg.configFile."systemd/user/wayland-wm@hyprland.desktop.service.d/10-cleanup-stale-session.conf".text = ''
|
||||||
[Service]
|
[Service]
|
||||||
ExecStopPost=${cleanupStaleGraphicalSession}
|
ExecStopPost=${cleanupStaleGraphicalSession}
|
||||||
|
|||||||
Reference in New Issue
Block a user