diff --git a/.config/hypr/hyprland.conf b/.config/hypr/hyprland.conf index 5aa5217..87955aa 100644 --- a/.config/hypr/hyprland.conf +++ b/.config/hypr/hyprland.conf @@ -17,15 +17,16 @@ exec-once = dbus-update-activation-environment --systemd & exec-once = hyprpaper exec-once = hypridle exec-once = waybar -c ~/.config/waybar/config & -exec-once = fcitx5 -d & -exec-once = mako & -exec-once = bash -c "mkfifo /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob && tail -f /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob | wob & disown" & +exec-once = fcitx5 -d & # Keyboard +exec-once = mako & # Notifications +exec-once = bash -c "mkfifo /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob && tail -f /tmp/$HYPRLAND_INSTANCE_SIGNATURE.wob | wob & disown" & # Audio bar exec-once = /usr/lib/polkit-kde-authentication-agent-1 & # exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP -exec-once = hyprctl setcursor Adwaita 20 -# exec-once = xwaylandvideobridge +exec-once = hyprctl setcursor Adwaita 24 exec-once = wl-clip-persist --clipboard regular +exec-once = 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 &" & +exec-once = xwaylandvideobridge #------------------------ # General configurations @@ -46,11 +47,17 @@ input { natural_scroll = yes scroll_factor = 0.2 } - sensitivity = 0 # [-1.0 - 1.0] accel_profile = flat } +device { + name = elecom-elecom-opticalmouse + sensitivity = -0.45 +} + + + cursor { no_warps = true } @@ -91,7 +98,7 @@ dwindle { special_scale_factor = 0.8 split_width_multiplier = 1.0 use_active_for_splits = true - pseudotile = yes + # pseudotile = yes preserve_split = yes } @@ -104,13 +111,13 @@ misc { enable_swallow = true swallow_regex = focus_on_activate = true - vfr = 1 - new_window_takes_over_fullscreen = 2 + # vfr = 1 +# new_window_takes_over_fullscreen = 2 } gestures { - workspace_swipe = true - workspace_swipe_fingers = 4 +# workspace_swipe = true +# workspace_swipe_fingers = 4 workspace_swipe_distance = 250 workspace_swipe_invert = true workspace_swipe_min_speed_to_force = 15 @@ -121,6 +128,8 @@ gestures { xwayland { force_zero_scaling = true } +env = GDK_SCALE,2 +env = XCURSOR_SIZE,24 # device { # name = epic-mouse-v1 @@ -143,7 +152,11 @@ bind = CTRL ALT, T, exec, alacritty # Screenshot bind = , PRINT, exec, grimblast --notify --freeze copysave area - +layerrule { + name = no_anim_for_selection + no_anim = on + match:namespace = selection +} # Kill bind = $mainMod, Q, killactive, @@ -193,10 +206,9 @@ bind = $mainMod, right, movefocus, r bind = $mainMod, up, movefocus, u bind = $mainMod, down, movefocus, d -bind = ALT, Tab, cyclenext, +bind = ALT, Tab, cyclenext bind = ALT, Tab, bringactivetotop, - # Window movement bind = $mainMod SHIFT,left, movewindow, l bind = $mainMod SHIFT,right, movewindow, r @@ -208,7 +220,7 @@ bind = $mainMod ALT, right, swapwindow, r bind = $mainMod ALT, up, swapwindow, u bind = $mainMod ALT, down, swapwindow, d -bind = $mainMod, D, togglesplit +bind = $mainMod, D, layoutmsg, togglesplit # Window resize @@ -267,41 +279,37 @@ bind = $mainMod CTRL, right, movetoworkspace, +1 # windows rules #--------------- -windowrule = float, Rofi +windowrule = float on, match:class ^(Rofi)$ -windowrule = float, pavucontrol +windowrule = float on, size 960 540, match:class ^(org.pulseaudio.pavucontrol)$ -windowrulev2 = float,class:^(blueman-manager)$ +windowrule = float on, match:class ^(org.gnome.FileRoller)$ -windowrulev2 = float,class:^(xdg-desktop-portal-gtk)$ -windowrulev2 = float,class:^(xdg-desktop-portal-kde)$ -windowrulev2 = float,class:^(xdg-desktop-portal-hyprland)$ +windowrule = float on, match:class ^(blueman-manager)$ -windowrulev2 = float,class:^(org.kde.polkit-kde-authentication-agent-1)$ +windowrule = float on, match:class ^(xdg-desktop-portal-gtk)$ +windowrule = float on, match:class ^(xdg-desktop-portal-kde)$ +windowrule = float on, match:class ^(xdg-desktop-portal-hyprland)$ -windowrulev2 = float,class:^(CachyOSHello)$ +windowrule = float on, match:class ^(org.kde.polkit-kde-authentication-agent-1)$ -windowrulev2 = float,class:^(zenity)$ +windowrule = float on, match:class ^(CachyOSHello)$ -windowrulev2 = float,class:^()$,title:^(Steam - Self Updater)$ +windowrule = float on, match:class ^(zenity)$ -windowrulev2 = float,class:^()$,title:^(Picture in picture)$ -windowrule = float,title:^(Picture-in-Picture)$ -windowrule = size 960 540,title:^(Picture-in-Picture)$ -windowrule = move 25%-,title:^(Picture-in-Picture)$ +windowrule = float on, match:class ^()$, match:title ^(Steam - Self Updater)$ -windowrule = float,nemo -windowrule = move 25%-,nemo -windowrule = size 1080 540,nemo +windowrule = float on, match:class ^()$, match:title ^(Picture in picture)$ +windowrule = float on, size 960 540, match:title ^(Picture-in-Picture)$ -windowrule = animation slide right,alacritty +windowrule = float on, size 1080 540, match:class ^(nemo)$ -windowrule = float, discord -windowrule = float, vesktop +windowrule = animation slide right, match:class ^(alacritty)$ + +windowrule = float on, match:class ^(discord)$ +windowrule = float on, match:class ^(vesktop)$ + +windowrule = float on, match:class ^(Matplotlib)$ # XWayland workaround -windowrulev2 = opacity 0.0 override, class:^(xwaylandvideobridge)$ -windowrulev2 = noanim, class:^(xwaylandvideobridge)$ -windowrulev2 = noinitialfocus, class:^(xwaylandvideobridge)$ -windowrulev2 = maxsize 1 1, class:^(xwaylandvideobridge)$ -windowrulev2 = noblur, class:^(xwaylandvideobridge)$ +windowrule = opacity 0.0 override, no_anim on, no_initial_focus on, max_size 1 1, no_blur on, no_focus on, match:class ^(xwaylandvideobridge)$ diff --git a/.config/hypr/hyprland.lua b/.config/hypr/hyprland.lua new file mode 100644 index 0000000..6257bd8 --- /dev/null +++ b/.config/hypr/hyprland.lua @@ -0,0 +1,332 @@ +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 + 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 +-------------------- +-- TODO: bezier/animation shape is one of the least-standardized +-- parts of the new API across the examples I found. hl.curve() is +-- confirmed for bezier curves; the `animation =` line itself may +-- need to be hl.config({ animations = { animation = {...} } }) on +-- your build — check `hyprctl` / the wiki's Animations page. +hl.curve("overshot", { type = "bezier", points = { { 0.13, 0.99 }, { 0.29, 1.1 } } }) + +hl.config({ + animations = { + enabled = true, + animation = { + { "windows", 1, 4, "overshot", "slide" }, + { "windowsOut", 1, 5, "default", "popin 80%" }, + { "border", 1, 5, "default" }, + { "fade", 1, 8, "default" }, + { "workspaces", 1, 6, "overshot", "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.window.focus({ direction = "l" })) +hl.bind(mainMod .. " + right", hl.dsp.window.focus({ direction = "r" })) +hl.bind(mainMod .. " + up", hl.dsp.window.focus({ direction = "u" })) +hl.bind(mainMod .. " + down", hl.dsp.window.focus({ direction = "d" })) + +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_msg("togglesplit")) -- TODO: verify layoutmsg dispatcher name + +-- 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.move()) +hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize()) + +-- Switch workspaces +for i = 1, 9 do + hl.bind(mainMod .. " + " .. tostring(i), hl.dsp.workspace.change(tostring(i))) +end +hl.bind(mainMod .. " + 0", hl.dsp.workspace.change("10")) + +hl.bind("CTRL + ALT + right", hl.dsp.workspace.change("e+1")) +hl.bind("CTRL + ALT + left", hl.dsp.workspace.change("e-1")) + +hl.bind(mainMod .. " + mouse_down", hl.dsp.workspace.change("e+1")) +hl.bind(mainMod .. " + mouse_up", hl.dsp.workspace.change("e-1")) + +-- Window workspace movement +for i = 1, 9 do + hl.bind(mainMod .. " + CTRL + " .. tostring(i), hl.dsp.window.move_to_workspace(tostring(i))) +end +hl.bind(mainMod .. " + CTRL + 0", hl.dsp.window.move_to_workspace("10")) +hl.bind(mainMod .. " + CTRL + left", hl.dsp.window.move_to_workspace("-1")) +hl.bind(mainMod .. " + CTRL + right", hl.dsp.window.move_to_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 = true, + no_anim = true, + no_initial_focus = true, + max_size = "1 1", + no_blur = true, + no_focus = true, + match = { class = "^(xwaylandvideobridge)$" }, +}) \ No newline at end of file diff --git a/.config/hypr/hyprpaper.conf b/.config/hypr/hyprpaper.conf index 953aea4..4ac36a5 100644 --- a/.config/hypr/hyprpaper.conf +++ b/.config/hypr/hyprpaper.conf @@ -1,2 +1,7 @@ -preload = ~/Pictures/wallpaper/mountains_lake.png -wallpaper = , ~/Pictures/wallpaper/mountains_lake.png +splash = false +wallpaper { + monitor = + path = ~/Pictures/wallpaper/temple-1-dark.jpg + fit_mode = cover +} + diff --git a/.config/hypr/monitors.conf b/.config/hypr/monitors.conf index 315e383..3adfb8d 100644 --- a/.config/hypr/monitors.conf +++ b/.config/hypr/monitors.conf @@ -1,4 +1,4 @@ -# Generated by nwg-displays on 2025-02-01 at 16:12:38. Do not edit manually. +# Generated by nwg-displays on 2026-06-04 at 16:27:02. Do not edit manually. -monitor=eDP-1,3072x1920@60.0,2987x869,2.0 -monitor=DP-1,1920x1080@60.0,1067x749,1.0 +monitor=eDP-1,3072x1920@60.0,3201x953,2.0 +monitor=DP-1,1920x1080@60.0,1281x833,1.0 diff --git a/.config/hypr/monitors.lua b/.config/hypr/monitors.lua new file mode 100644 index 0000000..80181cf --- /dev/null +++ b/.config/hypr/monitors.lua @@ -0,0 +1,14 @@ +-- Generated by nwg-displays on 2026-06-04 at 16:27:02. Do not edit manually. + +hl.monitor({ + output = "eDP-1", + mode = "3072x1920@60.0", + position = "3201x953", + scale = 2.0 +}) +hl.monitor({ + output = "DP-1", + mode = "1920x1080@60.0", + position = "1281x833", + scale = 1.0 +}) diff --git a/.config/hypr/scripts/screenshot b/.config/hypr/scripts/screenshot new file mode 100755 index 0000000..ecc11b9 --- /dev/null +++ b/.config/hypr/scripts/screenshot @@ -0,0 +1,3 @@ +#!/usr/bin/bash +grim -g "$(slurp)" - | wl-copy -t image/png +notify-send "Screenshot copied to clipboard" diff --git a/.config/hypr/scripts/screenshot_area b/.config/hypr/scripts/screenshot_area new file mode 100755 index 0000000..52218e2 --- /dev/null +++ b/.config/hypr/scripts/screenshot_area @@ -0,0 +1,3 @@ +#!/usr/bin/bash +grimblast copy area || exit +notify-send "Screenshot copied to clipboard" diff --git a/.config/hypr/scripts/screenshot_full b/.config/hypr/scripts/screenshot_full new file mode 100755 index 0000000..0608891 --- /dev/null +++ b/.config/hypr/scripts/screenshot_full @@ -0,0 +1,3 @@ +#!/usr/bin/bash +grimblast copy output || exit +notify-send "Screenshot copied to clipboard"