Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion default/hypr/bindings/tiling.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,22 @@ o.bind("SUPER + W", "Close window", hl.dsp.window.close())
o.bind("SUPER + Q", "Close window", hl.dsp.window.close())
o.bind("CTRL + ALT + DELETE", "Close all windows", "omarchy-hyprland-window-close-all")

o.bind("SUPER + J", "Toggle window split", hl.dsp.layout("togglesplit"))
-- togglesplit is dwindle-only; sending it on a scrolling workspace raises
-- "no such layoutmsg for scrolling". consume_or_expel is the scrolling analog:
-- stack a lone column into its neighbor, or expel a stacked window back out.
o.bind("SUPER + J", "Toggle window split", function()
local workspace = hl.get_active_special_workspace() or hl.get_active_workspace()
if not workspace or (workspace.windows or 0) < 2 then
return
end

local layout = workspace.tiled_layout
if layout == "scrolling" then
hl.dispatch(hl.dsp.layout("consume_or_expel next"))
elseif layout == "dwindle" then
hl.dispatch(hl.dsp.layout("togglesplit"))
end
end)
o.bind("SUPER + P", "Pseudo window", hl.dsp.window.pseudo())
o.bind("SUPER + T", "Toggle window floating/tiling", hl.dsp.window.float({ action = "toggle" }))
o.bind("SUPER + F", "Full screen", hl.dsp.window.fullscreen({ mode = "fullscreen" }))
Expand Down
107 changes: 107 additions & 0 deletions test/shell.d/hyprland-window-split-toggle-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/bash

source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"

require_command lua

HOME="$(mktemp -d)" OMARCHY_PATH="$ROOT" lua <<'LUA' || fail "SUPER + J split toggle loads under a Hyprland stub"
package.path = os.getenv("OMARCHY_PATH") .. "/?.lua;" .. package.path

local function proxy()
return setmetatable({}, {
__index = function(self, key)
local value = proxy()
rawset(self, key, value)
return value
end,
__call = function()
return {}
end,
})
end

local dispatched = {}
local split_toggle

hl = {
dsp = {
layout = function(msg)
return { kind = "layout", msg = msg }
end,
exec_cmd = function(command)
return { kind = "exec", arg = command }
end,
window = proxy(),
focus = proxy(),
workspace = proxy(),
group = proxy(),
},
bind = function(keys, dispatcher)
if keys == "SUPER + J" then
split_toggle = dispatcher
end
end,
dispatch = function(dispatcher)
table.insert(dispatched, dispatcher)
end,
get_active_special_workspace = function()
return nil
end,
get_active_workspace = function()
return { tiled_layout = "dwindle", windows = 2 }
end
}

require("default.hypr.helpers")
require("default.hypr.bindings.tiling")

assert(type(split_toggle) == "function", "SUPER + J binds a layout-aware function")

split_toggle()
assert(#dispatched == 1)
assert(dispatched[1].kind == "layout")
assert(dispatched[1].msg == "togglesplit")

dispatched = {}
hl.get_active_workspace = function()
return { tiled_layout = "scrolling", windows = 2 }
end
split_toggle()
assert(#dispatched == 1)
assert(dispatched[1].kind == "layout")
assert(dispatched[1].msg == "consume_or_expel next")

dispatched = {}
hl.get_active_workspace = function()
return { tiled_layout = "scrolling", windows = 1 }
end
split_toggle()
assert(#dispatched == 0)

dispatched = {}
hl.get_active_workspace = function()
return { tiled_layout = "master", windows = 2 }
end
split_toggle()
assert(#dispatched == 0)

dispatched = {}
hl.get_active_workspace = function()
return nil
end
split_toggle()
assert(#dispatched == 0)

dispatched = {}
hl.get_active_special_workspace = function()
return { tiled_layout = "scrolling", windows = 2 }
end
hl.get_active_workspace = function()
error("must prefer the special workspace")
end
split_toggle()
assert(#dispatched == 1)
assert(dispatched[1].msg == "consume_or_expel next")
LUA

pass "SUPER + J dispatches togglesplit on dwindle and consume_or_expel on scrolling"