Compare commits

..
4 Commits
Author SHA1 Message Date
felis d82e219ec9 persist workspaces 2026-08-23 17:35:24 -07:00
felis 45976f7b8b add scrolling overview 2026-08-23 17:33:21 -07:00
felis 09d35cfc4d remove hyprspace 2026-08-23 16:57:44 -07:00
felis bdec7e77bf use hyprspace for layouts 2026-08-17 00:03:23 -07:00
10 changed files with 211 additions and 19 deletions
+1 -1
View File
@@ -13,11 +13,11 @@ local startup_commands = {
-- Graphical/session applications launched inside UWSM scopes.
commands.uwsm(settings.programs.terminal),
commands.uwsm("hyprpaper"),
commands.uwsm("firefox"),
commands.uwsm("wl-paste --type text --watch cliphist store"),
commands.uwsm("wl-paste --type image --watch cliphist store"),
commands.uwsm("noctalia"),
commands.uwsm("linux-wallpaper-engine")
}
-- This event only fires when Hyprland starts; reloading the config will not
+8 -10
View File
@@ -130,10 +130,10 @@ hl.bind(
-- One direction table drives arrow-key focus, Hyper+WASD focus/movement, and
-- moving the active workspace between adjacent monitors.
local directions = {
{ arrow = "left", key = "A", direction = "l", monitor = "left" },
{ arrow = "left", key = "A", direction = "l", monitor = "left" },
{ arrow = "right", key = "D", direction = "r", monitor = "right" },
{ arrow = "up", key = "W", direction = "u", monitor = "above", stage_message = "cycleprev" },
{ arrow = "down", key = "S", direction = "d", monitor = "below", stage_message = "cyclenext" },
{ arrow = "up", key = "W", direction = "u", monitor = "above", stage_message = "cycleprev" },
{ arrow = "down", key = "S", direction = "d", monitor = "below", stage_message = "cyclenext" },
}
for _, direction in ipairs(directions) do
@@ -286,14 +286,12 @@ hl.bind(
{ description = "Promote to master" }
)
-- Hyprtasking provides a visual overview of windows on all workspaces.
-- Toggle ScrollOverview with SUPER+g
hl.bind(
chord(hyper, "SPACE"),
function()
hl.plugin.hyprtasking.toggle("all")
end,
{ description = "Toggle all-workspace window overview" }
)
chord(hyper, "SPACE"), function()
hl.plugin.scrolloverview.overview("toggle all")
end)
-- Toggle a focused client into an 80%-sized centered floating mode. Returning
-- it to tiled mode lets the active layout restore its previous geometry.
+9
View File
@@ -30,5 +30,14 @@ hl.config({
hyprstage = {
sidebar_side = "right",
},
overview = {
panelColor = "#1d4580",
panelBorderColor = "#05494d",
workspaceActiveBackground = "rgba(49, 50, 68, 0.8)",
workspaceActiveBorder = "rgb(203, 166, 247)",
onBottom = false,
autoDrag = true,
showSpecialWorkspace = true,
}
},
})
+110
View File
@@ -0,0 +1,110 @@
local lastWorkspaceScrollBind
local function table_value(value, ...)
if value == nil then
return nil
end
for _, key in ipairs({ ... }) do
local ok, item = pcall(function()
return value[key]
end)
if ok and item ~= nil then
return item
end
end
return nil
end
local function last_workspace_state()
local monitor = hl.get_monitor_at_cursor() or hl.get_active_monitor()
if not monitor then
return false, nil
end
local activeWorkspace = table_value(monitor, "active_workspace")
local activeWorkspaceId = table_value(activeWorkspace, "id")
if type(activeWorkspaceId) ~= "number" or activeWorkspaceId <= 0 then
return false, nil
end
local activeWorkspaceWindows = table_value(activeWorkspace, "windows")
if type(activeWorkspaceWindows) ~= "number" or activeWorkspaceWindows == 0 then
return false, nil
end
local lastWorkspaceId
for _, workspace in ipairs(hl.get_workspaces()) do
local id = table_value(workspace, "id")
if type(id) == "number"
and id > 0
and table_value(workspace, "special") ~= true
and table_value(workspace, "monitor") == monitor then
lastWorkspaceId = math.max(lastWorkspaceId or id, id)
end
end
return activeWorkspaceId == lastWorkspaceId, monitor
end
local function create_workspace_at_end()
local isLastWorkspace, monitor = last_workspace_state()
if not isLastWorkspace or not monitor then
return
end
hl.dispatch(hl.dsp.focus({ monitor = table_value(monitor, "name") }))
hl.dispatch(hl.dsp.focus({ workspace = "emptynm" }))
end
local function update_last_workspace_scroll_bind()
if not lastWorkspaceScrollBind then
return
end
local enabled = false
if hl.get_current_submap() == "scrolloverview" then
enabled = last_workspace_state()
end
lastWorkspaceScrollBind:set_enabled(enabled)
end
hl.define_submap("scrolloverview", function()
hl.bind("left", hl.plugin.scrolloverview.navigate("left"))
hl.bind("right", hl.plugin.scrolloverview.navigate("right"))
hl.bind("up", hl.plugin.scrolloverview.navigate("up"))
hl.bind("down", hl.plugin.scrolloverview.navigate("down"))
hl.bind("return", hl.plugin.scrolloverview.overview("select"))
hl.bind("escape", hl.plugin.scrolloverview.overview("off"))
hl.bind("mouse:272", function()
-- Select the clicked window, or just the workspace if no window was clicked, then close the overview. This is the default behaviour if submap is not defined.
hl.plugin.scrolloverview.overview("select")
hl.plugin.scrolloverview.window("select")
hl.plugin.scrolloverview.overview("off")
end, { mouse = true })
hl.bind("mouse:274", hl.plugin.scrolloverview.window("close"), { mouse = true })
lastWorkspaceScrollBind = hl.bind("mouse_down", create_workspace_at_end)
lastWorkspaceScrollBind:set_enabled(false)
end)
hl.on("workspace.active", update_last_workspace_scroll_bind)
hl.on("workspace.created", update_last_workspace_scroll_bind)
hl.on("workspace.removed", update_last_workspace_scroll_bind)
hl.on("workspace.move_to_monitor", update_last_workspace_scroll_bind)
hl.on("window.open", update_last_workspace_scroll_bind)
hl.on("window.close", update_last_workspace_scroll_bind)
hl.on("window.move_to_workspace", update_last_workspace_scroll_bind)
hl.on("monitor.focused", update_last_workspace_scroll_bind)
hl.on("keybinds.submap", update_last_workspace_scroll_bind)
local lastWorkspaceScrollTimer = hl.timer(update_last_workspace_scroll_bind, {
timeout = 50,
type = "repeat",
})
update_last_workspace_scroll_bind()
+20 -1
View File
@@ -11,7 +11,7 @@ return {
-- Store raw executable names here. Callers decide whether a command should
-- be wrapped with `uwsm-app` or executed directly.
programs = {
terminal = "alacritty",
terminal = "kitty",
file_manager = "dolphin",
launcher = "hyprlauncher",
},
@@ -39,11 +39,30 @@ return {
name = "bilibili",
selector = "name:bilibili",
key = "F1",
layout = "stage"
},
{
name = "im",
selector = "name:im",
key = "F2",
layout = "scrolling"
},
},
-- .config/hypr/hyprland.lua
plugin = {
scrolloverview = {
gesture_distance = 300, -- how far is the "max" for the gesture
scale = 0.5, -- preferred overview scale
workspace_gap = 100,
layout = "vertical", -- vertical or horizontal
wallpaper = 2, -- 0: global only, 1: per-workspace only, 2: both
blur = true, -- blur only the main overview wallpaper
shadow = {
enabled = true,
range = 50,
},
},
}
}
+7
View File
@@ -43,6 +43,13 @@ local rules = {
move = "20 monitor_h-120",
float = true,
},
{
name = "confine-dota2-cursor",
match = {
class = "dota2",
},
confine_pointer = true,
},
}
-- Register every declarative rule with Hyprland.
+22 -2
View File
@@ -1,10 +1,30 @@
-- Create persistent master-layout workspaces from the shared workspace list.
-- Create persistent numbered workspaces and dedicated named workspaces.
local settings = require("config.settings")
-- Number keys address workspaces 1-9 directly and the 0 key addresses
-- workspace 10. Odd-numbered workspaces live on the left/primary monitor;
-- even-numbered workspaces, including workspace 10, live on the right/secondary
-- monitor.
for workspace = 1, 10 do
local monitor = settings.monitors.primary.output
if workspace % 2 == 0 then
monitor = settings.monitors.secondary.output
end
hl.workspace_rule({
workspace = tostring(workspace),
monitor = monitor,
persistent = true,
})
end
-- Named workspaces keep their individually selected layouts and remain on the
-- right-hand monitor.
for _, workspace in ipairs(settings.named_workspaces) do
hl.workspace_rule({
workspace = workspace.selector,
layout = "master",
layout = workspace.layout or "master",
layout_opts = {
orientation = "left",
},
+3
View File
@@ -16,6 +16,9 @@ local modules = {
"config.window_rules",
"config.keybinds",
"config.autostart",
-- Scrolling Overview Config
"config.scrolling_overview",
}
-- Requiring a module applies that domain's configuration through the global
+6
View File
@@ -2,4 +2,10 @@ theme {
color_scheme = /usr/share/color-schemes/BreezeDark.colors
style = Breeze
icon_theme = breeze-dark
font = Source Han Sans CN
font_size = 11
font_fixed = monospace
font_fixed_size = 11
}
+25 -5
View File
@@ -1,9 +1,13 @@
-- Generated by Noctalia
local primary = "rgb(fff59b)"
local surface = "rgb(070722)"
local secondary = "rgb(a9aefe)"
local error = "rgb(fd4663)"
local primary = "rgb(7aa2f7)"
local surface = "rgb(1a1b26)"
local on_surface = "rgb(c0caf5)"
local secondary = "rgb(bb9af7)"
local on_secondary = "rgb(16161e)"
local error = "rgb(f7768e)"
local on_error = "rgb(16161e)"
local shadow = "rgb(15161e)"
local function apply_theme()
hl.config({
@@ -13,7 +17,14 @@ local function apply_theme()
inactive_border = surface,
},
},
decoration = {
shadow = {
color = shadow,
},
glow = {
color = shadow,
},
},
group = {
col = {
border_active = secondary,
@@ -23,12 +34,17 @@ local function apply_theme()
},
groupbar = {
gradients = true,
col = {
active = secondary,
inactive = surface,
locked_active = error,
locked_inactive = surface,
},
text_color = on_secondary,
text_color_inactive = on_surface,
text_color_locked_active = on_error,
text_color_locked_inactive = on_surface,
},
},
})
@@ -38,8 +54,12 @@ return {
colors = {
primary = primary,
surface = surface,
on_surface = on_surface,
secondary = secondary,
on_secondary = on_secondary,
error = error,
on_error = on_error,
shadow = shadow,
},
apply_theme = apply_theme
}