local M = {} function M.setup(opts) local terminal = opts.terminal local menu = opts.menu local browser = opts.browser local browserPrivate = opts.browserPrivate -- Import and setup hy3 plugin helper local hy3 = hl.plugin.hy3 if not hy3 then hy3 = setmetatable({}, { __index = function(_, k) return function(...) return function() print("hy3 plugin is not loaded, cannot call " .. k) end end end, }) end -- Track and write split state to /tmp/hy3_split for status bars like Wayle local current_split = "H" local function set_split(dir) current_split = dir local f = io.open("/tmp/hy3_split", "w") if f then f:write(dir) f:close() end end set_split("H") -- Initialize local mainMod = "SUPER" -- Sets "Windows" key as main modifier -- Example binds, see https://wiki.hypr.land/Configuring/Basics/Binds/ for more hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd(terminal)) hl.bind(mainMod .. " + Q", hl.dsp.window.close()) hl.bind(mainMod .. " + SHIFT + E", hl.dsp.exit()) hl.bind(mainMod .. " + SHIFT + R", function() hl.exec_cmd("hyprctl reload && notify-send 'Hyprland config reloaded'") end) hl.bind(mainMod .. " + E", hl.dsp.exec_cmd(terminal .. " fish -c 'y; exec fish'")) hl.bind(mainMod .. " + SPACE", hl.dsp.window.float({ action = "toggle" })) hl.bind(mainMod .. " + F", hl.dsp.window.fullscreen()) hl.bind(mainMod .. " + D", hl.dsp.exec_cmd(menu)) hl.bind(mainMod .. " + B", hl.dsp.exec_cmd(browser)) hl.bind(mainMod .. " + SHIFT + B", hl.dsp.exec_cmd(browserPrivate)) hl.bind(mainMod .. " + P", hl.dsp.window.pseudo()) -- hl.bind(mainMod .. " + S", hl.dsp.exec_cmd("hyprquickframe")) hl.bind( mainMod .. " + S", hl.dsp.exec_cmd( ' grim -g "$(slurp)" - | satty -f - --copy-command wl-copy -o "~/Pictures/Screenshots/%Y%m%d_%H%M%S.png"' ) ) -- hl.bind(mainMod .. " + G", hl.dsp.exec_cmd("python /home/sortedcord/Projects/firecrawl-search/main.py")) -- Move focus with mainMod + arrow keys (hy3 plugin aware) hl.bind(mainMod .. " + left", hy3.move_focus("left")) hl.bind(mainMod .. " + right", hy3.move_focus("right")) hl.bind(mainMod .. " + up", hy3.move_focus("up")) hl.bind(mainMod .. " + down", hy3.move_focus("down")) -- Move focus with mainMod + hjkl (hy3 plugin aware) hl.bind(mainMod .. " + H", hy3.move_focus("l")) hl.bind(mainMod .. " + J", hy3.move_focus("d")) hl.bind(mainMod .. " + K", hy3.move_focus("u")) hl.bind(mainMod .. " + L", hy3.move_focus("r")) hl.bind(mainMod .. " + W", hl.dsp.exec_cmd("/home/sortedcord/.config/rofi/launch.sh -show window")) -- Move window with mainMod + SHIFT + hjkl (hy3 plugin aware) hl.bind(mainMod .. " + SHIFT + H", hy3.move_window("l")) hl.bind(mainMod .. " + SHIFT + J", hy3.move_window("d")) hl.bind(mainMod .. " + SHIFT + K", hy3.move_window("u")) hl.bind(mainMod .. " + SHIFT + L", hy3.move_window("r")) -- i3-like container and layout controls -- Toggle layout tabbed hl.bind(mainMod .. " + SHIFT + T", function() hl.dispatch(hy3.change_group("toggletab")) if current_split == "T" then set_split("H") else set_split("T") end end) -- Split layout horizontal / vertical toggle hl.bind(mainMod .. " + SHIFT + G", function() hl.dispatch(hy3.change_group("opposite")) if current_split == "H" then set_split("V") elseif current_split == "V" then set_split("H") end end) -- Pre-split vertical (V), horizontal (C), or tab (X) hl.bind(mainMod .. " + V", function() hl.dispatch(hy3.make_group("v", { toggle = true })) set_split("V") end) hl.bind(mainMod .. " + C", function() hl.dispatch(hy3.make_group("h", { toggle = true })) set_split("H") end) hl.bind(mainMod .. " + X", function() hl.dispatch(hy3.make_group("tab", { toggle = true })) set_split("T") end) -- Focus parent (A) / focus child (SHIFT + A) hl.bind(mainMod .. " + A", hy3.change_focus("raise")) hl.bind(mainMod .. " + SHIFT + A", hy3.change_focus("lower")) -- Cycle tabs with Super + Alt + Left/Right hl.bind(mainMod .. " + ALT + left", hy3.focus_tab({ direction = "l", wrap = true })) hl.bind(mainMod .. " + ALT + right", hy3.focus_tab({ direction = "r", wrap = true })) -- Switch workspaces with mainMod + [0-9] -- Move active window/container to a workspace with mainMod + SHIFT + [0-9] (hy3 plugin aware) for i = 1, 10 do local key = i % 10 -- 10 maps to key 0 hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i })) hl.bind(mainMod .. " + SHIFT + " .. key, hy3.move_to_workspace(tostring(i))) end -- Move window to other monitor with mod+semicolon hl.bind(mainMod .. " + semicolon", hl.dsp.window.move({ monitor = "+1" })) -- Swap windows between monitors (mod+shift+semicolon) -- Detect which monitor we're on and use the correct focus direction hl.bind(mainMod .. " + SHIFT + semicolon", function() local active_monitor = hl.get_active_monitor() local focus_direction = "r" -- If we're on the rightmost monitor (HDMI-A-1), focus left instead if active_monitor.name == "HDMI-A-1" then focus_direction = "l" end -- Move window to next monitor hl.dispatch(hl.dsp.window.move({ monitor = "+1" })) -- Focus a window on the current monitor using the correct direction (hy3 plugin aware) hl.dispatch(hy3.move_focus(focus_direction)) -- Move the newly focused window back to original monitor hl.dispatch(hl.dsp.window.move({ monitor = "-1" })) end) -- Example special workspace (scratchpad) -- hl.bind(mainMod .. " + S", hl.dsp.workspace.toggle_special("magic")) -- hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" })) -- Scroll through existing workspaces with mainMod + scroll -- hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" })) -- hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" })) hl.bind(mainMod .. " + Y", hl.dsp.focus({ workspace = "e+1" })) hl.bind(mainMod .. " + T", hl.dsp.focus({ workspace = "e-1" })) -- Move/resize windows with mainMod + LMB/RMB and dragging hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) -- Laptop multimedia keys for volume and LCD brightness hl.bind( "XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true } ) hl.bind( "XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true, repeating = true } ) hl.bind( "XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true, repeating = true } ) hl.bind( "XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true, repeating = true } ) hl.bind( "XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%+"), { locked = true, repeating = true } ) hl.bind( "XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%-"), { locked = true, repeating = true } ) -- Requires playerctl hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true }) hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true }) hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true }) hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true }) -- Cursor controls (simplified - submaps not supported in Lua API) -- Jump cursor to a position hl.bind( "SUPER + G + A", hl.dsp.exec_cmd("hyprctl dispatch submap reset && wl-kbptr && hyprctl dispatch submap cursor") ) -- Cursor movement hl.bind("SUPER + G + J", hl.dsp.exec_cmd("wlrctl pointer move 0 10"), { repeating = true }) hl.bind("SUPER + G + K", hl.dsp.exec_cmd("wlrctl pointer move 0 -10"), { repeating = true }) hl.bind("SUPER + G + L", hl.dsp.exec_cmd("wlrctl pointer move 10 0"), { repeating = true }) hl.bind("SUPER + G + H", hl.dsp.exec_cmd("wlrctl pointer move -10 0"), { repeating = true }) -- Left button hl.bind("SUPER + G + S", hl.dsp.exec_cmd("wlrctl pointer click left")) -- Middle button hl.bind("SUPER + G + D", hl.dsp.exec_cmd("wlrctl pointer click middle")) -- Right button hl.bind("SUPER + G + F", hl.dsp.exec_cmd("wlrctl pointer click right")) -- Scroll up and down hl.bind("SUPER + G + E", hl.dsp.exec_cmd("wlrctl pointer scroll 10 0"), { repeating = true }) hl.bind("SUPER + G + R", hl.dsp.exec_cmd("wlrctl pointer scroll -10 0"), { repeating = true }) -- Scroll left and right hl.bind("SUPER + G + T", hl.dsp.exec_cmd("wlrctl pointer scroll 0 -10"), { repeating = true }) hl.bind("SUPER + G + G", hl.dsp.exec_cmd("wlrctl pointer scroll 0 10"), { repeating = true }) end return M