-- ============================================================ -- Hyprland Lua config (converted from hyprlang .conf, v0.55+) -- Converted by Claude — please review the TODO-flagged lines, -- the Lua API surface is new and some dispatcher names/shapes -- are best-effort based on current docs/community examples. -- ============================================================ local mainMod = "SUPER" -------------------- -- Monitors -------------------- require("monitors") -------------------- -- Env vars -------------------- hl.env("GDK_SCALE", "2") hl.env("XCURSOR_SIZE", "24") -------------------- -- Auto start -------------------- hl.on("hyprland.start", function() -- Slow app launch fix hl.dispatch(hl.dsp.exec_cmd("systemctl --user import-environment")) hl.dispatch(hl.dsp.exec_cmd("hash dbus-update-activation-environment 2>/dev/null")) hl.dispatch(hl.dsp.exec_cmd("dbus-update-activation-environment --systemd")) hl.dispatch(hl.dsp.exec_cmd("hyprpaper")) hl.dispatch(hl.dsp.exec_cmd("hypridle")) hl.dispatch(hl.dsp.exec_cmd("waybar -c ~/.config/waybar/config")) hl.dispatch(hl.dsp.exec_cmd("fcitx5 -d")) -- Keyboard hl.dispatch(hl.dsp.exec_cmd("mako")) -- Notifications hl.dispatch(hl.dsp.exec_cmd( "bash -c \"mkfifo /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob && tail -f /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob | wob & disown\"" )) -- Audio bar hl.dispatch(hl.dsp.exec_cmd("/usr/lib/polkit-kde-authentication-agent-1")) hl.dispatch(hl.dsp.exec_cmd("hyprctl setcursor Adwaita 24")) hl.dispatch(hl.dsp.exec_cmd("wl-clip-persist --clipboard regular")) hl.dispatch(hl.dsp.exec_cmd( "bash -c \"sleep 1 && killall -e xdg-desktop-portal-hyprland && killall xdg-desktop-portal && /usr/lib/xdg-desktop-portal-hyprland & sleep 2 && /usr/lib/xdg-desktop-portal &\"" )) hl.dispatch(hl.dsp.exec_cmd("xwaylandvideobridge")) end) -------------------------- -- General configurations -------------------------- hl.config({ input = { kb_layout = "it", kb_variant = "", kb_model = "", -- kb_options = "grp:caps_toggle,grp_led:caps,altwin:swap_alt_win,ctrl:rctrl_ralt", kb_options = "", kb_rules = "", follow_mouse = 1, float_switch_override_focus = 2, touchpad = { natural_scroll = true, scroll_factor = 0.2, }, sensitivity = 0, -- [-1.0 - 1.0] accel_profile = "flat", }, cursor = { no_warps = true, }, general = { gaps_in = 3, gaps_out = 5, border_size = 2, ["col.active_border"] = "rgb(26a269)", ["col.inactive_border"] = "rgb(595959)", layout = "dwindle", -- master|dwindle -- apply_sens_to_raw = 0, }, decoration = { active_opacity = 1.0, inactive_opacity = 0.95, fullscreen_opacity = 1.0, rounding = 4, }, dwindle = { -- no_gaps_when_only = false, force_split = 0, special_scale_factor = 0.8, split_width_multiplier = 1.0, use_active_for_splits = true, -- pseudotile = true, preserve_split = true, }, misc = { -- disable_autoreload = true, disable_hyprland_logo = true, always_follow_on_dnd = true, layers_hog_keyboard_focus = true, animate_manual_resizes = false, enable_swallow = true, swallow_regex = "", focus_on_activate = true, -- vfr = true, -- new_window_takes_over_fullscreen = 2, }, gestures = { -- workspace_swipe = true, -- workspace_swipe_fingers = 4, workspace_swipe_distance = 250, workspace_swipe_invert = true, workspace_swipe_min_speed_to_force = 15, workspace_swipe_cancel_ratio = 0.5, workspace_swipe_create_new = false, }, xwayland = { force_zero_scaling = true, }, }) -- device { name = elecom-elecom-opticalmouse; sensitivity = -0.45 } hl.device({ name = "elecom-elecom-opticalmouse", sensitivity = -0.45, }) -- device { -- name = "epic-mouse-v1", -- sensitivity = -0.5, -- } -------------------- -- Animations -------------------- hl.curve("overshot", { type = "bezier", points = { { 0.13, 0.99 }, { 0.29, 1.1 } } }) hl.config({ animations = { enabled = true, -- master on/off switch }, }) hl.animation({ leaf = "windows", enabled = true, speed = 4, bezier = "overshot", style = "slide" }) hl.animation({ leaf = "windowsOut", enabled = true, speed = 5, bezier = "default", style = "popin 80%" }) hl.animation({ leaf = "border", enabled = true, speed = 5, bezier = "default" }) hl.animation({ leaf = "fade", enabled = true, speed = 8, bezier = "default" }) hl.animation({ leaf = "workspaces", enabled = true, speed = 6, bezier = "overshot", style = "slide" }) -------------------- -- Bindings -------------------- -- Terminal hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd("alacritty")) hl.bind(mainMod .. " + T", hl.dsp.exec_cmd("alacritty")) hl.bind("CTRL + ALT + T", hl.dsp.exec_cmd("alacritty")) -- Screenshot hl.bind("PRINT", hl.dsp.exec_cmd("grimblast --notify --freeze copysave area")) hl.layer_rule({ name = "no_anim_for_selection", no_anim = true, match = { namespace = "selection" }, }) -- Kill hl.bind(mainMod .. " + Q", hl.dsp.window.close()) hl.bind("ALT + F4", hl.dsp.window.close()) -- Floating and fullscreen hl.bind(mainMod .. " + F", hl.dsp.window.float({ action = "toggle" })) hl.bind(mainMod .. " + P", hl.dsp.window.pin()) -- TODO: verify dispatcher name for "pin" hl.bind(mainMod .. " + S", hl.dsp.window.fullscreen({ mode = 0 })) hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.fullscreen({ mode = 1 })) -- Wofi hl.bind(mainMod .. " + SPACE", hl.dsp.exec_cmd("wofi")) -- Volume control hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("pamixer -ud 2 && pamixer --get-volume > /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob"), { repeating = true }) hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("pamixer -ui 2 && pamixer --get-volume > /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob"), { repeating = true }) hl.bind("XF86AudioMute", hl.dsp.exec_cmd( "amixer sset Master toggle | sed -En '/\\[on\\]/ s/.*\\[([0-9]+)%\\].*/\\1/ p; /\\[off\\]/ s/.*/0/p' | head -1 > /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob"), { repeating = true }) -- Playback control hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause")) hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next")) hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous")) -- Screen brightness hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl s +2% && brightnessctl -m | awk -F, '{print $4}' | tr -d % > /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob"), { repeating = true }) hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl s 2%- && brightnessctl -m | awk -F, '{print $4}' | tr -d % > /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob"), { repeating = true }) -- Lock screen hl.bind("XF86PowerOff", hl.dsp.exec_cmd("hyprlock")) -- Reload hl.bind(mainMod .. " + CTRL + SHIFT + ALT + R", hl.dsp.exec_cmd("killall -SIGUSR2 waybar && hyprctl reload && notify-send \"Waybar and Hyprland reloaded\"")) -- Move focus hl.bind(mainMod .. " + left", hl.dsp.focus({ direction = "left" })) hl.bind(mainMod .. " + right", hl.dsp.focus({ direction = "right" })) hl.bind(mainMod .. " + up", hl.dsp.focus({ direction = "up" })) hl.bind(mainMod .. " + down", hl.dsp.focus({ direction = "down" })) hl.bind("ALT + Tab", function() hl.dispatch(hl.dsp.window.cycle_next()) hl.dispatch(hl.dsp.window.bring_to_top()) end) -- Window movement hl.bind(mainMod .. " + SHIFT + left", hl.dsp.window.move({ direction = "l" })) hl.bind(mainMod .. " + SHIFT + right", hl.dsp.window.move({ direction = "r" })) hl.bind(mainMod .. " + SHIFT + up", hl.dsp.window.move({ direction = "u" })) hl.bind(mainMod .. " + SHIFT + down", hl.dsp.window.move({ direction = "d" })) hl.bind(mainMod .. " + ALT + left", hl.dsp.window.swap({ direction = "l" })) hl.bind(mainMod .. " + ALT + right", hl.dsp.window.swap({ direction = "r" })) hl.bind(mainMod .. " + ALT + up", hl.dsp.window.swap({ direction = "u" })) hl.bind(mainMod .. " + ALT + down", hl.dsp.window.swap({ direction = "d" })) hl.bind(mainMod .. " + D", hl.dsp.layout("togglesplit")) -- dwindle only -- Window resize hl.bind(mainMod .. " + CTRL + SHIFT + left", hl.dsp.window.resize({ x = -15, y = 0, relative = true }), { repeating = true }) hl.bind(mainMod .. " + CTRL + SHIFT + right", hl.dsp.window.resize({ x = 15, y = 0, relative = true }), { repeating = true }) hl.bind(mainMod .. " + CTRL + SHIFT + up", hl.dsp.window.resize({ x = 0, y = -15, relative = true }), { repeating = true }) hl.bind(mainMod .. " + CTRL + SHIFT + down", hl.dsp.window.resize({ x = 0, y = 15, relative = true }), { repeating = true }) -- Windows mouse interaction hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) -- Switch workspaces for i = 1, 9 do hl.bind(mainMod .. " + " .. tostring(i), hl.dsp.focus({ workspace = i })) end hl.bind(mainMod .. " + 0", hl.dsp.focus({ workspace = 10 })) hl.bind("CTRL + ALT + right", hl.dsp.focus({ workspace = "e+1" })) hl.bind("CTRL + ALT + left", hl.dsp.focus({ workspace = "e-1" })) hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" })) hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" })) -- Window workspace movement for i = 1, 9 do hl.bind(mainMod .. " + CTRL + " .. tostring(i), hl.dsp.window.move({ workspace = i })) end hl.bind(mainMod .. " + CTRL + 0", hl.dsp.window.move({ workspace = 10 })) hl.bind(mainMod .. " + CTRL + left", hl.dsp.window.move({ workspace = "-1" })) hl.bind(mainMod .. " + CTRL + right", hl.dsp.window.move({ workspace = "+1" })) -- binds { -- workspace_back_and_forth = true, -- allow_workspace_cycles = true, -- } --------------- -- Window rules --------------- hl.window_rule({ float = true, match = { class = "^(Rofi)$" } }) hl.window_rule({ float = true, size = "960 540", match = { class = "^(org.pulseaudio.pavucontrol)$" } }) hl.window_rule({ float = true, match = { class = "^(org.gnome.FileRoller)$" } }) hl.window_rule({ float = true, match = { class = "^(blueman-manager)$" } }) hl.window_rule({ float = true, match = { class = "^(xdg-desktop-portal-gtk)$" } }) hl.window_rule({ float = true, match = { class = "^(xdg-desktop-portal-kde)$" } }) hl.window_rule({ float = true, match = { class = "^(xdg-desktop-portal-hyprland)$" } }) hl.window_rule({ float = true, match = { class = "^(org.kde.polkit-kde-authentication-agent-1)$" } }) hl.window_rule({ float = true, match = { class = "^(CachyOSHello)$" } }) hl.window_rule({ float = true, match = { class = "^(zenity)$" } }) hl.window_rule({ float = true, match = { class = "^()$", title = "^(Steam - Self Updater)$" } }) hl.window_rule({ float = true, match = { class = "^()$", title = "^(Picture in picture)$" } }) hl.window_rule({ float = true, size = "960 540", match = { title = "^(Picture-in-Picture)$" } }) hl.window_rule({ float = true, size = "1080 540", match = { class = "^(nemo)$" } }) hl.window_rule({ animation = "slide right", match = { class = "^(alacritty)$" } }) hl.window_rule({ float = true, match = { class = "^(discord)$" } }) hl.window_rule({ float = true, match = { class = "^(vesktop)$" } }) hl.window_rule({ float = true, match = { class = "^(Matplotlib)$" } }) -- XWayland workaround hl.window_rule({ opacity = "0.0 override", no_anim = true, no_initial_focus = true, max_size = "1 1", no_blur = true, no_focus = true, match = { class = "^(xwaylandvideobridge)$" }, })