diff --git a/.config/hypr/edit_here/hyprland.conf.deprecated b/.config/hypr/edit_here/hyprland.conf.deprecated new file mode 100644 index 00000000..02cfb93e --- /dev/null +++ b/.config/hypr/edit_here/hyprland.conf.deprecated @@ -0,0 +1,16 @@ +# ============================================================================== +# USER CONFIGURATION OVERLAY +# ============================================================================== +# This file sources all your custom configuration files. +# Edit the specific files in 'source/' to apply your changes. +# ============================================================================== + +source = ~/.config/hypr/edit_here/source/monitors.conf +source = ~/.config/hypr/edit_here/source/keybinds.conf +source = ~/.config/hypr/edit_here/source/appearance.conf +source = ~/.config/hypr/edit_here/source/autostart.conf +source = ~/.config/hypr/edit_here/source/plugins.conf +source = ~/.config/hypr/edit_here/source/window_rules.conf +source = ~/.config/hypr/edit_here/source/workspace_rules.conf +source = ~/.config/hypr/edit_here/source/environment_variables.conf +source = ~/.config/hypr/edit_here/source/input.conf diff --git a/.config/hypr/edit_here/hyprland.lua b/.config/hypr/edit_here/hyprland.lua new file mode 100644 index 00000000..feca3ada --- /dev/null +++ b/.config/hypr/edit_here/hyprland.lua @@ -0,0 +1,18 @@ +-- ============================================================================= +-- USER CONFIGURATION OVERLAY +-- ============================================================================= +-- This file sources all your custom configuration files. +-- Edit the specific files in 'source/' to apply your changes. +-- ============================================================================= + +local src = os.getenv("HOME") .. "/.config/hypr/edit_here/source/" + +dofile(src .. "monitors.lua") +dofile(src .. "keybinds.lua") +dofile(src .. "appearance.lua") +dofile(src .. "autostart.lua") +dofile(src .. "plugins.lua") +dofile(src .. "window_rules.lua") +dofile(src .. "workspace_rules.lua") +dofile(src .. "environment_variables.lua") +dofile(src .. "input.lua") diff --git a/.config/hypr/edit_here/source/appearance.conf.deprecated b/.config/hypr/edit_here/source/appearance.conf.deprecated new file mode 100644 index 00000000..5e82d42c --- /dev/null +++ b/.config/hypr/edit_here/source/appearance.conf.deprecated @@ -0,0 +1,157 @@ +# ============================================================================== +# USER CONFIGURATION: appearance.conf +# ============================================================================== +# Add your custom settings for appearance here. +# These will override or add to the defaults found in ~/.config/hypr/source/appearance.conf +# This file can also be edited with dusky appearance from the rofi menu or from dusky control center +# ============================================================================== + +# ------------------------------------------------------------------------------------------------- +# THEME SOURCE +# ------------------------------------------------------------------------------------------------- +# Sourcing colors generated by Matugen +source = ~/.config/matugen/generated/hyprland-colors.conf + +# ------------------------------------------------------------------------------------------------- +# 1. GENERAL APPEARANCE +# Control gaps, borders, and layout behavior. +# See: https://wiki.hyprland.org/Configuring/Variables/#general +# ------------------------------------------------------------------------------------------------- +general { + # --- Gaps & Borders --- + gaps_in = 6 # Gap between windows + gaps_out = 12 # Gap between windows and monitor edges + gaps_workspaces = 0 # Gap between workspaces (when sliding) + border_size = 2 # Size of window borders + + # --- Colors --- + # Uses variables from the sourced matugen file + col.active_border = $primary + col.inactive_border = $inverse_on_surface + + # --- Behavior --- + # RESIZING: Set to true. This allows you to resize windows by clicking and dragging + # on the gaps/border area, rather than hitting the exact 2px pixel border. + resize_on_border = false + + # TEARING: Allows lower latency in games. + # NOTE: To use this, you must also apply 'windowrulev2 = immediate, class:^(game_class)$' + allow_tearing = true + + # Default layout engine + layout = dwindle + + # --- Snapping --- + # Controls how floating windows snap to each other and edges + snap { + enabled = false + window_gap = 10 # Min gap (px) before snapping to another window + monitor_gap = 10 # Min gap (px) before snapping to monitor edge + border_overlap = false # If true, windows snap with overlapping borders + } +} + +# ------------------------------------------------------------------------------------------------- +# 2. DECORATION +# Shadows, Blur, Opacity, and Rounding. +# See: https://wiki.hyprland.org/Configuring/Variables/#decoration +# ------------------------------------------------------------------------------------------------- +decoration { + # --- Rounding --- + rounding = 6 + rounding_power = 6.0 + + # --- Opacity --- + active_opacity = 0.8 + inactive_opacity = 0.6 + fullscreen_opacity = 1.0 + + # --- Dimming --- + dim_inactive = true + dim_strength = 0.2 + dim_special = 0.8 # Stronger dimming for special workspace + + # --- Shadows --- + # Enabled because your hardware (12700H) can easily handle it. + shadow { + enabled = true + range = 35 + render_power = 2 # 1-4. Higher is faster falloff (sharper looking) + sharp = false # If true, renders a sharp shadow (retro style) + scale = 1.0 # Scale of the shadow (1.0 = window size) + color = rgba(1a1a1aee) + # color = $primary + # offset = 0 0 # Displaces shadow (x, y) + } + + # --- Blur --- + # Enabled for aesthetic depth. + blur { + enabled = true + size = 4 # Radius + passes = 2 # Quality (2 is a good balance of perf/looks) + new_optimizations = true + ignore_opacity = true # Blurs behind transparent windows even if opacity is high + xray = true + + # Texture & Quality + noise = 0.0217 + contrast = 0.8916 # Contrast modulation for blur + brightness = 0.8172 # Brightness modulation for blur + vibrancy = 0.1696 # Saturation of blurred colors + + # Specifics + popups = false # Whether to blur right-click menus/popups + } + + # --- Shaders --- + # screen_shader = ~/.config/hypr/shaders/grayscale_advanced.glsl +} + +# ------------------------------------------------------------------------------------------------- +# 3. ANIMATIONS +# See: https://wiki.hyprland.org/Configuring/Animations/ +# ------------------------------------------------------------------------------------------------- + +source = ~/.config/hypr/source/animations/active/active.conf + +# ------------------------------------------------------------------------------------------------- +# 4. LAYOUTS +# ------------------------------------------------------------------------------------------------- +dwindle { + preserve_split = true + # smart_split = false # If true, splits based on mouse position. + # smart_resizing = false # If true, resizing direction is determined by mouse pos. +} + +master { + new_status = master +} + +# ------------------------------------------------------------------------------------------------- +# 5. MISCELLANEOUS & PERFORMANCE +# See: https://wiki.hyprland.org/Configuring/Variables/#misc +# ------------------------------------------------------------------------------------------------- +misc { + force_default_wallpaper = 1 # Set to 0 to enable the anime mascot + disable_hyprland_logo = true + disable_splash_rendering = true +} + +# ------------------------------------------------------------------------------------------------- +# 6. BINDS (Visual specific) +# ------------------------------------------------------------------------------------------------- +binds { + allow_pin_fullscreen = true +} + +# debug { +# overlay = true +# } +# ------------------------------------------------------------------------------------------------- +# 7. SMART GAPS (Single Window Override) +# Applied automatically when only 1 window is tiled or fullscreened on a workspace. +# ------------------------------------------------------------------------------------------------- +$single_window_gap = 10 +workspace = w[tv1], gapsout:$single_window_gap, gapsin:0 +workspace = f[1], gapsout:$single_window_gap, gapsin:0 diff --git a/.config/hypr/edit_here/source/appearance.lua b/.config/hypr/edit_here/source/appearance.lua new file mode 100644 index 00000000..b0da19cd --- /dev/null +++ b/.config/hypr/edit_here/source/appearance.lua @@ -0,0 +1,125 @@ +-- ============================================================================= +-- USER CONFIGURATION: appearance.lua +-- ============================================================================= +-- Add your custom appearance settings here. +-- These will override or add to the defaults found in +-- ~/.config/hypr/source/appearance.lua +-- This file can also be edited with: +-- dusky appearance (from the Rofi menu or Dusky Control Center) +-- ============================================================================= + +local home = os.getenv("HOME") + +-- THEME SOURCE: Load colors generated by Matugen +dofile(home .. "/.config/matugen/generated/hyprland-colors.lua") + +-- ------------------------------------------------------------------------------------------------- +-- 1. GENERAL APPEARANCE — override defaults +-- ------------------------------------------------------------------------------------------------- +hl.config({ + general = { + gaps_in = 6, + gaps_out = 12, + gaps_workspaces = 0, + border_size = 2, + + -- Colors from Matugen (globals set by hyprland-colors.lua above) + col = { + active_border = primary, + inactive_border = inverse_on_surface, + }, + + resize_on_border = false, + allow_tearing = true, + layout = "dwindle", + + snap = { + enabled = false, + window_gap = 10, + monitor_gap = 10, + border_overlap = false, + }, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 2. DECORATION +-- ------------------------------------------------------------------------------------------------- +hl.config({ + decoration = { + rounding = 6, + rounding_power = 6.0, + + active_opacity = 0.8, + inactive_opacity = 0.6, + fullscreen_opacity = 1.0, + + dim_inactive = true, + dim_strength = 0.2, + dim_special = 0.8, + + shadow = { + enabled = true, + range = 35, + render_power = 2, + sharp = false, + scale = 1.0, + color = "rgba(1a1a1aee)", + }, + + blur = { + enabled = true, + size = 4, + passes = 2, + new_optimizations = true, + ignore_opacity = true, + xray = true, + + noise = 0.0217, + contrast = 0.8916, + brightness = 0.8172, + vibrancy = 0.1696, + + popups = false, + }, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 3. ANIMATIONS — load the currently active preset +-- ------------------------------------------------------------------------------------------------- +dofile(home .. "/.config/hypr/source/animations/active/active.lua") + +-- ------------------------------------------------------------------------------------------------- +-- 4. LAYOUTS +-- ------------------------------------------------------------------------------------------------- +hl.config({ + dwindle = { preserve_split = true }, + master = { new_status = "master" }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 5. MISCELLANEOUS & PERFORMANCE +-- ------------------------------------------------------------------------------------------------- +hl.config({ + misc = { + force_default_wallpaper = 1, + disable_hyprland_logo = true, + disable_splash_rendering = true, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 6. BINDS (Visual specific) +-- ------------------------------------------------------------------------------------------------- +hl.config({ + binds = { allow_pin_fullscreen = true }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 7. SMART GAPS (Single Window Override) +-- Applied automatically when only 1 window is tiled or fullscreened on a workspace. +-- ------------------------------------------------------------------------------------------------- +local single_window_gap = 10 +hl.workspace_rule({ workspace = "w[tv1]", gaps_out = single_window_gap, gaps_in = 0 }) +hl.workspace_rule({ workspace = "f[1]", gaps_out = single_window_gap, gaps_in = 0 }) diff --git a/.config/hypr/edit_here/source/autostart.conf.deprecated b/.config/hypr/edit_here/source/autostart.conf.deprecated new file mode 100644 index 00000000..3cbcd0cd --- /dev/null +++ b/.config/hypr/edit_here/source/autostart.conf.deprecated @@ -0,0 +1,18 @@ +# ============================================================================== +# USER CONFIGURATION: autostart.conf +# ============================================================================== +# Add your custom settings for autostart here. +# These will override or add to the defaults found in ~/.config/hypr/source/autostart.conf +# ============================================================================== + +# Set pipewire buffer size to 128 +exec-once = pw-metadata -n settings 0 clock.force-quantum 128 + +# Autostart solaar +exec-once = solaar --window=hide + +# Create the headless output (it will be HEADLESS-2 based on your logs) +exec-once = hyprctl output create headless + +# Start Sunshine as a child process so it inherits the socket signature +exec-once = bash -c "sleep 2 && sunshine" diff --git a/.config/hypr/edit_here/source/autostart.lua b/.config/hypr/edit_here/source/autostart.lua new file mode 100644 index 00000000..2a93f037 --- /dev/null +++ b/.config/hypr/edit_here/source/autostart.lua @@ -0,0 +1,30 @@ +-- ============================================================================= +-- USER CONFIGURATION: autostart.lua +-- ============================================================================= +-- Add your custom autostart entries here. +-- These will override or add to the defaults found in +-- ~/.config/hypr/source/autostart.lua +-- ============================================================================= + +local home = os.getenv("HOME") + +-- Set pipewire buffer size to 128 (reduces audio latency) +hl.on("hyprland.start", function() + hl.exec_cmd("pw-metadata -n settings 0 clock.force-quantum 128") +end) + +-- Autostart solaar (Logitech peripheral manager) — hidden in tray +hl.on("hyprland.start", function() + hl.exec_cmd("solaar --window=hide") +end) + +-- Create a headless virtual output (used for Sunshine/Moonlight streaming) +-- It will appear as HEADLESS-2 based on your monitor config +hl.on("hyprland.start", function() + hl.exec_cmd("hyprctl output create headless") +end) + +-- Start Sunshine as a child process so it inherits the Hyprland socket signature +hl.on("hyprland.start", function() + hl.exec_cmd("bash -c 'sleep 2 && sunshine'") +end) diff --git a/.config/hypr/edit_here/source/default_apps.conf.deprecated b/.config/hypr/edit_here/source/default_apps.conf.deprecated new file mode 100644 index 00000000..2dd2d795 --- /dev/null +++ b/.config/hypr/edit_here/source/default_apps.conf.deprecated @@ -0,0 +1,13 @@ +# ============================================================================== +# USER CONFIGURATION: default_apps.conf +# ============================================================================== +# Override default applications here. +# These variables are sourced at the very top of hyprland.conf so they +# are available for use in all other configuration files. +# ============================================================================== + +$terminal = kitty +$fileManager = nemo +$menu = rofi -show drun +$browser = firefox +$textEditor = gnome-text-editor diff --git a/.config/hypr/edit_here/source/default_apps.lua b/.config/hypr/edit_here/source/default_apps.lua new file mode 100644 index 00000000..d2d3d136 --- /dev/null +++ b/.config/hypr/edit_here/source/default_apps.lua @@ -0,0 +1,13 @@ +-- ============================================================================= +-- USER CONFIGURATION: default_apps.lua +-- ============================================================================= +-- Override default applications here. +-- These globals are set before all other config files load, so they are +-- available everywhere. +-- ============================================================================= + +terminal = "kitty" +fileManager = "nemo" +menu = "rofi -show drun" +browser = "firefox" +textEditor = "gnome-text-editor" diff --git a/.config/hypr/edit_here/source/environment_variables.conf.deprecated b/.config/hypr/edit_here/source/environment_variables.conf.deprecated new file mode 100644 index 00000000..cd1830c4 --- /dev/null +++ b/.config/hypr/edit_here/source/environment_variables.conf.deprecated @@ -0,0 +1,8 @@ +# ============================================================================== +# USER CONFIGURATION: environment_variables.conf +# ============================================================================== +# Add your custom settings for environment_variables here. +# These will override or add to the defaults found in ~/.config/hypr/source/environment_variables.conf +# NOTE: it's strongly advised to place your environment variables in the uwsm files in ~/.config/uwsm/{env,env-hyprland} +# ============================================================================== + diff --git a/.config/hypr/edit_here/source/environment_variables.lua b/.config/hypr/edit_here/source/environment_variables.lua new file mode 100644 index 00000000..5d8abf52 --- /dev/null +++ b/.config/hypr/edit_here/source/environment_variables.lua @@ -0,0 +1,11 @@ +-- ============================================================================= +-- USER CONFIGURATION: environment_variables.lua +-- ============================================================================= +-- Add your custom environment variables here. +-- These will override or add to the defaults found in +-- ~/.config/hypr/source/environment_variables.lua +-- +-- NOTE: It is strongly advised to place environment variables in UWSM files: +-- ~/.config/uwsm/env (compositor-agnostic variables) +-- ~/.config/uwsm/env-hyprland (Hyprland-specific variables) +-- ============================================================================= diff --git a/.config/hypr/edit_here/source/input.conf.deprecated b/.config/hypr/edit_here/source/input.conf.deprecated new file mode 100644 index 00000000..17878540 --- /dev/null +++ b/.config/hypr/edit_here/source/input.conf.deprecated @@ -0,0 +1,156 @@ +# ============================================================================== +# USER CONFIGURATION: input.conf +# ============================================================================== +# Add your custom settings for input here. +# These will override or add to the defaults found in ~/.config/hypr/source/input.conf +# This file can also be edited with dusky input from the rofi menu or from dusky control center +# ============================================================================== +# ------------------------------------------------------------------------------------------------- +# 1. KEYBOARD & LANGUAGE +# ------------------------------------------------------------------------------------------------- +input { + kb_layout = us + + # TUI: Dropdown - Common options like "caps:escape", "grp:alt_shift_toggle" + # This is a high-value configuration for developers. + kb_options = + + resolve_binds_by_sym = false + numlock_by_default = true + + # TUI: Slider [10 - 100] + repeat_rate = 35 + + # TUI: Slider [100 - 1000] + repeat_delay = 250 +} + +# ------------------------------------------------------------------------------------------------- +# 2. MOUSE & POINTER ACCELERATION +# ------------------------------------------------------------------------------------------------- +input { + # 0: Cursor movement doesn't change focus + # 1: Cursor movement changes focus to window under cursor (Default) + # 2: Detached focus (Click to focus keyboard, mouse follows independently) + # 3: Completely separate focus + follow_mouse = 1 + + # TUI: Slider [-1.0 to 1.0] + sensitivity = -0.4 + + # TUI: Dropdown [flat, adaptive, custom] + # "Adaptive" is generally better for touchpads/desktop use. "Flat" for gaming. + accel_profile = flat + + # TUI: Toggle [true/false] - "Raw Input" for gamers. + # Bypasses most pointer settings. Critical for high-end mice. + force_no_accel = true + + # TUI: Toggle [true/false] + left_handed = false + + # TUI: Toggle [true/false] - Useful for preventing focus stealing + mouse_refocus = true +} + +# ------------------------------------------------------------------------------------------------- +# 3. SCROLLING & TRACKBALLS +# ------------------------------------------------------------------------------------------------- +input { + # TUI: Toggle [true/false] - "Natural Scrolling" (MacOS style) for mice + natural_scroll = false + + # TUI: Dropdown [2fg, edge, on_button_down, no_scroll] + # Vital for trackball users. + scroll_method = 2fg + + # Only relevant if scroll_method is on_button_down + scroll_button = 0 + scroll_button_lock = false +} + +# ------------------------------------------------------------------------------------------------- +# 4. TOUCHPAD +# ------------------------------------------------------------------------------------------------- +input { + touchpad { + # TUI: Toggle [true/false] + natural_scroll = true + + # TUI: Toggle [true/false] - "Disable while typing" + disable_while_typing = true + + # TUI: Toggle [true/false] - "Tap to click" + tap-to-click = true + + # TUI: Toggle [true/false] - "Mac-style Right Click" + # true = 2-finger click is right click usually. + # false = Physical click on bottom-right is right click. + clickfinger_behavior = false + + # TUI: Toggle [true/false] + drag_lock = false + } +} + +# ------------------------------------------------------------------------------------------------- +# 5. CURSOR BEHAVIOR & RENDERING +# ------------------------------------------------------------------------------------------------- +cursor { + # TUI: Toggle [true/false] - Sync XCursor theme with GSettings + sync_gsettings_theme = true + + # TUI: Dropdown [0, 1, 2] - CRITICAL for Nvidia/VMs + # 0 = Use HW cursors (Performance) + # 1 = Force SW cursors (Compatibility / Fixes disappearing cursor) + # 2 = Auto (Disable when tearing) + no_hardware_cursors = 2 + + # TUI: Dropdown [0, 1, 2] - Nvidia Specific optimization + # 0 = Off, 1 = On, 2 = Auto + use_cpu_buffer = 2 + + # TUI: Toggle [true/false] - Hides cursor when typing + # Great for "distraction free" coding. + hide_on_key_press = false + + # TUI: Slider [0 - 60] - Hide cursor after X seconds of inactivity (0=never) + inactive_timeout = 0 + + # TUI: Dropdown [0, 1, 2] - Workflow Preference + # 0 = Disabled (Cursor stays put) + # 1 = Enabled (Cursor moves to center of focused window) + # 2 = Force + warp_on_change_workspace = 0 + + # TUI: Dropdown [0, 1, 2] - Gaming / VRR Specific + # Prevents framerate spikes in VRR games by pausing cursor updates + # 0 = Off, 1 = On, 2 = Auto + no_break_fs_vrr = 2 + + # TUI: Slider [1.0 - 5.0] - Accessibility / Presentation + # Sets the zoom level for the magnifier. + zoom_factor = 1.0 +} + +# ------------------------------------------------------------------------------------------------- +# 6. GESTURE PHYSICS (Tuning) +# ------------------------------------------------------------------------------------------------- +# Note: The actual actions are in the dispatchers below. +# This block controls the "feel" of the swipes. +gestures { + # TUI: Slider [100 - 1000] - "Swipe Distance" + workspace_swipe_distance = 300 + + # TUI: Slider [0.0 - 1.0] - "Swipe Cancellation Threshold" + workspace_swipe_cancel_ratio = 0.5 + + # TUI: Toggle [true/false] - "Invert Swipe Direction" + workspace_swipe_invert = true + + # TUI: Toggle [true/false] - "Swipe to Create New Workspace" + workspace_swipe_create_new = true + + # TUI: Toggle [true/false] - "Swipe Forever" (Don't clamp at neighbors) + workspace_swipe_forever = false +} diff --git a/.config/hypr/edit_here/source/input.lua b/.config/hypr/edit_here/source/input.lua new file mode 100644 index 00000000..33c241ae --- /dev/null +++ b/.config/hypr/edit_here/source/input.lua @@ -0,0 +1,82 @@ +-- ============================================================================= +-- USER CONFIGURATION: input.lua +-- ============================================================================= +-- Add your custom input settings here. +-- These will override or add to the defaults found in +-- ~/.config/hypr/source/input.lua +-- This file can also be edited with: +-- dusky input (from the Rofi menu or Dusky Control Center) +-- ============================================================================= + +-- ------------------------------------------------------------------------------------------------- +-- 1. KEYBOARD & LANGUAGE +-- ------------------------------------------------------------------------------------------------- +hl.config({ + input = { + kb_layout = "us", + kb_options = "", -- e.g. "caps:escape", "grp:alt_shift_toggle" + + resolve_binds_by_sym = false, + numlock_by_default = true, + repeat_rate = 35, + repeat_delay = 250, + + -- ----------------------------------------------------------------- + -- 2. MOUSE & POINTER ACCELERATION + -- ----------------------------------------------------------------- + follow_mouse = 1, + sensitivity = -0.2, + accel_profile = "flat", + force_no_accel = true, + left_handed = false, + mouse_refocus = true, + + -- ----------------------------------------------------------------- + -- 3. SCROLLING & TRACKBALLS + -- ----------------------------------------------------------------- + natural_scroll = false, + scroll_method = "2fg", + scroll_button = 0, + scroll_button_lock = false, + + -- ----------------------------------------------------------------- + -- 4. TOUCHPAD + -- ----------------------------------------------------------------- + touchpad = { + natural_scroll = true, + disable_while_typing = true, + tap_to_click = true, + clickfinger_behavior = false, + drag_lock = false, + }, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 5. CURSOR BEHAVIOR & RENDERING +-- ------------------------------------------------------------------------------------------------- +hl.config({ + cursor = { + sync_gsettings_theme = true, + no_hardware_cursors = 2, + use_cpu_buffer = 2, + hide_on_key_press = false, + inactive_timeout = 0, + warp_on_change_workspace = 0, + no_break_fs_vrr = 2, + zoom_factor = 1.0, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 6. GESTURE PHYSICS (Tuning) +-- ------------------------------------------------------------------------------------------------- +hl.config({ + gestures = { + workspace_swipe_distance = 300, + workspace_swipe_cancel_ratio = 0.5, + workspace_swipe_invert = true, + workspace_swipe_create_new = true, + workspace_swipe_forever = false, + }, +}) diff --git a/.config/hypr/edit_here/source/keybinds.conf.deprecated b/.config/hypr/edit_here/source/keybinds.conf.deprecated new file mode 100644 index 00000000..9a76fae0 --- /dev/null +++ b/.config/hypr/edit_here/source/keybinds.conf.deprecated @@ -0,0 +1,39 @@ +# ============================================================================== +# USER CONFIGURATION: keybinds.conf +# ============================================================================== +# Add your custom settings for keybinds here. +# These will override or add to the defaults found in ~/.config/hypr/source/keybinds.conf +# This file can also be edited with dusky keybinds manager from the rofi menu or from dusky control center +# ============================================================================== + +# Auto-generated by FM Switcher +bindd = $mainMod, E, File Manager, exec, uwsm-app $fileManager + +# Auto-generated by Browser Switcher +bindd = $mainMod, W, Launch Browser, exec, uwsm-app -- $browser + +# Auto-generated by Text Editor Switcher +bindd = $mainMod, R, Open Text Editor, exec, uwsm-app $textEditor + +# Auto-generated by Terminal Switcher +bindd = $mainMod, Q, Launch Terminal, exec, uwsm-app -- $terminal + +# -- TERMINAL-CLIPBOARD-START -- +unbind = $mainMod, V +bindd = $mainMod, V, Clipboard History, exec, $scripts/clipboard/close_terminal_clipboard.sh uwsm-app -- kitty --class terminal_clipboard.sh -e "$scripts/clipboard/terminal_clipboard.sh" +# -- TERMINAL-CLIPBOARD-END -- + +# ========================================= +# GAMING MODE (Submap Passthrough) +# ========================================= +# Press Super + F12 to disable all Hyprland binds. +bind = $mainMod, F12, submap, clean + +# This starts the "clean" submap where no other binds exist +submap = clean + +# The ONLY keybind that works in this state is the one to exit it +bind = $mainMod, F12, submap, reset + +# This resets back to the global Hyprland binds +submap = reset diff --git a/.config/hypr/edit_here/source/keybinds.lua b/.config/hypr/edit_here/source/keybinds.lua new file mode 100644 index 00000000..ce760051 --- /dev/null +++ b/.config/hypr/edit_here/source/keybinds.lua @@ -0,0 +1,44 @@ +-- ============================================================================= +-- USER CONFIGURATION: keybinds.lua +-- ============================================================================= +-- Add your custom keybinds here. +-- These will override or add to the defaults found in +-- ~/.config/hypr/source/keybinds.lua +-- This file can also be edited with: +-- dusky keybinds manager (from the Rofi menu or Dusky Control Center) +-- ============================================================================= + +local mainMod = "SUPER" +local home = os.getenv("HOME") + +-- App variables come from edit_here/source/default_apps.lua (loaded first) + +-- Auto-generated by FM Switcher +hl.bind(mainMod .. " + E", hl.dsp.exec_cmd("uwsm-app " .. fileManager), { description = "File Manager" }) + +-- Auto-generated by Browser Switcher +hl.bind(mainMod .. " + W", hl.dsp.exec_cmd("uwsm-app -- " .. browser), { description = "Launch Browser" }) + +-- Auto-generated by Text Editor Switcher +hl.bind(mainMod .. " + R", hl.dsp.exec_cmd("uwsm-app " .. textEditor), { description = "Open Text Editor" }) + +-- Auto-generated by Terminal Switcher +hl.bind(mainMod .. " + Q", hl.dsp.exec_cmd("uwsm-app -- " .. terminal), { description = "Launch Terminal" }) + +-- Override the base clipboard bind: terminal-based clipboard manager +-- First remove the base bind (rofi clipboard), then set the terminal one: +hl.unbind(mainMod .. " + V") +hl.bind(mainMod .. " + V", + hl.dsp.exec_cmd(home .. "/user_scripts/clipboard/close_terminal_clipboard.sh uwsm-app -- kitty --class terminal_clipboard.sh -e " .. home .. "/user_scripts/clipboard/terminal_clipboard.sh"), + { description = "Clipboard History" }) + +-- ========================================= +-- GAMING MODE (Submap Passthrough) +-- ========================================= +-- Press Super + F12 to disable all Hyprland binds. +hl.bind(mainMod .. " + F12", hl.dsp.submap("clean")) + +hl.define_submap("clean", function() + -- The ONLY keybind that works in this state is the one to exit it + hl.bind(mainMod .. " + F12", hl.dsp.submap("reset")) +end) diff --git a/.config/hypr/edit_here/source/monitors.conf.deprecated b/.config/hypr/edit_here/source/monitors.conf.deprecated new file mode 100644 index 00000000..dbda65d8 --- /dev/null +++ b/.config/hypr/edit_here/source/monitors.conf.deprecated @@ -0,0 +1,11 @@ +# Generated by Dusky Monitor Wizard on 20260321_114029 + +# Global Settings +debug { + vfr = true +} + +# Monitor Rules +monitor = DP-1, 1920x1080@144.00, 0x0, 1 + +monitor = HEADLESS-2, disable diff --git a/.config/hypr/edit_here/source/monitors.lua b/.config/hypr/edit_here/source/monitors.lua new file mode 100644 index 00000000..76d368fc --- /dev/null +++ b/.config/hypr/edit_here/source/monitors.lua @@ -0,0 +1,7 @@ + +-- Global Settings +hl.config({ debug = { vfr = true } }) + +-- Monitor Rules +hl.monitor({ output = "DP-1", mode = "1920x1080@144.00", position = "0x0", scale = 1.00, bitdepth = 10 }) +hl.monitor({ output = "HEADLESS-2", disabled = true }) diff --git a/.config/hypr/edit_here/source/plugins.conf.deprecated b/.config/hypr/edit_here/source/plugins.conf.deprecated new file mode 100644 index 00000000..8d4b2e89 --- /dev/null +++ b/.config/hypr/edit_here/source/plugins.conf.deprecated @@ -0,0 +1,7 @@ +# ============================================================================== +# USER CONFIGURATION: plugins.conf +# ============================================================================== +# Add your custom settings for plugins here. +# These will override or add to the defaults found in ~/.config/hypr/source/plugins.conf +# ============================================================================== + diff --git a/.config/hypr/edit_here/source/plugins.lua b/.config/hypr/edit_here/source/plugins.lua new file mode 100644 index 00000000..31fab932 --- /dev/null +++ b/.config/hypr/edit_here/source/plugins.lua @@ -0,0 +1,7 @@ +-- ============================================================================= +-- USER CONFIGURATION: plugins.lua +-- ============================================================================= +-- Add your custom plugin settings here. +-- These will override or add to the defaults found in +-- ~/.config/hypr/source/plugins.lua +-- ============================================================================= diff --git a/.config/hypr/edit_here/source/window_rules.conf.deprecated b/.config/hypr/edit_here/source/window_rules.conf.deprecated new file mode 100644 index 00000000..bdb3588f --- /dev/null +++ b/.config/hypr/edit_here/source/window_rules.conf.deprecated @@ -0,0 +1,10 @@ +# ============================================================================== +# USER CONFIGURATION: window_rules.conf +# ============================================================================== +# Add your custom settings for window_rules here. +# These will override or add to the defaults found in ~/.config/hypr/source/window_rules.conf +# ============================================================================== + +# force emulators to bypass tiling and hit fullscreen immediately +windowrule = match:class ^(com.libretro.RetroArch)$, fullscreen on, idle_inhibit always +windowrule = match:class ^(info.cemu.Cemu)$, fullscreen on, idle_inhibit always diff --git a/.config/hypr/edit_here/source/window_rules.lua b/.config/hypr/edit_here/source/window_rules.lua new file mode 100644 index 00000000..06a6ad33 --- /dev/null +++ b/.config/hypr/edit_here/source/window_rules.lua @@ -0,0 +1,25 @@ +-- ============================================================================= +-- USER CONFIGURATION: window_rules.lua +-- ============================================================================= +-- Add your custom window rules here. +-- These will override or add to the defaults found in +-- ~/.config/hypr/source/window_rules.lua +-- ============================================================================= + +hl.config({ + layerrule = { + -- Disable selection-tool animation during area screenshots + "noanim, ^selection$" + }, + + windowrulev2 = { + -- Force emulators to bypass tiling and hit fullscreen immediately + "fullscreen, class:^(com.libretro.RetroArch)$", + "fullscreen, class:^(info.cemu.Cemu)$", + + -- If that truncated 'i>' was 'idleinhibit focus', you just add + -- another string for the same class like this: + "idleinhibit focus, class:^(com.libretro.RetroArch)$", + "idleinhibit focus, class:^(info.cemu.Cemu)$" + } +}) diff --git a/.config/hypr/edit_here/source/workspace_rules.conf.deprecated b/.config/hypr/edit_here/source/workspace_rules.conf.deprecated new file mode 100644 index 00000000..3f0cbbc1 --- /dev/null +++ b/.config/hypr/edit_here/source/workspace_rules.conf.deprecated @@ -0,0 +1,82 @@ +# ============================================================================== +# USER CONFIGURATION: workspace_rules.conf +# ============================================================================== +# Add your custom rules for workspace here. +# These will override or add to the defaults found in : +# ~/.config/hypr/source/workspace_rules.conf +# +# This file can also be edited with dusky workspace manager tui, +# which can be found in dusky control center +# ============================================================================== +# USER CONFIGURATION: workspace_rules.conf +# Managed by Dusky TUI - Granular Matrix v4.4.1 +# ============================================================================== + +# --- Global Rules --- +$global_layout = dwindle +workspace = r[11-99], layout:$global_layout + +# --- Ephemeral Global Override (Resets on reboot) --- +$ephemeral_layout = monocle +$ephemeral_enabled = false + +# --- Individual Workspaces (1-10) --- +$ws1_layout = dwindle +$ws1_persistent = false +$ws1_master_orient = left +$ws1_scroll_dir = right +workspace = 1, layout:$ws1_layout, persistent:$ws1_persistent, layoutopt:orientation:$ws1_master_orient, layoutopt:direction:$ws1_scroll_dir + +$ws2_layout = dwindle +$ws2_persistent = false +$ws2_master_orient = left +$ws2_scroll_dir = right +workspace = 2, layout:$ws2_layout, persistent:$ws2_persistent, layoutopt:orientation:$ws2_master_orient, layoutopt:direction:$ws2_scroll_dir + +$ws3_layout = dwindle +$ws3_persistent = false +$ws3_master_orient = left +$ws3_scroll_dir = right +workspace = 3, layout:$ws3_layout, persistent:$ws3_persistent, layoutopt:orientation:$ws3_master_orient, layoutopt:direction:$ws3_scroll_dir + +$ws4_layout = dwindle +$ws4_persistent = false +$ws4_master_orient = left +$ws4_scroll_dir = right +workspace = 4, layout:$ws4_layout, persistent:$ws4_persistent, layoutopt:orientation:$ws4_master_orient, layoutopt:direction:$ws4_scroll_dir + +$ws5_layout = dwindle +$ws5_persistent = false +$ws5_master_orient = left +$ws5_scroll_dir = right +workspace = 5, layout:$ws5_layout, persistent:$ws5_persistent, layoutopt:orientation:$ws5_master_orient, layoutopt:direction:$ws5_scroll_dir + +$ws6_layout = dwindle +$ws6_persistent = false +$ws6_master_orient = left +$ws6_scroll_dir = right +workspace = 6, layout:$ws6_layout, persistent:$ws6_persistent, layoutopt:orientation:$ws6_master_orient, layoutopt:direction:$ws6_scroll_dir + +$ws7_layout = dwindle +$ws7_persistent = false +$ws7_master_orient = left +$ws7_scroll_dir = right +workspace = 7, layout:$ws7_layout, persistent:$ws7_persistent, layoutopt:orientation:$ws7_master_orient, layoutopt:direction:$ws7_scroll_dir + +$ws8_layout = dwindle +$ws8_persistent = false +$ws8_master_orient = left +$ws8_scroll_dir = right +workspace = 8, layout:$ws8_layout, persistent:$ws8_persistent, layoutopt:orientation:$ws8_master_orient, layoutopt:direction:$ws8_scroll_dir + +$ws9_layout = dwindle +$ws9_persistent = false +$ws9_master_orient = left +$ws9_scroll_dir = right +workspace = 9, layout:$ws9_layout, persistent:$ws9_persistent, layoutopt:orientation:$ws9_master_orient, layoutopt:direction:$ws9_scroll_dir + +$ws10_layout = dwindle +$ws10_persistent = false +$ws10_master_orient = left +$ws10_scroll_dir = right +workspace = 10, layout:$ws10_layout, persistent:$ws10_persistent, layoutopt:orientation:$ws10_master_orient, layoutopt:direction:$ws10_scroll_dir diff --git a/.config/hypr/edit_here/source/workspace_rules.lua b/.config/hypr/edit_here/source/workspace_rules.lua new file mode 100644 index 00000000..a07b3b58 --- /dev/null +++ b/.config/hypr/edit_here/source/workspace_rules.lua @@ -0,0 +1,40 @@ +-- ============================================================================= +-- USER CONFIGURATION: workspace_rules.lua +-- ============================================================================= +-- Add your custom workspace rules here. +-- These will override or add to the defaults found in: +-- ~/.config/hypr/source/workspace_rules.lua +-- +-- Managed by Dusky TUI - Granular Matrix v4.4.1 +-- ============================================================================= + +-- --- Global Rules --- +local global_layout = "dwindle" +hl.workspace_rule({ workspace = "r[11-99]", layout = global_layout }) + +-- --- Ephemeral Global Override (Resets on reboot) --- +-- local ephemeral_layout = "monocle" +-- local ephemeral_enabled = false + +-- --- Individual Workspaces (1-10) --- +local ws = { + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, + { layout = "dwindle", persistent = false, master_orient = "left", scroll_dir = "right" }, +} + +for i, w in ipairs(ws) do + hl.workspace_rule({ + workspace = tostring(i), + layout = w.layout, + persistent = w.persistent, + layout_opts = { orientation = w.master_orient, direction = w.scroll_dir }, + }) +end diff --git a/.config/hypr/hyprland.conf b/.config/hypr/hyprland.conf deleted file mode 100644 index cc9fa24a..00000000 --- a/.config/hypr/hyprland.conf +++ /dev/null @@ -1,78 +0,0 @@ -source = ~/.config/hypr/edit_here/source/default_apps.conf - - - - - -# DO NOT EDIT THIS FILE, if you want to configure something, edit the file -# at this location. ~/.config/hypr/edit_here/ - - - - - -# ----------------------------------------------------- -# HYPRLAND MAIN CONFIGURATION -# ----------------------------------------------------- -# User: [dusky] -# System: UWSM Managed -# ----------------------------------------------------- - -# 1. MONITORS -# Must be first. Everything (workspaces, scaling, bar positioning) -# depends on the physical layout being established. -source = ~/.config/hypr/source/monitors.conf - -# 2. PROGRAMS & ENVIRONMENT -# (Note: Most ENV vars are handled by `~/.config/uwsm/env` files) -# If you have Hyprland-specific vars that UWSM shouldn't see, put them here. -# This is also a good place to define $terminal, $fileManager, etc. -# I am assuming 'permissions.conf' contains Polkit agents or specific envs. -source = ~/.config/hypr/source/permissions.conf - -# 3. PLUGINS -# Plugins must be loaded before "Appearance" or "Keybinds" if those files -# reference plugin-specific variables or dispatchers. -# source = ~/.config/hypr/source/plugins.conf - -# 4. INPUT DEVICES -# Keyboard layouts, mouse sensitivity, and touchpad gestures. -# Loaded early so keybinds can map correctly to devices if needed. -source = ~/.config/hypr/source/input.conf - - -# 5. APPEARANCE -# General settings, decorations (rounding, blur), animations, and colors. -source = ~/.config/hypr/source/appearance.conf - -# 6. WINDOW RULES & WORKSPACES -# Defines how windows behave (floating, tiling, opacity) before they are opened. -source = ~/.config/hypr/source/window_rules.conf - -# 7. KEYBINDINGS -# Binds actions to keys. Loaded after everything else so all dispatchers -# (plugin or standard) and rules are available. -source = ~/.config/hypr/source/keybinds.conf - -# 8. AUTOSTART -# Since you use UWSM, ensure this file uses `exec-once = uwsm-app -- ...` -# We load this LATE so that when apps launch, the monitors, inputs, -# and window rules are already fully applied. -source = ~/.config/hypr/source/autostart.conf - -# 9. Environment Variables. -source = ~/.config/hypr/source/environment_variables.conf - -# 10. Workspace Rules -source = ~/.config/hypr/source/workspace_rules.conf - -# ----------------------------------------------------- -# LOCAL OVERRIDES (GIT IGNORED) -# ----------------------------------------------------- -# This file is for machine-specific settings (e.g., a specific monitor -# setup for work vs home) or testing changes without committing them. -# It is loaded LAST to overwrite any setting above. - - -# Source User Custom Config Overlay -source = ~/.config/hypr/edit_here/hyprland.conf diff --git a/.config/hypr/hyprland.lua b/.config/hypr/hyprland.lua new file mode 100644 index 00000000..619d0167 --- /dev/null +++ b/.config/hypr/hyprland.lua @@ -0,0 +1,53 @@ +local home = os.getenv("HOME") +local hypr = home .. "/.config/hypr" +local src = hypr .. "/source" + +-- ============================================================================= +-- HYPRLAND MAIN CONFIGURATION — Lua entry point +-- ============================================================================= +-- User: [dusky] +-- System: UWSM Managed +-- +-- DO NOT EDIT THIS FILE. Configure in: ~/.config/hypr/edit_here/ +-- ============================================================================= + +-- Default apps — sourced first so $terminal / $browser etc. are available +-- to every subsequent file. +dofile(hypr .. "/edit_here/source/default_apps.lua") + +-- 1. MONITORS — must be first; everything (workspaces, scaling, bars) +-- depends on the physical layout being established. +dofile(src .. "/monitors.lua") + +-- 2. PERMISSIONS / ECOSYSTEM +dofile(src .. "/permissions.lua") + +-- 3. PLUGINS (uncomment if you use hyprpm-managed plugins) +-- dofile(src .. "/plugins.lua") + +-- 4. INPUT DEVICES — keyboard, mouse, touchpad, gestures +dofile(src .. "/input.lua") + +-- 5. APPEARANCE — gaps, borders, decorations, animations, colors +dofile(src .. "/appearance.lua") + +-- 6. WINDOW RULES & LAYER RULES +dofile(src .. "/window_rules.lua") + +-- 7. KEYBINDINGS — loaded after rules so all dispatchers are available +dofile(src .. "/keybinds.lua") + +-- 8. AUTOSTART — uses uwsm-app wrappers; loaded late so monitor/input/rules +-- are already applied when apps launch. +dofile(src .. "/autostart.lua") + +-- 9. ENVIRONMENT VARIABLES +dofile(src .. "/environment_variables.lua") + +-- 10. WORKSPACE RULES +dofile(src .. "/workspace_rules.lua") + +-- ============================================================================= +-- USER OVERRIDES — loaded last to take priority over everything above +-- ============================================================================= +dofile(hypr .. "/edit_here/hyprland.lua") diff --git a/.config/hypr/source/animations/active/active.conf.deprecated b/.config/hypr/source/animations/active/active.conf.deprecated new file mode 100644 index 00000000..0d78374f --- /dev/null +++ b/.config/hypr/source/animations/active/active.conf.deprecated @@ -0,0 +1,42 @@ +# ----------------------------------------------------- +# FLUID Dusky: The "Showcase" Edition +# ----------------------------------------------------- +# Tuned daily driving: Slower, cinematic, and +# perfectly fluid. +# ----------------------------------------------------- + +animations { + enabled = true + + # Goes past the target (1.1) and snaps back. + # Used for: Windows opening, Rofi, Workspaces. + bezier = overshot, 0.05, 0.9, 0.1, 1.1 + # Standard ease-out. No bounce, just a clean stop. + # Used for: Fading opacity. + bezier = fluid, 0.25, 1, 0, 1 + # A slightly tighter curve than fluid, good for closing things. + # Used for: Windows closing. + bezier = snap, 0.5, 0.9, 0.1, 1.05 + # Starts fast, decelerates very slowly. + # Used for: Sliding menus and closing layers. + bezier = menu_decel, 0.1, 1, 0, 1 + # Constant speed, no acceleration. + # Used for: Border color cycling. + bezier = liner, 1, 1, 1, 1 + + # -- Window Animations -- + animation = windowsIn, 1, 7, overshot, popin 80% + animation = windowsOut, 1, 5, snap, popin 80% + animation = windowsMove, 1, 7, overshot, slide + animation = border, 1, 2, liner + animation = borderangle, 1, 40, liner, once + animation = fade, 1, 5, fluid + animation = layersIn, 1, 6, overshot, popin 70% + # Layers Close (specifidcally a fix for screenshots) + animation = layersOut, 0, 0, menu_decel, slide + animation = fadeLayersIn, 1, 5, menu_decel + animation = fadeLayersOut, 1, 4, menu_decel + animation = workspaces, 1, 8, overshot, slide + animation = specialWorkspace, 1, 8, overshot, slidevert + +} diff --git a/.config/hypr/source/animations/active/active.lua b/.config/hypr/source/animations/active/active.lua new file mode 100644 index 00000000..9b374f16 --- /dev/null +++ b/.config/hypr/source/animations/active/active.lua @@ -0,0 +1,23 @@ +-- ----------------------------------------------------- +-- FAST PRESET: High Performance / Low Latency (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) +hl.curve("md3_decel", { type = "bezier", points = { {0.05, 0.7}, {0.1, 1} } }) +hl.curve("instant", { type = "bezier", points = { {0, 1}, {0, 1} } }) + +-- Windows: Instant snap with barely visible deceleration (~30ms) +hl.animation({ leaf = "windows", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsIn", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +-- Border: Instant feedback +hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "linear" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "md3_decel" }) +-- Layers: Snappy but not jarring +hl.animation({ leaf = "layers", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +-- Workspaces: Fast horizontal slide (~200ms) +hl.animation({ leaf = "workspaces", enabled = true, speed = 2.5, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 2.5, bezier = "md3_decel", style = "slidevert" }) diff --git a/.config/hypr/source/animations/disable.conf.deprecated b/.config/hypr/source/animations/disable.conf.deprecated new file mode 100644 index 00000000..23143da4 --- /dev/null +++ b/.config/hypr/source/animations/disable.conf.deprecated @@ -0,0 +1,8 @@ + +# // ▄▀█ █▄░█ █ █▀▄▀█ ▄▀█ ▀█▀ █ █▀█ █▄░█ +# // █▀█ █░▀█ █ █░▀░█ █▀█ ░█░ █ █▄█ █░▀█ + +# See https://wiki.hyprland.org/Configuring/Animations/ + +animations:enabled=false + diff --git a/.config/hypr/source/animations/disable.lua b/.config/hypr/source/animations/disable.lua new file mode 100644 index 00000000..d08163c6 --- /dev/null +++ b/.config/hypr/source/animations/disable.lua @@ -0,0 +1,4 @@ +-- ANIMATION DISABLED PRESET +-- See https://wiki.hypr.land/Configuring/Animations/ + +hl.config({ animations = { enabled = false } }) diff --git a/.config/hypr/source/animations/fade.conf.deprecated b/.config/hypr/source/animations/fade.conf.deprecated new file mode 100644 index 00000000..0e9c33a2 --- /dev/null +++ b/.config/hypr/source/animations/fade.conf.deprecated @@ -0,0 +1,43 @@ +# ----------------------------------------------------- +# FADE PRESET: Pure Opacity / Ethereal +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Curves for Fading --- + bezier = sine, 0.5, 0.5, 0.5, 0.5 + bezier = sharpFade, 0.33, 1, 0.68, 1 + bezier = linear, 0, 0, 1, 1 + + # --- Animation Configs --- + + # Windows: THE FIX + # Windows don't have a 'fade' style. + # We set them to 'popin 100%' (no scaling) and make them fast (but not instant, + # or the fade might be skipped). + # The actual visual "fade" is handled by the 'animation = fade' line below. + animation = windows, 1, 3, sharpFade, popin 100% + animation = windowsIn, 1, 3, sharpFade, popin 100% + animation = windowsOut, 1, 3, sharpFade, popin 100% + + # Windows Move: Needs to slide to feel natural + animation = windowsMove, 1, 4, sine, slide + + # Border: Pulse effect + animation = border, 1, 5, sine + animation = fade, 1, 5, sine + + # Layers (Waybar, etc.): Dissolve in + # 'fade' IS valid for layers + animation = layers, 1, 4, sharpFade, fade + animation = layersIn, 1, 4, sharpFade, fade + animation = layersOut, 1, 2, sharpFade, fade + animation = fadeLayersIn, 1, 3, sharpFade + animation = fadeLayersOut, 1, 2, sharpFade + + # Workspaces: Cross-Dissolve + # 'fade' IS valid for workspaces + animation = workspaces, 1, 6, sine, fade + animation = specialWorkspace, 1, 6, sine, fade +} diff --git a/.config/hypr/source/animations/fade.lua b/.config/hypr/source/animations/fade.lua new file mode 100644 index 00000000..7dee8df9 --- /dev/null +++ b/.config/hypr/source/animations/fade.lua @@ -0,0 +1,28 @@ +-- ----------------------------------------------------- +-- FADE PRESET: Pure Opacity / Ethereal +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +hl.curve("sine", { type = "bezier", points = { {0.5, 0.5}, {0.5, 0.5} } }) +hl.curve("sharpFade", { type = "bezier", points = { {0.33, 1}, {0.68, 1} } }) +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) + +-- Windows: popin 100% (no scaling) so the actual visual fade comes from 'fade' +hl.animation({ leaf = "windows", enabled = true, speed = 3, bezier = "sharpFade", style = "popin 100%" }) +hl.animation({ leaf = "windowsIn", enabled = true, speed = 3, bezier = "sharpFade", style = "popin 100%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 3, bezier = "sharpFade", style = "popin 100%" }) +-- Windows Move: Needs to slide to feel natural +hl.animation({ leaf = "windowsMove", enabled = true, speed = 4, bezier = "sine", style = "slide" }) +-- Border: Pulse effect +hl.animation({ leaf = "border", enabled = true, speed = 5, bezier = "sine" }) +hl.animation({ leaf = "fade", enabled = true, speed = 5, bezier = "sine" }) +-- Layers: Dissolve in +hl.animation({ leaf = "layers", enabled = true, speed = 4, bezier = "sharpFade", style = "fade" }) +hl.animation({ leaf = "layersIn", enabled = true, speed = 4, bezier = "sharpFade", style = "fade" }) +hl.animation({ leaf = "layersOut", enabled = true, speed = 2, bezier = "sharpFade", style = "fade" }) +hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 3, bezier = "sharpFade" }) +hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 2, bezier = "sharpFade" }) +-- Workspaces: Cross-Dissolve +hl.animation({ leaf = "workspaces", enabled = true, speed = 6, bezier = "sine", style = "fade" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 6, bezier = "sine", style = "fade" }) diff --git a/.config/hypr/source/animations/horizontal_bounce.conf.deprecated b/.config/hypr/source/animations/horizontal_bounce.conf.deprecated new file mode 100644 index 00000000..7913f496 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_bounce.conf.deprecated @@ -0,0 +1,31 @@ +# ----------------------------------------------------- +# POP PRESET: Bouncy, Gelatinous, Fun +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Bouncy Curves --- + # High bounce (1.6 = 60% overshoot). Very exaggerated. + bezier = jelly, 0.1, 0.9, 0.1, 1.3 + bezier = bounce, 0.1, 1.5, 0.2, 1.1 + + # --- Animation Configs --- + + # Windows: They pop in from the center like bubbles + animation = windowsIn, 1, 6, jelly, popin 60% + animation = windowsOut, 1, 4, bounce, popin 60% + animation = windowsMove, 1, 6, jelly, slide + + # Border + animation = border, 1, 10, jelly + animation = fade, 1, 5, jelly + + # Layers + animation = layers, 1, 6, jelly, popin 10% + + # Workspaces: Trampoline effect + animation = workspaces, 1, 7, jelly, slide + animation = specialWorkspace, 1, 7, jelly, slidevert + +} diff --git a/.config/hypr/source/animations/horizontal_bounce.lua b/.config/hypr/source/animations/horizontal_bounce.lua new file mode 100644 index 00000000..e4000553 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_bounce.lua @@ -0,0 +1,22 @@ +-- ----------------------------------------------------- +-- POP PRESET: Bouncy, Gelatinous, Fun (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- High bounce (1.3 = 30% overshoot). Very exaggerated. +hl.curve("jelly", { type = "bezier", points = { {0.1, 0.9}, {0.1, 1.3} } }) +hl.curve("bounce", { type = "bezier", points = { {0.1, 1.5}, {0.2, 1.1} } }) + +-- Windows: Pop in from the center like bubbles +hl.animation({ leaf = "windowsIn", enabled = true, speed = 6, bezier = "jelly", style = "popin 60%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 4, bezier = "bounce", style = "popin 60%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 6, bezier = "jelly", style = "slide" }) +-- Border +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "jelly" }) +hl.animation({ leaf = "fade", enabled = true, speed = 5, bezier = "jelly" }) +-- Layers +hl.animation({ leaf = "layers", enabled = true, speed = 6, bezier = "jelly", style = "popin 10%" }) +-- Workspaces: Trampoline effect (horizontal) +hl.animation({ leaf = "workspaces", enabled = true, speed = 7, bezier = "jelly", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 7, bezier = "jelly", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_dusky.conf.deprecated b/.config/hypr/source/animations/horizontal_dusky.conf.deprecated new file mode 100644 index 00000000..0d78374f --- /dev/null +++ b/.config/hypr/source/animations/horizontal_dusky.conf.deprecated @@ -0,0 +1,42 @@ +# ----------------------------------------------------- +# FLUID Dusky: The "Showcase" Edition +# ----------------------------------------------------- +# Tuned daily driving: Slower, cinematic, and +# perfectly fluid. +# ----------------------------------------------------- + +animations { + enabled = true + + # Goes past the target (1.1) and snaps back. + # Used for: Windows opening, Rofi, Workspaces. + bezier = overshot, 0.05, 0.9, 0.1, 1.1 + # Standard ease-out. No bounce, just a clean stop. + # Used for: Fading opacity. + bezier = fluid, 0.25, 1, 0, 1 + # A slightly tighter curve than fluid, good for closing things. + # Used for: Windows closing. + bezier = snap, 0.5, 0.9, 0.1, 1.05 + # Starts fast, decelerates very slowly. + # Used for: Sliding menus and closing layers. + bezier = menu_decel, 0.1, 1, 0, 1 + # Constant speed, no acceleration. + # Used for: Border color cycling. + bezier = liner, 1, 1, 1, 1 + + # -- Window Animations -- + animation = windowsIn, 1, 7, overshot, popin 80% + animation = windowsOut, 1, 5, snap, popin 80% + animation = windowsMove, 1, 7, overshot, slide + animation = border, 1, 2, liner + animation = borderangle, 1, 40, liner, once + animation = fade, 1, 5, fluid + animation = layersIn, 1, 6, overshot, popin 70% + # Layers Close (specifidcally a fix for screenshots) + animation = layersOut, 0, 0, menu_decel, slide + animation = fadeLayersIn, 1, 5, menu_decel + animation = fadeLayersOut, 1, 4, menu_decel + animation = workspaces, 1, 8, overshot, slide + animation = specialWorkspace, 1, 8, overshot, slidevert + +} diff --git a/.config/hypr/source/animations/horizontal_dusky.lua b/.config/hypr/source/animations/horizontal_dusky.lua new file mode 100644 index 00000000..e6448c67 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_dusky.lua @@ -0,0 +1,32 @@ +-- ----------------------------------------------------- +-- FLUID Dusky: The "Showcase" Edition (Horizontal) +-- ----------------------------------------------------- +-- Tuned daily driving: Slower, cinematic, and +-- perfectly fluid. +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Goes past the target (1.1) and snaps back. +hl.curve("overshot", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.1} } }) +-- Standard ease-out. No bounce, just a clean stop. +hl.curve("fluid", { type = "bezier", points = { {0.25, 1}, {0, 1} } }) +-- A slightly tighter curve than fluid, good for closing things. +hl.curve("snap", { type = "bezier", points = { {0.5, 0.9}, {0.1, 1.05} } }) +-- Starts fast, decelerates very slowly. +hl.curve("menu_decel", { type = "bezier", points = { {0.1, 1}, {0, 1} } }) +-- Constant speed, no acceleration. +hl.curve("liner", { type = "bezier", points = { {1, 1}, {1, 1} } }) + +hl.animation({ leaf = "windowsIn", enabled = true, speed = 7, bezier = "overshot", style = "popin 80%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 5, bezier = "snap", style = "popin 80%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 7, bezier = "overshot", style = "slide" }) +hl.animation({ leaf = "border", enabled = true, speed = 2, bezier = "liner" }) +hl.animation({ leaf = "borderangle", enabled = true, speed = 40, bezier = "liner", style = "once" }) +hl.animation({ leaf = "fade", enabled = true, speed = 5, bezier = "fluid" }) +hl.animation({ leaf = "layersIn", enabled = true, speed = 6, bezier = "overshot", style = "popin 70%" }) +hl.animation({ leaf = "layersOut", enabled = false, speed = 0 }) +hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 5, bezier = "menu_decel" }) +hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 4, bezier = "menu_decel" }) +hl.animation({ leaf = "workspaces", enabled = true, speed = 8, bezier = "overshot", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 8, bezier = "overshot", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_exagurated.conf.deprecated b/.config/hypr/source/animations/horizontal_exagurated.conf.deprecated new file mode 100644 index 00000000..7c3d56b7 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_exagurated.conf.deprecated @@ -0,0 +1,31 @@ +# ----------------------------------------------------- +# GELATIN PRESET: Maximum Wobble +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Boing" Curve --- + # 1.7 overshoot is absolutely ridiculous. + bezier = boing, 0.4, 0.8, 0.2, 1.7 + # A curve that dips below zero for "anticipation" + bezier = slingshot, 0.4, -0.4, 0, 1.2 + + # --- Animation Configs --- + + # Windows: They pull back (slingshot) then fly in and wobble (boing) + animation = windowsIn, 1, 8, boing, popin 10% + animation = windowsOut, 1, 8, boing, popin 80% + animation = windowsMove, 1, 8, boing, slide + + # Border: Even the borders pulse + animation = border, 1, 10, boing + animation = fade, 1, 5, boing + + # Layers: Your Waybar will look like it's made of rubber + animation = layers, 1, 10, boing, slide + + # Workspaces: The entire screen is a trampoline + animation = workspaces, 1, 10, boing, slide + animation = specialWorkspace, 1, 10, boing, slidevert +} diff --git a/.config/hypr/source/animations/horizontal_exagurated.lua b/.config/hypr/source/animations/horizontal_exagurated.lua new file mode 100644 index 00000000..bae8615e --- /dev/null +++ b/.config/hypr/source/animations/horizontal_exagurated.lua @@ -0,0 +1,23 @@ +-- ----------------------------------------------------- +-- GELATIN PRESET: Maximum Wobble (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- 1.7 overshoot is absolutely ridiculous. +hl.curve("boing", { type = "bezier", points = { {0.4, 0.8}, {0.2, 1.7} } }) +-- A curve that dips below zero for "anticipation" +hl.curve("slingshot", { type = "bezier", points = { {0.4, -0.4}, {0, 1.2} } }) + +-- Windows: Pull back (slingshot) then fly in and wobble (boing) +hl.animation({ leaf = "windowsIn", enabled = true, speed = 8, bezier = "boing", style = "popin 10%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 8, bezier = "boing", style = "popin 80%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 8, bezier = "boing", style = "slide" }) +-- Border: Even the borders pulse +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "boing" }) +hl.animation({ leaf = "fade", enabled = true, speed = 5, bezier = "boing" }) +-- Layers: Rubber Waybar +hl.animation({ leaf = "layers", enabled = true, speed = 10, bezier = "boing", style = "slide" }) +-- Workspaces: The entire screen is a trampoline (horizontal) +hl.animation({ leaf = "workspaces", enabled = true, speed = 10, bezier = "boing", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 10, bezier = "boing", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_fast.conf.deprecated b/.config/hypr/source/animations/horizontal_fast.conf.deprecated new file mode 100644 index 00000000..5715a3a4 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_fast.conf.deprecated @@ -0,0 +1,34 @@ +# ----------------------------------------------------- +# FAST PRESET: High Performance / Low Latency +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Linear / Sharp Curves --- + bezier = linear, 0, 0, 1, 1 + bezier = md3_decel, 0.05, 0.7, 0.1, 1 + bezier = instant, 0, 1, 0, 1 + + # --- Animation Configs --- + + # Windows: Instant snap with barely visible deceleration + # Duration 2 = ~30ms. Blink and you miss it. + animation = windows, 1, 2, md3_decel, slide + animation = windowsIn, 1, 2, md3_decel, slide + animation = windowsOut, 1, 2, md3_decel, slide + animation = windowsMove, 1, 2, md3_decel, slide + + # Border: Instant feedback + animation = border, 1, 1, linear + animation = fade, 1, 2, md3_decel + + # Layers: Snappy but not jarring + animation = layers, 1, 2, md3_decel, slide + + # Workspaces: Fast vertical slide (200ms) + # Enough context to see the movement, fast enough not to wait. + animation = workspaces, 1, 2.5, md3_decel, slide + animation = specialWorkspace, 1, 2.5, md3_decel, slidevert + +} diff --git a/.config/hypr/source/animations/horizontal_fast.lua b/.config/hypr/source/animations/horizontal_fast.lua new file mode 100644 index 00000000..9b374f16 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_fast.lua @@ -0,0 +1,23 @@ +-- ----------------------------------------------------- +-- FAST PRESET: High Performance / Low Latency (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) +hl.curve("md3_decel", { type = "bezier", points = { {0.05, 0.7}, {0.1, 1} } }) +hl.curve("instant", { type = "bezier", points = { {0, 1}, {0, 1} } }) + +-- Windows: Instant snap with barely visible deceleration (~30ms) +hl.animation({ leaf = "windows", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsIn", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +-- Border: Instant feedback +hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "linear" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "md3_decel" }) +-- Layers: Snappy but not jarring +hl.animation({ leaf = "layers", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +-- Workspaces: Fast horizontal slide (~200ms) +hl.animation({ leaf = "workspaces", enabled = true, speed = 2.5, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 2.5, bezier = "md3_decel", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_hallucination.conf.deprecated b/.config/hypr/source/animations/horizontal_hallucination.conf.deprecated new file mode 100644 index 00000000..f9cbffb6 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_hallucination.conf.deprecated @@ -0,0 +1,45 @@ +# ----------------------------------------------------- +# TRIP PRESET: Psychedelic, Wavy, Disorienting +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Hallucination" Curves --- + # Starts by going backwards (-0.55), shoots way past target (1.55), then settles. + # This creates a massive "wobble" effect. + bezier = hallucination, 0.68, -0.55, 0.265, 1.55 + + # Slow, lazy wave for fading + bezier = dream, 0.4, 0, 0.2, 1 + + # Constant rotation + bezier = linear, 0, 0, 1, 1 + + # --- Animation Configs --- + + # Windows: The "Breathing" Effect + # They shrink first, then explode in. Duration 9 makes it slow and deliberate. + animation = windowsIn, 1, 9, hallucination, popin 0% + animation = windowsOut, 1, 9, hallucination, popin 0% + + # Windows Move: Swimming through syrup + animation = windowsMove, 1, 9, hallucination, slide + + # Border: THE SPIN + # This makes your border colors rotate infinitely. + # (Requires gradient borders in 'general' settings to be visible) + animation = border, 1, 10, dream + animation = borderangle, 1, 100, linear, loop + + # Fade: Long, slow dissolves + animation = fade, 1, 10, dream + + # Layers: Drifting in from the void + animation = layers, 1, 8, dream, popin 50% + + # Workspaces: The "Warp Tunnel" + # slidefade 80% creates a massive ghosting trail effect when switching. + animation = workspaces, 1, 12, dream, slidefade 80% + animation = specialWorkspace, 1, 12, dream, slidevertfade 80% +} diff --git a/.config/hypr/source/animations/horizontal_hallucination.lua b/.config/hypr/source/animations/horizontal_hallucination.lua new file mode 100644 index 00000000..47c08312 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_hallucination.lua @@ -0,0 +1,28 @@ +-- ----------------------------------------------------- +-- TRIP PRESET: Psychedelic, Wavy, Disorienting (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Starts backwards (-0.55), shoots past target (1.55), then settles. +hl.curve("hallucination", { type = "bezier", points = { {0.68, -0.55}, {0.265, 1.55} } }) +-- Slow, lazy wave for fading +hl.curve("dream", { type = "bezier", points = { {0.4, 0}, {0.2, 1} } }) +-- Constant rotation +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) + +-- Windows: The "Breathing" Effect +hl.animation({ leaf = "windowsIn", enabled = true, speed = 9, bezier = "hallucination", style = "popin 0%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 9, bezier = "hallucination", style = "popin 0%" }) +-- Windows Move: Swimming through syrup +hl.animation({ leaf = "windowsMove", enabled = true, speed = 9, bezier = "hallucination", style = "slide" }) +-- Border: THE SPIN +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "dream" }) +hl.animation({ leaf = "borderangle", enabled = true, speed = 100, bezier = "linear", style = "loop" }) +-- Fade: Long, slow dissolves +hl.animation({ leaf = "fade", enabled = true, speed = 10, bezier = "dream" }) +-- Layers: Drifting in from the void +hl.animation({ leaf = "layers", enabled = true, speed = 8, bezier = "dream", style = "popin 50%" }) +-- Workspaces: The "Warp Tunnel" (horizontal) +hl.animation({ leaf = "workspaces", enabled = true, speed = 12, bezier = "dream", style = "slidefade 80%" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 12, bezier = "dream", style = "slidevertfade 80%" }) diff --git a/.config/hypr/source/animations/horizontal_mechanical.conf.deprecated b/.config/hypr/source/animations/horizontal_mechanical.conf.deprecated new file mode 100644 index 00000000..24e80ef9 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_mechanical.conf.deprecated @@ -0,0 +1,33 @@ +# ----------------------------------------------------- +# RIGID PRESET: Mechanical, Stiff, Precision +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Hard Curves --- + # The "Block" - constant speed then instant stop. + bezier = hard, 0, 1, 0, 1 + # The "Piston" - fast acceleration, hard brake. + bezier = piston, 0.5, 0, 0.5, 1 + + # --- Animation Configs --- + + # Windows: Slide in like metal plates + # No popin (scaling), just pure sliding. + animation = windows, 1, 4, hard, slide + animation = windowsMove, 1, 4, piston, slide + + # Borders: Instant snap (flashing) + animation = border, 1, 1, hard + animation = fade, 1, 2, hard + + # Layers: Mechanical entry + animation = layers, 1, 3, hard, slide + + # Workspaces: Hydraulic Lift + # Slidevert with zero fade. It looks like a physical machine moving. + animation = workspaces, 1, 5, hard, slide + animation = specialWorkspace, 1, 5, hard, slidevert + +} diff --git a/.config/hypr/source/animations/horizontal_mechanical.lua b/.config/hypr/source/animations/horizontal_mechanical.lua new file mode 100644 index 00000000..6de84776 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_mechanical.lua @@ -0,0 +1,22 @@ +-- ----------------------------------------------------- +-- RIGID PRESET: Mechanical, Stiff, Precision (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- The "Block" - constant speed then instant stop. +hl.curve("hard", { type = "bezier", points = { {0, 1}, {0, 1} } }) +-- The "Piston" - fast acceleration, hard brake. +hl.curve("piston", { type = "bezier", points = { {0.5, 0}, {0.5, 1} } }) + +-- Windows: Slide in like metal plates (no popin/scaling, pure sliding) +hl.animation({ leaf = "windows", enabled = true, speed = 4, bezier = "hard", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 4, bezier = "piston", style = "slide" }) +-- Borders: Instant snap (flashing) +hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "hard" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "hard" }) +-- Layers: Mechanical entry +hl.animation({ leaf = "layers", enabled = true, speed = 3, bezier = "hard", style = "slide" }) +-- Workspaces: Hydraulic Press (horizontal) +hl.animation({ leaf = "workspaces", enabled = true, speed = 5, bezier = "hard", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 5, bezier = "hard", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_minimal.conf.deprecated b/.config/hypr/source/animations/horizontal_minimal.conf.deprecated new file mode 100644 index 00000000..9403d3a1 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_minimal.conf.deprecated @@ -0,0 +1,37 @@ +animations { + enabled = true + + # -------------------------------------------------------- + # Bezier Curves + # -------------------------------------------------------- + bezier = pro, 0.05, 0.9, 0.1, 1.0 + bezier = snap, 0.05, 0.9, 0.1, 1.05 + + # -------------------------------------------------------- + # Application Windows (Speed: 3 - Relaxed/Clear) + # -------------------------------------------------------- + animation = windows, 1, 3, snap, popin 80% + animation = windowsOut, 1, 3, snap, popin 80% + animation = windowsMove, 1, 3, snap + + # -------------------------------------------------------- + # UI Layers: Rofi, Waybar (Speed: 2 - Snappy) + # -------------------------------------------------------- + # This '2' is the key. It makes layers faster than windows. + # We use 'slide' generally, but can override direction in layer rules. + animation = layers, 1, 2, pro, slide + animation = fade, 1, 2, pro + + # fix for screenshot gray capture + animation = layersOut, 0, 0, + + animation = border, 1, 3, pro + + # -------------------------------------------------------- + # Workspaces (vertical Slide) + # -------------------------------------------------------- + animation = workspaces, 1, 3, pro, slide + + # Special Workspace (Scratchpad) + animation = specialWorkspace, 1, 3, pro, slidevert +} diff --git a/.config/hypr/source/animations/horizontal_minimal.lua b/.config/hypr/source/animations/horizontal_minimal.lua new file mode 100644 index 00000000..1997e52c --- /dev/null +++ b/.config/hypr/source/animations/horizontal_minimal.lua @@ -0,0 +1,22 @@ +-- ----------------------------------------------------- +-- MINIMAL PRESET: Clean & Snappy (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +hl.curve("pro", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.0} } }) +hl.curve("snap", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.05} } }) + +-- Application Windows +hl.animation({ leaf = "windows", enabled = true, speed = 3, bezier = "snap", style = "popin 80%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 3, bezier = "snap", style = "popin 80%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 3, bezier = "snap" }) +-- UI Layers: Rofi, Waybar +hl.animation({ leaf = "layers", enabled = true, speed = 2, bezier = "pro", style = "slide" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "pro" }) +-- Fix for screenshot gray capture +hl.animation({ leaf = "layersOut", enabled = false, speed = 0 }) +hl.animation({ leaf = "border", enabled = true, speed = 3, bezier = "pro" }) +-- Workspaces (horizontal slide) +hl.animation({ leaf = "workspaces", enabled = true, speed = 3, bezier = "pro", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 3, bezier = "pro", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_rage.conf.deprecated b/.config/hypr/source/animations/horizontal_rage.conf.deprecated new file mode 100644 index 00000000..ce1aa523 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_rage.conf.deprecated @@ -0,0 +1,35 @@ +# ----------------------------------------------------- +# SLAP PRESET: Aggressive, Instant Impact +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Impact" Curve --- + # Starts at 0, goes straight to 1. No easing. + bezier = linear, 0, 0, 1, 1 + # Accelerate only + bezier = accel, 1, 0, 1, 0.5 + + # --- Animation Configs --- + + # Windows: Fast entry (3), hard stop. + animation = windowsIn, 1, 3, accel, slide + # Windows Out: They drop like rocks. + animation = windowsOut, 1, 3, accel, slide + + # Windows Move: Zero smoothing. + animation = windowsMove, 1, 2, linear, slide + + # Border + animation = border, 1, 1, linear + animation = fade, 1, 2, linear + + # Layers + animation = layers, 1, 2, accel, slide + + # Workspaces: Fast vertical slam + animation = workspaces, 1, 3, accel, slide + animation = specialWorkspace, 1, 3, accel, slidevert + +} diff --git a/.config/hypr/source/animations/horizontal_rage.lua b/.config/hypr/source/animations/horizontal_rage.lua new file mode 100644 index 00000000..9b241add --- /dev/null +++ b/.config/hypr/source/animations/horizontal_rage.lua @@ -0,0 +1,24 @@ +-- ----------------------------------------------------- +-- SLAP PRESET: Aggressive, Instant Impact (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Starts at 0, goes straight to 1. No easing. +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) +-- Accelerate only +hl.curve("accel", { type = "bezier", points = { {1, 0}, {1, 0.5} } }) + +-- Windows: Fast entry (3), hard stop. +hl.animation({ leaf = "windowsIn", enabled = true, speed = 3, bezier = "accel", style = "slide" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 3, bezier = "accel", style = "slide" }) +-- Windows Move: Zero smoothing. +hl.animation({ leaf = "windowsMove", enabled = true, speed = 2, bezier = "linear", style = "slide" }) +-- Border +hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "linear" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "linear" }) +-- Layers +hl.animation({ leaf = "layers", enabled = true, speed = 2, bezier = "accel", style = "slide" }) +-- Workspaces: Fast horizontal slam +hl.animation({ leaf = "workspaces", enabled = true, speed = 3, bezier = "accel", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 3, bezier = "accel", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_slowmotion.conf.deprecated b/.config/hypr/source/animations/horizontal_slowmotion.conf.deprecated new file mode 100644 index 00000000..8dca35a2 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_slowmotion.conf.deprecated @@ -0,0 +1,28 @@ +# ----------------------------------------------------- +# DRAMA PRESET: Slow Motion Cinematic +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Suspense" Curve --- + # Starts incredibly slow, rushes in the middle, slows down again. + bezier = slowmo, 0.85, 0, 0.15, 1 + + # --- Animation Configs --- + + # Windows: 15 (approx 1.5 seconds). It feels like forever. + animation = windows, 1, 15, slowmo, slide + animation = windowsMove, 1, 15, slowmo, slide + + # Border: A slow, ominous color change + animation = border, 1, 20, slowmo + animation = fade, 1, 20, slowmo + + # Layers + animation = layers, 1, 12, slowmo, slide + + # Workspaces: A grand, sweeping scene transition + animation = workspaces, 1, 20, slowmo, slide + animation = specialWorkspace, 1, 20, slowmo, slidevert +} diff --git a/.config/hypr/source/animations/horizontal_slowmotion.lua b/.config/hypr/source/animations/horizontal_slowmotion.lua new file mode 100644 index 00000000..e2b42762 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_slowmotion.lua @@ -0,0 +1,20 @@ +-- ----------------------------------------------------- +-- DRAMA PRESET: Slow Motion Cinematic (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Starts incredibly slow, rushes in the middle, slows down again. +hl.curve("slowmo", { type = "bezier", points = { {0.85, 0}, {0.15, 1} } }) + +-- Windows: ~1.5 seconds. It feels like forever. +hl.animation({ leaf = "windows", enabled = true, speed = 15, bezier = "slowmo", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 15, bezier = "slowmo", style = "slide" }) +-- Border: A slow, ominous color change +hl.animation({ leaf = "border", enabled = true, speed = 20, bezier = "slowmo" }) +hl.animation({ leaf = "fade", enabled = true, speed = 20, bezier = "slowmo" }) +-- Layers +hl.animation({ leaf = "layers", enabled = true, speed = 12, bezier = "slowmo", style = "slide" }) +-- Workspaces: Grand, sweeping scene transition (horizontal) +hl.animation({ leaf = "workspaces", enabled = true, speed = 20, bezier = "slowmo", style = "slide" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 20, bezier = "slowmo", style = "slidevert" }) diff --git a/.config/hypr/source/animations/horizontal_vertical_air.conf.deprecated b/.config/hypr/source/animations/horizontal_vertical_air.conf.deprecated new file mode 100644 index 00000000..b418a0d3 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_vertical_air.conf.deprecated @@ -0,0 +1,33 @@ +# ----------------------------------------------------- +# AIR PRESET: Floaty, Soft, Ethereal +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Soft Curves --- + # Slow start, slow end. Like a feather falling. + bezier = soft, 0.3, 0.3, 0.2, 1 + bezier = softIn, 0.4, 0, 1, 1 + + # --- Animation Configs --- + + # Windows: Drift in with opacity changes + # slidefade 15% gives it that "ghost" tail effect + animation = windowsIn, 1, 8, soft, slidefade 15% + animation = windowsOut, 1, 8, softIn, slidefade 15% + animation = windowsMove, 1, 8, soft, slidefade 15% + + # Border & Fade: Very slow transition + animation = border, 1, 10, soft + animation = fade, 1, 10, soft + + # Layers: Gentle drift + animation = layers, 1, 6, soft, slidefade 10% + + # Workspaces: The "Elevator in the Clouds" + # Long duration (10), vertical slide with heavy fade. + animation = workspaces, 1, 10, soft, slidefade 40% + animation = specialWorkspace, 1, 10, soft, slidefadevert 40% + +} diff --git a/.config/hypr/source/animations/horizontal_vertical_air.lua b/.config/hypr/source/animations/horizontal_vertical_air.lua new file mode 100644 index 00000000..5048f1d5 --- /dev/null +++ b/.config/hypr/source/animations/horizontal_vertical_air.lua @@ -0,0 +1,23 @@ +-- ----------------------------------------------------- +-- AIR PRESET: Floaty, Soft, Ethereal (Horizontal) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Slow start, slow end. Like a feather falling. +hl.curve("soft", { type = "bezier", points = { {0.3, 0.3}, {0.2, 1} } }) +hl.curve("softIn", { type = "bezier", points = { {0.4, 0}, {1, 1} } }) + +-- Windows: Drift in with opacity changes +-- slidefade 15% gives it that "ghost" tail effect +hl.animation({ leaf = "windowsIn", enabled = true, speed = 8, bezier = "soft", style = "slidefade 15%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 8, bezier = "softIn", style = "slidefade 15%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 8, bezier = "soft", style = "slidefade 15%" }) +-- Border & Fade: Very slow transition +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "soft" }) +hl.animation({ leaf = "fade", enabled = true, speed = 10, bezier = "soft" }) +-- Layers: Gentle drift +hl.animation({ leaf = "layers", enabled = true, speed = 6, bezier = "soft", style = "slidefade 10%" }) +-- Workspaces: Elevator in the Clouds (horizontal with heavy fade) +hl.animation({ leaf = "workspaces", enabled = true, speed = 10, bezier = "soft", style = "slidefade 40%" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 10, bezier = "soft", style = "slidefadevert 40%" }) diff --git a/.config/hypr/source/animations/vertical_bounce.conf.deprecated b/.config/hypr/source/animations/vertical_bounce.conf.deprecated new file mode 100644 index 00000000..56227495 --- /dev/null +++ b/.config/hypr/source/animations/vertical_bounce.conf.deprecated @@ -0,0 +1,31 @@ +# ----------------------------------------------------- +# POP PRESET: Bouncy, Gelatinous, Fun +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Bouncy Curves --- + # High bounce (1.6 = 60% overshoot). Very exaggerated. + bezier = jelly, 0.1, 0.9, 0.1, 1.3 + bezier = bounce, 0.1, 1.5, 0.2, 1.1 + + # --- Animation Configs --- + + # Windows: They pop in from the center like bubbles + animation = windowsIn, 1, 6, jelly, popin 60% + animation = windowsOut, 1, 4, bounce, popin 60% + animation = windowsMove, 1, 6, jelly, slide + + # Border + animation = border, 1, 10, jelly + animation = fade, 1, 5, jelly + + # Layers + animation = layers, 1, 6, jelly, popin 10% + + # Workspaces: Trampoline effect + animation = workspaces, 1, 7, jelly, slidevert + animation = specialWorkspace, 1, 7, jelly, slide + +} diff --git a/.config/hypr/source/animations/vertical_bounce.lua b/.config/hypr/source/animations/vertical_bounce.lua new file mode 100644 index 00000000..84be7337 --- /dev/null +++ b/.config/hypr/source/animations/vertical_bounce.lua @@ -0,0 +1,22 @@ +-- ----------------------------------------------------- +-- POP PRESET: Bouncy, Gelatinous, Fun (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- High bounce (1.3 = 30% overshoot). Very exaggerated. +hl.curve("jelly", { type = "bezier", points = { {0.1, 0.9}, {0.1, 1.3} } }) +hl.curve("bounce", { type = "bezier", points = { {0.1, 1.5}, {0.2, 1.1} } }) + +-- Windows: Pop in from the center like bubbles +hl.animation({ leaf = "windowsIn", enabled = true, speed = 6, bezier = "jelly", style = "popin 60%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 4, bezier = "bounce", style = "popin 60%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 6, bezier = "jelly", style = "slide" }) +-- Border +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "jelly" }) +hl.animation({ leaf = "fade", enabled = true, speed = 5, bezier = "jelly" }) +-- Layers +hl.animation({ leaf = "layers", enabled = true, speed = 6, bezier = "jelly", style = "popin 10%" }) +-- Workspaces: Trampoline effect (vertical) +hl.animation({ leaf = "workspaces", enabled = true, speed = 7, bezier = "jelly", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 7, bezier = "jelly", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_dusky.conf.deprecated b/.config/hypr/source/animations/vertical_dusky.conf.deprecated new file mode 100644 index 00000000..afa80af9 --- /dev/null +++ b/.config/hypr/source/animations/vertical_dusky.conf.deprecated @@ -0,0 +1,42 @@ +# ----------------------------------------------------- +# FLUID Dusky: The "Showcase" Edition +# ----------------------------------------------------- +# Tuned daily driving: Slower, cinematic, and +# perfectly fluid. +# ----------------------------------------------------- + +animations { + enabled = true + + # Goes past the target (1.1) and snaps back. + # Used for: Windows opening, Rofi, Workspaces. + bezier = overshot, 0.05, 0.9, 0.1, 1.1 + # Standard ease-out. No bounce, just a clean stop. + # Used for: Fading opacity. + bezier = fluid, 0.25, 1, 0, 1 + # A slightly tighter curve than fluid, good for closing things. + # Used for: Windows closing. + bezier = snap, 0.5, 0.9, 0.1, 1.05 + # Starts fast, decelerates very slowly. + # Used for: Sliding menus and closing layers. + bezier = menu_decel, 0.1, 1, 0, 1 + # Constant speed, no acceleration. + # Used for: Border color cycling. + bezier = liner, 1, 1, 1, 1 + + # -- Window Animations -- + animation = windowsIn, 1, 7, overshot, popin 80% + animation = windowsOut, 1, 5, snap, popin 80% + animation = windowsMove, 1, 7, overshot, slide + animation = border, 1, 2, liner + animation = borderangle, 1, 40, liner, once + animation = fade, 1, 5, fluid + animation = layersIn, 1, 6, overshot, popin 70% + # Layers Close (specifidcally a fix for screenshots) + animation = layersOut, 0, 0, menu_decel, slide + animation = fadeLayersIn, 1, 5, menu_decel + animation = fadeLayersOut, 1, 4, menu_decel + animation = workspaces, 1, 8, overshot, slidevert + animation = specialWorkspace, 1, 8, overshot, slide + +} diff --git a/.config/hypr/source/animations/vertical_dusky.lua b/.config/hypr/source/animations/vertical_dusky.lua new file mode 100644 index 00000000..4fcbdd59 --- /dev/null +++ b/.config/hypr/source/animations/vertical_dusky.lua @@ -0,0 +1,33 @@ +-- ----------------------------------------------------- +-- FLUID Dusky: The "Showcase" Edition (Vertical) +-- ----------------------------------------------------- +-- Tuned daily driving: Slower, cinematic, and +-- perfectly fluid. +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Goes past the target (1.1) and snaps back. +hl.curve("overshot", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.1} } }) +-- Standard ease-out. No bounce, just a clean stop. +hl.curve("fluid", { type = "bezier", points = { {0.25, 1}, {0, 1} } }) +-- A slightly tighter curve than fluid, good for closing things. +hl.curve("snap", { type = "bezier", points = { {0.5, 0.9}, {0.1, 1.05} } }) +-- Starts fast, decelerates very slowly. +hl.curve("menu_decel", { type = "bezier", points = { {0.1, 1}, {0, 1} } }) +-- Constant speed, no acceleration. +hl.curve("liner", { type = "bezier", points = { {1, 1}, {1, 1} } }) + +hl.animation({ leaf = "windowsIn", enabled = true, speed = 7, bezier = "overshot", style = "popin 80%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 5, bezier = "snap", style = "popin 80%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 7, bezier = "overshot", style = "slide" }) +hl.animation({ leaf = "border", enabled = true, speed = 2, bezier = "liner" }) +hl.animation({ leaf = "borderangle", enabled = true, speed = 40, bezier = "liner", style = "once" }) +hl.animation({ leaf = "fade", enabled = true, speed = 5, bezier = "fluid" }) +hl.animation({ leaf = "layersIn", enabled = true, speed = 6, bezier = "overshot", style = "popin 70%" }) +hl.animation({ leaf = "layersOut", enabled = false, speed = 0 }) +hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 5, bezier = "menu_decel" }) +hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 4, bezier = "menu_decel" }) +-- Vertical workspaces +hl.animation({ leaf = "workspaces", enabled = true, speed = 8, bezier = "overshot", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 8, bezier = "overshot", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_exagurated.conf.deprecated b/.config/hypr/source/animations/vertical_exagurated.conf.deprecated new file mode 100644 index 00000000..2480e0aa --- /dev/null +++ b/.config/hypr/source/animations/vertical_exagurated.conf.deprecated @@ -0,0 +1,31 @@ +# ----------------------------------------------------- +# GELATIN PRESET: Maximum Wobble +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Boing" Curve --- + # 1.7 overshoot is absolutely ridiculous. + bezier = boing, 0.4, 0.8, 0.2, 1.7 + # A curve that dips below zero for "anticipation" + bezier = slingshot, 0.4, -0.4, 0, 1.2 + + # --- Animation Configs --- + + # Windows: They pull back (slingshot) then fly in and wobble (boing) + animation = windowsIn, 1, 8, boing, popin 10% + animation = windowsOut, 1, 8, boing, popin 80% + animation = windowsMove, 1, 8, boing, slide + + # Border: Even the borders pulse + animation = border, 1, 10, boing + animation = fade, 1, 5, boing + + # Layers: Your Waybar will look like it's made of rubber + animation = layers, 1, 10, boing, slide + + # Workspaces: The entire screen is a trampoline + animation = workspaces, 1, 10, boing, slidevert + animation = specialWorkspace, 1, 10, boing, slide +} diff --git a/.config/hypr/source/animations/vertical_exagurated.lua b/.config/hypr/source/animations/vertical_exagurated.lua new file mode 100644 index 00000000..f97a4f40 --- /dev/null +++ b/.config/hypr/source/animations/vertical_exagurated.lua @@ -0,0 +1,20 @@ +-- ----------------------------------------------------- +-- GELATIN PRESET: Maximum Wobble (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- 1.7 overshoot is absolutely ridiculous. +hl.curve("boing", { type = "bezier", points = { {0.4, 0.8}, {0.2, 1.7} } }) +-- A curve that dips below zero for "anticipation" +hl.curve("slingshot", { type = "bezier", points = { {0.4, -0.4}, {0, 1.2} } }) + +hl.animation({ leaf = "windowsIn", enabled = true, speed = 8, bezier = "boing", style = "popin 10%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 8, bezier = "boing", style = "popin 80%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 8, bezier = "boing", style = "slide" }) +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "boing" }) +hl.animation({ leaf = "fade", enabled = true, speed = 5, bezier = "boing" }) +hl.animation({ leaf = "layers", enabled = true, speed = 10, bezier = "boing", style = "slide" }) +-- Workspaces: Trampoline (vertical) +hl.animation({ leaf = "workspaces", enabled = true, speed = 10, bezier = "boing", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 10, bezier = "boing", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_fast.conf.deprecated b/.config/hypr/source/animations/vertical_fast.conf.deprecated new file mode 100644 index 00000000..0ec25724 --- /dev/null +++ b/.config/hypr/source/animations/vertical_fast.conf.deprecated @@ -0,0 +1,34 @@ +# ----------------------------------------------------- +# FAST PRESET: High Performance / Low Latency +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Linear / Sharp Curves --- + bezier = linear, 0, 0, 1, 1 + bezier = md3_decel, 0.05, 0.7, 0.1, 1 + bezier = instant, 0, 1, 0, 1 + + # --- Animation Configs --- + + # Windows: Instant snap with barely visible deceleration + # Duration 2 = ~30ms. Blink and you miss it. + animation = windows, 1, 2, md3_decel, slide + animation = windowsIn, 1, 2, md3_decel, slide + animation = windowsOut, 1, 2, md3_decel, slide + animation = windowsMove, 1, 2, md3_decel, slide + + # Border: Instant feedback + animation = border, 1, 1, linear + animation = fade, 1, 2, md3_decel + + # Layers: Snappy but not jarring + animation = layers, 1, 2, md3_decel, slide + + # Workspaces: Fast vertical slide (200ms) + # Enough context to see the movement, fast enough not to wait. + animation = workspaces, 1, 2.5, md3_decel, slidevert + animation = specialWorkspace, 1, 2.5, md3_decel, slide + +} diff --git a/.config/hypr/source/animations/vertical_fast.lua b/.config/hypr/source/animations/vertical_fast.lua new file mode 100644 index 00000000..6e147521 --- /dev/null +++ b/.config/hypr/source/animations/vertical_fast.lua @@ -0,0 +1,23 @@ +-- ----------------------------------------------------- +-- FAST PRESET: High Performance / Low Latency (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) +hl.curve("md3_decel", { type = "bezier", points = { {0.05, 0.7}, {0.1, 1} } }) +hl.curve("instant", { type = "bezier", points = { {0, 1}, {0, 1} } }) + +-- Windows: Instant snap with barely visible deceleration (~30ms) +hl.animation({ leaf = "windows", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsIn", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +-- Border: Instant feedback +hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "linear" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "md3_decel" }) +-- Layers: Snappy but not jarring +hl.animation({ leaf = "layers", enabled = true, speed = 2, bezier = "md3_decel", style = "slide" }) +-- Workspaces: Fast vertical slide (~200ms) +hl.animation({ leaf = "workspaces", enabled = true, speed = 2.5, bezier = "md3_decel", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 2.5, bezier = "md3_decel", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_hallucination.conf.deprecated b/.config/hypr/source/animations/vertical_hallucination.conf.deprecated new file mode 100644 index 00000000..b2193ef2 --- /dev/null +++ b/.config/hypr/source/animations/vertical_hallucination.conf.deprecated @@ -0,0 +1,45 @@ +# ----------------------------------------------------- +# TRIP PRESET: Psychedelic, Wavy, Disorienting +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Hallucination" Curves --- + # Starts by going backwards (-0.55), shoots way past target (1.55), then settles. + # This creates a massive "wobble" effect. + bezier = hallucination, 0.68, -0.55, 0.265, 1.55 + + # Slow, lazy wave for fading + bezier = dream, 0.4, 0, 0.2, 1 + + # Constant rotation + bezier = linear, 0, 0, 1, 1 + + # --- Animation Configs --- + + # Windows: The "Breathing" Effect + # They shrink first, then explode in. Duration 9 makes it slow and deliberate. + animation = windowsIn, 1, 9, hallucination, popin 0% + animation = windowsOut, 1, 9, hallucination, popin 0% + + # Windows Move: Swimming through syrup + animation = windowsMove, 1, 9, hallucination, slide + + # Border: THE SPIN + # This makes your border colors rotate infinitely. + # (Requires gradient borders in 'general' settings to be visible) + animation = border, 1, 10, dream + animation = borderangle, 1, 100, linear, loop + + # Fade: Long, slow dissolves + animation = fade, 1, 10, dream + + # Layers: Drifting in from the void + animation = layers, 1, 8, dream, popin 50% + + # Workspaces: The "Warp Tunnel" + # slidefade 80% creates a massive ghosting trail effect when switching. + animation = workspaces, 1, 12, dream, slidevertfade 80% + animation = specialWorkspace, 1, 12, dream, slidefade 80% +} diff --git a/.config/hypr/source/animations/vertical_hallucination.lua b/.config/hypr/source/animations/vertical_hallucination.lua new file mode 100644 index 00000000..94c8513a --- /dev/null +++ b/.config/hypr/source/animations/vertical_hallucination.lua @@ -0,0 +1,23 @@ +-- ----------------------------------------------------- +-- TRIP PRESET: Psychedelic, Wavy, Disorienting (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Starts backwards (-0.55), shoots past target (1.55), then settles. +hl.curve("hallucination", { type = "bezier", points = { {0.68, -0.55}, {0.265, 1.55} } }) +-- Slow, lazy wave for fading +hl.curve("dream", { type = "bezier", points = { {0.4, 0}, {0.2, 1} } }) +-- Constant rotation +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) + +hl.animation({ leaf = "windowsIn", enabled = true, speed = 9, bezier = "hallucination", style = "popin 0%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 9, bezier = "hallucination", style = "popin 0%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 9, bezier = "hallucination", style = "slide" }) +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "dream" }) +hl.animation({ leaf = "borderangle", enabled = true, speed = 100, bezier = "linear", style = "loop" }) +hl.animation({ leaf = "fade", enabled = true, speed = 10, bezier = "dream" }) +hl.animation({ leaf = "layers", enabled = true, speed = 8, bezier = "dream", style = "popin 50%" }) +-- Workspaces: The "Warp Tunnel" (vertical) +hl.animation({ leaf = "workspaces", enabled = true, speed = 12, bezier = "dream", style = "slidevertfade 80%" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 12, bezier = "dream", style = "slidefade 80%" }) diff --git a/.config/hypr/source/animations/vertical_mechanical.conf.deprecated b/.config/hypr/source/animations/vertical_mechanical.conf.deprecated new file mode 100644 index 00000000..25b6ed3c --- /dev/null +++ b/.config/hypr/source/animations/vertical_mechanical.conf.deprecated @@ -0,0 +1,33 @@ +# ----------------------------------------------------- +# RIGID PRESET: Mechanical, Stiff, Precision +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Hard Curves --- + # The "Block" - constant speed then instant stop. + bezier = hard, 0, 1, 0, 1 + # The "Piston" - fast acceleration, hard brake. + bezier = piston, 0.5, 0, 0.5, 1 + + # --- Animation Configs --- + + # Windows: Slide in like metal plates + # No popin (scaling), just pure sliding. + animation = windows, 1, 4, hard, slide + animation = windowsMove, 1, 4, piston, slide + + # Borders: Instant snap (flashing) + animation = border, 1, 1, hard + animation = fade, 1, 2, hard + + # Layers: Mechanical entry + animation = layers, 1, 3, hard, slide + + # Workspaces: Hydraulic Lift + # Slidevert with zero fade. It looks like a physical machine moving. + animation = workspaces, 1, 5, hard, slidevert + animation = specialWorkspace, 1, 5, hard, slide + +} diff --git a/.config/hypr/source/animations/vertical_mechanical.lua b/.config/hypr/source/animations/vertical_mechanical.lua new file mode 100644 index 00000000..ee6aa151 --- /dev/null +++ b/.config/hypr/source/animations/vertical_mechanical.lua @@ -0,0 +1,19 @@ +-- ----------------------------------------------------- +-- RIGID PRESET: Mechanical, Stiff, Precision (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- The "Block" - constant speed then instant stop. +hl.curve("hard", { type = "bezier", points = { {0, 1}, {0, 1} } }) +-- The "Piston" - fast acceleration, hard brake. +hl.curve("piston", { type = "bezier", points = { {0.5, 0}, {0.5, 1} } }) + +hl.animation({ leaf = "windows", enabled = true, speed = 4, bezier = "hard", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 4, bezier = "piston", style = "slide" }) +hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "hard" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "hard" }) +hl.animation({ leaf = "layers", enabled = true, speed = 3, bezier = "hard", style = "slide" }) +-- Workspaces: Hydraulic Lift (vertical) +hl.animation({ leaf = "workspaces", enabled = true, speed = 5, bezier = "hard", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 5, bezier = "hard", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_minimal.conf.deprecated b/.config/hypr/source/animations/vertical_minimal.conf.deprecated new file mode 100644 index 00000000..f3060ad1 --- /dev/null +++ b/.config/hypr/source/animations/vertical_minimal.conf.deprecated @@ -0,0 +1,37 @@ +animations { + enabled = true + + # -------------------------------------------------------- + # Bezier Curves + # -------------------------------------------------------- + bezier = pro, 0.05, 0.9, 0.1, 1.0 + bezier = snap, 0.05, 0.9, 0.1, 1.05 + + # -------------------------------------------------------- + # Application Windows (Speed: 3 - Relaxed/Clear) + # -------------------------------------------------------- + animation = windows, 1, 3, snap, popin 80% + animation = windowsOut, 1, 3, snap, popin 80% + animation = windowsMove, 1, 3, snap + + # -------------------------------------------------------- + # UI Layers: Rofi, Waybar (Speed: 2 - Snappy) + # -------------------------------------------------------- + # This '2' is the key. It makes layers faster than windows. + # We use 'slide' generally, but can override direction in layer rules. + animation = layers, 1, 2, pro, slide + animation = fade, 1, 2, pro + + # fix for screenshot gray capture + animation = layersOut, 0, 0, + + animation = border, 1, 3, pro + + # -------------------------------------------------------- + # Workspaces (vertical Slide) + # -------------------------------------------------------- + animation = workspaces, 1, 3, pro, slidevert + + # Special Workspace (Scratchpad) + animation = specialWorkspace, 1, 3, pro, slide +} diff --git a/.config/hypr/source/animations/vertical_minimal.lua b/.config/hypr/source/animations/vertical_minimal.lua new file mode 100644 index 00000000..cee2740d --- /dev/null +++ b/.config/hypr/source/animations/vertical_minimal.lua @@ -0,0 +1,22 @@ +-- ----------------------------------------------------- +-- MINIMAL PRESET: Clean & Snappy (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +hl.curve("pro", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.0} } }) +hl.curve("snap", { type = "bezier", points = { {0.05, 0.9}, {0.1, 1.05} } }) + +-- Application Windows +hl.animation({ leaf = "windows", enabled = true, speed = 3, bezier = "snap", style = "popin 80%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 3, bezier = "snap", style = "popin 80%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 3, bezier = "snap" }) +-- UI Layers: Rofi, Waybar +hl.animation({ leaf = "layers", enabled = true, speed = 2, bezier = "pro", style = "slide" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "pro" }) +-- Fix for screenshot gray capture +hl.animation({ leaf = "layersOut", enabled = false, speed = 0 }) +hl.animation({ leaf = "border", enabled = true, speed = 3, bezier = "pro" }) +-- Workspaces (vertical slide) +hl.animation({ leaf = "workspaces", enabled = true, speed = 3, bezier = "pro", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 3, bezier = "pro", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_rage.conf.deprecated b/.config/hypr/source/animations/vertical_rage.conf.deprecated new file mode 100644 index 00000000..afc8f744 --- /dev/null +++ b/.config/hypr/source/animations/vertical_rage.conf.deprecated @@ -0,0 +1,35 @@ +# ----------------------------------------------------- +# SLAP PRESET: Aggressive, Instant Impact +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Impact" Curve --- + # Starts at 0, goes straight to 1. No easing. + bezier = linear, 0, 0, 1, 1 + # Accelerate only + bezier = accel, 1, 0, 1, 0.5 + + # --- Animation Configs --- + + # Windows: Fast entry (3), hard stop. + animation = windowsIn, 1, 3, accel, slide + # Windows Out: They drop like rocks. + animation = windowsOut, 1, 3, accel, slide + + # Windows Move: Zero smoothing. + animation = windowsMove, 1, 2, linear, slide + + # Border + animation = border, 1, 1, linear + animation = fade, 1, 2, linear + + # Layers + animation = layers, 1, 2, accel, slide + + # Workspaces: Fast vertical slam + animation = workspaces, 1, 3, accel, slidevert + animation = specialWorkspace, 1, 3, accel, slide + +} diff --git a/.config/hypr/source/animations/vertical_rage.lua b/.config/hypr/source/animations/vertical_rage.lua new file mode 100644 index 00000000..8f0f60bc --- /dev/null +++ b/.config/hypr/source/animations/vertical_rage.lua @@ -0,0 +1,20 @@ +-- ----------------------------------------------------- +-- SLAP PRESET: Aggressive, Instant Impact (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Starts at 0, goes straight to 1. No easing. +hl.curve("linear", { type = "bezier", points = { {0, 0}, {1, 1} } }) +-- Accelerate only +hl.curve("accel", { type = "bezier", points = { {1, 0}, {1, 0.5} } }) + +hl.animation({ leaf = "windowsIn", enabled = true, speed = 3, bezier = "accel", style = "slide" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 3, bezier = "accel", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 2, bezier = "linear", style = "slide" }) +hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "linear" }) +hl.animation({ leaf = "fade", enabled = true, speed = 2, bezier = "linear" }) +hl.animation({ leaf = "layers", enabled = true, speed = 2, bezier = "accel", style = "slide" }) +-- Workspaces: Fast vertical slam +hl.animation({ leaf = "workspaces", enabled = true, speed = 3, bezier = "accel", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 3, bezier = "accel", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_slowmotion.conf.deprecated b/.config/hypr/source/animations/vertical_slowmotion.conf.deprecated new file mode 100644 index 00000000..cdbdbb5b --- /dev/null +++ b/.config/hypr/source/animations/vertical_slowmotion.conf.deprecated @@ -0,0 +1,28 @@ +# ----------------------------------------------------- +# DRAMA PRESET: Slow Motion Cinematic +# ----------------------------------------------------- + +animations { + enabled = true + + # --- The "Suspense" Curve --- + # Starts incredibly slow, rushes in the middle, slows down again. + bezier = slowmo, 0.85, 0, 0.15, 1 + + # --- Animation Configs --- + + # Windows: 15 (approx 1.5 seconds). It feels like forever. + animation = windows, 1, 15, slowmo, slide + animation = windowsMove, 1, 15, slowmo, slide + + # Border: A slow, ominous color change + animation = border, 1, 20, slowmo + animation = fade, 1, 20, slowmo + + # Layers + animation = layers, 1, 12, slowmo, slide + + # Workspaces: A grand, sweeping scene transition + animation = workspaces, 1, 20, slowmo, slidevert + animation = specialWorkspace, 1, 20, slowmo, slide +} diff --git a/.config/hypr/source/animations/vertical_slowmotion.lua b/.config/hypr/source/animations/vertical_slowmotion.lua new file mode 100644 index 00000000..9c03d6c2 --- /dev/null +++ b/.config/hypr/source/animations/vertical_slowmotion.lua @@ -0,0 +1,20 @@ +-- ----------------------------------------------------- +-- DRAMA PRESET: Slow Motion Cinematic (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Starts incredibly slow, rushes in the middle, slows down again. +hl.curve("slowmo", { type = "bezier", points = { {0.85, 0}, {0.15, 1} } }) + +-- Windows: ~1.5 seconds. It feels like forever. +hl.animation({ leaf = "windows", enabled = true, speed = 15, bezier = "slowmo", style = "slide" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 15, bezier = "slowmo", style = "slide" }) +-- Border: A slow, ominous color change +hl.animation({ leaf = "border", enabled = true, speed = 20, bezier = "slowmo" }) +hl.animation({ leaf = "fade", enabled = true, speed = 20, bezier = "slowmo" }) +-- Layers +hl.animation({ leaf = "layers", enabled = true, speed = 12, bezier = "slowmo", style = "slide" }) +-- Workspaces: Grand, sweeping scene transition (vertical) +hl.animation({ leaf = "workspaces", enabled = true, speed = 20, bezier = "slowmo", style = "slidevert" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 20, bezier = "slowmo", style = "slide" }) diff --git a/.config/hypr/source/animations/vertical_vertical_air.conf.deprecated b/.config/hypr/source/animations/vertical_vertical_air.conf.deprecated new file mode 100644 index 00000000..e26aee6f --- /dev/null +++ b/.config/hypr/source/animations/vertical_vertical_air.conf.deprecated @@ -0,0 +1,33 @@ +# ----------------------------------------------------- +# AIR PRESET: Floaty, Soft, Ethereal +# ----------------------------------------------------- + +animations { + enabled = true + + # --- Soft Curves --- + # Slow start, slow end. Like a feather falling. + bezier = soft, 0.3, 0.3, 0.2, 1 + bezier = softIn, 0.4, 0, 1, 1 + + # --- Animation Configs --- + + # Windows: Drift in with opacity changes + # slidefade 15% gives it that "ghost" tail effect + animation = windowsIn, 1, 8, soft, slidefade 15% + animation = windowsOut, 1, 8, softIn, slidefade 15% + animation = windowsMove, 1, 8, soft, slidefade 15% + + # Border & Fade: Very slow transition + animation = border, 1, 10, soft + animation = fade, 1, 10, soft + + # Layers: Gentle drift + animation = layers, 1, 6, soft, slidefade 10% + + # Workspaces: The "Elevator in the Clouds" + # Long duration (10), vertical slide with heavy fade. + animation = workspaces, 1, 10, soft, slidefadevert 40% + animation = specialWorkspace, 1, 10, soft, slidefade 40% + +} diff --git a/.config/hypr/source/animations/vertical_vertical_air.lua b/.config/hypr/source/animations/vertical_vertical_air.lua new file mode 100644 index 00000000..6e7d1f30 --- /dev/null +++ b/.config/hypr/source/animations/vertical_vertical_air.lua @@ -0,0 +1,22 @@ +-- ----------------------------------------------------- +-- AIR PRESET: Floaty, Soft, Ethereal (Vertical) +-- ----------------------------------------------------- + +hl.config({ animations = { enabled = true } }) + +-- Slow start, slow end. Like a feather falling. +hl.curve("soft", { type = "bezier", points = { {0.3, 0.3}, {0.2, 1} } }) +hl.curve("softIn", { type = "bezier", points = { {0.4, 0}, {1, 1} } }) + +-- Windows: Drift in with opacity changes +hl.animation({ leaf = "windowsIn", enabled = true, speed = 8, bezier = "soft", style = "slidefade 15%" }) +hl.animation({ leaf = "windowsOut", enabled = true, speed = 8, bezier = "softIn", style = "slidefade 15%" }) +hl.animation({ leaf = "windowsMove", enabled = true, speed = 8, bezier = "soft", style = "slidefade 15%" }) +-- Border & Fade: Very slow transition +hl.animation({ leaf = "border", enabled = true, speed = 10, bezier = "soft" }) +hl.animation({ leaf = "fade", enabled = true, speed = 10, bezier = "soft" }) +-- Layers: Gentle drift +hl.animation({ leaf = "layers", enabled = true, speed = 6, bezier = "soft", style = "slidefade 10%" }) +-- Workspaces: Elevator in the Clouds (vertical) +hl.animation({ leaf = "workspaces", enabled = true, speed = 10, bezier = "soft", style = "slidefadevert 40%" }) +hl.animation({ leaf = "specialWorkspace", enabled = true, speed = 10, bezier = "soft", style = "slidefade 40%" }) diff --git a/.config/hypr/source/appearance.conf b/.config/hypr/source/appearance.conf.deprecated similarity index 100% rename from .config/hypr/source/appearance.conf rename to .config/hypr/source/appearance.conf.deprecated diff --git a/.config/hypr/source/appearance.lua b/.config/hypr/source/appearance.lua new file mode 100644 index 00000000..d2b6a3b7 --- /dev/null +++ b/.config/hypr/source/appearance.lua @@ -0,0 +1,146 @@ +-- ============================================================================= +-- APPEARANCE — Base Configuration +-- ============================================================================= +-- DO NOT EDIT THIS FILE. +-- Configure appearance in ~/.config/hypr/edit_here/source/appearance.lua +-- which is loaded last and overrides these defaults. +-- ============================================================================= + +-- ------------------------------------------------------------------------------------------------- +-- 1. GENERAL APPEARANCE +-- Control gaps, borders, and layout behavior. +-- See: https://wiki.hypr.land/Configuring/Variables/#general +-- ------------------------------------------------------------------------------------------------- +hl.config({ + general = { + -- Gaps & Borders + gaps_in = 6, -- Gap between windows + gaps_out = 12, -- Gap between windows and monitor edges + gaps_workspaces = 0, -- Gap between workspaces (when sliding) + border_size = 2, -- Size of window borders + + -- Behavior + -- resize_on_border: allows resizing by dragging on the gap/border area + resize_on_border = false, + + -- allow_tearing: lower latency in games + -- NOTE: also set 'windowrule immediate' on the game class + allow_tearing = true, + + -- Default layout engine + layout = "dwindle", + + -- Snapping: controls how floating windows snap to each other and edges + snap = { + enabled = false, + window_gap = 10, -- min gap (px) before snapping to another window + monitor_gap = 10, -- min gap (px) before snapping to monitor edge + border_overlap = false, + }, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 2. DECORATION +-- Shadows, Blur, Opacity, and Rounding. +-- See: https://wiki.hypr.land/Configuring/Variables/#decoration +-- ------------------------------------------------------------------------------------------------- +hl.config({ + decoration = { + -- Rounding + rounding = 6, + rounding_power = 6.0, + + -- Opacity + active_opacity = 0.95, + inactive_opacity = 0.8, + fullscreen_opacity = 1.0, + + -- Dimming + dim_inactive = false, + dim_strength = 0.2, + dim_special = 0.8, -- stronger dimming for special workspace + + -- Shadows + shadow = { + enabled = true, + range = 35, + render_power = 2, -- 1-4; higher = faster falloff (sharper) + sharp = false, + scale = 1.0, + color = "rgba(1a1a1aee)", + }, + + -- Blur + blur = { + enabled = true, + size = 4, -- radius + passes = 2, -- quality (2 = good perf/looks balance) + new_optimizations = true, + ignore_opacity = true, -- blur behind transparent windows + xray = true, + + -- Texture & Quality + noise = 0.0217, + contrast = 0.8916, + brightness = 0.8172, + vibrancy = 0.1696, + + -- Specifics + popups = false, -- whether to blur right-click menus/popups + }, + + -- screen_shader = home .. "/.config/hypr/shaders/grayscale_advanced.glsl" + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 3. ANIMATIONS +-- The active animation preset is sourced from the animations directory. +-- See: https://wiki.hypr.land/Configuring/Animations/ +-- (Overridden in edit_here/source/appearance.lua to load the user's chosen preset) +-- ------------------------------------------------------------------------------------------------- +dofile(os.getenv("HOME") .. "/.config/hypr/source/animations/active/active.lua") + +-- ------------------------------------------------------------------------------------------------- +-- 4. LAYOUTS +-- ------------------------------------------------------------------------------------------------- +hl.config({ + dwindle = { + preserve_split = true, + -- smart_split = false, + -- smart_resizing = false, + }, + master = { + new_status = "master", + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 5. MISCELLANEOUS & PERFORMANCE +-- See: https://wiki.hypr.land/Configuring/Variables/#misc +-- ------------------------------------------------------------------------------------------------- +hl.config({ + misc = { + force_default_wallpaper = 1, -- set to 0 to enable the anime mascot + disable_hyprland_logo = true, + disable_splash_rendering = true, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 6. BINDS (Visual specific) +-- ------------------------------------------------------------------------------------------------- +hl.config({ + binds = { + allow_pin_fullscreen = true, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 7. SMART GAPS (Single Window Override) +-- Applied automatically when only 1 window is tiled or fullscreened on a workspace. +-- ------------------------------------------------------------------------------------------------- +local single_window_gap = 10 +hl.workspace_rule({ workspace = "w[tv1]", gaps_out = single_window_gap, gaps_in = 0 }) +hl.workspace_rule({ workspace = "f[1]", gaps_out = single_window_gap, gaps_in = 0 }) diff --git a/.config/hypr/source/autostart.conf b/.config/hypr/source/autostart.conf.deprecated similarity index 100% rename from .config/hypr/source/autostart.conf rename to .config/hypr/source/autostart.conf.deprecated diff --git a/.config/hypr/source/autostart.lua b/.config/hypr/source/autostart.lua new file mode 100644 index 00000000..6c085274 --- /dev/null +++ b/.config/hypr/source/autostart.lua @@ -0,0 +1,33 @@ +-- ============================================================================= +-- AUTOSTART — Base Services +-- ============================================================================= +-- Optimized for: Arch Linux | Hyprland | UWSM +-- Wrap all apps in 'uwsm-app --' so systemd tracks them properly. +-- ============================================================================= + +local home = os.getenv("HOME") + +-- --- BACKGROUND SERVICES --- + +-- Wallpaper engine +hl.on("hyprland.start", function() hl.exec_cmd("uwsm-app -- awww-daemon") end) + +-- hypridle is managed via its systemd service — no exec-once needed. + +-- --- CLIPBOARD MANAGER --- +hl.on("hyprland.start", function() + hl.exec_cmd("uwsm-app -- wl-paste --type text --watch cliphist store") + hl.exec_cmd("uwsm-app -- wl-paste --type image --watch cliphist store") + hl.exec_cmd("uwsm-app -- wl-clip-persist --clipboard regular") +end) + +-- --- OPTIONAL / USER INTERFACE --- +hl.on("hyprland.start", function() + hl.exec_cmd("uwsm-app -- " .. home .. "/user_scripts/waybar/waybar_autostart.sh") +end) + +-- --- SLOW APP LAUNCH FIX — propagate environment to systemd and dbus --- +hl.on("hyprland.start", function() + hl.exec_cmd("systemctl --user import-environment $(env | cut -d'=' -f 1)") + hl.exec_cmd("dbus-update-activation-environment --systemd --all") +end) diff --git a/.config/hypr/source/environment_variables.conf b/.config/hypr/source/environment_variables.conf.deprecated similarity index 100% rename from .config/hypr/source/environment_variables.conf rename to .config/hypr/source/environment_variables.conf.deprecated diff --git a/.config/hypr/source/environment_variables.lua b/.config/hypr/source/environment_variables.lua new file mode 100644 index 00000000..35d1a5ea --- /dev/null +++ b/.config/hypr/source/environment_variables.lua @@ -0,0 +1,12 @@ +-- ============================================================================= +-- ENVIRONMENT VARIABLES +-- ============================================================================= +-- NOTE: It is strongly advised to place environment variables in UWSM files: +-- ~/.config/uwsm/env (compositor-agnostic variables) +-- ~/.config/uwsm/env-hyprland (Hyprland-specific variables) +-- +-- This file only sets the single variable required to suppress a Hyprland +-- startup warning. +-- ============================================================================= + +hl.env("XDG_CURRENT_DESKTOP", "Hyprland") diff --git a/.config/hypr/source/input.conf b/.config/hypr/source/input.conf.deprecated similarity index 100% rename from .config/hypr/source/input.conf rename to .config/hypr/source/input.conf.deprecated diff --git a/.config/hypr/source/input.lua b/.config/hypr/source/input.lua new file mode 100644 index 00000000..7aacbef0 --- /dev/null +++ b/.config/hypr/source/input.lua @@ -0,0 +1,127 @@ +-- ============================================================================= +-- INPUT — Base Configuration +-- ============================================================================= +-- DO NOT EDIT THIS FILE. +-- Configure input in ~/.config/hypr/edit_here/source/input.lua +-- which is loaded last and overrides these defaults. +-- ============================================================================= + +-- ------------------------------------------------------------------------------------------------- +-- 1. KEYBOARD & LANGUAGE +-- ------------------------------------------------------------------------------------------------- +hl.config({ + input = { + kb_layout = "us", + kb_options = "", -- e.g. "caps:escape", "grp:alt_shift_toggle" + + resolve_binds_by_sym = false, + numlock_by_default = true, + + repeat_rate = 35, -- [10-100] + repeat_delay = 250, -- [100-1000] + + -- ----------------------------------------------------------------- + -- 2. MOUSE & POINTER ACCELERATION + -- ----------------------------------------------------------------- + + -- 0 = cursor movement doesn't change focus + -- 1 = cursor movement changes focus (default) + -- 2 = detached focus (click to focus keyboard, mouse follows independently) + -- 3 = completely separate focus + follow_mouse = 1, + + sensitivity = 0, -- [-1.0 to 1.0] + accel_profile = "adaptive", -- flat | adaptive | custom + force_no_accel = false, -- "raw input" — bypasses most pointer settings + left_handed = false, + mouse_refocus = true, + + -- ----------------------------------------------------------------- + -- 3. SCROLLING & TRACKBALLS + -- ----------------------------------------------------------------- + natural_scroll = false, + scroll_method = "2fg", -- 2fg | edge | on_button_down | no_scroll + scroll_button = 0, + scroll_button_lock = false, + + -- ----------------------------------------------------------------- + -- 4. TOUCHPAD + -- ----------------------------------------------------------------- + touchpad = { + natural_scroll = true, + disable_while_typing = true, + tap_to_click = true, + clickfinger_behavior = false, + drag_lock = false, + }, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 5. CURSOR BEHAVIOR & RENDERING +-- ------------------------------------------------------------------------------------------------- +hl.config({ + cursor = { + sync_gsettings_theme = true, + + -- 0 = HW cursors (performance) + -- 1 = force SW cursors (compatibility / fixes disappearing cursor) + -- 2 = auto (disable when tearing) + no_hardware_cursors = 2, + + -- Nvidia specific optimization — 0 = off, 1 = on, 2 = auto + use_cpu_buffer = 2, + + hide_on_key_press = false, + inactive_timeout = 0, -- hide cursor after X seconds (0 = never) + + -- 0 = disabled, 1 = move to center of focused window, 2 = force + warp_on_change_workspace = 0, + + -- VRR-specific — 0 = off, 1 = on, 2 = auto + no_break_fs_vrr = 2, + + zoom_factor = 1.0, -- [1.0 - 5.0] magnifier zoom level + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 6. GESTURE PHYSICS (Tuning) +-- ------------------------------------------------------------------------------------------------- +hl.config({ + gestures = { + workspace_swipe_distance = 300, + workspace_swipe_cancel_ratio = 0.5, + workspace_swipe_invert = true, + workspace_swipe_create_new = true, + workspace_swipe_forever = false, + }, +}) + +-- ------------------------------------------------------------------------------------------------- +-- 7. GESTURE BINDINGS +-- ------------------------------------------------------------------------------------------------- + +-- 3-finger up swipe → hyprexpo toggle +hl.gesture({ fingers = 3, direction = "up", action = function() hl.exec_cmd("hyprctl dispatch hyprexpo:expo toggle") end }) + +-- 3-finger left swipe (unbound — customize in edit_here) +-- hl.gesture({ fingers = 3, direction = "left", action = function() end }) + +-- 3-finger down swipe → mute audio +hl.gesture({ fingers = 3, direction = "down", action = function() hl.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle") end }) + +-- 3-finger right swipe → play/pause +hl.gesture({ fingers = 3, direction = "right", action = function() hl.exec_cmd("playerctl play-pause") end }) + +-- 4-finger horizontal → brightness +hl.gesture({ fingers = 4, direction = "left", action = function() hl.exec_cmd("brightnessctl -e4 -n2 set 10%-") end }) +hl.gesture({ fingers = 4, direction = "right", action = function() hl.exec_cmd("brightnessctl -e4 -n2 set 10%+") end }) + +-- 4-finger vertical → volume +hl.gesture({ fingers = 4, direction = "up", action = function() hl.exec_cmd("wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 10%+") end }) +hl.gesture({ fingers = 4, direction = "down", action = function() hl.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%-") end }) + +-- 3-finger pinch → lock screen / screenshot +hl.gesture({ fingers = 3, direction = "pinchout", action = function() hl.exec_cmd("hyprlock --immediate") end }) +hl.gesture({ fingers = 3, direction = "pinchin", action = function() hl.exec_cmd("slurp | grim -g - - | swappy -f -") end }) diff --git a/.config/hypr/source/keybinds.conf b/.config/hypr/source/keybinds.conf.deprecated similarity index 100% rename from .config/hypr/source/keybinds.conf rename to .config/hypr/source/keybinds.conf.deprecated diff --git a/.config/hypr/source/keybinds.lua b/.config/hypr/source/keybinds.lua new file mode 100644 index 00000000..a87acd70 --- /dev/null +++ b/.config/hypr/source/keybinds.lua @@ -0,0 +1,278 @@ +-- ============================================================================= +-- KEYBINDINGS +-- ============================================================================= +-- DO NOT EDIT THIS FILE. +-- Add or override keybinds in ~/.config/hypr/edit_here/source/keybinds.lua +-- +-- Application launcher binds (SUPER+Q/W/E/R) are intentionally left to the +-- user's edit_here file, so they can pick their preferred apps. +-- ============================================================================= + +local mainMod = "SUPER" +local home = os.getenv("HOME") +local scripts = home .. "/user_scripts" + +-- Accessibility: enable anti-aliasing bypass for cursor zoom +hl.config({ cursor = { zoom_disable_aa = true } }) + +-- ============================================================================= +-- 2. APPLICATION LAUNCHERS (UWSM Wrapped) +-- ============================================================================= + +-- Launchers for Q/W/E/R are in edit_here/source/keybinds.lua (app-dependent) + +-- Menus +hl.bind("ALT + SPACE", hl.dsp.exec_cmd("pkill rofi; rofi -show drun -run-command 'uwsm app -- {cmd}'"), { description = "Launch Menu for Apps" }) +hl.bind("CTRL + SHIFT + SPACE",hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. home .. "/user_scripts/rofi/keybindings.sh"), { description = "Show Keybinds" }) +hl.bind(mainMod .. " + CTRL + SPACE", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/emoji.sh"), { description = "Search Emojis" }) +hl.bind(mainMod .. " + CTRL + SHIFT + SPACE", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/calculator.sh"), { description = "Calculator" }) +hl.bind(mainMod .. " + SHIFT + SPACE", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/rofi_theme.sh"), { description = "Matugen Theme Config" }) +hl.bind("CTRL + SPACE", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/rofi_wallpaper_selctor.sh"), { description = "Rofi Wallpaper Selector" }) +hl.bind(mainMod .. " + SPACE", hl.dsp.exec_cmd("gdbus call --session --dest com.github.dusky.controlcenter --object-path /com/github/dusky/controlcenter --method org.freedesktop.Application.Activate '{}'"), { description = "System Menu" }) +hl.bind("CTRL + ALT + SPACE", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/dusky_glance.sh"), { description = "Dusky Glance" }) + +-- Rofi Powermenu +hl.bind("ALT + SHIFT + SPACE", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; rofi -show power-menu -modi power-menu:" .. scripts .. "/rofi/powermenu.sh"), { description = "Power Menu" }) + +-- System Monitor (btop) +hl.bind("CTRL + SHIFT + escape", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " --class btop -e btop"), { description = "System Monitor" }) + +-- --- System Utilities --- +hl.bind("ALT + 1", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " --class wifitui -e wifitui"), { description = "Wi-Fi Manager" }) +hl.bind("ALT + 2", hl.dsp.exec_cmd("uwsm-app -- blueman-manager"), { description = "Bluetooth Manager" }) +hl.bind("ALT + 3", hl.dsp.exec_cmd("uwsm-app -- pavucontrol"), { description = "Audio Mixer" }) +hl.bind("ALT + 4", hl.dsp.exec_cmd("uwsm-app -- waypaper"), { description = "Wallpaper App" }) +hl.bind(mainMod .. " + apostrophe", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/theme_matugen/theme_ctl.sh next"), { description = "Cycle Next Wallpaper" }) +hl.bind(mainMod .. " + SHIFT + apostrophe", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/rofi/rofi_wallpaper_selctor.sh --next-fav"), { description = "Cycle Fav Wallpaper" }) + +-- Drive Locking/Unlocking (Browser) +hl.bind("ALT + 5", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " -e " .. scripts .. "/drives/drive_manager.sh unlock browser"), { description = "Unlock Browser" }) +hl.bind("ALT + SHIFT + 5", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " -e " .. scripts .. "/drives/drive_manager.sh lock browser"), { locked = true, description = "Lock Browser" }) + +-- ============================================================================= +-- PASSTHROUGH / GAME MODE (disables all other keybinds) +-- ============================================================================= +-- Enter passthrough: show notification then switch submap +hl.bind("ALT + 6", + hl.dsp.exec_cmd("notify-send -u critical -t 3000 'Passthrough Enabled' 'Press ALT+6 to exit'; hyprctl dispatch submap passthrough"), + { locked = true, description = "Disable Game Mode (Disable Keybinds)" }) + +hl.define_submap("passthrough", function() + -- Only bind active inside passthrough: exit key + hl.bind("ALT + 6", + hl.dsp.exec_cmd("notify-send -u low -t 2000 'Passthrough Disabled' 'Keybinds restored'; hyprctl dispatch submap reset"), + { locked = true, description = "Game Mode (Enable Keybinds)" }) +end) + +-- --- Display Management (ASUS TUF F15) --- +hl.bind("ALT + 7", hl.dsp.exec_cmd("hyprctl keyword monitor eDP-1,1920x1080@48,0x0,1.6 && sleep 2 && hyprctl keyword misc:vrr 0"), { locked = true, description = "Set Refresh rate to 48Hz Asus Tuf" }) +hl.bind("ALT + 8", hl.dsp.exec_cmd("hyprctl keyword monitor eDP-1,1920x1080@144,0x0,1.6 && sleep 2 && hyprctl keyword misc:vrr 1"), { locked = true, description = "Set Refresh rate to 144Hz Asus Tuf" }) + +-- --- Screen Rotate --- +hl.bind("CTRL + ALT + R", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/hypr/screen_rotate.sh -90"), { locked = true, description = "Rotate Screen Clockwise" }) +hl.bind("CTRL + ALT + SHIFT + R", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/hypr/screen_rotate.sh +90"), { locked = true, description = "Rotate Screen Anti-Clockwise" }) + +-- --- Screen DPMS toggle --- +hl.bind("ALT + F7", hl.dsp.exec_cmd("sleep 1 && hyprctl dispatch dpms off"), { locked = true, description = "Screen Off DPMS" }) +hl.bind("ALT + F8", hl.dsp.exec_cmd("hyprctl dispatch dpms on"), { locked = true, description = "Screen On DPMS" }) + +-- Waybar +hl.bind("ALT + 9", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/waybar/waybar_autostart.sh"), { description = "Start Waybar for 1 Min" }) +hl.bind("ALT + 0", hl.dsp.exec_cmd("pkill waybar"), { locked = true, description = "Kill Waybar" }) +hl.bind(mainMod .. " + ALT + W", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/waybar/dusky_waybars.sh --toggle"), { description = "Waybar Swap Configs" }) +hl.bind(mainMod .. " + ALT + SHIFT + W", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/waybar/dusky_waybars.sh --back_toggle"), { description = "Waybar Swap Configs (Back)" }) + +-- wlogout +hl.bind("ALT + F4", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/wlogout/wlogout_scale.sh"), { description = "Logout Menu" }) + +-- Hyprland Reload +hl.bind("ALT + R", hl.dsp.exec_cmd("hyprctl reload"), { locked = true, description = "Reload Hyprland" }) + +-- Dusky QuickPanel (Sliders) +hl.bind("ALT + V", hl.dsp.exec_cmd("gdbus call --session --dest org.dusky.quickpanal --object-path /org/dusky/quickpanal --method org.freedesktop.Application.Activate '{}'"), { description = "Dusky QuickPanel" }) + +-- ============================================================================= +-- 3. CUSTOM SCRIPTS & UTILITIES +-- ============================================================================= + +-- ASUS Hardware: Fan & Keyboard Light Control +hl.bind("XF86Launch3", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " --class asusctl.sh -e sudo " .. scripts .. "/asus/asusctl.sh"), { description = "ASUS Control" }) + +-- Display Scale Adjustment +hl.bind(mainMod .. " + F", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/hypr/adjust_scale.py +"), { locked = true, repeating = true, description = "Scale Up" }) +hl.bind(mainMod .. " + SHIFT + F", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/hypr/adjust_scale.py -"), { locked = true, repeating = true, description = "Scale Down" }) + +-- Performance: Process Terminator +hl.bind(mainMod .. " + semicolon", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " --class performance.sh -e " .. scripts .. "/performance/services_and_process_terminator.sh"), { description = "Kill Process" }) + +-- wayclick script +hl.bind(mainMod .. " + U", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/wayclick/dusky_wayclick.sh"), { description = "Key Press Sound" }) +hl.bind(mainMod .. " + SHIFT + U", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/mako_osd/dusky_keys/dusky_keys.sh"), { description = "OSD Key Presses" }) + +-- Opacity & Blur Toggles +hl.bind(mainMod .. " + ALT + period", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/hypr/hypr_blur_opacity_shadow_toggle.sh"), { locked = true, description = "Toggle Blur/Opacity" }) +hl.bind(mainMod .. " + period", hl.dsp.window.set_prop({ prop = "opaque", value = "toggle" }), { locked = true, description = "Toggle Per-Window Opacity" }) +hl.bind(mainMod .. " + comma", hl.dsp.window.set_prop({ prop = "no_blur", value = "toggle" }), { locked = true, description = "Toggle Per-Window Blur" }) + +-- --- Accessibility: Zoom --- +hl.bind("SUPER + equal", hl.dsp.exec_cmd("sh -c \"hyprctl keyword cursor:zoom_factor \\\"$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {print $2 * 1.25}')\\\"\""), { repeating = true, description = "Zoom In" }) +hl.bind("SUPER + minus", hl.dsp.exec_cmd("sh -c \"hyprctl keyword cursor:zoom_factor \\\"$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {val = $2 / 1.25; if (val < 1.0) val = 1.0; print val}')\\\"\""), { repeating = true, description = "Zoom Out" }) +hl.bind("SUPER + BACKSPACE", hl.dsp.exec_cmd("hyprctl keyword cursor:zoom_factor 1.0"), { locked = true, description = "Reset Zoom" }) + +-- Hyprshade (Visual Filters) +hl.bind(mainMod .. " + ALT + S", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/shader_menu.sh"), { description = "Shader Menu" }) +hl.bind(mainMod .. " + ALT + X", hl.dsp.exec_cmd("hyprshade off"), { locked = true, description = "Disable Shader" }) +hl.bind(mainMod .. " + ALT + V", hl.dsp.exec_cmd("hyprshade on vibrance"), { locked = true, description = "Vibrant Shader" }) + +-- Hyprland Animations Rofi Menu +hl.bind(mainMod .. " + ALT + A", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; rofi -show animations -modi 'animations:" .. scripts .. "/rofi/hypr_anim.sh'"), { description = "Animation Rofi Menu" }) + +-- --- Clipboard & Screenshot --- + +-- Rofi Clipboard +hl.bind(mainMod .. " + V", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; rofi -modi 'clipboard:" .. scripts .. "/rofi/rofi_cliphist.sh' -show clipboard"), { description = "Clipboard History" }) + +hl.bind(mainMod .. " + B", hl.dsp.exec_cmd("pkill hyprpicker || hyprpicker -a"), { description = "Color Picker" }) + +-- Screenshots +hl.bind(mainMod .. " + S", hl.dsp.exec_cmd(scripts .. "/images/dusky_screenshot.sh --region --freeze --no-notify"), { description = "Quick Screenshot" }) +hl.bind("SHIFT + Print", hl.dsp.exec_cmd("grim - | wl-copy && notify-send 'Fullscreen Screenshot in Clipboard'"), { locked = true, description = "Full Screen Quick Screenshot" }) +hl.bind(mainMod .. " + SHIFT + S", hl.dsp.exec_cmd(scripts .. "/images/dusky_screenshot.sh --region --freeze --annotate --no-notify --tool arrow"), { description = "Screenshot and Annotation" }) +hl.bind("Print", hl.dsp.exec_cmd("pgrep -x swappy || (grim - | uwsm-app -- satty -f -)"), { description = "Fullscreen Screenshot and Annotation" }) +hl.bind("SHIFT + CTRL + ALT + SPACE", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/dusky_rofi_screenshot.sh"), { description = "Dusky Screenshoter" }) + +-- Google Image Search +hl.bind(mainMod .. " + G", hl.dsp.exec_cmd(scripts .. "/google_image_search/google_image_search.sh"), { description = "Image Search (Select and search)" }) + +-- OCR (Tesseract) +hl.bind(mainMod .. " + T", hl.dsp.exec_cmd("pgrep tesseract || (slurp | grim -g - - | tesseract stdin stdout -l eng | wl-copy)"), { description = "OCR Selection" }) +hl.bind(mainMod .. " + SHIFT + T", hl.dsp.exec_cmd("grim - | tesseract stdin stdout -l eng | wl-copy"), { description = "OCR Fullscreen" }) + +-- Ollama Sidebar +hl.bind(mainMod .. " + ALT + O", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " --class ollama_terminal.sh -e " .. scripts .. "/llm/ollama_terminal.sh"), { description = "AI LLM Ollama Chat" }) + +-- Music Recognition +hl.bind(mainMod .. " + ALT + M", hl.dsp.exec_cmd("uwsm-app -- " .. terminal .. " --hold --class music_recognition.sh -e " .. scripts .. "/music/music_recognition.sh"), { description = "Music Recognition aka Shazam" }) + +-- --- AI & Voice Tools --- +hl.bind(mainMod .. " + O", hl.dsp.exec_cmd("wl-copy \"$(wl-paste -p)\" && uwsm-app -- " .. scripts .. "/tts_stt/dusky_kokoro/trigger.sh"), { description = "TTS Kokoro GPU" }) +hl.bind(mainMod .. " + SHIFT + O", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/audio/router/TTS_VC.sh"), { description = "TTS VC" }) +hl.bind(mainMod .. " + I", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/tts_stt/dusky_parakeet/trigger.sh"), { description = "STT Parakeet GPU" }) + +-- ============================================================================= +-- NOTIFICATION ACTIONS (MAKO + ROFI) +-- ============================================================================= +hl.bind(mainMod .. " + N", hl.dsp.exec_cmd("uwsm-app -- pkill rofi; " .. scripts .. "/rofi/rofi_mako.sh"), { description = "Notification History" }) +hl.bind(mainMod .. " + ALT + D", hl.dsp.exec_cmd("makoctl dismiss -a"), { locked = true, description = "Clear Screen Notifications" }) +hl.bind(mainMod .. " + ALT + F", hl.dsp.exec_cmd("makoctl menu -- rofi -dmenu -p 'Action: '"), { description = "Interact with Current Notification" }) + +-- --- Screen Lock --- +hl.bind(mainMod .. " + M", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/hyprlock/lock.sh"), { description = "Lock Screen" }) + +-- ============================================================================= +-- 4. WINDOW MANAGEMENT +-- ============================================================================= +hl.bind(mainMod .. " + C", hl.dsp.window.close(), { description = "Close Window" }) +hl.bind(mainMod .. " + A", hl.dsp.window.fullscreen({ mode = "fullscreen" }), { description = "Window Fullscreen" }) +hl.bind(mainMod .. " + SHIFT + A", hl.dsp.window.fullscreen({ mode = "maximized" }), { description = "Window Maximize" }) +hl.bind(mainMod .. " + X", hl.dsp.window.pin(), { description = "Pin Window" }) +hl.bind(mainMod .. " + Y", hl.dsp.layout("togglesplit"), { description = "Toggle Window Split" }) +hl.bind(mainMod .. " + SHIFT + D", hl.dsp.window.pseudo(), { description = "Toggle Pseudo" }) + +-- Smart Float: Toggle float → Resize to 90% → Center +hl.bind(mainMod .. " + D", + hl.dsp.exec_cmd("if hyprctl -j activewindow | jq -e '.floating | not'; then hyprctl --batch 'dispatch togglefloating; dispatch resizeactive exact 90% 90%; dispatch centerwindow'; else hyprctl dispatch togglefloating; fi"), + { description = "Toggle Float" }) + +-- --- Focus Movement (hold-repeatable) --- +hl.bind(mainMod .. " + h", hl.dsp.focus({ direction = "l" }), { repeating = true, description = "Focus Left" }) +hl.bind(mainMod .. " + l", hl.dsp.focus({ direction = "r" }), { repeating = true, description = "Focus Right" }) +hl.bind(mainMod .. " + k", hl.dsp.focus({ direction = "u" }), { repeating = true, description = "Focus Up" }) +hl.bind(mainMod .. " + j", hl.dsp.focus({ direction = "d" }), { repeating = true, description = "Focus Down" }) + +-- --- Window Movement (hold-repeatable) --- +hl.bind(mainMod .. " + SHIFT + h", hl.dsp.window.move({ direction = "l" }), { repeating = true, description = "Move Left" }) +hl.bind(mainMod .. " + SHIFT + l", hl.dsp.window.move({ direction = "r" }), { repeating = true, description = "Move Right" }) +hl.bind(mainMod .. " + SHIFT + k", hl.dsp.window.move({ direction = "u" }), { repeating = true, description = "Move Up" }) +hl.bind(mainMod .. " + SHIFT + j", hl.dsp.window.move({ direction = "d" }), { repeating = true, description = "Move Down" }) + +-- --- Window Resizing (hold-repeatable) --- +hl.bind(mainMod .. " + right", hl.dsp.window.resize({ x = 30, y = 0, relative = true }), { repeating = true, description = "Resize Width +" }) +hl.bind(mainMod .. " + left", hl.dsp.window.resize({ x = -30, y = 0, relative = true }), { repeating = true, description = "Resize Width -" }) +hl.bind(mainMod .. " + up", hl.dsp.window.resize({ x = 0, y = -30, relative = true }), { repeating = true, description = "Resize Height -" }) +hl.bind(mainMod .. " + down", hl.dsp.window.resize({ x = 0, y = 30, relative = true }), { repeating = true, description = "Resize Height +" }) + +-- ============================================================================= +-- 5. WORKSPACE MANAGEMENT (Context-Aware / Banked) +-- ============================================================================= + +local ws_script = home .. "/user_scripts/hypr/multi_monitor_workspace.sh" + +-- Switch to Workspace (Context Relative) +for i = 1, 10 do + local key = i % 10 + hl.bind(mainMod .. " + " .. key, hl.dsp.exec_cmd(ws_script .. " workspace " .. i), { description = "Switch To Context " .. i }) + hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.exec_cmd(ws_script .. " movetoworkspace " .. i), { description = "Move To Context " .. i }) + hl.bind(mainMod .. " + ALT + " .. key, hl.dsp.exec_cmd(ws_script .. " movetoworkspacesilent " .. i), { description = "Silent Move To Context " .. i }) +end + +-- --- Back and forth with last workspace --- +hl.bind(mainMod .. " + TAB", hl.dsp.focus({ workspace = "previous" }), { repeating = true, description = "Last Workspace" }) + +-- Cycle Workspaces +hl.bind("ALT + SHIFT + TAB", hl.dsp.focus({ workspace = "e-1" }), { repeating = true, description = "Cycle Backward" }) +hl.bind(mainMod .. " + SHIFT + TAB", hl.dsp.focus({ workspace = "e+1" }), { repeating = true, description = "Cycle Next WS" }) + +-- Special Workspace (Scratchpad) +hl.bind(mainMod .. " + Z", hl.dsp.workspace.toggle_special("magic"), { description = "Toggle Scratchpad" }) +hl.bind(mainMod .. " + SHIFT + Z", hl.dsp.window.move({ workspace = "special:magic" }), { description = "Move to Scratchpad" }) + +-- Special Workspace for Spotify +hl.bind(mainMod .. " + SHIFT + M", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/spotify/spotify_toggle.sh")) + +-- ============================================================================= +-- 6. MOUSE BINDINGS +-- ============================================================================= +hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true, description = "Move Window" }) +hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true, description = "Resize Window" }) + +-- ============================================================================= +-- 7. HARDWARE & MEDIA KEYS +-- ============================================================================= + +-- Volume +hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --vol-up 5"), { locked = true, repeating = true, description = "Volume up" }) +hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --vol-down 5"), { locked = true, repeating = true, description = "Volume down" }) +hl.bind("XF86AudioMute", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --vol-mute"), { locked = true, repeating = true, description = "Mute" }) +hl.bind("XF86AudioMicMute", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --mic-mute"), { locked = true, repeating = true, description = "Mute microphone" }) + +-- Brightness +hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --bright-up 5"), { locked = true, repeating = true, description = "Brightness up" }) +hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --bright-down 5"), { locked = true, repeating = true, description = "Brightness down" }) + +-- Precise Adjustments (Alt Modifier) +hl.bind("ALT + XF86AudioRaiseVolume", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --vol-up 1"), { locked = true, repeating = true, description = "Volume up precise" }) +hl.bind("ALT + XF86AudioLowerVolume", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --vol-down 1"), { locked = true, repeating = true, description = "Volume down precise" }) +hl.bind("ALT + XF86MonBrightnessUp", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --bright-up 1"), { locked = true, repeating = true, description = "Brightness up precise" }) +hl.bind("ALT + XF86MonBrightnessDown", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --bright-down 1"), { locked = true, repeating = true, description = "Brightness down precise" }) + +-- Keyboard Backlight +hl.bind("XF86KbdBrightnessUp", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --kbd-bright-up 10"), { locked = true, repeating = true, description = "Keyboard Brightness up" }) +hl.bind("XF86KbdBrightnessDown", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --kbd-bright-down 10"), { locked = true, repeating = true, description = "Keyboard Brightness down" }) + +-- Player Controls (routed through script for OSD feedback) +hl.bind("XF86AudioNext", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --next"), { locked = true, description = "Next track" }) +hl.bind("XF86AudioPrev", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --prev"), { locked = true, description = "Previous track" }) +hl.bind("XF86AudioPlay", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --play-pause"), { locked = true, description = "Play" }) +hl.bind("XF86AudioPause", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --play-pause"), { locked = true, description = "Pause" }) +hl.bind("XF86AudioStop", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --stop"), { locked = true, description = "Stop" }) +hl.bind(mainMod .. " + P", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --play-pause"), { locked = true, description = "Toggle Pause" }) + +-- Custom Audio/Mic Switching Scripts +hl.bind("ALT + P", hl.dsp.exec_cmd(scripts .. "/mako_osd/osd_router/osd_router.sh --vol-mute"), { locked = true, description = "Mute Audio" }) +hl.bind("ALT + M", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/audio/mono_audio_pipewire.py"), { locked = true, description = "Mono Audio Toggle" }) +hl.bind("ALT + O", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/audio/audio_switch.sh"), { locked = true, description = "Switch Audio Output" }) +hl.bind("ALT + I", hl.dsp.exec_cmd("uwsm-app -- " .. scripts .. "/audio/mic_switch.sh"), { locked = true, description = "Switch Mic Input" }) + +-- Calculator +hl.bind("XF86Calculator", hl.dsp.exec_cmd("uwsm-app -- gnome-calculator"), { description = "Calculator" }) diff --git a/.config/hypr/source/monitors.conf b/.config/hypr/source/monitors.conf.deprecated similarity index 100% rename from .config/hypr/source/monitors.conf rename to .config/hypr/source/monitors.conf.deprecated diff --git a/.config/hypr/source/monitors.lua b/.config/hypr/source/monitors.lua new file mode 100644 index 00000000..daf84da3 --- /dev/null +++ b/.config/hypr/source/monitors.lua @@ -0,0 +1,11 @@ +-- ============================================================================= +-- MONITORS — Base Configuration +-- ============================================================================= +-- DO NOT EDIT THIS FILE. +-- Configure your monitors in ~/.config/hypr/edit_here/source/monitors.lua +-- which is loaded last and overrides these defaults. +-- ============================================================================= + +-- Fallback: auto-detect all connected monitors with preferred mode +-- This is intentionally minimal; actual setup lives in edit_here. +hl.monitor({ output = "", mode = "preferred", position = "auto", scale = 1 }) diff --git a/.config/hypr/source/permissions.conf b/.config/hypr/source/permissions.conf.deprecated similarity index 100% rename from .config/hypr/source/permissions.conf rename to .config/hypr/source/permissions.conf.deprecated diff --git a/.config/hypr/source/permissions.lua b/.config/hypr/source/permissions.lua new file mode 100644 index 00000000..b41881fe --- /dev/null +++ b/.config/hypr/source/permissions.lua @@ -0,0 +1,24 @@ +-- ============================================================================= +-- SYSTEM PERMISSIONS ("HARDENED MODE") +-- ============================================================================= +-- By default, Hyprland allows apps to capture the screen via standard portals. +-- Uncomment the ecosystem block ONLY if you want to lock down your system and +-- manually whitelist every app that needs screen access. +-- +-- hl.config({ ecosystem = { enforce_permissions = true } }) +-- ============================================================================= + +-- --- Whitelist (only active if ecosystem enforcement is enabled above) --- + +-- Allow standard screenshot tools +hl.permission({ binary = "/usr/(bin|local/bin)/grim", type = "screencopy", mode = "allow" }) +hl.permission({ binary = "/usr/(bin|local/bin)/slurp", type = "screencopy", mode = "allow" }) + +-- Allow the Portal (CRITICAL: this is what OBS uses) +hl.permission({ binary = "/usr/(lib|libexec|lib64)/xdg-desktop-portal-hyprland", type = "screencopy", mode = "allow" }) + +-- Allow Waybar (for workspace/window info modules) +hl.permission({ binary = "/usr/bin/waybar", type = "screencopy", mode = "allow" }) + +-- Hyprpm (plugin manager) +hl.permission({ binary = "/usr/(bin|local/bin)/hyprpm", type = "plugin", mode = "allow" }) diff --git a/.config/hypr/source/plugins.conf b/.config/hypr/source/plugins.conf.deprecated similarity index 100% rename from .config/hypr/source/plugins.conf rename to .config/hypr/source/plugins.conf.deprecated diff --git a/.config/hypr/source/plugins.lua b/.config/hypr/source/plugins.lua new file mode 100644 index 00000000..9ae05bbf --- /dev/null +++ b/.config/hypr/source/plugins.lua @@ -0,0 +1,23 @@ +-- ============================================================================= +-- PLUGINS CONFIGURATION +-- ============================================================================= +-- Hyprland plugins: reloads your plugins on start +-- Manage plugins with: hyprpm add / enable / disable / update +-- ============================================================================= + +-- Reload all installed/enabled hyprpm plugins on startup +hl.on("hyprland.start", function() + hl.exec_cmd("hyprpm reload") +end) + +-- hyprexpo plugin configuration +-- (only takes effect if hyprexpo is installed via hyprpm) +if hl.plugin and hl.plugin.hyprexpo then + hl.plugin.hyprexpo.configure({ + columns = 3, + gap_size = 5, + bg_col = "rgb(111111)", + workspace_method = "first 1", -- [center/first] [workspace] + gesture_distance = 300, -- how far is the "max" for the gesture + }) +end diff --git a/.config/hypr/source/window_rules.conf b/.config/hypr/source/window_rules.conf.deprecated similarity index 98% rename from .config/hypr/source/window_rules.conf rename to .config/hypr/source/window_rules.conf.deprecated index 42646461..ae4f0a3a 100644 --- a/.config/hypr/source/window_rules.conf +++ b/.config/hypr/source/window_rules.conf.deprecated @@ -1278,6 +1278,47 @@ windowrule { center = on } +#--- WireGuard terminal windows --- +windowrule { + name = dusky_wg_new + match:class = ^(dusky_wg_new)$ + float = on + size = 700 480 + center = on +} + +windowrule { + name = dusky_wg_setup + match:class = ^(dusky_wg_setup)$ + float = on + size = 700 420 + center = on +} + +windowrule { + name = dusky_wg_status + match:class = ^(dusky_wg_status)$ + float = on + size = 720 400 + center = on +} + +windowrule { + name = dusky_wg_edit + match:class = ^(dusky_wg_edit)$ + float = on + size = 700 420 + center = on +} + +windowrule { + name = dusky_wg_delete + match:class = ^(dusky_wg_delete)$ + float = on + size = 500 200 + center = on +} + #--- music recognition script--- windowrule { name = music_recognition.sh diff --git a/.config/hypr/source/window_rules.lua b/.config/hypr/source/window_rules.lua new file mode 100644 index 00000000..b4e16466 --- /dev/null +++ b/.config/hypr/source/window_rules.lua @@ -0,0 +1,393 @@ +-- ============================================================================= +-- WINDOW RULES & LAYER RULES +-- ============================================================================= +-- DO NOT EDIT THIS FILE. +-- Add custom rules in ~/.config/hypr/edit_here/source/window_rules.lua +-- ============================================================================= + +-- ----------------------------------------------------------------------------- +-- GLOBAL / XWAYLAND SETTINGS +-- ----------------------------------------------------------------------------- +hl.config({ xwayland = { force_zero_scaling = true } }) + +-- ----------------------------------------------------------------------------- +-- APPLICATION-SPECIFIC FLOATS & VISUALS +-- ----------------------------------------------------------------------------- + +--— Firefox: Float "About" Dialog — +hl.window_rule({ name = "float-firefox-about", match = { title = "^(About Mozilla Firefox)$" }, float = true }) + +--— Firefox: Float "Library" Window — +hl.window_rule({ name = "float-firefox-library", match = { class = "^(firefox)$", title = "^(Library)$" }, float = true }) + +--— Firefox: YouTube Full Opacity — +hl.window_rule({ name = "opaque-firefox-youtube", match = { class = "^(firefox)$", title = ".*YouTube.*" }, opaque = true }) + +--— Firefox: Figma Full Opacity — +hl.window_rule({ name = "opaque-firefox-figma", match = { class = "^(firefox)$", title = ".*Figma.*" }, opaque = true }) + +--— Firefox: Pixabay Full Opacity — +hl.window_rule({ name = "opaque-firefox-pixabay", match = { class = "^(firefox)$", title = ".*Pixabay.*" }, opaque = true }) + +--— MPV: Always Float & Small — +hl.window_rule({ name = "float-mpv", match = { class = "^(mpv)$" }, float = true, opaque = true, size = "640 360", center = true }) + +--— Wine/Proton: Hide empty tray windows — +hl.window_rule({ name = "xembedsniproxy", match = { class = "^$", title = "^$" }, opacity = "0.0 override 0.0 override", no_blur = true }) + +-- ----------------------------------------------------------------------------- +-- QBITTORRENT: Floating Logic (Layered Approach) +-- ----------------------------------------------------------------------------- + +-- 1. Default Policy: Float ALL qBittorrent windows +hl.window_rule({ name = "float_qbittorrent_all", match = { class = "^(org.qbittorrent.qBittorrent)$" }, float = true, center = true, size = "650 450" }) + +-- 2. Exception: Force the Main Window to Tile +hl.window_rule({ name = "tile_qbittorrent_main", match = { class = "^(org.qbittorrent.qBittorrent)$", title = "^(qBittorrent v).*$" }, float = false }) + +-- ----------------------------------------------------------------------------- +-- GAMES AND GAME LAUNCHERS +-- ----------------------------------------------------------------------------- +hl.window_rule({ name = "PrismLauncher", match = { class = "org.prismlauncher.PrismLauncher" }, float = true }) +hl.window_rule({ name = "Minecraft", match = { class = "com.mojang.minecraft.java-edition" }, opaque = true }) +hl.window_rule({ name = "Tetr.io", match = { class = "tetrio-desktop" }, opaque = true }) +hl.window_rule({ name = "SuperTuxKart", match = { class = "supertuxkart" }, opaque = true }) +hl.window_rule({ name = "ROBLOX", match = { class = "org.vinegarhq.Sober" }, opaque = true }) + +-- ----------------------------------------------------------------------------- +-- STEAM +-- ----------------------------------------------------------------------------- +hl.window_rule({ name = "steam-general", match = { class = "^(steam)$" }, float = true, opaque = true }) +hl.window_rule({ name = "steam-main-window", match = { class = "^(steam)$", title = "^(Steam)$" }, size = "1100 600", center = true }) +hl.window_rule({ name = "steam-friends", match = { class = "^(steam)$", title = "^(Friends List)$" }, size = "460 580" }) +hl.window_rule({ name = "steam-idle", match = { class = "^(steam)$" }, idle_inhibit = "fullscreen" }) + +-- ----------------------------------------------------------------------------- +-- SHOW ME THE KEY (Key Visualizer) +-- ----------------------------------------------------------------------------- +hl.window_rule({ + name = "showmethekey-floating", + match = { class = "^(showmethekey-gtk)$", title = "^(Floating Window - Show Me The Key)$" }, + float = true, + pin = true, + size = "470 50", + move = "((monitor_w-window_w)/2) (monitor_h-window_h-20)", + no_dim = true, + border_size = 0, + opaque = true, +}) + +-- ----------------------------------------------------------------------------- +-- COMMON DESKTOP / GNOME / QT UTILITIES +-- ----------------------------------------------------------------------------- +hl.window_rule({ name = "uGet", match = { title = "^(uGet)$" }, float = true, size = "889 505", center = true }) +hl.window_rule({ name = "float-calculator", match = { class = "^(org.gnome.Calculator)$" }, float = true, size = "360 616", center = true }) +hl.window_rule({ name = "gnome-camera", match = { class = "^(org.gnome.Snapshot)$" }, float = true, size = "528 298", center = true }) +hl.window_rule({ name = "float-cameractrls", match = { class = "^(hu.irl.cameractrls)$", title = "^(/dev/.*)$" }, float = true, size = "624 353", center = true }) +hl.window_rule({ name = "float-loupe", match = { class = "^(org.gnome.Loupe)$" }, float = true, size = "900 600", center = true, opaque = true }) +hl.window_rule({ name = "float-clocks", match = { class = "^(org.gnome.clocks)$" }, float = true, size = "602 297", center = true }) +hl.window_rule({ name = "gparted", match = { class = "^(GParted)$" }, float = true, size = "652 431", center = true }) +hl.window_rule({ name = "grsync", match = { class = "^(grsync)$" }, float = true, size = "650 458", center = true }) +hl.window_rule({ name = "float-blueman", match = { class = "^(blueman-manager)$" }, float = true, size = "530 313", center = true }) +hl.window_rule({ name = "handbrake", match = { class = "^(fr.handbrake.ghb)$" }, float = true, size = "970 698", center = true }) +hl.window_rule({ name = "seahorse", match = { class = "^(org.gnome.seahorse.Application)$" }, float = true, size = "827 632", center = true }) +hl.window_rule({ name = "bluetui", match = { class = "^(bluetui)$" }, float = true, size = "551 362", center = true }) +hl.window_rule({ name = "airmon_ng", match = { class = "^(airmon_ng.sh)$" }, float = true, size = "775 450", center = true }) +hl.window_rule({ name = "iphone_vnc", match = { class = "^(iphone_vnc.sh)$" }, float = true, size = "650 423", center = true }) +hl.window_rule({ name = "btrfs_stats", match = { class = "^(btrfs_zstd_compression_stats.sh)$" }, float = true, size = "650 423", center = true }) +hl.window_rule({ name = "tailscale_setup", match = { class = "^(tailscale_setup)$" }, float = true, size = "782 676", center = true }) +hl.window_rule({ name = "tailscale_remove", match = { class = "^(tailscale_uninstall)$" }, float = true, size = "775 450", center = true }) +hl.window_rule({ name = "kew", match = { class = "^(kew)$" }, float = true, size = "652 576", center = true }) +hl.window_rule({ name = "file_manager_switcher", match = { class = "^(235_file_manager_switch.sh)$" }, float = true, size = "634 445", center = true }) +hl.window_rule({ name = "browser_switcher", match = { class = "^(236_browser_switcher.sh)$" }, float = true, size = "634 445", center = true }) +hl.window_rule({ name = "text_editor_switch",match = { class = "^(237_text_editer_switcher.sh)$" }, float = true, size = "634 445", center = true }) +hl.window_rule({ name = "terminal_switcher", match = { class = "^(238_terminal_switcher.sh)$" }, float = true, size = "634 445", center = true }) +hl.window_rule({ name = "plugin_manager", match = { class = "^(356_dusky_plugin_manager.sh)$" }, float = true, size = "772 554", center = true }) +hl.window_rule({ name = "ftp_setup", match = { class = "^(250_ftp_arch.sh)$" }, float = true, size = "652 576", center = true }) +hl.window_rule({ name = "hosts_block", match = { class = "^(325_hosts_files_block.sh)$" }, float = true, size = "780 548", center = true }) +hl.window_rule({ name = "locale_tui", match = { class = "^(locale_tui.sh)$" }, float = true, size = "780 548", center = true }) +hl.window_rule({ name = "mako_tui_glance", match = { class = "^(glance_mako_tui.sh)$" }, float = true, size = "780 548", center = true }) +hl.window_rule({ name = "change_ftp_dir", match = { class = "^(change_ftp_directory_server.sh)$" }, float = true, size = "652 576", center = true }) +hl.window_rule({ name = "arp_scan", match = { class = "^(arp_scan.sh)$" }, float = true, size = "652 576", center = true }) +hl.window_rule({ name = "openssh_setup", match = { class = "^(02_openssh_setup.sh)$" }, float = true, size = "652 576", center = true }) +hl.window_rule({ name = "clipboard_persist", match = { class = "^(390_clipboard_persistance.sh)$" }, float = true, size = "805 323", center = true }) +hl.window_rule({ name = "cache_purge", match = { class = "^(cache_purge.sh)$" }, float = true, size = "589 529", center = true }) +hl.window_rule({ name = "mouse_btn_reverse", match = { class = "^(mouse_button_reverse.sh)$" }, float = true, size = "589 529", center = true }) +hl.window_rule({ name = "git_config", match = { class = "^(300_git_config.sh)$" }, float = true, size = "726 389", center = true }) +hl.window_rule({ name = "new_github_repo", match = { class = "^(305_new_github_repo_to_backup.sh)$" }, float = true, size = "726 689", center = true }) +hl.window_rule({ name = "relink_github", match = { class = "^(310_reconnect_and_push_new_changes_to_github.sh)$" }, float = true, size = "726 689", center = true }) +hl.window_rule({ name = "io_monitor", match = { class = "^(io_monitor.sh)$" }, float = true, size = "960 300", center = true }) +hl.window_rule({ name = "terminal_clipboard",match = { class = "^(terminal_clipboard.sh)$" }, float = true, no_anim = true, size = "840 520", center = true }) +hl.window_rule({ name = "asusctl", match = { class = "^(asusctl.sh)$" }, float = true, size = "789 534", center = true }) +hl.window_rule({ name = "nvim_reset", match = { class = "^(01_reset_neovim.sh)$" }, float = true, size = "730 454", center = true }) +hl.window_rule({ name = "cli_plugins", match = { class = "^(02_cli_plugins_download.sh)$" }, float = true, size = "730 454", center = true }) +hl.window_rule({ name = "nvim_manager", match = { class = "^(dusky_neovim_manager.sh)$" }, float = true, size = "532 475", center = true }) +hl.window_rule({ name = "paru_optional", match = { class = "^(090_paru_packages_optional%.sh)$" }, float = true, size = "831 572" }) +hl.window_rule({ name = "zram_config", match = { class = "^(205_zram_configuration.sh)$" }, float = true, size = "907 377", center = true }) +hl.window_rule({ name = "limine_setup", match = { class = "^(01_limine_setup.sh)$" }, float = true, size = "730 454", center = true }) +hl.window_rule({ name = "snapper_subvol", match = { class = "^(02_snapper_isolation_subvolume.sh)$" }, float = true, size = "730 454", center = true }) +hl.window_rule({ name = "snapper_hooks", match = { class = "^(03_snapper_pacman_hooks.sh)$" }, float = true, size = "730 454", center = true }) +hl.window_rule({ name = "swappiness", match = { class = "^(210_zram_optimize_swappiness%.sh)$" }, float = true, size = "938 500", center = true }) +hl.window_rule({ name = "gpu_env", match = { class = "^(000_configure_uwsm_gpu%.sh)$" }, float = true, size = "702 492", center = true }) +hl.window_rule({ name = "wayclick_setup", match = { class = "^(dusky_wayclick.sh)$" }, float = true, size = "831 572" }) +hl.window_rule({ name = "wayclick_tui", match = { class = "^(dusky_tui_wayclick.sh)$" }, float = true, size = "780 510" }) +hl.window_rule({ name = "wayclick_sounds", match = { class = "^(wayclick_soundpacks_download.sh)$" }, float = true, size = "580 810" }) +hl.window_rule({ name = "tty_autologin", match = { class = "^(285_tty_autologin.sh)$" }, float = true, size = "730 454", center = true }) +hl.window_rule({ name = "dusky_monitor", match = { class = "^(dusky_monitor.sh)$" }, float = true, size = "802 469", center = true }) +hl.window_rule({ name = "dusky_keybinds", match = { class = "^(dusky_keybinds.sh)$" }, float = true, size = "(monitor_w*0.9) (monitor_h*0.9)", move = "(monitor_w*0.05) (monitor_h*0.05)" }) +hl.window_rule({ name = "dusky_appearances", match = { class = "^(dusky_appearances.sh)$" }, float = true, size = "781 507", center = true }) +hl.window_rule({ name = "dusky_workspace", match = { class = "^(dusky_workspace_manager.sh)$" }, float = true, size = "781 507", center = true }) +hl.window_rule({ name = "dusky_matugen", match = { class = "^(dusky_matugen_presets.sh)$" }, float = true, size = "820 620", center = true }) +hl.window_rule({ name = "dusky_input", match = { class = "^(dusky_input.sh)$" }, float = true, size = "781 507", center = true }) +hl.window_rule({ name = "tui_mako", match = { class = "^(tui_mako.sh)$" }, float = true, size = "781 507", center = true }) +hl.window_rule({ name = "dusky_gsettings", match = { class = "^(dusky_gsettings.sh)$" }, float = true, size = "781 507", center = true }) +hl.window_rule({ name = "dconf_editor", match = { class = "^(ca%.desrt%.dconf-editor)$" }, float = true, size = "979 642" }) +hl.window_rule({ name = "dusky_power", match = { class = "^(dusky_power.sh)$" }, float = true, size = "790 530", center = true }) +hl.window_rule({ name = "dusky_battery", match = { class = "^(dusky_battery_notify.sh)$" }, float = true, size = "790 530", center = true }) +hl.window_rule({ name = "battery_service", match = { class = "^(135_battery_notify_service.sh)$" }, float = true, size = "504 501", center = true }) +hl.window_rule({ name = "dusky_hypridle", match = { class = "^(dusky_hypridle.sh)$" }, float = true, size = "784 529", center = true }) +hl.window_rule({ name = "fastfetch", match = { class = "^(fastfetch)$" }, float = true, size = "943 393", center = true }) +hl.window_rule({ name = "dusky_winrules", match = { class = "^(dusky_window_rules.sh)$" }, float = true, size = "1000 750", center = true }) +hl.window_rule({ name = "dysk", match = { class = "^(dysk)$" }, float = true, size = "1005 298", center = true }) +hl.window_rule({ name = "performance", match = { class = "^(performance.sh)$" }, float = true, size = "566 569", center = true }) + +-- Kokoro TTS: Floating corner widget +hl.window_rule({ + name = "kokoro", + match = { class = "^(kokoro)$" }, + float = true, + pin = true, + size = "254 90", + move = "(monitor_w-window_w-8) (monitor_h-window_h-8)", + no_dim = true, + opaque = true, +}) + +hl.window_rule({ name = "kokoro_installer", match = { class = "^(kokoro_installer.sh)$" }, float = true, pin = true, size = "876 601" }) +hl.window_rule({ name = "parakeet_installer", match = { class = "^(parakeet_installer.sh)$" }, float = true, pin = true, size = "876 601" }) +hl.window_rule({ name = "peaclock", match = { class = "^(peaclock)$" }, float = true, size = "406 179", center = true }) +hl.window_rule({ name = "wifitui", match = { class = "^(wifitui)$" }, float = true, size = "596 318", center = true }) +hl.window_rule({ name = "dusky_network", match = { class = "^(dusky_network.sh)$" }, float = true, size = "741 579", center = true }) +hl.window_rule({ name = "tray_tui", match = { class = "^(tray-tui)$" }, float = true, size = "791 488", center = true }) +hl.window_rule({ name = "cava", match = { class = "^(cava)$" }, float = true, size = "791 488", center = true }) +hl.window_rule({ name = "htop", match = { class = "^(htop)$" }, float = true, size = "1080 607", center = true }) +hl.window_rule({ name = "dgop", match = { class = "^(dgop)$" }, float = true, size = "1080 607", center = true }) +hl.window_rule({ name = "btop", match = { class = "^(btop)$" }, float = true, size = "1080 607", center = true }) +hl.window_rule({ name = "nvim", match = { class = "^(nvim)$" }, float = true, size = "455 549", center = true }) + +-- GNOME Text Editor: large editor for hypr config +hl.window_rule({ name = "gnome-text-editor", match = { class = "^(org.gnome.TextEditor)$" }, + float = true, size = "(monitor_w*0.65) (monitor_h*0.92)", move = "(monitor_w*0.05) (monitor_h*0.05)", center = true }) + +hl.window_rule({ name = "errands", match = { title = "^(Errands)$" }, float = true, size = "519 614", center = true }) +hl.window_rule({ name = "backups", match = { class = "^(thunar)$", title = "^(dusky_backups - Thunar)$" }, float = true, size = "(monitor_w*0.5612) (monitor_h*0.8)", center = true }) +hl.window_rule({ name = "yazi_backup", match = { class = "^(yazi)$", title = "^(Backup Viewer)$" }, float = true, size = "(monitor_w*0.6283) (monitor_h*0.8600)", center = true }) + +-- Dusky Control Center +hl.window_rule({ + name = "dusky_control_center", + match = { title = "^(Dusky Control Center)$", class = "^(com.github.dusky.controlcenter)$" }, + float = true, + animation = "slide down", + size = "(monitor_w*0.50) (monitor_h*0.92)", + center = true, +}) + +-- Dusky QuickPanel (sliders) +hl.window_rule({ + name = "dusky_quickpanal", + match = { title = "^(dusky_quickpanal.py)$", class = "^(org.dusky.quickpanal)$" }, + float = true, + animation = "slide right", + no_dim = true, + rounding = 20, + move = "(monitor_w-window_w-20) (monitor_h-window_h-20)", + border_size = 0, +}) + +hl.window_rule({ name = "audiorouter-popup", match = { class = "^(dev%.audiorouter%.popup)$" }, float = true, center = true, size = "(monitor_w*0.4557) (monitor_h*0.9324)" }) +hl.window_rule({ name = "disks", match = { title = "^(Disks)$", class = "^(org.gnome.DiskUtility)$" }, float = true, size = "890 512", center = true }) +hl.window_rule({ name = "baobab", match = { class = "^(org.gnome.baobab)$" }, float = true, size = "1152 648", center = true }) +hl.window_rule({ name = "thunar_rename", match = { class = "Thunar", title = "^Rename.*$" }, float = true }) + +hl.window_rule({ name = "sysbench", match = { class = "^(sysbench_benchmark.sh)$" }, float = true, size = "567 658", center = true }) +hl.window_rule({ name = "ntfs_fix", match = { class = "^(ntfs_fix.sh)$" }, float = true, size = "766 485", center = true }) +hl.window_rule({ name = "power_saver", match = { class = "^(power_saver.sh)$" }, float = true, size = "737 628", center = true }) +hl.window_rule({ name = "power_saver_off", match = { class = "^(power_saver_off.sh)$" }, float = true, size = "568 456", center = true }) +hl.window_rule({ name = "aur_fallback", match = { class = "^(080_aur_paru_fallback_yay.sh)$" }, float = true, size = "567 658", center = true }) +hl.window_rule({ name = "warp_setup", match = { class = "^(085_warp.sh)$" }, float = true, size = "567 658", center = true }) +hl.window_rule({ name = "preload_config", match = { class = "^(335_preload_config.sh)$" }, float = true, size = "889 669", center = true }) +hl.window_rule({ name = "sddm_setup", match = { class = "^(465_sddm_setup.sh)$" }, float = true, size = "889 669", center = true }) +hl.window_rule({ name = "update_dusky", match = { class = "^(update_dusky.sh)$" }, float = true, size = "1192 710", center = true }) +hl.window_rule({ name = "system_update", match = { class = "^(system_update.sh)$" }, float = true, pin = true, size = "1192 710", center = true }) + +hl.window_rule({ name = "ORCHESTRA", match = { class = "^(ORCHESTRA.sh)$" }, float = true, size = "(monitor_w*0.9) (monitor_h*0.9)", move = "(monitor_w*0.05) (monitor_h*0.05)" }) +hl.window_rule({ name = "deploy_dotfiles", match = { class = "^(deploy_dotfiles.sh)$" }, float = true, size = "(monitor_w*0.9) (monitor_h*0.9)", move = "(monitor_w*0.05) (monitor_h*0.05)" }) +hl.window_rule({ name = "restore_stash", match = { class = "^(restore_stash.sh)$" }, float = true, size = "1192 710", center = true }) +hl.window_rule({ name = "send_logs", match = { class = "^(send_logs.sh)$" }, float = true, size = "500 250", center = true }) +hl.window_rule({ name = "about_dusky", match = { class = "^(about_dusky.sh)$" }, float = true, size = "503 264", center = true }) + +-- Ollama sidebar: left-edge slide panel +hl.window_rule({ + name = "ollama_sidebar", + match = { class = "^(ollama_terminal.sh)$" }, + float = true, + size = "(monitor_w*0.28) (monitor_h*0.88)", + animation = "slide left", + rounding = 9, + move = "(monitor_w*0.038) (monitor_h*0.5 - window_h*0.5)", +}) + +hl.window_rule({ name = "dusky_service_toggle", match = { class = "^(dusky_service_toggle.sh)$" }, float = true, size = "840 598", center = true }) + +-- WireGuard terminal windows +hl.window_rule({ name = "dusky_wg_new", match = { class = "^(dusky_wg_new)$" }, float = true, size = "700 480", center = true }) +hl.window_rule({ name = "dusky_wg_setup", match = { class = "^(dusky_wg_setup)$" }, float = true, size = "700 420", center = true }) +hl.window_rule({ name = "dusky_wg_status", match = { class = "^(dusky_wg_status)$" }, float = true, size = "720 400", center = true }) +hl.window_rule({ name = "dusky_wg_edit", match = { class = "^(dusky_wg_edit)$" }, float = true, size = "700 420", center = true }) +hl.window_rule({ name = "dusky_wg_delete", match = { class = "^(dusky_wg_delete)$" }, float = true, size = "500 200", center = true }) + +hl.window_rule({ name = "music_recognition", match = { class = "^(music_recognition.sh)$" }, float = true, size = "409 147", center = true }) +hl.window_rule({ name = "hyprlock_switcher", match = { class = "^(dusky_hyprlock_switcher.sh)$" }, float = true, size = "821 508", center = true }) +hl.window_rule({ name = "dusky_waybars", match = { class = "^(dusky_waybars.sh)$" }, float = true, size = "780 510", center = true }) +hl.window_rule({ name = "float-zathura", match = { class = "^(org.pwmt.zathura)$" }, float = true, size = "655 526", center = true }) +hl.window_rule({ name = "float-waypaper", match = { class = "^(waypaper)$" }, float = true, size = "786 492", center = true }) +hl.window_rule({ name = "float-share-picker", match = { class = "^(hyprland-share-picker)$" }, float = true, size = "500 300", center = true }) +hl.window_rule({ name = "float-nwg-look", match = { class = "^(nwg-look)$" }, float = true, size = "627 464", center = true }) +hl.window_rule({ name = "float-kvantum", match = { class = "^(kvantummanager)$" }, float = true, size = "585 512", center = true }) +hl.window_rule({ name = "float-qt6ct", match = { class = "^(qt6ct)$" }, float = true, size = "700 609", center = true }) +hl.window_rule({ name = "float-qt5ct", match = { class = "^(qt5ct)$" }, float = true, size = "636 665", center = true }) +hl.window_rule({ name = "float-guifetch", match = { class = "^(guifetch)$" }, float = true, size = "800 500", center = true }) +hl.window_rule({ name = "float-pavucontrol", match = { class = "^(pavucontrol|org.pulseaudio.pavucontrol)$" }, float = true, size = "643 422", center = true }) +hl.window_rule({ name = "float-nm-editor", match = { class = "^(nm-connection-editor)$" }, float = true, size = "432 423", center = true }) + +hl.window_rule({ name = "float_vm_viewer", match = { class = "^(virt-manager)$", title = "^(.* on QEMU/KVM)$" }, + float = true, center = true, size = "1043 634" }) + +-- satty (annotation tool) +hl.window_rule({ name = "satty", match = { class = "^(com%.gabm%.satty)$" }, + center = true, float = true, opaque = true, animation = "slide down", size = "1115 624" }) + +-- ----------------------------------------------------------------------------- +-- PICTURE-IN-PICTURE (PiP) & PINNED WINDOWS +-- ----------------------------------------------------------------------------- + +-- PiP: bottom-right corner, pinned +hl.window_rule({ + name = "pip-global", + match = { title = "^([Pp]icture[-\\s]?[Ii]n[-\\s]?[Pp]icture)(.*)$" }, + float = true, + pin = true, + size = "248 140", + move = "(monitor_w-window_w-20) (monitor_h-window_h-20)", + no_dim = true, + opaque = true, +}) + +-- Pinned Window Styling: green border for any pinned window +hl.window_rule({ + name = "style-pinned-windows", + match = { pin = true }, + no_dim = true, + border_color = "rgb(328E6E)", + border_size = 2, + animation = "slide down", +}) + +-- ----------------------------------------------------------------------------- +-- GLOBAL WINDOW BEHAVIORS +-- ----------------------------------------------------------------------------- + +-- Persistent Size: floating windows remember their size on reopen +hl.window_rule({ name = "global-persistent-size", match = { float = true }, persistent_size = true }) + +-- Prevent Maximize Events: force apps to respect tiling/floating rules +hl.window_rule({ name = "global-suppress-maximize", match = { class = ".*" }, suppress_event = "maximize" }) + +-- ----------------------------------------------------------------------------- +-- XWAYLAND / PHANTOM WINDOW FIX +-- ----------------------------------------------------------------------------- +-- Invisible XWayland tooltips/drag-previews that steal focus +hl.window_rule({ + name = "fix-xwayland-phantom", + match = { class = "^$", title = "^$", xwayland = true, float = true, fullscreen = false, pin = false }, + no_focus = true, +}) + +-- ----------------------------------------------------------------------------- +-- FULLSCREEN & VISUAL STYLING +-- ----------------------------------------------------------------------------- +hl.window_rule({ + name = "style-fullscreen", + match = { fullscreen = true }, + border_color = "rgb(E2971F)", + border_size = 4, + rounding = 0, +}) + +-- ----------------------------------------------------------------------------- +-- COMMON DIALOGS / FILE PICKERS +-- ----------------------------------------------------------------------------- + +-- Title-based dialogs +hl.window_rule({ + name = "float-dialogs-title", + match = { title = "^(Open|Open File|Select a File|Choose wallpaper|Open Folder|Save As|Library|File Upload|Authentication Required|Add Folder to Workspace|Choose Files|Confirm to replace files|File Operation Progress)(.*)$|^(.*dialog.*)$" }, + float = true, + center = true, + size = "816 537", +}) + +-- Class-based dialogs +hl.window_rule({ + name = "float-dialogs-class", + match = { class = "^(org.gnome.FileRoller|[Xx]dg-desktop-portal-gtk|.*dialog.*)$" }, + float = true, + center = true, + size = "816 537", +}) + +-- ----------------------------------------------------------------------------- +-- LAYER RULES (rofi, mako, wlogout, waybar) +-- Check layers with: hyprctl layers +-- ----------------------------------------------------------------------------- + +-- Rofi: blur + dim backdrop +hl.layer_rule({ name = "blur-rofi", match = { namespace = "rofi" }, blur = true, dim_around = true, ignore_alpha = 0.0 }) + +-- Mako (notifications) +hl.layer_rule({ name = "mako", match = { namespace = "notifications" }, blur = true, ignore_alpha = 0.0 }) + +-- wlogout +hl.layer_rule({ name = "wlogout", match = { namespace = "logout_dialog" }, blur = true, ignore_alpha = 0.0 }) + +-- slurp screenshot selection: no blur, no animation +hl.layer_rule({ name = "selection", match = { namespace = "selection" }, blur = false, no_anim = true }) + +-- Waybar: blur + xray +hl.layer_rule({ name = "waybar_blur", match = { namespace = "waybar" }, blur = true, blur_popups = true, xray = true, ignore_alpha = 0.54 }) + +-- ----------------------------------------------------------------------------- +-- SPECIAL WORKSPACE: magic (scratchpad) +-- ----------------------------------------------------------------------------- +hl.workspace_rule({ workspace = "special:magic", gaps_out = 20, gaps_in = 6 }) + +hl.window_rule({ + name = "style-magic-workspace", + match = { workspace = "special:magic" }, + border_color = primary, -- 'primary' is set by appearance.lua → hyprland-colors.lua + border_size = 1, +}) + +-- ----------------------------------------------------------------------------- +-- GLOBAL MISC CONFIG (focus/fullscreen behavior) +-- ----------------------------------------------------------------------------- +hl.config({ + misc = { + -- 0 = do nothing, 1 = overlay new window, 2 = unfullscreen + on_focus_under_fullscreen = 2, + -- Force new windows to spawn on the current workspace + initial_workspace_tracking = 1, + focus_on_activate = true, + }, +}) diff --git a/.config/hypr/source/workspace_rules.conf b/.config/hypr/source/workspace_rules.conf.deprecated similarity index 100% rename from .config/hypr/source/workspace_rules.conf rename to .config/hypr/source/workspace_rules.conf.deprecated diff --git a/.config/hypr/source/workspace_rules.lua b/.config/hypr/source/workspace_rules.lua new file mode 100644 index 00000000..344230f9 --- /dev/null +++ b/.config/hypr/source/workspace_rules.lua @@ -0,0 +1,13 @@ +-- ============================================================================= +-- WORKSPACE RULES — Base Configuration +-- ============================================================================= +-- DO NOT EDIT THIS FILE. +-- Configure workspace rules in ~/.config/hypr/edit_here/source/workspace_rules.lua +-- which is loaded last and overrides these defaults. +-- ============================================================================= +-- +-- IMMUTABLE BASE — Do not edit manually. +-- Standard workspace rules (1-10) and the global fallback (11-99) are strictly +-- managed by the Dusky TUI Variable-Proxy Engine. +-- (The user configuration is sourced via edit_here/hyprland.lua at the end of +-- the main entry point to ensure user priority.) diff --git a/.config/matugen/config.toml b/.config/matugen/config.toml index 20197b0b..a44f8f38 100644 --- a/.config/matugen/config.toml +++ b/.config/matugen/config.toml @@ -65,6 +65,11 @@ post_hook = ''' input_path = '~/.config/matugen/templates/hyprland-colors.conf' output_path = '~/.config/matugen/generated/hyprland-colors.conf' +[templates.hyprland_lua] +input_path = '~/.config/matugen/templates/hyprland-colors.lua' +output_path = '~/.config/matugen/generated/hyprland-colors.lua' +post_hook = 'hyprctl reload || :' + [templates.hyprlock] input_path = '~/.config/matugen/templates/hyprlock-colors.conf' output_path = '~/.config/matugen/generated/hyprlock-colors.conf' @@ -130,14 +135,14 @@ ln -nfs "$HOME/.config/matugen/generated/opencode.json" "$HOME/.config/opencode/ pkill -SIGUSR1 -x kitty || : ''' -# [templates.vscode] -# input_path = '~/.config/matugen/templates/vscode.json' -# output_path = '~/.config/matugen/generated/vscode.json' -# post_hook = ''' -# if command -v vscodium >/dev/null 2>&1; then -# ln -nfs "$HOME/.config/matugen/generated/vscode.json" "$HOME/.config/VSCodium/User/settings.json" -# fi -# ''' +[templates.vscode] +input_path = '~/.config/matugen/templates/vscode.json' +output_path = '~/.config/matugen/generated/vscode.json' +post_hook = ''' + if command -v code >/dev/null 2>&1; then + ln -nfs "$HOME/.config/matugen/generated/vscode.json" "$HOME/.config/Code/User/settings.json" + fi +''' # [templates.alacritty] # input_path = '~/.config/matugen/templates/alacritty.toml' @@ -166,12 +171,12 @@ post_hook = ''' ln -nfs "$HOME/.config/matugen/generated/yazi-theme.toml" "$HOME/.config/yazi/theme.toml" ''' -# [templates.zathura] -# input_path = '~/.config/matugen/templates/zathura-colors' -# output_path = '~/.config/matugen/generated/zathura-colors' -# post_hook = ''' -# ln -nfs "$HOME/.config/matugen/generated/zathura-colors" "$HOME/.config/zathura/zathurarc" -# ''' +[templates.zathura] +input_path = '~/.config/matugen/templates/zathura-colors' +output_path = '~/.config/matugen/generated/zathura-colors' +post_hook = ''' +ln -nfs "$HOME/.config/matugen/generated/zathura-colors" "$HOME/.config/zathura/zathurarc" +''' # [templates.starship] # input_path = '~/.config/matugen/templates/starship-colors.toml' @@ -214,15 +219,15 @@ post_hook = ''' fi ''' -# [templates.vesktop] -# input_path = '~/.config/matugen/templates/midnight-discord.css' -# output_path = '~/.config/matugen/generated/midnight-discord.css' -# post_hook = ''' -# if command -v vesktop >/dev/null 2>&1; then -# mkdir -p "$HOME/.config/vesktop/themes/" -# ln -nfs "$HOME/.config/matugen/generated/midnight-discord.css" "$HOME/.config/vesktop/themes/midnight-discord.css" -# fi -# ''' +[templates.vesktop] +input_path = '~/.config/matugen/templates/midnight-discord.css' +output_path = '~/.config/matugen/generated/midnight-discord.css' +post_hook = ''' +if command -v vesktop >/dev/null 2>&1; then + mkdir -p "$HOME/.config/vesktop/themes/" + ln -nfs "$HOME/.config/matugen/generated/midnight-discord.css" "$HOME/.config/vesktop/themes/midnight-discord.css" +fi +''' # [templates.beeper] # input_path = '~/.config/matugen/templates/beeper.css' @@ -234,16 +239,16 @@ post_hook = ''' # fi # ''' -# [templates.spicetify] -# input_path = '~/.config/matugen/templates/spotify-colors.ini' -# output_path = '~/.config/matugen/generated/spotify-colors.ini' -# post_hook = ''' -# if command -v spicetify >/dev/null 2>&1 && [ -d "$HOME/.config/spicetify/Themes/Comfy" ]; then -# ln -nfs "$HOME/.config/matugen/generated/spotify-colors.ini" "$HOME/.config/spicetify/Themes/Comfy/color.ini" -# spicetify apply -n || : -# hyprctl dispatch sendshortcut "CTRL_SHIFT, R, class:^(Spotify)$" || : -# fi -# ''' +[templates.spicetify] +input_path = '~/.config/matugen/templates/spotify-colors.ini' +output_path = '~/.config/matugen/generated/spotify-colors.ini' +post_hook = ''' +if command -v spicetify >/dev/null 2>&1 && [ -d "$HOME/.config/spicetify/Themes/Comfy" ]; then + ln -nfs "$HOME/.config/matugen/generated/spotify-colors.ini" "$HOME/.config/spicetify/Themes/Comfy/color.ini" + spicetify apply -n || : + hyprctl dispatch sendshortcut "CTRL SHIFT, R, class:^(spotify)$" || : +fi +''' # [templates.steam] # input_path = '~/.config/matugen/templates/steam.css' @@ -286,12 +291,12 @@ post_hook = ''' systemctl --user restart dusky.service || : ''' -[templates.dusky_quickpanal] +[templates.dusky_sliders] input_path = '/dev/null' output_path = '/dev/null' post_hook = ''' - systemctl --user reset-failed dusky_quickpanal.service || : - systemctl --user restart dusky_quickpanal.service || : + systemctl --user reset-failed dusky_sliders.service || : + systemctl --user restart dusky_sliders.service || : ''' @@ -319,8 +324,26 @@ post_hook = ''' # ''' [templates.firefox_websites] -input_path = '~/.config/matugen/templates/firefox_websites.css' +input_path = '~/.config/matugen/templates/firefox_websites.css' output_path = '~/.config/matugen/generated/firefox_websites.css' -post_hook = ''' - ln -nfs "/home/dusk/.config/matugen/generated/firefox_websites.css" "/home/dusk/.config/mozilla/firefox/tox6bnxb.default-release/chrome/colors.css" +post_hook = ''' + ln -nfs "$HOME/.config/matugen/generated/firefox_websites.css" "$HOME/.mozilla/firefox/nnnsdkhm.default-release/chrome/colors.css" +''' + +[templates.zen] +input_path = '~/.config/matugen/templates/zen-matugen.css' +output_path = '~/.config/zen/u8q2ykl6.Default (release)/chrome/matugen-colors.css' + +[templates.sddm_sync] +input_path = '~/.config/matugen/templates/colors.css' +output_path = '~/.config/matugen/generated/sddm-sync-check' +post_hook = 'printf "%s" "{{image}}" > /tmp/sddm-sync-pending' + +[templates.razer] +input_path = '~/.config/matugen/templates/razer_sync.sh' +output_path = '~/.config/matugen/generated/razer_sync.sh' +post_hook = ''' + if command -v polychromatic-cli >/dev/null 2>&1; then + bash ~/.config/matugen/generated/razer_sync.sh || : + fi ''' diff --git a/.config/matugen/templates/hyprland-colors.lua b/.config/matugen/templates/hyprland-colors.lua new file mode 100644 index 00000000..276f83fb --- /dev/null +++ b/.config/matugen/templates/hyprland-colors.lua @@ -0,0 +1,8 @@ +-- Generated by Matugen — do not edit manually. +-- Source image: {{image}} +-- Regenerate by running: theme_ctl refresh + +image = "{{image}}" +<* for name, value in colors *> +{{name}} = "rgba({{value.default.hex_stripped}}ff)" +<* endfor *> diff --git a/.config/matugen/templates/razer_sync.sh b/.config/matugen/templates/razer_sync.sh new file mode 100644 index 00000000..aa4409d8 --- /dev/null +++ b/.config/matugen/templates/razer_sync.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# Sync active theme color to Razer keyboard via Polychromatic. +# Set RAZER_DEVICE to match your device name (polychromatic-cli --list-devices). +# Skips silently if polychromatic-cli is not installed or no device is found. + +RAZER_DEVICE="${RAZER_DEVICE:-Razer Huntsman Mini}" +command -v polychromatic-cli >/dev/null 2>&1 || exit 0 + +# Stealing the light theme's primary color for maximum physical LED saturation and brightness +polychromatic-cli -n "$RAZER_DEVICE" -o static -c "{{colors.primary.light.hex}}" || : diff --git a/.config/waybar/01_horizontal_block/config.jsonc b/.config/waybar/01_horizontal_block/config.jsonc new file mode 100644 index 00000000..3fc881fa --- /dev/null +++ b/.config/waybar/01_horizontal_block/config.jsonc @@ -0,0 +1,284 @@ +//horizontal_block + +{ + "layer": "top", + "exclusive": true, + "reload_style_on_change": true, + "position": "top", + "spacing": 4, + "height": 40, + "margin-top": 6, + "margin-left": 10, + "margin-right": 10, + "margin-bottom": 0, + + // --- MODULE LAYOUT --- + "modules-left": [ + "custom/launcher", + "clock", + "custom/weather", + "custom/inhibit-suspend", + "custom/updates", + "custom/notification", + "custom/theme-toggle", + "custom/net-speed", + "tray" + ], + + "modules-center": [ + "hyprland/workspaces" + ], + + "modules-right": [ + "mpris", + "network", + "bluetooth", + "pulseaudio#output", + "backlight", + "cpu", + "memory", + "battery", + "custom/power" + ], + + // --- MODULE CONFIGURATION --- + + "custom/launcher": { + "format": "󰣇", + "on-click": "python3 ~/user_scripts/dusky_system/control_center/dusky_control_center.py", + "tooltip-format": "Control Center" + }, + + "clock": { + "format": "{:%I:%M %p}", + "format-alt": "󰃭 {:%A, %B %d}", + "tooltip-format": "{calendar}", + "on-click-right": "uwsm-app -- gnome-clocks", + "on-click-middle": "uwsm-app -- kitty --class peaclock -e peaclock", + "calendar": { + "mode": "month", + "mode-mon-col": 3, + "weeks-pos": "right", + "on-scroll": 1, + "format": { + "months": "{}", + "days": "{}", + "weeks": "W{}", + "weekdays": "{}", + "today": " {} " + } + } + }, + + "custom/weather": { + "format": "{}", + "exec": "curl -s 'wttr.in/?format=%c%t' | head -c 15", + "interval": 1800, + "tooltip-format": "Weather Conditions" + }, + + "custom/inhibit-suspend": { + "format": "{}", + "exec": "if pgrep -x 'hypridle' > /dev/null; then echo '{\"text\": \"󰾪\", \"tooltip\": \"Idle enabled. Click to disable.\", \"class\": \"enabled\"}'; else echo '{\"text\": \"󰅶\", \"tooltip\": \"Idle disabled. Click to enable.\", \"class\": \"disabled\"}'; fi", + "return-type": "json", + "interval": 5, + "signal": 9, + "on-click": "uwsm-app -- ~/user_scripts/waybar/toggle_hypridle.sh", + "escape": true + }, + + "custom/updates": { + "format": "󰏔 {}", + "exec": "checkupdates 2>/dev/null | wc -l || echo 0", + "interval": 3600, + "on-click": "kitty sh -c 'command -v yay >/dev/null && yay || paru'", + "tooltip-format": "System Updates" + }, + + "custom/notification": { + "format": "{icon}", + "format-icons": { + "notification": "󱅫", + "none": "󰂚", + "dnd-notification": "󱏧", + "dnd-none": "󰂛", + "inhibited-notification": "󱅫", + "inhibited-none": "󰂚", + "dnd-inhibited-notification": "󱏧", + "dnd-inhibited-none": "󰂛" + }, + "return-type": "json", + "exec-if": "which makoctl", + "exec": "~/user_scripts/waybar/mako.sh", + "on-click": "~/user_scripts/rofi/rofi_mako.sh", + "on-click-right": "makoctl mode -t do-not-disturb && pkill -RTMIN+8 waybar", + "signal": 8, + "escape": true, + "tooltip-format": "Notifications\n\n LMB Toggle Panel\n RMB Do Not Disturb" + }, + + "custom/theme-toggle": { + "format": "", + "tooltip-format": "Theme Controls\n\n LMB Dark Mode\n RMB Light Mode\n MMB Wallpaper", + "on-click": "uwsm-app -- ~/user_scripts/theme_matugen/theme_ctl.sh set --mode dark", + "on-click-right": "uwsm-app -- ~/user_scripts/theme_matugen/theme_ctl.sh set --mode light", + "on-click-middle": "uwsm-app -- waypaper" + }, + + "tray": { + "icon-size": 15, + "spacing": 6, + "show-passive-items": true + }, + + "hyprland/workspaces": { + "on-click": "activate", + "format": "{icon}", + "format-window-separator": " ", + "window-rewrite-default": "", + "window-rewrite": { + "class": "", + "class": "", + "class": "", + "class": "󰕼", + "class": "󰨞", + "class": "󰝰", + "class": "", + "class": "󰎞" + }, + "persistent-workspaces": { + "*": 5 + }, + "on-scroll-up": "hyprctl dispatch workspace e-1", + "on-scroll-down": "hyprctl dispatch workspace e+1" + }, + + "mpris": { + "format": "{player_icon} {title}", + "format-paused": "{status_icon} {title}", + "format-stopped": "", + "max-length": 25, + "player-icons": { + "default": "󰎆", + "mpv": "󰎇", + "spotify": "󰓇", + "firefox": "󰈹" + }, + "status-icons": { + "paused": "󰏤" + }, + "tooltip-format": "{player} - {artist}\n{title}\n{album}", + "on-click": "playerctl play-pause", + "on-scroll-up": "playerctl next", + "on-scroll-down": "playerctl previous" + }, + + "custom/net-speed": { + "exec": "$HOME/user_scripts/waybar/network/network_meter_calling.sh --horizontal", + "return-type": "json", + "format": "{}", + "interval": 1, + "tooltip": true + }, + + "network": { + "format-wifi": "󰤨", + "format-ethernet": "󰈀", + "format-disconnected": "󰤭", + "format-linked": "󰈁", + "tooltip-format-wifi": "󰤨 {essid}\n󱑽 {signalStrength}%\n󰩟 {ipaddr}", + "tooltip-format-ethernet": "󰈀 Ethernet\n󰩟 {ipaddr}", + "tooltip-format-disconnected": "󰤭 Disconnected", + "on-click": "uwsm-app -- kitty --class wifitui -e wifitui" + }, + + "bluetooth": { + "format": "󰂯", + "format-disabled": "󰂲", + "format-connected": "󰂱 {num_connections}", + "format-connected-battery": "󰂱 {device_battery_percentage}%", + "tooltip-format": "{controller_alias}\n{controller_address}\n\n{device_enumerate}", + "tooltip-format-connected": "{controller_alias}\n\n{device_enumerate}", + "tooltip-format-enumerate-connected": "󰂱 {device_alias}", + "tooltip-format-enumerate-connected-battery": "󰂱 {device_alias} ({device_battery_percentage}%)", + "on-click": "uwsm-app -- blueman-manager", + "on-click-right": "uwsm-app -- kitty --class bluetui -e bluetui" + }, + + "pulseaudio#output": { + "format": "{icon} {volume}%", + "format-muted": "󰖁", + "format-bluetooth": "󰂰 {volume}%", + "format-bluetooth-muted": "󰂲", + "format-icons": { + "headphone": "󰋋", + "hands-free": "󰋎", + "headset": "󰋎", + "phone": "", + "portable": "", + "car": "", + "default": ["󰕿", "󰖀", "󰕾"] + }, + "on-click": "uwsm-app -- pavucontrol", + "on-click-right": "uwsm-app -- kitty --class cava -e cava", + "on-click-middle": "pactl set-sink-mute @DEFAULT_SINK@ toggle", + "on-scroll-up": "pactl set-sink-volume @DEFAULT_SINK@ +5%", + "on-scroll-down": "pactl set-sink-volume @DEFAULT_SINK@ -5%", + "tooltip-format": "{desc}\nVolume: {volume}%\n\nLMB: Pavucontrol\nRMB: Cava\nMMB: Mute Toggle\nScroll: Volume", + "scroll-step": 5, + "max-volume": 150 + }, + + "backlight": { + "format": "{icon} {percent}", + "tooltip-format": "Brightness: {percent}%\n\n LMB Brightness\n RMB Night Light\n MMB Shaders", + "on-click": "uwsm-app -- ~/user_scripts/sliders/dusky_sliders.py", + "on-click-right": "uwsm-app -- ~/user_scripts/sliders/dusky_sliders.py", + "on-click-middle": "uwsm-app -- ~/user_scripts/rofi/shader_menu.sh", + "on-scroll-up": "brightnessctl set +5%", + "on-scroll-down": "brightnessctl set 5%-", + "format-icons": ["󰃞", "󰃟", "󰃠"] + }, + + "cpu": { + "interval": 2, + "format": "󰍛 {usage}%", + "on-click": "kitty -e btop", + "states": { + "warning": 70, + "critical": 90 + } + }, + + "memory": { + "interval": 2, + "format": "󰘚 {percentage}%", + "on-click": "uwsm-app -- kitty --class io_monitor.sh -e $HOME/user_scripts/drives/io_monitor.sh", + "states": { + "warning": 70, + "critical": 90 + } + }, + + "battery": { + "states": { + "good": 80, + "warning": 30, + "critical": 15 + }, + "on-click": "uwsm-app -- kitty --class power_saver.sh --hold -e $HOME/user_scripts/battery/power_saving/power_saver.sh", + "on-click-right": "uwsm-app -- kitty --class dusky_hypridle.sh -e $HOME/user_scripts/hypridle/dusky_hypridle.sh", + "format": "{icon} {capacity}%", + "format-charging": "󰂄 {capacity}%", + "format-plugged": "󰚥 {capacity}%", + "format-full": "󰁹 Full", + "tooltip-format": "{timeTo}\n\n󱟦 Health: {health}%\n󱐋 Power: {power:.2f}W", + "format-icons": ["󰂎", "󰁺", "󰁻", "󰁼", "󰁽", "󰁾", "󰁿", "󰂀", "󰂁", "󰂂", "󰁹"] + }, + + "custom/power": { + "format": "⏻", + "on-click": "uwsm-app -- ~/user_scripts/wlogout/wlogout_scale.sh", + "tooltip-format": "Power Menu" + } +} diff --git a/.zshrc b/.zshrc deleted file mode 100644 index cd11873d..00000000 --- a/.zshrc +++ /dev/null @@ -1,768 +0,0 @@ -# ============================================================================= -# ~/.zshrc - Zsh Configuration -# -# This configuration is structured for clarity and performance. -# Sections are ordered logically: -# 1. Environment Variables & Path -# 2. History Configuration -# 3. Completion System -# 4. Keybindings (Vi-Mode) -# 5. Aliases and Functions -# 6. Plugin & Prompt Initialization -# 7. Auto login INTO UWSM HYPRLAND WITH TTY1 -# ============================================================================= - -# Exit early if not interactive -[[ -o interactive ]] || return - -# ----------------------------------------------------------------------------- -# [1] ENVIRONMENT VARIABLES & PATH -# ----------------------------------------------------------------------------- -# Set core applications and configure the system's search path for executables. -# These are fundamental for defining your work environment. - -# Set the default terminal emulator. -export TERMINAL='kitty' -# Set the default web browser. -#export BROWSER='firefox' - -# Set the default editor (Critical for TTY/SSH/Yazi) -export EDITOR='nvim' -export VISUAL='nvim' - -# --- Compilation Optimization --- -# 1. Parallelism: Use ALL available processing units. -# $(nproc) dynamically counts cores on any machine this runs on. -export MAKEFLAGS="-j$(nproc)" - -# --- Pyenv (Python Version Management) --- -# Initializes pyenv to manage multiple Python versions. - -## export PYENV_ROOT="$HOME/.pyenv" -## export PATH="$PYENV_ROOT/bin:$PATH" -## if command -v pyenv 1>/dev/null 2>&1; then -## eval "$(pyenv init --path)" -## eval "$(pyenv init -)" -## fi - -# Configure the path where Zsh looks for commands. -# Uncomment and modify if you have local binaries (e.g., in ~/.local/bin). -# export PATH="$HOME/.local/bin:$PATH" - -# ----------------------------------------------------------------------------- -# [2] HISTORY CONFIGURATION -# ----------------------------------------------------------------------------- -# Configure how Zsh records and manages your command history. Robust history -# settings are crucial for an efficient workflow. - -# Set the number of history lines to keep in memory during the session. -HISTSIZE=50000 -# Set the number of history lines to save in the history file (~/.zsh_history). -SAVEHIST=25000 -# Specify the location of the history file. -HISTFILE=~/.zsh_history - -# Use `setopt` to fine-tune history behavior. -setopt APPEND_HISTORY # Append new history entries instead of overwriting. -setopt INC_APPEND_HISTORY # Write history to file immediately after command execution. -setopt SHARE_HISTORY # Share history between all concurrent shell sessions. -setopt HIST_EXPIRE_DUPS_FIRST # When trimming history, delete duplicates first. -setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again. -setopt HIST_IGNORE_SPACE # Ignore commands starting with space. -setopt HIST_VERIFY # Expand history (!!) into the buffer, don't run immediately. - -# ----------------------------------------------------------------------------- -# [3] COMPLETION SYSTEM -# ----------------------------------------------------------------------------- - -setopt EXTENDED_GLOB # Enable extended globbing features (e.g., `^` for negation). - -# Optimized initialization: Only regenerate cache once every 24 hours. -autoload -Uz compinit -local zcompdump="${ZDOTDIR:-$HOME}/.zcompdump" -local dump_cache=($zcompdump(#qN.mh-24)) # Array expansion forces glob evaluation without subshells - -if (( ${#dump_cache} )); then - compinit -C # Trust the fresh cache, skip checks (FAST) -else - compinit # Cache is old or missing, regenerate it (SLOW) - # Explicitly touch the file to reset the timer - touch "$zcompdump" -fi - -# Style the completion menu. -# ':completion:*' is a pattern that applies to all completion widgets. -zstyle ':completion:*' menu select # Enable menu selection on the first Tab press. -zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}" # Colorize the completion menu using LS_COLORS. -zstyle ':completion:*:descriptions' format '%B%d%b' # Format descriptions for clarity (bold). -zstyle ':completion:*' group-name '' # Group completions by type without showing group names. -zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' # Case-insensitive matching. - -# ----------------------------------------------------------------------------- -# [4] KEYBINDINGS & SHELL OPTIONS -# ----------------------------------------------------------------------------- -# Define keybindings and enable various shell options for a better user experience. - -# --- Vi Mode Keybindings --- -# Enables the use of Vim-like keybindings in the shell for modal editing. -bindkey -v -# Set the timeout for ambiguous key sequences (in centiseconds). -# 1 = 10ms, making the transition to normal mode in Vi mode practically instantaneous. -export KEYTIMEOUT=1 - -# --- Neovim Integration --- -# Press 'v' in normal mode to edit the current command in Neovim. -autoload -U edit-command-line -zle -N edit-command-line -bindkey -M vicmd v edit-command-line - -# --- Search History with Up/Down --- -# If you type "git" and press Up, it finds the last "git" command. -autoload -U history-search-end -zle -N history-beginning-search-backward-end history-search-end -zle -N history-beginning-search-forward-end history-search-end -bindkey "${terminfo[kcuu1]:-^[[A}" history-beginning-search-backward-end -bindkey "${terminfo[kcud1]:-^[[B}" history-beginning-search-forward-end - -# --- General Shell Options (`setopt`) --- -setopt INTERACTIVE_COMMENTS # Allow comments (like this one) in an interactive shell. -setopt GLOB_DOTS # Include dotfiles (e.g., .config) in globbing results. -setopt NO_CASE_GLOB # Perform case-insensitive globbing. -setopt AUTO_PUSHD # Automatically push directories onto the directory stack. -setopt PUSHD_IGNORE_DUPS # Don't push duplicate directories onto the stack. - - -# ----------------------------------------------------------------------------- -# [5] ALIASES & FUNCTIONS -# ----------------------------------------------------------------------------- -# Define shortcuts (aliases) and small scripts (functions) to reduce typing -# and streamline common tasks. - -# --- Aliases --- - -# alias ls='ls --color=auto' # Always use color for `ls`. -# alias la='ls -A' # List all entries except for . and .. -# alias ll='ls -alF' # List all files in long format. -# alias l='ls -CF' # List entries by columns. - -# Safety First -alias cp='cp -iv' -alias mv='mv -iv' -alias rm='rm -I' -alias ln='ln -v' - -alias disk_usage='sudo btrfs filesystem usage /' # The TRUTH about BTRFS space -alias df='df -hT' # Show filesystem types - -# VNC iphone daemon. -alias iphone_vnc='~/user_scripts/networking/iphone_vnc.sh' - -# wifi security -alias wifi_security='~/user_scripts/networking/ax201_wifi_testing.sh' - -#Theme Switcher -alias darkmode='~/user_scripts/theme_matugen/matugen_config.sh --mode dark' -alias lightmode='~/user_scripts/theme_matugen/matugen_config.sh --mode light' - -#submit logs -alias sendlogs='~/user_scripts/arch_setup_scripts/send_logs.sh --auto' - -# update dusky -alias update_dusky='~/user_scripts/update_dusky/update_dusky.sh' - -# update dusky reset -alias dusky_force_sync_github='~/user_scripts/update_dusky/dusky_force_sync_github.sh' - -# Check if eza is installed -if command -v eza >/dev/null; then - alias ls='eza --icons --group-directories-first' - alias ll='eza --icons --group-directories-first -l --git' - alias la='eza --icons --group-directories-first -la --git' - alias lt='eza --icons --group-directories-first --tree --level=2' -else - # Fallback to standard ls if eza is missing - alias ls='ls --color=auto' - alias ll='ls -lh' - alias la='ls -A' -fi - -alias diff='delta --side-by-side' -alias grep='grep --color=auto' -alias egrep='egrep --color=auto' -alias fgrep='fgrep --color=auto' - -#alias cat='bat' - -#alias for using gdu instead of ncdu -alias ncdu='gdu' - -#alias for disk io realtime. -alias io_drives='~/user_scripts/drives/io_monitor.sh' - -# 1. Base Bare Repo Alias -# (Defined first for logical clarity, though strictly not required by Zsh) -alias git_dusky='/usr/bin/git --git-dir=$HOME/dusky/ --work-tree=$HOME' - -# 2. Add List Alias (FIXED with Subshell) -# The ( ) runs this specific command inside $HOME so the paths match, -# but it DOES NOT change your actual terminal directory. -alias git_dusky_add_list='(cd $HOME && git_dusky add --pathspec-from-file=.git_dusky_list)' - -# 3. Alias for discarding all local changes (both staged and unstaged) and revert the state of tracked files to exactly match the last commit (HEAD), this is a destructive operation. (DANGER ZONE) -alias git_dusky_restore='echo "git --git-dir=$HOME/dusky/ --work-tree=$HOME reset --hard HEAD" && git_dusky reset --hard HEAD' - -# 4. Delta/Diff Alias -alias gitdelta='git_dusky_add_list && git_dusky diff HEAD' - -# 5. Lazygit Bare Repo Alias -alias lazygit_dusky='lazygit --git-dir=$HOME/dusky/ --work-tree=$HOME' - -# unlock block_devices -alias unlock='$HOME/user_scripts/drives/drive_manager.sh unlock' - -# lock block_devices -alias lock='$HOME/user_scripts/drives/drive_manager.sh lock' - - -# Battery stats - -batstat() { - # Isolate shell options for predictable execution - emulate -L zsh - - local bat="" target="" mode="static" output_format="human" - local arg d dev_type cap stat curr volt power - float watts=0.0 - - # The Architect-Grade Help Page - _show_help() { - printf "\e[1;34m::\e[0m \e[1mbatstat\e[0m - Zero-fork battery monitor\n\n" - printf "\e[1mUSAGE:\e[0m\n" - printf " batstat [COMMAND] [FORMAT] [TARGET]\n\n" - printf "\e[1mCOMMANDS:\e[0m\n" - printf " \e[32mhelp\e[0m Show this help page (default with no args)\n" - printf " \e[32mstatic\e[0m Print the current battery stats once and exit\n" - printf " \e[32mlive\e[0m Run a flicker-free, 1-second updating TUI\n\n" - printf "\e[1mFORMATS (Static mode only):\e[0m\n" - printf " \e[32mhuman\e[0m Standard readable output (default)\n" - printf " \e[32mjson\e[0m Output as a JSON object (for Waybar/Eww integration)\n" - printf " \e[32mterse\e[0m Raw values only: \n\n" - printf "\e[1mTARGET:\e[0m\n" - printf " Optional battery name (e.g., BAT1, macsmc-battery).\n" - printf " If omitted, auto-detects the first available battery natively.\n\n" - printf "\e[1mEXAMPLES:\e[0m\n" - printf " batstat live\n" - printf " batstat static json\n" - printf " batstat terse static BAT1\n" - } - - # Trigger help if absolutely no arguments are passed - if (( $# == 0 )); then - _show_help - return 0 - fi - - # Order-independent argument parser - for arg in "$@"; do - case "$arg" in - help|-h|--help) _show_help; return 0 ;; - live) mode="live" ;; - static) mode="static" ;; - json) output_format="json" ;; - terse) output_format="terse" ;; - human) output_format="human" ;; - *) target="$arg" ;; # Unrecognized flags are assumed to be battery targets - esac - done - - # Hardware Detection: Target specific battery or find the first one natively - if [[ -n "$target" && -d "/sys/class/power_supply/$target" ]]; then - bat="/sys/class/power_supply/$target" - else - # (N) prevents failure if the directory is completely empty - for d in /sys/class/power_supply/*(N); do - if [[ -f "$d/type" ]]; then - read -r dev_type < "$d/type" 2>/dev/null - if [[ "$dev_type" == "Battery" ]]; then - bat="$d" - break - fi - fi - done - fi - - if [[ -z "$bat" ]]; then - printf "Error: No battery detected in /sys/class/power_supply/\n" >&2 - return 1 - fi - - # Core Logic: True Zero-Fork - _get_bat_stats() { - read -r cap < "$bat/capacity" 2>/dev/null - read -r stat < "$bat/status" 2>/dev/null - - cap=${cap:-"N/A"} - stat=${stat:-"Unknown"} - - # Native Zsh floating-point arithmetic - if [[ -f "$bat/power_now" ]]; then - read -r power < "$bat/power_now" 2>/dev/null - (( watts = ${power:-0} / 1000000.0 )) - elif [[ -f "$bat/current_now" && -f "$bat/voltage_now" ]]; then - read -r curr < "$bat/current_now" 2>/dev/null - read -r volt < "$bat/voltage_now" 2>/dev/null - (( watts = (${curr:-0} * ${volt:-0}) / 1000000000000.0 )) - fi - - # Route the output format - if [[ "$output_format" == "json" ]]; then - printf '{"capacity": "%s", "power_w": %.2f, "status": "%s"}' "$cap" "$watts" "$stat" - elif [[ "$output_format" == "terse" ]]; then - printf "%s %.2f %s" "$cap" "$watts" "$stat" - else - printf "Capacity: %s%% | Power Draw: %.2f W (%s)" "$cap" "$watts" "$stat" - fi - } - - # Execution Engine - if [[ "$mode" == "live" ]]; then - # UX Guardrail: Prevent JSON/Terse spam in the live TUI - if [[ "$output_format" != "human" ]]; then - printf "Warning: '%s' format is meant for static scripts. Forcing 'human' output for live TUI.\n" "$output_format" >&2 - output_format="human" - sleep 1.5 - fi - - printf "\e[?25l" # Hide cursor - - # Zsh native 'always' block guarantees clean teardown - { - while true; do - printf "\r\e[K" - _get_bat_stats - sleep 1 - done - } always { - printf "\e[?25h\n" # Restore cursor and drop a clean newline - } - else - _get_bat_stats - printf "\n" - fi -} - - -# Weather query via wttr.in -# Usage: wthr [location] -# use with "-s" flag to only get one line. -wthr() { - # Check if the first argument is '-s' (short) - if [[ "$1" == "-s" ]]; then - shift # Remove the -s from arguments - local location="${(j:+:)@}" - curl "wttr.in/${location}?format=%c+%t" - else - local location="${(j:+:)@}" - curl "wttr.in/${location}" - fi -} - - -# for troubleshoting scripts -source ~/.config/zshrc/logs -source ~/.config/zshrc/logs_old - -# share zram1 directory with waydroid at pictures point inside waydroid -# Function to remount Waydroid pictures to ZRAM -waydroid_bind() { - local target="$HOME/.local/share/waydroid/data/media/0/Pictures" - local source="/mnt/zram1" - - # 1. Attempt to unmount recursively. - # 2>/dev/null silences the error if it's not mounted. - # || true ensures the script doesn't abort if you have 'set -e' active or strict chaining. - sudo umount -R "$target" 2>/dev/null || true - - # 2. Perform the bind mount - # We check if the source exists first to avoid mounting nothing. - if [[ -d "$source" ]]; then - sudo mount --bind "$source" "$target" - echo "Successfully bound $source to Waydroid Pictures." - else - echo "Error: Source $source does not exist." - return 1 - fi -} - -# === -# use `command sudo nvim ...` to escape the funtion if you ever dont want sudoedit to be used. -# === -# sudo edit nvim sudoedit -# Function to intercept 'sudo nvim' and convert it to 'sudoedit' -sudo() { - # Check if we are trying to run nvim - if [[ "$1" == "nvim" ]]; then - shift # Remove 'nvim' - - # Check if there are actually files to edit - if [[ $# -eq 0 ]]; then - echo "Error: sudoedit requires a filename." - return 1 - fi - - # Pass the filenames to sudoedit - command sudoedit "$@" - else - # Run standard sudo for everything else - command sudo "$@" - fi -} - -# YAZI -#change the current working directory when exiting Yazi - -function y() { - local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" cwd - yazi "$@" --cwd-file="$tmp" - if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then - builtin cd -- "$cwd" - fi - rm -f -- "$tmp" -} - -# --- sysbench benchmark --- -alias run_sysbench='~/user_scripts/performance/sysbench_benchmark.sh' - -# --- nvidia vfio bind/unbind --- -alias nvidia_bind='~/user_scripts/nvidia_passthrough/nvidia_vfio_bind_unbind.sh --bind' -alias nvidia_unbind='~/user_scripts/nvidia_passthrough/nvidia_vfio_bind_unbind.sh --unbind' - -#-- LM- Studio-- -llm() { - /mnt/media/Documents/do_not_delete_linux/appimages/LM-Studio*(om[1]) "$@" -} -# The (om[1]) glob qualifier picks the most recently modified file (newest first) - -# --- Functions --- -# Creates a directory and changes into it. -mkcd() { - mkdir -p "$1" && cd "$1" -} - -# --- Windows 10 KVM Manager --- -# HOW TO USE -# Start VM: win start -# Open Looking Glass: win view -# Do both (One-click gaming): win launch -# Kill it: win kill - -win() { - local vm="win10" - local shm_file="/dev/shm/looking-glass" - local lg_cmd="looking-glass-client -f ${shm_file} -m KEY_F6" - - # Helper for colored output - local p_info() { echo -e "\e[34m[WIN10]\e[0m $1"; } - local p_err() { echo -e "\e[31m[ERROR]\e[0m $1"; } - - case "$1" in - start) - p_info "Starting VM..." - sudo virsh start "$vm" - ;; - stop|shutdown) - p_info "Sending shutdown signal..." - sudo virsh shutdown "$vm" - ;; - kill|destroy) - p_info "Forcefully destroying VM..." - sudo virsh destroy "$vm" - ;; - reboot) - p_info "Rebooting VM..." - sudo virsh reboot "$vm" - ;; - view|lg|show) - if [ -f "$shm_file" ]; then - p_info "Launching Looking Glass..." - eval "$lg_cmd" - else - p_err "Looking Glass SHM file not found. Is the VM running?" - fi - ;; - # --- Advanced Options --- - launch|play) - # Starts VM and waits for Looking Glass to be ready - p_info "Two birds one stone: Starting VM and waiting for Looking Glass..." - sudo virsh start "$vm" 2>/dev/null - - p_info "Waiting for Shared Memory..." - # Efficient bash wait loop (timeout after 30s) - local timeout=30 - while [ ! -f "$shm_file" ] && [ $timeout -gt 0 ]; do - sleep 1 - ((timeout--)) - done - - if [ -f "$shm_file" ]; then - p_info "Ready! Launching Client..." - eval "$lg_cmd" - else - p_err "Timed out waiting for VM graphics." - fi - ;; - status) - sudo virsh domstate "$vm" - ;; - edit) - sudo virsh edit "$vm" - ;; - *) - echo "Usage: win {start|shutdown|destroy|reboot|view|launch|status|edit}" - ;; - esac -} - -# --- Auto-Completion for 'win' --- -# This makes hitting 'tab' show your options -_win_completion() { - local -a commands - commands=('start' 'shutdown' 'destroy' 'reboot' 'view' 'launch' 'status' 'edit') - _describe 'command' commands -} -compdef _win_completion win - - -# ============================================================================= -# Pacman/Expac Utility: Unified Package Querying (Platinum Edition) -# Usage: pkg [count] -# ============================================================================= - -# DRY Header Helper — defined once at source time. -# Args: $1 = title string, $2 = count integer -_pkg_header() { - print -P "\n%F{blue}::%f %B${1}%b (Top ${2})" - print -P "%F{238}------------------------------------------------------------%f" - # Precisely aligned header: 19 chars (Date) + 2 spaces + 8 chars (Size) + 2 spaces + Package - print -P "%F{242}INSTALL DATE SIZE PACKAGE%f" - print -P "%F{238}------------------------------------------------------------%f" -} - -pkg() { - # 1. Dependency Validation - if (( ! $+commands[expac] )); then - print -u2 -P "\n%F{red}✖ Error:%f 'expac' is not installed." - print -u2 -P " Please install it first: %F{cyan}sudo pacman -S expac%f\n" - return 1 - fi - - # 2. State Initialization - local target="all" - local metric="" - local -i count=20 - local -i show_help=0 - - if (( $# == 0 )); then - show_help=1 - fi - - # 3. Argument Tokenizer: Case-insensitive, order-agnostic - for arg in "$@"; do - case "${arg:l}" in - help|-h|--help) - show_help=1 - ;; - explicit|user) - target="explicit" - ;; - all) - target="all" - ;; - hogs|size) - metric="size" - ;; - new|recent|latest) - metric="new" - ;; - old|ancient) - metric="old" - ;; - *) - if [[ "$arg" =~ ^[1-9][0-9]*$ ]]; then - count="$arg" - else - print -u2 -P "\n%F{red}✖ Error:%f Unknown argument or invalid count: '%F{yellow}$arg%f'" - print -u2 -P " Run %F{green}pkg help%f for usage details.\n" - return 1 - fi - ;; - esac - done - - # 4. Help Menu Overlay - if (( show_help )); then - print -P "\n%F{blue}::%f %Bpkg%b — Advanced Package Query Tool" - print -P "%F{238}------------------------------------------------------------%f" - print -P "%F{green}Usage:%f pkg [target] [metric] [count]" - print -P " %F{242}(Arguments can be provided in ANY order)%f\n" - - print -P "%BTargets:%b (Default: all)" - print -P " %F{cyan}all%f - System-wide packages (includes dependencies)" - print -P " %F{cyan}explicit%f, %F{cyan}user%f - Only packages you explicitly installed\n" - - print -P "%BMetrics:%b (Default: size)" - print -P " %F{cyan}size%f, %F{cyan}hogs%f - Sort by installed size (largest first)" - print -P " %F{cyan}new%f, %F{cyan}recent%f, %F{cyan}latest%f - Sort by installation date (newest first)" - print -P " %F{cyan}old%f, %F{cyan}ancient%f - Sort by installation date (oldest first)\n" - - print -P "%BExamples:%b" - print -P " %F{yellow}pkg explicit new 20%f # Top 20 most recently explicitly installed" - print -P " %F{yellow}pkg 50 size%f # Top 50 largest packages overall" - print -P " %F{yellow}pkg old%f # Top 20 oldest packages overall\n" - return 0 - fi - - # Set default metric - [[ -z "$metric" ]] && metric="size" - - # 5. Dynamic Pipeline Construction - # We lock expac to ALWAYS output: Date | Size(bytes) | Name - local -a expac_args=(--timefmt='%Y-%m-%d %H:%M:%S' '%l|%m|%n') - local -a sort_cmd - local title_metric="" - - # We sort against specific pipe-delimited columns (-t '|') - case "$metric" in - size) - title_metric="Largest" - sort_cmd=(sort -t '|' -k2 -rn) # Sort numerically by column 2 (Size) - ;; - new) - title_metric="Newest" - sort_cmd=(sort -t '|' -k1 -r) # Sort reverse-chronologically by column 1 (Date) - ;; - old) - title_metric="Oldest" - sort_cmd=(sort -t '|' -k1) # Sort chronologically by column 1 (Date) - ;; - esac - - local title_full="" - if [[ "$target" == "explicit" ]]; then - title_full="${title_metric} Explicitly Installed Packages" - else - title_full="${title_metric} Installed Packages (Overall)" - fi - - # 6. Core Execution Pipeline - _pkg_header "$title_full" "$count" - - # Raw ANSI color injection via Awk stream processing - # $1 = Date(Grey), $2 = Size(Yellow), $3 = Name(Bold Arch Blue) - local awk_color='{ printf "\033[38;5;246m%s\033[0m \033[38;5;220m%s\033[0m \033[1;38;5;39m%s\033[0m\n", $1, $2, $3 }' - - # Notice the `numfmt --padding=8`. This guarantees right-alignment of sizes (e.g. ' 4.8GiB') without needing `column` - if [[ "$target" == "explicit" ]]; then - pacman -Qeq | expac "${expac_args[@]}" - 2>/dev/null | "${sort_cmd[@]}" | head -n "$count" | numfmt --to=iec-i --suffix=B --field=2 --delimiter='|' --padding=8 | awk -F '|' "$awk_color" - else - expac "${expac_args[@]}" 2>/dev/null | "${sort_cmd[@]}" | head -n "$count" | numfmt --to=iec-i --suffix=B --field=2 --delimiter='|' --padding=8 | awk -F '|' "$awk_color" - fi - - print "" -} - -# Native Zsh tab-completion — proper named function, unambiguously correct. -_pkg() { - _arguments \ - "1:command:(hogs size all explicit user new recent latest old ancient help)" \ - "2:count: " -} -compdef _pkg pkg - -# ----------------------------------------------------------------------------- -# [6] PLUGINS & PROMPT INITIALIZATION -# ----------------------------------------------------------------------------- -# Self-Healing Cache: -# 1. Checks if the static init file exists. -# 2. Checks if the binary (starship/fzf) has been updated (is newer than the cache). -# 3. Regenerates the cache automatically if needed. - -# --- Starship Prompt --- -# Define paths -_starship_cache="$HOME/.starship-init.zsh" -_starship_bin="$(command -v starship)" - -# Only proceed if starship is actually installed -if [[ -n "$_starship_bin" ]]; then - if [[ ! -f "$_starship_cache" || "$_starship_bin" -nt "$_starship_cache" ]]; then - starship init zsh --print-full-init >! "$_starship_cache" - fi - source "$_starship_cache" -fi - -# --- Fuzzy Finder (fzf) --- -_fzf_cache="$HOME/.fzf-init.zsh" -_fzf_bin="$(command -v fzf)" - -if [[ -n "$_fzf_bin" ]]; -then - # Check if fzf supports the --zsh flag -if $_fzf_bin --zsh > /dev/null 2>&1; then - if [[ ! -f "$_fzf_cache" || "$_fzf_bin" -nt "$_fzf_cache" ]]; then - $_fzf_bin --zsh >! "$_fzf_cache" - fi - source "$_fzf_cache" - else - # Fallback for older fzf versions - if [[ -f ~/.fzf.zsh ]]; then - source ~/.fzf.zsh - fi - fi -fi - - -# -- Zoxide (Cached) -- -_zoxide_cache="$HOME/.zoxide-init.zsh" -_zoxide_bin="$(command -v zoxide)" - -if [[ -n "$_zoxide_bin" ]]; then - if [[ ! -f "$_zoxide_cache" || "$_zoxide_bin" -nt "$_zoxide_cache" ]]; then - "$_zoxide_bin" init zsh >! "$_zoxide_cache" - fi - source "$_zoxide_cache" -fi -unset _zoxide_cache _zoxide_bin - - -# --- Autosuggestions --- -if [ -f /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh ]; then - # Config MUST be set before sourcing - ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=60' - source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh -fi - -# --- Syntax Highlighting (Must be last) --- -if [[ -f "/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]]; then - source "/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" -fi - - - -# Cleanup variables to keep environment clean -unset _starship_cache _starship_bin _fzf_cache _fzf_bin - -# ----------------------------------------------------------------------------- -# [7] Auto login INTO UWSM HYPRLAND WITH TTY1 -# ----------------------------------------------------------------------------- - -# Check if we are on tty1 and no display server is running -# Using native $TTY and $WAYLAND_DISPLAY variables avoids the overhead of spawning $(tty) subshells -if [[ -z "$DISPLAY" && -z "$WAYLAND_DISPLAY" && "$TTY" == "/dev/tty1" ]]; then - if uwsm check may-start; then - exec uwsm start hyprland.desktop - fi -fi - -# ============================================================================= -# End of ~/.zshrc -# ============================================================================= diff --git a/Documents/pensive/.obsidian/snippets/matugen-theme.css b/Documents/pensive/.obsidian/snippets/matugen-theme.css deleted file mode 120000 index 0551d8af..00000000 --- a/Documents/pensive/.obsidian/snippets/matugen-theme.css +++ /dev/null @@ -1 +0,0 @@ -/home/dusk/.config/matugen/generated/obsidian-theme.css \ No newline at end of file diff --git a/user_scripts/arch_setup_scripts/scripts/235_file_manager_switch.sh b/user_scripts/arch_setup_scripts/scripts/235_file_manager_switch.sh index 5b11ed19..445d360d 100755 --- a/user_scripts/arch_setup_scripts/scripts/235_file_manager_switch.sh +++ b/user_scripts/arch_setup_scripts/scripts/235_file_manager_switch.sh @@ -48,7 +48,7 @@ declare -ra FM_CATALOG=( ) # Paths -declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.conf" +declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.lua" declare -r CONF_BINDS="${HOME}/.config/hypr/edit_here/source/keybinds.conf" declare -r STATE_FILE="${HOME}/.config/dusky/settings/filemanager_switch" @@ -175,7 +175,7 @@ switch_file_manager() { return 1 fi - # 2. Update Variable (default_apps.conf) + # 2. Update Variable (default_apps.lua) if [[ ! -f "$CONF_VARS" ]]; then log_action 1 "Config not found: $CONF_VARS" return 1 @@ -184,49 +184,16 @@ switch_file_manager() { local new_vars new_vars=$(awk -v val="$target" ' BEGIN { found=0 } - /^[\t ]*\$fileManager[\t ]*=/ { - print "$fileManager = " val + /^[\t ]*fileManager[\t ]*=/ { + print "fileManager = \"" val "\"" found=1 next } { print } - END { if(!found) print "$fileManager = " val } + END { if(!found) print "fileManager = \"" val "\"" } ' "$CONF_VARS") atomic_write "$CONF_VARS" "$new_vars" - # 3. Update Keybind (keybinds.conf) - if [[ ! -f "$CONF_BINDS" ]]; then - log_action 1 "Keybinds not found: $CONF_BINDS" - return 1 - fi - - local exec_cmd - if [[ "$t_type" == "1" ]]; then - exec_cmd="uwsm-app -- \$terminal -e \$fileManager" - else - exec_cmd="uwsm-app \$fileManager" - fi - - local new_binds - new_binds=$(awk -v new_cmd="$exec_cmd" ' - BEGIN { found=0 } - /bindd[ \t]*=.*,[ \t]*File Manager[ \t]*,/ { - split($0, parts, ",") - printf "%s,%s,%s, exec, %s\n", parts[1], parts[2], parts[3], new_cmd - found=1 - next - } - { print } - END { - if(!found) { - print "" - print "# Auto-generated by FM Switcher" - print "bindd = $mainMod, E, File Manager, exec, " new_cmd - } - } - ' "$CONF_BINDS") - atomic_write "$CONF_BINDS" "$new_binds" - # 4. Update MIME Defaults if command -v xdg-mime &>/dev/null; then xdg-mime default "$t_desktop" inode/directory 2>/dev/null || true @@ -246,7 +213,7 @@ switch_file_manager() { detect_current() { # Robust grep/cut to find current variable if [[ -f "$CONF_VARS" ]]; then - CURRENT_FM_KEY=$(grep -m1 '^[[:space:]]*\$fileManager[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") + CURRENT_FM_KEY=$(grep -m1 '^[[:space:]]*fileManager[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") CURRENT_FM_KEY="${CURRENT_FM_KEY//[[:space:]]/}" # Safe check for empty strings under set -e diff --git a/user_scripts/arch_setup_scripts/scripts/236_browser_switcher.sh b/user_scripts/arch_setup_scripts/scripts/236_browser_switcher.sh index 26deec82..67cefa74 100755 --- a/user_scripts/arch_setup_scripts/scripts/236_browser_switcher.sh +++ b/user_scripts/arch_setup_scripts/scripts/236_browser_switcher.sh @@ -39,7 +39,7 @@ declare -ra BROWSER_CATALOG=( ) # Paths -declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.conf" +declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.lua" declare -r CONF_BINDS="${HOME}/.config/hypr/edit_here/source/keybinds.conf" declare -r STATE_FILE="${HOME}/.config/dusky/settings/browser_switch" @@ -166,7 +166,7 @@ switch_browser() { return 1 fi - # 2. Update Variable (default_apps.conf) + # 2. Update Variable (default_apps.lua) if [[ ! -f "$CONF_VARS" ]]; then log_action 1 "Config not found: $CONF_VARS" return 1 @@ -175,49 +175,16 @@ switch_browser() { local new_vars new_vars=$(awk -v val="$target" ' BEGIN { found=0 } - /^[\t ]*\$browser[\t ]*=/ { - print "$browser = " val + /^[\t ]*browser[\t ]*=/ { + print "browser = \"" val "\"" found=1 next } { print } - END { if(!found) print "$browser = " val } + END { if(!found) print "browser = \"" val "\"" } ' "$CONF_VARS") atomic_write "$CONF_VARS" "$new_vars" - # 3. Update Keybind (keybinds.conf) - if [[ ! -f "$CONF_BINDS" ]]; then - log_action 1 "Keybinds not found: $CONF_BINDS" - return 1 - fi - - local exec_cmd - if [[ "$t_type" == "1" ]]; then - exec_cmd="uwsm-app -- \$terminal -e \$browser" - else - exec_cmd="uwsm-app -- \$browser" - fi - - local new_binds - new_binds=$(awk -v new_cmd="$exec_cmd" ' - BEGIN { found=0 } - /bindd[ \t]*=.*,[ \t]*Launch Browser[ \t]*,/ { - split($0, parts, ",") - printf "%s,%s,%s, exec, %s\n", parts[1], parts[2], parts[3], new_cmd - found=1 - next - } - { print } - END { - if(!found) { - print "" - print "# Auto-generated by Browser Switcher" - print "bindd = $mainMod, W, Launch Browser, exec, " new_cmd - } - } - ' "$CONF_BINDS") - atomic_write "$CONF_BINDS" "$new_binds" - # 4. Update MIME Defaults if command -v xdg-mime &>/dev/null; then xdg-mime default "$t_desktop" x-scheme-handler/http 2>/dev/null || true @@ -246,7 +213,7 @@ switch_browser() { detect_current() { # Robust grep/cut to find current variable if [[ -f "$CONF_VARS" ]]; then - CURRENT_BROWSER_KEY=$(grep -m1 '^[[:space:]]*\$browser[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") + CURRENT_BROWSER_KEY=$(grep -m1 '^[[:space:]]*browser[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") CURRENT_BROWSER_KEY="${CURRENT_BROWSER_KEY//[[:space:]]/}" # Safe check for empty strings under set -e diff --git a/user_scripts/arch_setup_scripts/scripts/237_text_editer_switcher.sh b/user_scripts/arch_setup_scripts/scripts/237_text_editer_switcher.sh index e210b5ae..e0a69396 100755 --- a/user_scripts/arch_setup_scripts/scripts/237_text_editer_switcher.sh +++ b/user_scripts/arch_setup_scripts/scripts/237_text_editer_switcher.sh @@ -48,7 +48,7 @@ declare -ra EDITOR_CATALOG=( ) # Paths -declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.conf" +declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.lua" declare -r CONF_BINDS="${HOME}/.config/hypr/edit_here/source/keybinds.conf" declare -r STATE_FILE="${HOME}/.config/dusky/settings/texteditor_switch" @@ -175,7 +175,7 @@ switch_text_editor() { return 1 fi - # 2. Update Variable (default_apps.conf) + # 2. Update Variable (default_apps.lua) if [[ ! -f "$CONF_VARS" ]]; then log_action 1 "Config not found: $CONF_VARS" return 1 @@ -184,49 +184,16 @@ switch_text_editor() { local new_vars new_vars=$(awk -v val="$target" ' BEGIN { found=0 } - /^[\t ]*\$textEditor[\t ]*=/ { - print "$textEditor = " val + /^[\t ]*textEditor[\t ]*=/ { + print "textEditor = \"" val "\"" found=1 next } { print } - END { if(!found) print "$textEditor = " val } + END { if(!found) print "textEditor = \"" val "\"" } ' "$CONF_VARS") atomic_write "$CONF_VARS" "$new_vars" - # 3. Update Keybind (keybinds.conf) - if [[ ! -f "$CONF_BINDS" ]]; then - log_action 1 "Keybinds not found: $CONF_BINDS" - return 1 - fi - - local exec_cmd - if [[ "$t_type" == "1" ]]; then - exec_cmd="uwsm-app -- \$terminal --class $target -e \$textEditor" - else - exec_cmd="uwsm-app \$textEditor" - fi - - local new_binds - new_binds=$(awk -v new_cmd="$exec_cmd" ' - BEGIN { found=0 } - /bindd[ \t]*=.*,[ \t]*Open Text Editor[ \t]*,/ { - split($0, parts, ",") - printf "%s,%s,%s, exec, %s\n", parts[1], parts[2], parts[3], new_cmd - found=1 - next - } - { print } - END { - if(!found) { - print "" - print "# Auto-generated by Text Editor Switcher" - print "bindd = $mainMod, R, Open Text Editor, exec, " new_cmd - } - } - ' "$CONF_BINDS") - atomic_write "$CONF_BINDS" "$new_binds" - # 4. Update MIME Defaults if command -v xdg-mime &>/dev/null; then xdg-mime default "$t_desktop" text/plain 2>/dev/null || true @@ -246,7 +213,7 @@ switch_text_editor() { detect_current() { # Robust grep/cut to find current variable if [[ -f "$CONF_VARS" ]]; then - CURRENT_EDITOR_KEY=$(grep -m1 '^[[:space:]]*\$textEditor[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") + CURRENT_EDITOR_KEY=$(grep -m1 '^[[:space:]]*textEditor[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") CURRENT_EDITOR_KEY="${CURRENT_EDITOR_KEY//[[:space:]]/}" # Safe check for empty strings under set -e diff --git a/user_scripts/arch_setup_scripts/scripts/238_terminal_switcher.sh b/user_scripts/arch_setup_scripts/scripts/238_terminal_switcher.sh index 92eaa13c..36e5bcd1 100755 --- a/user_scripts/arch_setup_scripts/scripts/238_terminal_switcher.sh +++ b/user_scripts/arch_setup_scripts/scripts/238_terminal_switcher.sh @@ -37,7 +37,7 @@ declare -ra TERM_CATALOG=( ) # Paths -declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.conf" +declare -r CONF_VARS="${HOME}/.config/hypr/edit_here/source/default_apps.lua" declare -r CONF_BINDS="${HOME}/.config/hypr/edit_here/source/keybinds.conf" declare -r STATE_FILE="${HOME}/.config/dusky/settings/terminal_switch" @@ -162,7 +162,7 @@ switch_terminal() { return 1 fi - # 2. Update Variable (default_apps.conf) + # 2. Update Variable (default_apps.lua) if [[ ! -f "$CONF_VARS" ]]; then log_action 1 "Config not found: $CONF_VARS" return 1 @@ -171,43 +171,16 @@ switch_terminal() { local new_vars new_vars=$(awk -v val="$target" ' BEGIN { found=0 } - /^[\t ]*\$terminal[\t ]*=/ { - print "$terminal = " val + /^[\t ]*terminal[\t ]*=/ { + print "terminal = \"" val "\"" found=1 next } { print } - END { if(!found) print "$terminal = " val } + END { if(!found) print "terminal = \"" val "\"" } ' "$CONF_VARS") atomic_write "$CONF_VARS" "$new_vars" - # 3. Update Keybind (keybinds.conf) - if [[ ! -f "$CONF_BINDS" ]]; then - log_action 1 "Keybinds not found: $CONF_BINDS" - return 1 - fi - - local exec_cmd="uwsm-app -- \$terminal" - local new_binds - new_binds=$(awk -v new_cmd="$exec_cmd" ' - BEGIN { found=0 } - /bindd[ \t]*=.*,[ \t]*Launch Terminal[ \t]*,/ { - split($0, parts, ",") - printf "%s,%s,%s, exec, %s\n", parts[1], parts[2], parts[3], new_cmd - found=1 - next - } - { print } - END { - if(!found) { - print "" - print "# Auto-generated by Terminal Switcher" - print "bindd = $mainMod, Q, Launch Terminal, exec, " new_cmd - } - } - ' "$CONF_BINDS") - atomic_write "$CONF_BINDS" "$new_binds" - # 4. Update State Files local legacy_state="false" [[ "$target" == "kitty" ]] && legacy_state="true" @@ -221,7 +194,7 @@ switch_terminal() { detect_current() { if [[ -f "$CONF_VARS" ]]; then - CURRENT_TERM_KEY=$(grep -m1 '^[[:space:]]*\$terminal[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") + CURRENT_TERM_KEY=$(grep -m1 '^[[:space:]]*terminal[[:space:]]*=' "$CONF_VARS" | cut -d'=' -f2 | tr -d ' "' || echo "unknown") CURRENT_TERM_KEY="${CURRENT_TERM_KEY//[[:space:]]/}" if [[ -z "$CURRENT_TERM_KEY" ]]; then diff --git a/user_scripts/dusky_system/control_center/dusky_config.yaml b/user_scripts/dusky_system/control_center/dusky_config.yaml index 135f1662..957ed3c4 100644 --- a/user_scripts/dusky_system/control_center/dusky_config.yaml +++ b/user_scripts/dusky_system/control_center/dusky_config.yaml @@ -186,7 +186,7 @@ pages: icon: view-refresh-symbolic on_press: type: exec - command: hyprctl reload + command: sh -c 'hyprctl reload && hyprctl notify 1 2000 0 " Config reloaded"' terminal: false - type: grid_card properties: @@ -980,12 +980,12 @@ pages: enabled: type: exec command: kitty --class power_saver.sh --title "Enable Power Saver" --hold - sh -c "$HOME/user_scripts/battery/power_saving/power_saver.sh" + sh -c "$HOME/user_scripts/battery/power_saver.sh --enable" terminal: false disabled: type: exec - command: kitty --class power_saver_off.sh --title "Disable Power Saver" - --hold sh -c "$HOME/user_scripts/battery/power_saving_off/power_saver_off.sh" + command: kitty --class power_saver.sh --title "Disable Power Saver" --hold + sh -c "$HOME/user_scripts/battery/power_saver.sh --disable" terminal: false - type: button properties: @@ -1685,7 +1685,7 @@ pages: button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/hyprland.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/hyprland.lua" terminal: false - type: navigation @@ -1708,7 +1708,7 @@ pages: button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/keybinds.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/keybinds.lua" - icon: input-keyboard-symbolic button_text: "TUI" style: suggested @@ -1725,7 +1725,7 @@ pages: button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/input.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/input.lua" - icon: input-mouse-symbolic button_text: "TUI" style: suggested @@ -1760,12 +1760,12 @@ pages: - type: button properties: title: User Environment - description: ~/.config/hypr/edit_here/source/environment_variables.conf + description: ~/.config/hypr/edit_here/source/environment_variables.lua icon: text-x-script-symbolic button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/environment_variables.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/environment_variables.lua" - type: button properties: title: UWSM Global @@ -1805,7 +1805,7 @@ pages: button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/monitors.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/monitors.lua" - icon: video-display-symbolic button_text: "TUI" style: suggested @@ -1822,7 +1822,7 @@ pages: button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/window_rules.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/window_rules.lua" - icon: application-x-addon-symbolic button_text: "TUI" style: suggested @@ -1850,7 +1850,7 @@ pages: button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/appearance.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/appearance.lua" - icon: applications-graphics-symbolic button_text: "TUI" style: suggested @@ -1867,7 +1867,7 @@ pages: button_text: "File" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/workspace_rules.conf" + command: gnome-text-editor "$HOME/.config/hypr/edit_here/source/workspace_rules.lua" - icon: applications-graphics-symbolic button_text: "TUI" style: suggested @@ -1928,7 +1928,7 @@ pages: interval: 5 on_change: type: exec - command: "ln -sf $HOME/.config/waybar/{value}/config.jsonc $HOME/.config/waybar/config.jsonc; ln -sf $HOME/.config/waybar/{value}/style.css $HOME/.config/waybar/style.css; killall -SIGUSR2 waybar" + command: "ln -sf $HOME/.config/waybar/{value}/config.jsonc $HOME/.config/waybar/config.jsonc; ln -sf $HOME/.config/waybar/{value}/style.css $HOME/.config/waybar/style.css; $HOME/user_scripts/waybar/waybar_autostart.sh" - type: section properties: @@ -2131,53 +2131,53 @@ pages: items: - type: button properties: - title: Hyprland.conf + title: Hyprland.lua button_text: "View" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/hyprland.conf" + command: gnome-text-editor "$HOME/.config/hypr/hyprland.lua" - type: button properties: title: Environment Variables button_text: "View" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/source/environment_variables.conf" + command: gnome-text-editor "$HOME/.config/hypr/source/environment_variables.lua" - type: button properties: title: Appearance button_text: "View" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/source/appearance.conf" + command: gnome-text-editor "$HOME/.config/hypr/source/appearance.lua" - type: button properties: title: Autostart button_text: "View" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/source/autostart.conf" + command: gnome-text-editor "$HOME/.config/hypr/source/autostart.lua" - type: button properties: title: Keybinds button_text: "View" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/source/keybinds.conf" + command: gnome-text-editor "$HOME/.config/hypr/source/keybinds.lua" - type: button properties: title: Window Rules button_text: "View" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/source/window_rules.conf" + command: gnome-text-editor "$HOME/.config/hypr/source/window_rules.lua" - type: button properties: title: Input button_text: "View" on_press: type: exec - command: gnome-text-editor "$HOME/.config/hypr/source/input.conf" + command: gnome-text-editor "$HOME/.config/hypr/source/input.lua" - id: keybinds title: Keybinds @@ -2888,6 +2888,13 @@ pages: value: type: exec command: hyprctl version | grep Hyprland | awk '{print $2}' + - type: label + properties: + title: Config Mode + icon: text-x-script + value: + type: exec + command: "test -f $HOME/.config/hypr/hyprland.lua && echo 'Lua' || echo 'Legacy'" - type: section properties: title: System Information diff --git a/user_scripts/hypr/adjust_scale.py b/user_scripts/hypr/adjust_scale.py index 3995676c..9a0168fa 100755 --- a/user_scripts/hypr/adjust_scale.py +++ b/user_scripts/hypr/adjust_scale.py @@ -10,7 +10,7 @@ # --- Immutable Configuration --- CONFIG_DIR = Path.home() / ".config/hypr/edit_here/source" -CONFIG_FILE = CONFIG_DIR / "monitors.conf" +CONFIG_FILE = CONFIG_DIR / "monitors.lua" NOTIFY_TAG = "hypr_scale_adjust" MIN_LOGICAL_WIDTH = 640 MIN_LOGICAL_HEIGHT = 360 @@ -99,7 +99,7 @@ def compute_next_scale(current: float, direction: str, phys_w: int, phys_h: int) return max(candidates) def update_config_atomically(monitor_name: str, new_scale: float) -> None: - """Updates the config via state machine and strict POSIX atomic replacement.""" + """Updates hl.monitor() scale in monitors.lua via strict POSIX atomic replacement.""" if not CONFIG_FILE.exists(): CONFIG_DIR.mkdir(parents=True, exist_ok=True) CONFIG_FILE.touch() @@ -111,64 +111,28 @@ def update_config_atomically(monitor_name: str, new_scale: float) -> None: found = False log_debug(f"Updating config: {monitor_name} -> {new_scale:g}") - # 1. Process V2 Blocks - def v2_replacer(match: re.Match) -> str: + def lua_replacer(match: re.Match) -> str: nonlocal found - block = match.group(0) - if re.search(rf"^\s*output\s*=\s*{re.escape(monitor_name)}\b", block, re.MULTILINE): - if re.search(r"^\s*scale\s*=.*", block, re.MULTILINE): - block = re.sub(r"(^\s*scale\s*=).*$", rf"\1 {new_scale:g}", block, flags=re.MULTILINE) - else: - block = re.sub(r"(\s*)\}$", rf"\1 scale = {new_scale:g}\n}}", block) - found = True - return block - - config_text = re.sub(r"monitorv2\s*\{[^}]*\}", v2_replacer, config_text) + line = match.group(0) + if f'output = "{monitor_name}"' not in line: + return line + found = True + updated = re.sub(r'(\bscale\s*=\s*)[0-9.]+', rf'\g<1>{new_scale:g}', line) + if updated != line: + return updated + # No scale field yet — insert before closing }) + return re.sub(r'(\s*\}\s*\)\s*)$', rf', scale = {new_scale:g}\1', line) + + config_text = re.sub(r'^.*hl\.monitor\s*\(.*$', lua_replacer, config_text, flags=re.MULTILINE) - # 2. Process V1 Rules - if not found: - def v1_replacer(match: re.Match) -> str: - nonlocal found - mon_name = match.group(2).strip() - - if mon_name == monitor_name: - found = True - remainder = match.group(3) - comment = "" - - # FIX: Dynamically capture the comment and all preceding whitespace to preserve formatting - c_match = re.search(r'(\s*#.*)', remainder) - if c_match: - comment = c_match.group(1) - remainder = remainder[:c_match.start()] - - parts = remainder.split(",") - if len(parts) == 2: - if "disable" in parts[1].strip(): - parts = ["", " preferred", " auto", f" {new_scale:g}"] - else: - parts.extend([" auto", f" {new_scale:g}"]) - elif len(parts) == 3: - parts.append(f" {new_scale:g}") - elif len(parts) >= 4: - parts[3] = f" {new_scale:g}" - - return f"{match.group(1)}{match.group(2)}{','.join(parts)}{comment}" - return match.group(0) - - config_text = re.sub(r"^(\s*monitor\s*=\s*)([^,\n]+)(,.*)$", v1_replacer, config_text, flags=re.MULTILINE) - - # 3. Append entirely new rule if not found: log_info(f"Appending new entry for: {monitor_name}") - config_text += f"\nmonitor = {monitor_name}, preferred, auto, {new_scale:g}\n" + config_text += f'\nhl.monitor({{ output = "{monitor_name}", mode = "preferred", position = "auto", scale = {new_scale:g} }})\n' - # 4. Strict POSIX Atomic Write - fd, temp_path = tempfile.mkstemp(dir=real_path.parent, prefix=".monitors.conf.tmp.") + fd, temp_path = tempfile.mkstemp(dir=real_path.parent, prefix=".monitors.lua.tmp.") try: with os.fdopen(fd, 'w') as temp_file: temp_file.write(config_text) - os.chmod(temp_path, real_path.stat().st_mode) os.replace(temp_path, real_path) except Exception as e: @@ -192,21 +156,21 @@ def main(): notify("Monitor Scale", f"Limit Reached: {current_scale:g}", "normal") return - # Write the target scale to disk update_config_atomically(mon_name, new_scale) log_info(f"Applying scale {new_scale:g} via hyprctl reload") subprocess.run(["hyprctl", "reload"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - # State Verification: Deterministic polling to prevent async race conditions + # Poll for Hyprland to apply the new scale. Sleep first so we don't race + # the reload — querying immediately almost always returns the old value. actual_scale = current_scale - for _ in range(25): # Poll every 100ms for up to 2.5 seconds - time.sleep(0.1) + time.sleep(0.3) + for _ in range(22): # Poll every 100ms for up to ~2.5 seconds total _, _, _, polled_scale = get_active_monitor(mon_name) if abs(polled_scale - current_scale) > 0.000001: actual_scale = polled_scale break - actual_scale = polled_scale + time.sleep(0.1) # Verify if Wayland accepted the request or clamped it due to hardware limits if abs(actual_scale - new_scale) > 0.000001: diff --git a/user_scripts/hypr/dusky_appearances.sh b/user_scripts/hypr/dusky_appearances.sh index a85fb2a4..c5245fe9 100755 --- a/user_scripts/hypr/dusky_appearances.sh +++ b/user_scripts/hypr/dusky_appearances.sh @@ -14,7 +14,7 @@ shopt -s extglob # ▼ USER CONFIGURATION (EDIT THIS SECTION) ▼ # ============================================================================= -declare -r CONFIG_FILE="${HOME}/.config/hypr/edit_here/source/appearance.conf" +declare -r CONFIG_FILE="${HOME}/.config/hypr/edit_here/source/appearance.lua" declare -r APP_TITLE="Dusky Appearances" declare -r APP_VERSION="v7.8.0" @@ -33,23 +33,22 @@ declare -ra TABS=("Layout" "Decoration" "Blur" "Shadow" "Snap") # Item Registration register_items() { # Tab 0: Layout & General - register 0 "Gaps In" "gaps_in|int||0|100|1" "6" - register 0 "Gaps Out" "gaps_out|int||0|100|1" "12" + register 0 "Gaps In" "gaps_in|int|general|0|100|1" "6" + register 0 "Gaps Out" "gaps_out|int|general|0|100|1" "12" register 0 "Gaps Workspaces" "gaps_workspaces|int|general|0|100|1" "0" - register 0 "Border Size" "border_size|int||0|10|1" "2" + register 0 "Border Size" "border_size|int|general|0|10|1" "2" register 0 "Resize on Border" "resize_on_border|bool|general|||" "false" register 0 "Allow Tearing" "allow_tearing|bool|general|||" "true" - register 0 "Single Window Gap" '$single_window_gap|int||0|100|1' "10" # Tab 1: Decoration - register 1 "Rounding" "rounding|int||0|30|1" "6" - register 1 "Rounding Power" "rounding_power|float||0.0|10.0|0.1" "6.0" - register 1 "Active Opacity" "active_opacity|float||0.1|1.0|0.05" "1.0" - register 1 "Inactive Opacity" "inactive_opacity|float||0.1|1.0|0.05" "1.0" - register 1 "Fullscreen Opacity" "fullscreen_opacity|float||0.1|1.0|0.05" "1.0" - register 1 "Dim Inactive" "dim_inactive|bool||||" "true" - register 1 "Dim Strength" "dim_strength|float||0.0|1.0|0.05" "0.2" - register 1 "Dim Special" "dim_special|float||0.0|1.0|0.05" "0.8" + register 1 "Rounding" "rounding|int|decoration|0|30|1" "6" + register 1 "Rounding Power" "rounding_power|float|decoration|0.0|10.0|0.1" "6.0" + register 1 "Active Opacity" "active_opacity|float|decoration|0.1|1.0|0.05" "1.0" + register 1 "Inactive Opacity" "inactive_opacity|float|decoration|0.1|1.0|0.05" "1.0" + register 1 "Fullscreen Opacity" "fullscreen_opacity|float|decoration|0.1|1.0|0.05" "1.0" + register 1 "Dim Inactive" "dim_inactive|bool|decoration|||" "true" + register 1 "Dim Strength" "dim_strength|float|decoration|0.0|1.0|0.05" "0.2" + register 1 "Dim Special" "dim_special|float|decoration|0.0|1.0|0.05" "0.8" # Tab 2: Blur register 2 "Blur Enabled" "enabled|bool|blur|||" "false" @@ -68,8 +67,7 @@ register_items() { register 3 "Shadow Power" "render_power|int|shadow|1|4|1" "2" register 3 "Shadow Sharp" "sharp|bool|shadow|||" "false" register 3 "Shadow Scale" "scale|float|shadow|0.0|1.1|0.05" "1.0" - register 3 "Shadow Ignore Win" "ignore_window|bool|shadow|||" "true" - register 3 "Shadow Color" 'color|cycle|shadow|rgba(1a1a1aee),$primary||' 'rgba(1a1a1aee)' + register 3 "Shadow Color" 'color|cycle|shadow|rgba(1a1a1aee)||' 'rgba(1a1a1aee)' # Tab 4: Snap register 4 "Snap Enabled" "enabled|bool|snap|||" "false" @@ -80,7 +78,7 @@ register_items() { # Post-Write Hook post_write_action() { - : # Reload command here, e.g.: hyprctl reload &>/dev/null || : + hyprctl reload &>/dev/null || : } # ============================================================================= @@ -202,17 +200,18 @@ populate_config_cache() { fi done < <(LC_ALL=C awk ' BEGIN { depth = 0 } - /^[[:space:]]*#/ { next } + /^[[:space:]]*--/ { next } { line = $0 # Strip inline comments for structural parsing so "}" in comments doesn'"'"'t break blocks clean = line - sub(/[[:space:]]+#.*$/, "", clean) + sub(/[[:space:]]+--.*$/, "", clean) tmpline = clean - while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*\{/)) { + # Lua tables use "name = {" syntax; conf uses "name {" + while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*(=[[:space:]]*)?\{/)) { block_str = substr(tmpline, RSTART, RLENGTH) - sub(/[[:space:]]*\{/, "", block_str) + sub(/[[:space:]]*(=[[:space:]]*)?\{/, "", block_str) depth++ block_stack[depth] = block_str tmpline = substr(tmpline, RSTART + RLENGTH) @@ -225,8 +224,12 @@ populate_config_cache() { gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) gsub(/^[[:space:]]+|[[:space:]]+$/, "", val) # Strip trailing inline comment from value - sub(/[[:space:]]+#.*$/, "", val) + sub(/[[:space:]]+--.*$/, "", val) gsub(/^[[:space:]]+|[[:space:]]+$/, "", val) + # Strip trailing comma (Lua table syntax) + sub(/,$/, "", val) + # Strip surrounding double-quotes (Lua string values) + if (val ~ /^".*"$/) val = substr(val, 2, length(val) - 2) if (key != "") { current_block = (depth > 0) ? block_stack[depth] : "" print key "|" current_block "=" val @@ -266,13 +269,14 @@ write_value_to_file() { { line = $0 clean = line - sub(/^[[:space:]]*#.*/, "", clean) - sub(/[[:space:]]+#.*$/, "", clean) + sub(/^[[:space:]]*--.*/, "", clean) + sub(/[[:space:]]+--.*$/, "", clean) tmpline = clean - while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*\{/)) { + # Lua tables use "name = {" syntax; conf uses "name {" + while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*(=[[:space:]]*)?\{/)) { block_str = substr(tmpline, RSTART, RLENGTH) - sub(/[[:space:]]*\{/, "", block_str) + sub(/[[:space:]]*(=[[:space:]]*)?\{/, "", block_str) depth++ block_stack[depth] = block_str if (do_block && block_str == target_block && !in_target) { @@ -311,7 +315,19 @@ write_value_to_file() { match(rest, /^[[:space:]]*/) space_after = substr(rest, RSTART, RLENGTH) - print before_eq space_after new_value + # Detect trailing comma and surrounding quotes from the original value + old_val = substr(rest, RSTART + RLENGTH) + sub(/[[:space:]]+--.*$/, "", old_val) + gsub(/^[[:space:]]+|[[:space:]]+$/, "", old_val) + was_trailing = (old_val ~ /,$/) ? 1 : 0 + sub(/,$/, "", old_val) + was_quoted = (old_val ~ /^".*"$/) ? 1 : 0 + + out_val = new_value + if (was_quoted && !(new_value ~ /^".*"$/)) out_val = "\"" new_value "\"" + trailing = was_trailing ? "," : "" + + print before_eq space_after out_val trailing replaced = 1 } else { print line diff --git a/user_scripts/hypr/dusky_input.sh b/user_scripts/hypr/dusky_input.sh index 5b96ba92..a7691195 100755 --- a/user_scripts/hypr/dusky_input.sh +++ b/user_scripts/hypr/dusky_input.sh @@ -26,7 +26,7 @@ shopt -s extglob # ▼ USER CONFIGURATION (EDIT THIS SECTION) ▼ # ============================================================================= -declare -r CONFIG_FILE="${HOME}/.config/hypr/edit_here/source/input.conf" +declare -r CONFIG_FILE="${HOME}/.config/hypr/edit_here/source/input.lua" declare -r APP_TITLE="Dusky Input" declare -r APP_VERSION="v5.4.0 (Hardened)" @@ -63,7 +63,7 @@ register_items() { # Tab 2: Touchpad (Block: 'touchpad') register 2 "TP Nat Scroll" 'natural_scroll|bool|touchpad|||' "true" - register 2 "Tap to Click" 'tap-to-click|bool|touchpad|||' "true" + register 2 "Tap to Click" 'tap_to_click|bool|touchpad|||' "true" register 2 "Disable While Typing" 'disable_while_typing|bool|touchpad|||' "true" register 2 "Clickfinger Behav" 'clickfinger_behavior|bool|touchpad|||' "false" register 2 "Drag Lock" 'drag_lock|bool|touchpad|||' "false" @@ -87,7 +87,7 @@ register_items() { # Post-Write Hook post_write_action() { - : # Reload command here, e.g.: hyprctl reload &>/dev/null || : + hyprctl reload &>/dev/null || : } # ============================================================================= @@ -210,17 +210,18 @@ populate_config_cache() { fi done < <(LC_ALL=C awk ' BEGIN { depth = 0 } - /^[[:space:]]*#/ { next } + /^[[:space:]]*--/ { next } { line = $0 # Strip inline comments for structural parsing so "}" in comments doesn'"'"'t break blocks clean = line - sub(/[[:space:]]+#.*$/, "", clean) + sub(/[[:space:]]+--.*$/, "", clean) tmpline = clean - while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*\{/)) { + # Lua tables use "name = {" syntax; conf uses "name {" + while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*(=[[:space:]]*)?\{/)) { block_str = substr(tmpline, RSTART, RLENGTH) - sub(/[[:space:]]*\{/, "", block_str) + sub(/[[:space:]]*(=[[:space:]]*)?\{/, "", block_str) depth++ block_stack[depth] = block_str tmpline = substr(tmpline, RSTART + RLENGTH) @@ -233,8 +234,12 @@ populate_config_cache() { gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) gsub(/^[[:space:]]+|[[:space:]]+$/, "", val) # Strip trailing inline comment from value - sub(/[[:space:]]+#.*$/, "", val) + sub(/[[:space:]]+--.*$/, "", val) gsub(/^[[:space:]]+|[[:space:]]+$/, "", val) + # Strip trailing comma (Lua table syntax) + sub(/,$/, "", val) + # Strip surrounding double-quotes (Lua string values) + if (val ~ /^".*"$/) val = substr(val, 2, length(val) - 2) if (key != "") { current_block = (depth > 0) ? block_stack[depth] : "" print key "|" current_block "=" val @@ -274,13 +279,14 @@ write_value_to_file() { { line = $0 clean = line - sub(/^[[:space:]]*#.*/, "", clean) - sub(/[[:space:]]+#.*$/, "", clean) + sub(/^[[:space:]]*--.*/, "", clean) + sub(/[[:space:]]+--.*$/, "", clean) tmpline = clean - while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*\{/)) { + # Lua tables use "name = {" syntax; conf uses "name {" + while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*(=[[:space:]]*)?\{/)) { block_str = substr(tmpline, RSTART, RLENGTH) - sub(/[[:space:]]*\{/, "", block_str) + sub(/[[:space:]]*(=[[:space:]]*)?\{/, "", block_str) depth++ block_stack[depth] = block_str if (do_block && block_str == target_block && !in_target) { @@ -316,7 +322,19 @@ write_value_to_file() { match(rest, /^[[:space:]]*/) space_after = substr(rest, RSTART, RLENGTH) - print before_eq space_after new_value + # Detect trailing comma and surrounding quotes from the original value + old_val = substr(rest, RSTART + RLENGTH) + sub(/[[:space:]]+--.*$/, "", old_val) + gsub(/^[[:space:]]+|[[:space:]]+$/, "", old_val) + was_trailing = (old_val ~ /,$/) ? 1 : 0 + sub(/,$/, "", old_val) + was_quoted = (old_val ~ /^".*"$/) ? 1 : 0 + + out_val = new_value + if (was_quoted && !(new_value ~ /^".*"$/)) out_val = "\"" new_value "\"" + trailing = was_trailing ? "," : "" + + print before_eq space_after out_val trailing replaced = 1 } else { print line diff --git a/user_scripts/hypr/dusky_keybinds.sh b/user_scripts/hypr/dusky_keybinds.sh index e724c565..8797f0c4 100755 --- a/user_scripts/hypr/dusky_keybinds.sh +++ b/user_scripts/hypr/dusky_keybinds.sh @@ -47,14 +47,14 @@ readonly BRIGHT_WHITE=$'\033[0;97m' readonly DIM=$'\033[2m' # --- Paths --- -readonly SOURCE_CONF="${HOME}/.config/hypr/source/keybinds.conf" -readonly CUSTOM_CONF="${HOME}/.config/hypr/edit_here/source/keybinds.conf" +readonly SOURCE_CONF="${HOME}/.config/hypr/source/keybinds.lua" +readonly CUSTOM_CONF="${HOME}/.config/hypr/edit_here/source/keybinds.lua" readonly LOCK_FILE="${CUSTOM_CONF}.lock" # --- Sentinels --- readonly CREATE_MARKER_ID="__CREATE_NEW_BIND__" readonly SOURCE_INFO_MARKER="__SOURCE_DIRECTIVE_INFO__" -readonly EMPTY_BIND_TEMPLATE="bindd = " +readonly EMPTY_BIND_TEMPLATE="hl.bind(\"MOD + KEY\", hl.dsp.dispatch(\"ARG\"), { description = \"DESC\" })" # --- Dispatchers (populated at runtime if possible, otherwise fallback) --- declare -a KNOWN_DISPATCHERS=( @@ -165,11 +165,11 @@ _is_comment_or_blank() { } _is_bind_directive() { - [[ "$1" =~ ^[[:space:]]*(bind[a-z]*|unbind)[[:space:]]*= ]] + [[ "$1" =~ ^[[:space:]]*hl\.(bind|unbind)[[:space:]]*\( ]] } _is_unbind() { - [[ "$1" =~ ^[[:space:]]*unbind[[:space:]]*= ]] + [[ "$1" =~ ^[[:space:]]*hl\.unbind[[:space:]]*\( ]] } _is_submap_directive() { @@ -194,14 +194,20 @@ _extract_mods_key() { local -n _emk_mods="$1" local -n _emk_key="$2" local content="$3" - - _emk_mods="${content%%,*}" - local remainder="${content#*,}" - - if [[ "$remainder" == "$content" ]]; then - _emk_key="" + + # content is everything after hl.bind( or hl.unbind( + local binding="${content%%,*}" + binding="${binding#*\"}" + binding="${binding%%\"*}" + + if [[ "$binding" == *"+"* ]]; then + _emk_mods="${binding%%+*}" + _emk_key="${binding##*+}" + _emk_mods="${_emk_mods%%[[:space:]]}" + _emk_key="${_emk_key##[[:space:]]}" else - _emk_key="${remainder%%,*}" + _emk_mods="" + _emk_key="$binding" fi _trim _emk_mods "$_emk_mods" @@ -237,14 +243,9 @@ _extract_field() { _extract_dispatcher() { local bind_type="$1" local content="$2" - local flags="${bind_type#bind}" - - local dispatcher_idx=2 - if [[ "$flags" == *d* ]]; then - dispatcher_idx=3 - fi - - _extract_field "$content" "$dispatcher_idx" + local disp="${content#*hl.dsp.}" + disp="${disp%%(*}" + printf "%s" "$disp" } _validate_dispatcher() { @@ -859,7 +860,7 @@ main() { if [[ "$origin" == "CUST" ]]; then printf ' Remove custom entry from %s\n' "$CUSTOM_CONF" else - printf ' Append "unbind = %s, %s" to %s\n' "$del_mods" "$del_key" "$CUSTOM_CONF" + printf ' Append "hl.unbind(\"%s + %s\")" to %s\n' "$del_mods" "$del_key" "$CUSTOM_CONF" fi read -r -p "Press Enter to continue..." continue @@ -909,7 +910,7 @@ main() { if [[ -n "$bind_submap" ]]; then printf 'submap = %s\n' "$bind_submap" fi - printf 'unbind = %s, %s\n' "$del_mods" "$del_key" + printf 'hl.unbind(\"%s + %s\")\n' "$del_mods" "$del_key" if [[ -n "$bind_submap" ]]; then printf 'submap = reset\n' fi @@ -1129,7 +1130,7 @@ main() { if _exists_in_source "$orig_mods" "$orig_key" "$bind_submap"; then local nk_m="$orig_mods" nk_k="$orig_key" _normalize_bind_parts nk_m nk_k - unbind_map["${nk_m}|${nk_k}"]="unbind = ${orig_mods}, ${orig_key}" + unbind_map["${nk_m}|${nk_k}"]="hl.unbind(\"${orig_mods} + ${orig_key}\")" fi fi @@ -1137,7 +1138,7 @@ main() { if _exists_in_source "$new_mods" "$new_key" "$bind_submap"; then local nk_m="$new_mods" nk_k="$new_key" _normalize_bind_parts nk_m nk_k - unbind_map["${nk_m}|${nk_k}"]="unbind = ${new_mods}, ${new_key}" + unbind_map["${nk_m}|${nk_k}"]="hl.unbind(\"${new_mods} + ${new_key}\")" fi # Build newline-delimited string for display diff --git a/user_scripts/hypr/dusky_monitor.sh b/user_scripts/hypr/dusky_monitor.sh index 2ba4f750..115f4adb 100755 --- a/user_scripts/hypr/dusky_monitor.sh +++ b/user_scripts/hypr/dusky_monitor.sh @@ -26,7 +26,7 @@ export LC_NUMERIC=C declare -r APP_TITLE="DUSKY MONITOR WIZARD v4.0.0" declare -r APP_SUBTITLE="Hyprland Edition" -declare -r TARGET_CONFIG="${HOME}/.config/hypr/edit_here/source/monitors.conf" +declare -r TARGET_CONFIG="${HOME}/.config/hypr/edit_here/source/monitors.lua" declare -r BACKUP_DIR="/tmp/dusky_backups" declare -r DEBUG_LOG="/tmp/dusky_debug.log" @@ -225,6 +225,9 @@ refresh_hardware() { local vfr_status vfr_status=$(hyprctl getoption debug:vfr -j 2>/dev/null | jq -r '.int' 2>/dev/null) || vfr_status="1" + if [[ "$vfr_status" == "null" || -z "$vfr_status" || ! "$vfr_status" =~ ^[0-9]+$ ]]; then + vfr_status="1" + fi GLB_VFR=$vfr_status local json @@ -238,7 +241,7 @@ refresh_hardware() { extracted=$(printf '%s' "$json" | jq -r ' .[] | [ .name, - .description, + (.description | if . == "" then "Unknown" else . end), (.disabled // false | tostring), (.width | tostring), (.height | tostring), @@ -247,7 +250,7 @@ refresh_hardware() { (.transform | tostring), (.x | tostring), (.y | tostring), - ((.availableModes // []) | join(" ")), + ((.availableModes // []) | if length == 0 then "-" else join(" ") end), (.vrr // false | tostring), (.currentFormat // "XRGB8888") ] | @tsv @@ -356,26 +359,22 @@ save_config() { timestamp=$(date +%Y%m%d_%H%M%S) if [[ -f "$TARGET_CONFIG" ]]; then - cp -- "$TARGET_CONFIG" "${BACKUP_DIR}/monitors_${timestamp}.conf" 2>/dev/null || true + cp -- "$TARGET_CONFIG" "${BACKUP_DIR}/monitors_${timestamp}.lua" 2>/dev/null || true fi - _SAVE_TMPFILE=$(mktemp "${config_dir}/monitors.conf.XXXXXX") - - local batch_cmd="" + _SAVE_TMPFILE=$(mktemp "${config_dir}/monitors.lua.XXXXXX") { - printf '# Generated by Dusky Monitor Wizard on %s\n' "$timestamp" - printf '\n# Global Settings\n' + printf '-- Generated by Dusky Monitor Wizard on %s\n' "$timestamp" + printf '\n-- Global Settings\n' if (( GLB_VFR == 1 )); then - printf 'debug {\n vfr = true\n}\n' - batch_cmd+="keyword debug:vfr 1 ; " + printf 'hl.config({ debug = { vfr = true } })\n' else - printf 'debug {\n vfr = false\n}\n' - batch_cmd+="keyword debug:vfr 0 ; " + printf 'hl.config({ debug = { vfr = false } })\n' fi - printf '\n# Monitor Rules\n' + printf '\n-- Monitor Rules\n' local name for name in "${MON_LIST[@]}"; do local identifier="$name" @@ -384,8 +383,7 @@ save_config() { fi if [[ "${MON_ENABLED["$name"]}" == "false" ]]; then - printf 'monitor = %s, disable\n' "$identifier" - batch_cmd+="keyword monitor ${identifier},disable ; " + printf 'hl.monitor({ output = "%s", disabled = true })\n' "$identifier" continue fi @@ -398,15 +396,13 @@ save_config() { local bit=${MON_BITDEPTH["$name"]} local mirror=${MON_MIRROR["$name"]} - local rule_args="${identifier}, ${res}, ${x}x${y}, ${scale}" - (( transform != 0 )) && rule_args+=", transform, ${transform}" - [[ -n "$mirror" ]] && rule_args+=", mirror, ${mirror}" - (( bit == 10 )) && rule_args+=", bitdepth, 10" - (( vrr > 0 )) && rule_args+=", vrr, ${vrr}" - - printf 'monitor = %s\n' "$rule_args" - local clean_args="${rule_args//, /,}" - batch_cmd+="keyword monitor ${clean_args} ; " + printf 'hl.monitor({ output = "%s", mode = "%s", position = "%sx%s", scale = %s' \ + "$identifier" "$res" "$x" "$y" "$scale" + (( transform != 0 )) && printf ', transform = %d' "$transform" + [[ -n "$mirror" ]] && printf ', mirror = "%s"' "$mirror" + (( bit == 10 )) && printf ', bitdepth = 10' + (( vrr > 0 )) && printf ', vrr = %d' "$vrr" + printf ' })\n' done } > "$_SAVE_TMPFILE" @@ -421,9 +417,7 @@ save_config() { # CRITICAL FIX: Use cat > target to preserve symlinks/inodes (Pattern from Template) if cat "$_SAVE_TMPFILE" > "$TARGET_CONFIG"; then printf '\n%sApplying settings...%s\n' "$C_CYAN" "$C_RESET" - if [[ -n "$batch_cmd" ]]; then - hyprctl --batch "$batch_cmd" >/dev/null 2>&1 || true - fi + hyprctl reload >/dev/null 2>&1 || true log_debug "Saved and applied." rm -f -- "$_SAVE_TMPFILE" 2>/dev/null || : _SAVE_TMPFILE="" diff --git a/user_scripts/hypr/dusky_window_rules.sh b/user_scripts/hypr/dusky_window_rules.sh index c1a67a03..c00987c5 100755 --- a/user_scripts/hypr/dusky_window_rules.sh +++ b/user_scripts/hypr/dusky_window_rules.sh @@ -10,7 +10,7 @@ shopt -s extglob export LC_NUMERIC=C # --- Configuration --- -declare -r TARGET_FILE="${HOME}/.config/hypr/edit_here/source/window_rules.conf" +declare -r TARGET_FILE="${HOME}/.config/hypr/edit_here/source/window_rules.lua" declare -r APP_TITLE="Dusky Window Rule Generator" declare -r APP_VERSION="v4.5 (Engine v3.9.1)" @@ -165,43 +165,42 @@ scan_windows() { safe_title=$(escape_regex "$title") safe_name=$(sanitize_name "$initialClass") - # Build Block - rule_block="${C_DIVIDER}# -----------------------------------------------------${C_RESET}"$'\n' - rule_block+="# ${title}"$'\n' - - rule_block+="${C_GREEN}windowrule {${C_RESET}"$'\n' - rule_block+=" name = ${safe_name}"$'\n' - rule_block+=" match:class = ^(${safe_class})$"$'\n' - rule_block+=" ${C_COMMENT}# match:title = ^(${safe_title})\$${C_RESET}"$'\n' - - rule_block+=" float = on"$'\n' - rule_block+=" ${C_COMMENT}# pin = on${C_RESET}"$'\n' - - rule_block+=" size = ${w_w} ${w_h}"$'\n' - rule_block+=" ${C_COMMENT}# size = (monitor_w*${r_w}) (monitor_h*${r_h})${C_RESET}"$'\n' - - rule_block+=" move = ${local_x} ${local_y}"$'\n' - rule_block+=" ${C_COMMENT}# move = (monitor_w*${r_x}) (monitor_h*${r_y})${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# move = (monitor_w-window_w-20) (monitor_h-window_h-20)${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# center = on${C_RESET}"$'\n' - - rule_block+=$'\n'" ${C_COMMENT}# --- Visuals & Effects ---${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# opacity [active] [inactive]${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# opacity = 0.9 0.9${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# animation = popin${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# rounding = 10${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# border_color = rgb(ff0000)${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# no_blur = on${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# no_shadow = on${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# no_dim = on${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# opaque = on${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# dim_around = on${C_RESET}"$'\n' - - rule_block+=$'\n'" ${C_COMMENT}# --- Placement ---${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# workspace = 2${C_RESET}"$'\n' - rule_block+=" ${C_COMMENT}# monitor = DP-1${C_RESET}"$'\n' - - rule_block+="${C_GREEN}}${C_RESET}"$'\n' + # Build Block (Lua format) + rule_block="${C_DIVIDER}-- ---------------------------------------------------${C_RESET}"$'\n' + rule_block+="-- ${title}"$'\n' + + rule_block+="${C_GREEN}hl.window_rule({${C_RESET}"$'\n' + rule_block+=" name = \"${safe_name}\","$'\n' + rule_block+=" match = { class = \"^(${safe_class})\$\" },"$'\n' + rule_block+=" ${C_COMMENT}-- match = { title = \"^(${safe_title})\$\" },${C_RESET}"$'\n' + + rule_block+=" float = true,"$'\n' + rule_block+=" ${C_COMMENT}-- pin = true,${C_RESET}"$'\n' + + rule_block+=" size = \"${w_w} ${w_h}\","$'\n' + rule_block+=" ${C_COMMENT}-- size = \"(monitor_w*${r_w}) (monitor_h*${r_h})\",${C_RESET}"$'\n' + + rule_block+=" move = \"${local_x} ${local_y}\","$'\n' + rule_block+=" ${C_COMMENT}-- move = \"(monitor_w*${r_x}) (monitor_h*${r_y})\",${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- move = \"(monitor_w-window_w-20) (monitor_h-window_h-20)\",${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- center = true,${C_RESET}"$'\n' + + rule_block+=$'\n'" ${C_COMMENT}-- --- Visuals & Effects ---${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- opacity = \"0.9 override 0.9 override\",${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- anim_style = \"popin\",${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- rounding = 10,${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- border_color = \"rgb(ff0000)\",${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- no_blur = true,${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- no_shadow = true,${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- no_dim = true,${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- opaque = true,${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- dim_around = true,${C_RESET}"$'\n' + + rule_block+=$'\n'" ${C_COMMENT}-- --- Placement ---${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- workspace = 2,${C_RESET}"$'\n' + rule_block+=" ${C_COMMENT}-- monitor = \"DP-1\",${C_RESET}"$'\n' + + rule_block+="${C_GREEN}})"$'\n'"${C_RESET}" WINDOW_TITLES+=("${title:0:60}") WINDOW_CLASSES+=("$initialClass") diff --git a/user_scripts/hypr/dusky_workspace_manager.sh b/user_scripts/hypr/dusky_workspace_manager.sh index 60b52aae..c6510db5 100755 --- a/user_scripts/hypr/dusky_workspace_manager.sh +++ b/user_scripts/hypr/dusky_workspace_manager.sh @@ -20,7 +20,7 @@ shopt -s extglob declare -r HYPR_DIR="${HOME}/.config/hypr" declare -r EDIT_DIR="${HYPR_DIR}/edit_here/source" -declare -r CONFIG_FILE="${EDIT_DIR}/workspace_rules.conf" +declare -r CONFIG_FILE="${EDIT_DIR}/workspace_rules.lua" declare -r APP_TITLE="Dusky Workspace Manager" declare -r APP_VERSION="v4.4.1 (Production)" @@ -43,16 +43,16 @@ register_items() { local i for i in {1..10}; do register 0 "Workspace $i" "ws_${i}|menu||||" "" - register_child "ws_${i}" "Layout" "\$ws${i}_layout|cycle||dwindle,master,monocle,scrolling||" "dwindle" - register_child "ws_${i}" "Persistent" "\$ws${i}_persistent|bool||||" "false" - register_child "ws_${i}" "Master Orient" "\$ws${i}_master_orient|cycle||left,right,top,bottom,center||" "left" - register_child "ws_${i}" "Scroll Dir" "\$ws${i}_scroll_dir|cycle||right,left,up,down||" "right" + register_child "ws_${i}" "Layout" "ws${i}_layout|cycle||dwindle,master,monocle,scrolling||" "dwindle" + register_child "ws_${i}" "Persistent" "ws${i}_persistent|bool||||" "false" + register_child "ws_${i}" "Master Orient" "ws${i}_master_orient|cycle||left,right,top,bottom,center||" "left" + register_child "ws_${i}" "Scroll Dir" "ws${i}_scroll_dir|cycle||right,left,up,down||" "right" done # Tab 1: Global Rules & Temporary Overrides - register 1 "Temp Global Override Layout" '$ephemeral_layout|cycle||dwindle,master,monocle,scrolling||' "monocle" - register 1 "Temp Global Override State" '$ephemeral_enabled|bool||||' "false" - register 1 "Fallback Layout (WS 11+)" '$global_layout|cycle||dwindle,master,monocle,scrolling||' "dwindle" + register 1 "Temp Global Override Layout" 'ephemeral_layout|cycle||dwindle,master,monocle,scrolling||' "monocle" + register 1 "Temp Global Override State" 'ephemeral_enabled|bool||||' "false" + register 1 "Fallback Layout (WS 11+)" 'global_layout|cycle||dwindle,master,monocle,scrolling||' "dwindle" } # --- CHANGE 1 of 4: post_write_action sets flag instead of blocking --- @@ -66,12 +66,12 @@ _flush_reload() { _NEEDS_RELOAD=0 if command -v hyprctl &>/dev/null; then - local eph_val="${CONFIG_CACHE['$ephemeral_enabled|']:-false}" - local eph_layout="${CONFIG_CACHE['$ephemeral_layout|']:-dwindle}" + local eph_val="${CONFIG_CACHE['ephemeral_enabled|']:-false}" + local eph_layout="${CONFIG_CACHE['ephemeral_layout|']:-dwindle}" ( hyprctl reload || true if [[ "$eph_val" == "true" ]]; then - hyprctl keyword workspace "r[1-99], layout:$eph_layout" || true + hyprctl eval "hl.workspace_rule({workspace='r[1-99]',layout='${eph_layout}'})" || true fi ) /dev/null & disown 2>/dev/null || : @@ -152,37 +152,55 @@ log_err() { printf '%s[ERROR]%s %s\n' "$C_RED" "$C_RESET" "$1" >&2 } +_generate_workspace_config() { + local i + { + printf '-- ============================================================================\n' + printf '-- USER CONFIGURATION: workspace_rules.lua\n' + printf '-- Managed by Dusky TUI - Granular Matrix v4.4.1\n' + printf '-- WARNING: Edit via the TUI. Manual edits may be overwritten on format change.\n' + printf '-- ============================================================================\n\n' + + printf '-- Global layout for workspaces 11+\n' + printf 'global_layout = "dwindle"\n\n' + + printf '-- Ephemeral global override (applied at runtime, not persisted across reboot)\n' + printf 'ephemeral_layout = "monocle"\n' + printf 'ephemeral_enabled = false\n\n' + + printf '-- Per-workspace settings (workspaces 1-10)\n' + for i in {1..10}; do + printf 'ws%d_layout = "dwindle"\n' "$i" + printf 'ws%d_persistent = false\n' "$i" + printf 'ws%d_master_orient = "left"\n' "$i" + printf 'ws%d_scroll_dir = "right"\n' "$i" + done + printf '\n' + + printf '-- Apply global fallback rule\n' + printf 'hl.workspace_rule({ workspace = "r[11-99]", layout = global_layout })\n\n' + + printf '-- Apply per-workspace rules\n' + printf 'for i, w in ipairs({\n' + for i in {1..10}; do + printf ' { layout = ws%d_layout, persistent = ws%d_persistent, layout_opts = { orientation = ws%d_master_orient, direction = ws%d_scroll_dir } },\n' \ + "$i" "$i" "$i" "$i" + done + printf '}) do\n' + printf ' hl.workspace_rule({ workspace = tostring(i), layout = w.layout, persistent = w.persistent, layout_opts = w.layout_opts })\n' + printf 'end\n' + } > "${CONFIG_FILE}" +} + ensure_config_exists() { if [[ ! -d "${EDIT_DIR}" ]]; then mkdir -p -- "${EDIT_DIR}" fi - - # Auto-heal: Rebuild template if missing or empty - if [[ ! -f "${CONFIG_FILE}" || ! -s "${CONFIG_FILE}" ]]; then - { - printf '# ==============================================================================\n' - printf '# USER CONFIGURATION: workspace_rules.conf\n' - printf '# Managed by Dusky TUI - Granular Matrix v4.4.1\n' - printf '# ==============================================================================\n\n' - - printf '# --- Global Rules ---\n' - printf '$global_layout = dwindle\n' - printf 'workspace = r[11-99], layout:$global_layout\n\n' - - printf '# --- Ephemeral Global Override (Resets on reboot) ---\n' - printf '$ephemeral_layout = monocle\n' - printf '$ephemeral_enabled = false\n\n' - - printf '# --- Individual Workspaces (1-10) ---\n' - local i - for i in {1..10}; do - printf '$ws%d_layout = dwindle\n' "$i" - printf '$ws%d_persistent = false\n' "$i" - printf '$ws%d_master_orient = left\n' "$i" - printf '$ws%d_scroll_dir = right\n' "$i" - printf 'workspace = %d, layout:$ws%d_layout, persistent:$ws%d_persistent, layoutopt:orientation:$ws%d_master_orient, layoutopt:direction:$ws%d_scroll_dir\n\n' "$i" "$i" "$i" "$i" "$i" - done - } > "${CONFIG_FILE}" + + # Rebuild if missing, empty, or not in TUI-managed variable format (e.g. old conf or array format) + if [[ ! -f "${CONFIG_FILE}" || ! -s "${CONFIG_FILE}" ]] || \ + ! grep -qF 'ws1_layout' "${CONFIG_FILE}" 2>/dev/null; then + _generate_workspace_config fi } @@ -267,16 +285,16 @@ populate_config_cache() { fi done < <(LC_ALL=C awk ' BEGIN { depth = 0 } - /^[[:space:]]*#/ { next } + /^[[:space:]]*--/ { next } { line = $0 clean = line - sub(/[[:space:]]+#.*$/, "", clean) + sub(/[[:space:]]+--.*$/, "", clean) tmpline = clean - while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*\{/)) { + while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*(=[[:space:]]*)?\{/)) { block_str = substr(tmpline, RSTART, RLENGTH) - sub(/[[:space:]]*\{/, "", block_str) + sub(/[[:space:]]*(=[[:space:]]*)?\{/, "", block_str) depth++ block_stack[depth] = block_str tmpline = substr(tmpline, RSTART + RLENGTH) @@ -288,8 +306,11 @@ populate_config_cache() { val = substr(clean, eq_pos + 1) gsub(/^[[:space:]]+|[[:space:]]+$/, "", key) gsub(/^[[:space:]]+|[[:space:]]+$/, "", val) - sub(/[[:space:]]+#.*$/, "", val) + sub(/[[:space:]]+--.*$/, "", val) gsub(/^[[:space:]]+|[[:space:]]+$/, "", val) + # Strip trailing comma and surrounding quotes (Lua syntax) + sub(/,$/, "", val) + if (val ~ /^".*"$/) val = substr(val, 2, length(val) - 2) if (key != "") { current_block = (depth > 0) ? block_stack[depth] : "" print key "|" current_block "=" val @@ -331,13 +352,13 @@ write_value_to_file() { { line = $0 clean = line - sub(/^[[:space:]]*#.*/, "", clean) - sub(/[[:space:]]+#.*$/, "", clean) + sub(/^[[:space:]]*--.*/, "", clean) + sub(/[[:space:]]+--.*$/, "", clean) tmpline = clean - while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*\{/)) { + while (match(tmpline, /[a-zA-Z0-9_.:-]+[[:space:]]*(=[[:space:]]*)?\{/)) { block_str = substr(tmpline, RSTART, RLENGTH) - sub(/[[:space:]]*\{/, "", block_str) + sub(/[[:space:]]*(=[[:space:]]*)?\{/, "", block_str) depth++ block_stack[depth] = block_str if (do_block && block_str == target_block && !in_target) { @@ -364,15 +385,25 @@ write_value_to_file() { } if (do_replace) { - match(line, /^[[:space:]]*/) - leading = substr(line, RSTART, RLENGTH) eq = index(line, "=") before_eq = substr(line, 1, eq) rest = substr(line, eq + 1) match(rest, /^[[:space:]]*/) space_after = substr(rest, RSTART, RLENGTH) - print before_eq space_after new_value + # Detect trailing comma and surrounding quotes from the original value + old_val = substr(rest, RSTART + RLENGTH) + sub(/[[:space:]]+--.*$/, "", old_val) + gsub(/^[[:space:]]+|[[:space:]]+$/, "", old_val) + was_trailing = (old_val ~ /,$/) ? 1 : 0 + sub(/,$/, "", old_val) + was_quoted = (old_val ~ /^".*"$/) ? 1 : 0 + + out_val = new_value + if (was_quoted && !(new_value ~ /^".*"$/)) out_val = "\"" new_value "\"" + trailing = was_trailing ? "," : "" + + print before_eq space_after out_val trailing replaced = 1 } else { print line diff --git a/user_scripts/hypr/hypr_blur_opacity_shadow_toggle.sh b/user_scripts/hypr/hypr_blur_opacity_shadow_toggle.sh index dcda8ad1..ce241eb0 100755 --- a/user_scripts/hypr/hypr_blur_opacity_shadow_toggle.sh +++ b/user_scripts/hypr/hypr_blur_opacity_shadow_toggle.sh @@ -142,9 +142,9 @@ get_current_blur_state() { [[ -L "${CONFIG_FILE}" ]] && actual_config=$(realpath -m "${CONFIG_FILE}") state=$(awk ' - /^[[:space:]]*blur[[:space:]]*\{/ { in_block = 1; next } - in_block && /^[[:space:]]*enabled[[:space:]]*=[[:space:]]*true/ { found = "on" } - in_block && /^[[:space:]]*enabled[[:space:]]*=[[:space:]]*false/ { found = "off" } + /^[[:space:]]*blur[[:space:]]*=[[:space:]]*\{/ { in_block = 1; next } + in_block && /^[[:space:]]*enabled[[:space:]]*=[[:space:]]*true,?/ { found = "on" } + in_block && /^[[:space:]]*enabled[[:space:]]*=[[:space:]]*false,?/ { found = "off" } in_block && /\}/ { in_block = 0 } END { print (found ? found : "off") } ' "$actual_config" 2>/dev/null) || state="off" @@ -281,24 +281,8 @@ fi # --- Apply Changes at Runtime --- -declare -a HYPR_CMDS=( - "decoration:blur:enabled ${NEW_ENABLED}" - "decoration:shadow:enabled ${NEW_ENABLED}" - "decoration:active_opacity ${NEW_ACTIVE}" - "decoration:inactive_opacity ${NEW_INACTIVE}" -) - -hypr_errors=0 -for cmd in "${HYPR_CMDS[@]}"; do - # shellcheck disable=SC2086 - if ! hyprctl keyword $cmd &>/dev/null; then - ((hypr_errors++)) || true - fi -done - -if ((hypr_errors > 0)); then - printf 'Warning: %d hyprctl command(s) failed. Is Hyprland running?\n' "$hypr_errors" >&2 -fi +hyprctl eval "hl.config({decoration={blur={enabled=${NEW_ENABLED}},shadow={enabled=${NEW_ENABLED}},active_opacity=${NEW_ACTIVE},inactive_opacity=${NEW_INACTIVE}}})" &>/dev/null \ + || printf 'Warning: hl.config() failed. Is Hyprland running?\n' >&2 # Reload dynamic daemons if command -v makoctl &>/dev/null; then @@ -315,3 +299,6 @@ fi notify "$NOTIFY_MSG" exit 0 + + +exit 0 diff --git a/user_scripts/hypr/hypr_lua_proxy.py b/user_scripts/hypr/hypr_lua_proxy.py new file mode 100644 index 00000000..735dcda1 --- /dev/null +++ b/user_scripts/hypr/hypr_lua_proxy.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 +""" +hypr_lua_proxy.py — Hyprland IPC command-socket proxy for Lua config mode. + +Waybar (and other tools) send old-style dispatch strings like: + dispatch workspace 2 + dispatch togglespecialworkspace magic + +In Lua config mode, Hyprland evaluates the body as Lua, so those fail. +This proxy translates dispatches into valid Lua expressions before forwarding. + +The event socket (.socket2.sock) is handled separately by socat in +waybar_autostart.sh — pure pass-through needs no Python overhead. + +Usage: + Launched by waybar_autostart.sh which sets HYPRLAND_INSTANCE_SIGNATURE + to point waybar at the proxy directory instead of the real socket. +""" + +import asyncio +import os +import re +import sys +from contextlib import suppress + +# Real Hyprland socket directory +REAL_SIG = os.environ["HYPRLAND_INSTANCE_SIGNATURE"] +RUNTIME = os.environ.get("XDG_RUNTIME_DIR", f"/run/user/{os.getuid()}") +REAL_DIR = f"{RUNTIME}/hypr/{REAL_SIG}" + +# Proxy socket directory (predictable name, not session-specific) +PROXY_DIR = f"{RUNTIME}/hypr/lua_proxy" + + +# --------------------------------------------------------------------------- +# Dispatch translation table +# --------------------------------------------------------------------------- + +def translate(raw: str) -> str: + """Translate one old-style dispatch string to Lua, or return unchanged.""" + s = raw.strip() + + # dispatch workspace + m = re.match(r"^dispatch\s+workspace\s+(.+)$", s) + if m: + t = m.group(1).strip() + if re.match(r"^-?\d+$", t): + return f"dispatch hl.dsp.focus({{workspace={t}}})" + return f'dispatch hl.dsp.focus({{workspace="{t}"}})' + + # dispatch movetoworkspace + m = re.match(r"^dispatch\s+movetoworkspace\s+(.+)$", s) + if m: + t = m.group(1).strip() + if re.match(r"^-?\d+$", t): + return f"dispatch hl.dsp.window.move({{workspace={t}}})" + return f'dispatch hl.dsp.window.move({{workspace="{t}"}})' + + # dispatch movetoworkspacesilent + m = re.match(r"^dispatch\s+movetoworkspacesilent\s+(.+)$", s) + if m: + t = m.group(1).strip() + if re.match(r"^-?\d+$", t): + return f"dispatch hl.dsp.window.move({{workspace={t}, silent=true}})" + return f'dispatch hl.dsp.window.move({{workspace="{t}", silent=true}})' + + # dispatch togglespecialworkspace [name] + m = re.match(r"^dispatch\s+togglespecialworkspace\s*(.*)$", s) + if m: + name = m.group(1).strip() + if name: + return f'dispatch hl.dsp.workspace.toggle_special("{name}")' + return "dispatch hl.dsp.workspace.toggle_special()" + + return raw # pass through unchanged + + +# --------------------------------------------------------------------------- +# Command socket proxy (.socket.sock) — request/response, translates dispatches +# --------------------------------------------------------------------------- + +async def handle_command( + reader: asyncio.StreamReader, writer: asyncio.StreamWriter +) -> None: + try: + data = await asyncio.wait_for(reader.read(4096), timeout=2.0) + + cmd = data.decode("utf-8", errors="replace") + out = translate(cmd) + + real_reader, real_writer = await asyncio.open_unix_connection( + f"{REAL_DIR}/.socket.sock" + ) + try: + real_writer.write(out.encode("utf-8")) + real_writer.write_eof() + await real_writer.drain() + + try: + resp = await asyncio.wait_for(real_reader.read(65536), timeout=0.5) + except asyncio.TimeoutError: + resp = b"" + finally: + real_writer.close() + with suppress(Exception): + await real_writer.wait_closed() + + writer.write(resp) + await writer.drain() + except Exception as e: + print(f"[proxy] command error: {e}", file=sys.stderr) + finally: + with suppress(Exception): + writer.close() + with suppress(Exception): + await writer.wait_closed() + + +# --------------------------------------------------------------------------- +# Entry point — command socket only; event socket handled by socat +# --------------------------------------------------------------------------- + +async def main() -> None: + os.makedirs(PROXY_DIR, exist_ok=True) + + sock_path = f"{PROXY_DIR}/.socket.sock" + with suppress(FileNotFoundError): + os.unlink(sock_path) + + server = await asyncio.start_unix_server(handle_command, sock_path) + print(f"[proxy] command socket: {sock_path}", file=sys.stderr) + + async with server: + await server.serve_forever() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/user_scripts/hypr/monitor/adjust_scale.sh b/user_scripts/hypr/monitor/adjust_scale.sh index 985c9718..40e3de3b 100755 --- a/user_scripts/hypr/monitor/adjust_scale.sh +++ b/user_scripts/hypr/monitor/adjust_scale.sh @@ -64,12 +64,12 @@ trim() { # --- Initialization --- init_config_file() { - if [[ -f "${CONFIG_DIR}/monitors.conf" ]]; then - CONFIG_FILE="${CONFIG_DIR}/monitors.conf" - log_debug "Selected config: monitors.conf" + if [[ -f "${CONFIG_DIR}/monitors.lua" ]]; then + CONFIG_FILE="${CONFIG_DIR}/monitors.lua" + log_debug "Selected config: monitors.lua" else - CONFIG_FILE="${CONFIG_DIR}/monitors.conf" - log_debug "Creating new config: monitors.conf" + CONFIG_FILE="${CONFIG_DIR}/monitors.lua" + log_debug "Creating new config: monitors.lua" mkdir -p -- "${CONFIG_DIR}" : > "$CONFIG_FILE" fi diff --git a/user_scripts/hypr/monitor/dusky_monitor_old.sh b/user_scripts/hypr/monitor/dusky_monitor_old.sh index beeed881..4c7dc977 100755 --- a/user_scripts/hypr/monitor/dusky_monitor_old.sh +++ b/user_scripts/hypr/monitor/dusky_monitor_old.sh @@ -21,8 +21,8 @@ trap cleanup EXIT readonly CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/edit_here" readonly BACKUP_DIR="/tmp/hypr-wizard-backups" -CONFIG_FILE="${CONFIG_DIR}/monitors.conf" -[[ -f "${CONFIG_DIR}/source/monitors.conf" ]] && CONFIG_FILE="${CONFIG_DIR}/source/monitors.conf" +CONFIG_FILE="${CONFIG_DIR}/monitors.lua" +[[ -f "${CONFIG_DIR}/source/monitors.lua" ]] && CONFIG_FILE="${CONFIG_DIR}/source/monitors.lua" # ANSI color codes readonly C_R=$'\e[0m' C_RED=$'\e[31m' C_GRN=$'\e[32m' C_YLW=$'\e[33m' diff --git a/user_scripts/hypr/monitor/dusky_monitor_relatively_old.sh b/user_scripts/hypr/monitor/dusky_monitor_relatively_old.sh index b04b3e9e..9771f0bc 100755 --- a/user_scripts/hypr/monitor/dusky_monitor_relatively_old.sh +++ b/user_scripts/hypr/monitor/dusky_monitor_relatively_old.sh @@ -12,7 +12,7 @@ readonly VERSION="7.4.5" readonly CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/hypr/edit_here" # Backups stored in volatile /tmp (cleared on reboot) readonly BACKUP_DIR="/tmp/hypr-wizard-backups" -readonly CONFIG_FILE="${CONFIG_DIR}/source/monitors.conf" +readonly CONFIG_FILE="${CONFIG_DIR}/source/monitors.lua" readonly MAX_BACKUPS=20 # ANSI Colors & Styling diff --git a/user_scripts/hypr/multi_monitor_workspace.sh b/user_scripts/hypr/multi_monitor_workspace.sh index ad89988e..86df9b0e 100755 --- a/user_scripts/hypr/multi_monitor_workspace.sh +++ b/user_scripts/hypr/multi_monitor_workspace.sh @@ -47,11 +47,41 @@ fi # --- 6. Dispatch Logic --- +# Translate old-style dispatcher + target into a Lua expression for Hyprland's +# Lua config mode. hyprctl dispatch evaluates the body as Lua. +lua_dispatch() { + local disp="$1" + local tgt="$2" + local lua_tgt + + # Numeric targets are unquoted; named/relative targets are quoted strings. + if [[ "${tgt}" =~ ^-?[0-9]+$ ]]; then + lua_tgt="${tgt}" + else + lua_tgt="\"${tgt}\"" + fi + + case "${disp}" in + workspace) + exec hyprctl dispatch "hl.dsp.focus({workspace=${lua_tgt}})" + ;; + movetoworkspace) + exec hyprctl dispatch "hl.dsp.window.move({workspace=${lua_tgt}})" + ;; + movetoworkspacesilent) + exec hyprctl dispatch "hl.dsp.window.move({workspace=${lua_tgt}, silent=true})" + ;; + *) + exec hyprctl dispatch "${disp}" "${tgt}" + ;; + esac +} + # Case A: Pass-Through (Relative, Special, Named) # If the target is NOT a pure positive integer (contains chars, +, -, or is empty), -# we pass it directly to Hyprland without doing math. +# we pass it directly without doing math. if [[ ! "${target}" =~ ^[0-9]+$ ]]; then - exec hyprctl dispatch "${dispatcher}" "${target}" + lua_dispatch "${dispatcher}" "${target}" fi # Case B: Banked Navigation (Pure Integer) @@ -69,4 +99,4 @@ fi final_target=$(( (bank_base * 10) + target )) # Execute and replace process -exec hyprctl dispatch "${dispatcher}" "${final_target}" +lua_dispatch "${dispatcher}" "${final_target}" diff --git a/user_scripts/hypr/screen_rotate.sh b/user_scripts/hypr/screen_rotate.sh index a3fde241..5703af40 100755 --- a/user_scripts/hypr/screen_rotate.sh +++ b/user_scripts/hypr/screen_rotate.sh @@ -20,8 +20,8 @@ readonly C_RESET=$'\e[0m' # 2. Config Paths (Strictly ordered by priority for modular setups) # ------------------------------------------------------------------------------ readonly CONFIG_FILES=( - "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/edit_here/source/monitors.conf" - "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/source/monitors.conf" + "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/edit_here/source/monitors.lua" + "${XDG_CONFIG_HOME:-$HOME/.config}/hypr/source/monitors.lua" ) # 3. Exit Handling @@ -44,6 +44,7 @@ die() { # 4. Privilege & Dependency Checks # ------------------------------------------------------------------------------ command -v jq &> /dev/null || die "'jq' is missing. Install: sudo pacman -S jq" +command -v python3 &> /dev/null || die "'python3' is missing." command -v hyprctl &> /dev/null || die "'hyprctl' is missing." [[ $EUID -ne 0 ]] || die "Root detected. Run as standard user for socket access." @@ -78,69 +79,88 @@ IFS=' ' read -r NAME CURRENT_TRANSFORM FALLBACK_WIDTH FALLBACK_HEIGHT FALLBACK_R # Calculate new transform safely NEW_TRANSFORM=$(( (CURRENT_TRANSFORM + DIRECTION + 4) % 4 )) -# 7. Surgical Config Parsing (Source of Truth for Parameters) +# 7. Locate config file # ------------------------------------------------------------------------------ -BASE_RULE="" -RULE_SOURCE="IPC Fallback" - +CONF_FILE="" for conf in "${CONFIG_FILES[@]}"; do if [[ -f "$conf" ]]; then - # Use awk to find the last line defining this monitor (last-definition-wins, - # matching Hyprland's own config semantics) - matched_line=$(awk -v mon="$NAME" ' - $0 ~ "^[[:space:]]*monitor[[:space:]]*=[[:space:]]*" mon "[[:space:]]*," { - line = $0 - } - END { if (line != "") print line } - ' "$conf") - - if [[ -n "$matched_line" ]]; then - # Strip inline comments - matched_line="${matched_line%%#*}" - - # Bash native regex to extract everything after the equals sign - if [[ "$matched_line" =~ ^[[:space:]]*monitor[[:space:]]*=[[:space:]]*(.*)$ ]]; then - BASE_RULE="${BASH_REMATCH[1]}" - # Strip any resulting trailing whitespace efficiently - BASE_RULE="${BASE_RULE%"${BASE_RULE##*[![:space:]]}"}" - RULE_SOURCE="$conf" - break - fi - fi + CONF_FILE="$conf" + break fi done -# 8. Payload Assembly -# ------------------------------------------------------------------------------ -if [[ -n "$BASE_RULE" ]]; then - # STRATEGY A: Config Injection - # Strip any existing 'transform, X' pairs surgically using sed to prevent duplicates - CLEAN_RULE=$(sed -E 's/,[[:space:]]*transform[[:space:]]*,[[:space:]]*[0-7]//g' <<< "$BASE_RULE") - - # Append the new transform to the pristine config string - FINAL_PAYLOAD="${CLEAN_RULE}, transform, ${NEW_TRANSFORM}" -else - # STRATEGY B: IPC Reconstruction (Failsafe for transient/hot-plugged displays) - # Rebuild the string using exact values, avoiding 'preferred, auto' completely - FINAL_PAYLOAD="${NAME}, ${FALLBACK_WIDTH}x${FALLBACK_HEIGHT}@${FALLBACK_REFRESH}, ${FALLBACK_X}x${FALLBACK_Y}, ${FALLBACK_SCALE}, transform, ${NEW_TRANSFORM}" +if [[ -z "$CONF_FILE" ]]; then + # No config exists yet — create one at the primary edit_here location + CONF_FILE="${CONFIG_FILES[0]}" + mkdir -p "$(dirname "$CONF_FILE")" fi -# 9. Execution +# 8. Update monitors.lua with new transform and reload # ------------------------------------------------------------------------------ -printf '%s[INFO]%s Target: %s%s%s\n' "$C_BLUE" "$C_RESET" "$C_BOLD" "$NAME" "$C_RESET" -printf '%s[INFO]%s Source: %s\n' "$C_BLUE" "$C_RESET" "$RULE_SOURCE" -printf '%s[INFO]%s Payload: %s\n' "$C_YELLOW" "$C_RESET" "$FINAL_PAYLOAD" - -if hyprctl keyword monitor "$FINAL_PAYLOAD" > /dev/null; then +printf '%s[INFO]%s Target: %s%s%s | Transform: %d -> %d\n' \ + "$C_BLUE" "$C_RESET" "$C_BOLD" "$NAME" "$C_RESET" "$CURRENT_TRANSFORM" "$NEW_TRANSFORM" +printf '%s[INFO]%s Config: %s\n' "$C_BLUE" "$C_RESET" "$CONF_FILE" + +python3 - "$CONF_FILE" "$NAME" "$NEW_TRANSFORM" <<'PYEOF' \ + || die "Failed to update monitors.lua" +import sys, re, os, tempfile + +conf_path, mon_name, new_transform = sys.argv[1], sys.argv[2], sys.argv[3] + +try: + with open(conf_path, 'r') as f: + text = f.read() +except FileNotFoundError: + text = '' + +found = False + +def replacer(m): + global found + line = m.group(0) + if f'output = "{mon_name}"' not in line: + return line + found = True + # Remove first, then insert — reversing order would cause the removal regex + # to eat the value just inserted, leaving no transform field at all. + line = re.sub(r',\s*transform\s*=\s*\d+', '', line) + line = re.sub(r'(\s*\}\s*\)\s*)$', f', transform = {new_transform}\\1', line) + return line + +text = re.sub(r'^.*hl\.monitor\s*\(.*$', replacer, text, flags=re.MULTILINE) + +if not found: + text += f'\nhl.monitor({{ output = "{mon_name}", mode = "preferred", position = "auto", scale = 1, transform = {new_transform} }})\n' + +try: + orig_mode = os.stat(conf_path).st_mode +except FileNotFoundError: + orig_mode = 0o644 + +fd, tmp = tempfile.mkstemp(dir=os.path.dirname(conf_path), prefix='.monitors.lua.tmp.') +try: + with os.fdopen(fd, 'w') as f: + f.write(text) + os.chmod(tmp, orig_mode) + os.replace(tmp, conf_path) +except Exception as e: + os.remove(tmp) + sys.stderr.write(f'Atomic write failed: {e}\n') + sys.exit(1) +PYEOF + +# 9. Apply via reload +# ------------------------------------------------------------------------------ +if hyprctl reload > /dev/null; then printf '%s[SUCCESS]%s Rotation applied: %d -> %d\n' "$C_GREEN" "$C_RESET" "$CURRENT_TRANSFORM" "$NEW_TRANSFORM" if command -v notify-send &> /dev/null; then notify-send -a 'System' 'Display Rotated' \ - "$(printf 'Monitor: %s\nTransform: %d\nSource: %s' "$NAME" "$NEW_TRANSFORM" "${RULE_SOURCE##*/}")" \ + "$(printf 'Monitor: %s\nTransform: %d' "$NAME" "$NEW_TRANSFORM")" \ -h string:x-canonical-private-synchronous:display-rotate fi else - die "Hyprland rejected the monitor payload." + die "hyprctl reload failed." fi trap - EXIT diff --git a/user_scripts/images/dusky_screenshot.sh b/user_scripts/images/dusky_screenshot.sh index 3ecb418c..5d9bd848 100755 --- a/user_scripts/images/dusky_screenshot.sh +++ b/user_scripts/images/dusky_screenshot.sh @@ -101,7 +101,7 @@ freeze_screen() { if (( FREEZE )); then hyprpicker -r -z >/dev/null 2>&1 & FREEZE_PID=$! - sleep 0.12 + sleep 0.12 fi } diff --git a/user_scripts/rofi/hypr_anim.sh b/user_scripts/rofi/hypr_anim.sh index d1632106..f4d9da91 100755 --- a/user_scripts/rofi/hypr_anim.sh +++ b/user_scripts/rofi/hypr_anim.sh @@ -15,9 +15,9 @@ set -o pipefail readonly CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}" readonly ANIM_DIR="$CONFIG_DIR/hypr/source/animations" readonly LINK_DIR="$ANIM_DIR/active" -readonly DEST_FILE="$LINK_DIR/active.conf" +readonly DEST_FILE="$LINK_DIR/active.lua" readonly STATE_FILE="$CONFIG_DIR/dusky/settings/dusky_animiation" -readonly FALLBACK_ANIM="horizontal_dusky.conf" +readonly FALLBACK_ANIM="horizontal_dusky.lua" # Visual Assets (Nerd Fonts) readonly ICON_ACTIVE="" # Checkmark @@ -153,13 +153,13 @@ if [[ ! -d "$ANIM_DIR" ]]; then exit 0 fi -# Gather .conf files safely +# Gather .lua files safely shopt -s nullglob -files=("$ANIM_DIR"/*.conf) +files=("$ANIM_DIR"/*.lua) shopt -u nullglob if [[ ${#files[@]} -eq 0 ]]; then - printf '%s\0icon\x1f%s\x1finfo\x1fignore\n' "No .conf files found" "$ICON_ERROR" + printf '%s\0icon\x1f%s\x1finfo\x1fignore\n' "No .lua files found" "$ICON_ERROR" exit 0 fi diff --git a/user_scripts/rofi/keybindings.sh b/user_scripts/rofi/keybindings.sh index 66533d74..f142e21c 100755 --- a/user_scripts/rofi/keybindings.sh +++ b/user_scripts/rofi/keybindings.sh @@ -313,6 +313,13 @@ main() { selected_line=${records[selected_index]} IFS=$DELIM read -r _ dispatcher argument <<< "$selected_line" + # In Lua config mode all binds are stored as __lua + internal ID; the ID + # is an opaque per-session index and cannot be replayed via hyprctl dispatch. + if [[ "$dispatcher" == "__lua" ]]; then + hyprctl notify 1 2500 0 " Press the key combination to trigger this bind" 2>/dev/null || true + exit 0 + fi + if [[ -n $argument ]]; then hyprctl dispatch "$dispatcher" "$argument" || die "Failed to dispatch: $dispatcher $argument" else diff --git a/user_scripts/rofi/rofi_mako.sh b/user_scripts/rofi/rofi_mako.sh index 4f7485ab..c09597b0 100755 --- a/user_scripts/rofi/rofi_mako.sh +++ b/user_scripts/rofi/rofi_mako.sh @@ -119,7 +119,7 @@ case $ROFI_EXIT in # 2. Fallback for expired history items (Brings app to front safely) if [[ -n "$SELECTED_APP" && "$SELECTED_APP" != "notify-send" && "$SELECTED_APP" != "mako" ]]; then # Grouped and backgrounded cleanly to prevent Rofi/Hyprland hanging - { gtk-launch "$SELECTED_APP" || hyprctl dispatch exec "$SELECTED_APP"; } >/dev/null 2>&1 & + { gtk-launch "$SELECTED_APP" || uwsm-app -- "$SELECTED_APP"; } >/dev/null 2>&1 & fi fi diff --git a/user_scripts/rofi/shader_menu.sh b/user_scripts/rofi/shader_menu.sh index 153083de..5e5a61b2 100755 --- a/user_scripts/rofi/shader_menu.sh +++ b/user_scripts/rofi/shader_menu.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # -# Hyprshade Selector - Interactive shader picker with live preview -# Requires: rofi, hyprshade, flock +# Hyprland Shader Selector - Interactive shader picker with live preview +# Requires: rofi, hyprctl, flock, python3 # set -o errexit @@ -63,7 +63,7 @@ check_dependencies() { local -a missing=() local cmd - for cmd in rofi hyprshade flock; do + for cmd in rofi hyprctl flock python3; do command -v "$cmd" >/dev/null 2>&1 || missing+=("$cmd") done @@ -83,12 +83,22 @@ write_latest_token() { apply_shader_sync() { local shader="${1:-off}" - - if [[ "$shader" == "off" ]]; then - hyprshade off - else - hyprshade on "$shader" + local shader_path="" + + if [[ "$shader" != "off" ]]; then + # Resolve full path — check user shaders first, then system + if [[ -f "${HOME}/.config/hypr/shaders/${shader}.glsl" ]]; then + shader_path="${HOME}/.config/hypr/shaders/${shader}.glsl" + elif [[ -f "/usr/share/hyprshade/shaders/${shader}.glsl" ]]; then + shader_path="/usr/share/hyprshade/shaders/${shader}.glsl" + else + err "Shader file not found: ${shader}" + return 1 + fi fi + + # hl.config() is the Lua-mode equivalent of hyprctl keyword + hyprctl eval "hl.config({decoration={screen_shader='${shader_path}'}})" >/dev/null 2>&1 } queue_preview() { @@ -174,15 +184,28 @@ init() { trap 'exit 143' TERM trap 'exit 129' HUP - current_output=$(hyprshade current 2>/dev/null || true) - ORIGINAL_SHADER=$(trim "$current_output") - [[ -z "$ORIGINAL_SHADER" ]] && ORIGINAL_SHADER="off" - - if ! ls_output=$(hyprshade ls 2>/dev/null); then - err "Failed to list shaders" - exit 1 + # Get current shader via hyprctl (Lua-mode compatible) + local current_path + current_path=$(hyprctl -j getoption decoration:screen_shader 2>/dev/null \ + | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('str',''))" 2>/dev/null || true) + current_path=$(trim "$current_path") + if [[ -n "$current_path" && "$current_path" != "[[EMPTY]]" ]]; then + ORIGINAL_SHADER=$(basename "$current_path" .glsl) + else + ORIGINAL_SHADER="off" fi + # List shaders from user and system dirs + local -a shader_dirs=("${HOME}/.config/hypr/shaders" "/usr/share/hyprshade/shaders") + ls_output="" + for dir in "${shader_dirs[@]}"; do + [[ -d "$dir" ]] || continue + while IFS= read -r f; do + ls_output+="$(basename "$f" .glsl)"$'\n' + done < <(find "$dir" -maxdepth 1 -name "*.glsl" | sort) + done + [[ -n "$ls_output" ]] || { err "No shaders found"; exit 1; } + SHADERS=("off") while IFS= read -r line; do diff --git a/user_scripts/spotify/spotify_toggle.sh b/user_scripts/spotify/spotify_toggle.sh index 5c7f82a3..96fe1933 100755 --- a/user_scripts/spotify/spotify_toggle.sh +++ b/user_scripts/spotify/spotify_toggle.sh @@ -3,8 +3,8 @@ # Check if spotify process is running if pgrep -x "spotify" >/dev/null; then # If running, just toggle the special workspace - hyprctl dispatch movetoworkspacesilent "special:music,class:^(Spotify)$" - hyprctl dispatch togglespecialworkspace music + hyprctl dispatch "hl.dsp.window.move({workspace='special:music', window='class:^(Spotify)$', silent=true})" + hyprctl dispatch "hl.dsp.workspace.toggle_special('music')" else # If not running, launch it spotify & diff --git a/user_scripts/waybar/dusky_waybars.sh b/user_scripts/waybar/dusky_waybars.sh index 9dddd0dc..dac1ed23 100755 --- a/user_scripts/waybar/dusky_waybars.sh +++ b/user_scripts/waybar/dusky_waybars.sh @@ -33,7 +33,7 @@ readonly CONFIG_ROOT="${HOME}/.config/waybar" readonly APP_TITLE="Dusky Waybar Manager" readonly APP_VERSION="v4.8.1" -readonly -a UWSM_CMD=(uwsm-app -- waybar) +readonly -a UWSM_CMD=(systemd-run --user --setenv=HYPRLAND_INSTANCE_SIGNATURE=lua_proxy -- waybar) declare -ri MAX_DISPLAY_ROWS=14 declare -ri BOX_WIDTH=76 diff --git a/user_scripts/waybar/waybar_autostart.sh b/user_scripts/waybar/waybar_autostart.sh index 9a7c2163..135e1671 100755 --- a/user_scripts/waybar/waybar_autostart.sh +++ b/user_scripts/waybar/waybar_autostart.sh @@ -11,6 +11,8 @@ set -euo pipefail # --- Constants --- readonly APP_NAME="waybar" readonly TIMEOUT_SEC=5 +readonly PROXY_SCRIPT="$HOME/user_scripts/hypr/hypr_lua_proxy.py" +readonly PROXY_SIG="lua_proxy" # --- Terminal-Aware Colors (stderr detection) --- if [[ -t 2 ]]; then @@ -32,12 +34,13 @@ log_success() { printf '%s[OK]%s %s\n' "${C_GREEN}" "${C_RESET}" "$*" >&2; } log_err() { printf '%s[ERROR]%s %s\n' "${C_RED}" "${C_RESET}" "$*" >&2; } # --- Fallback Strategy --- -# Note: As discovered, this method may not cure the "workspace inheritance" +# Note: As discovered, this method may not cure the "workspace inheritance" # bug, but it ensures Waybar launches if systemd is broken. launch_fallback() { log_info "Attempting fallback launch (setsid)..." ( unset XDG_ACTIVATION_TOKEN DESKTOP_STARTUP_ID + export HYPRLAND_INSTANCE_SIGNATURE="${PROXY_SIG}" setsid "${APP_NAME}" "$@" /dev/null 2>&1 & ) log_success "${APP_NAME} launched (fallback mode)." @@ -79,6 +82,54 @@ else log_info "No running instance found." fi +# --- Lua IPC Proxy --- +# Command socket: Python proxy translates old-style "dispatch workspace N" +# into valid Lua expressions before forwarding to the real Hyprland socket. +# Event socket: socat pure pass-through (C-level, zero Python overhead). +PROXY_CMD_SOCK="${XDG_RUNTIME_DIR}/hypr/${PROXY_SIG}/.socket.sock" +PROXY_EVT_SOCK="${XDG_RUNTIME_DIR}/hypr/${PROXY_SIG}/.socket2.sock" + +# Retry hyprctl until the real instance is discoverable (race-safe) +REAL_DIR="" +for (( i = 0; i < 50; i++ )); do + _sig=$(hyprctl instances -j 2>/dev/null \ + | python3 -c 'import json,sys; print(json.load(sys.stdin)[0]["instance"])' 2>/dev/null || true) + if [[ -n "${_sig}" && -S "${XDG_RUNTIME_DIR}/hypr/${_sig}/.socket2.sock" ]]; then + REAL_DIR="${XDG_RUNTIME_DIR}/hypr/${_sig}" + break + fi + sleep 0.1 +done +[[ -n "${REAL_DIR}" ]] || { log_err "Could not locate real Hyprland socket — proxy aborted."; exit 1; } + +log_info "Restarting Lua IPC proxy..." + +# Stop and fully clear any previous proxy units before re-creating them +systemctl --user stop hypr-lua-proxy hypr-socat-proxy 2>/dev/null || true +systemctl --user reset-failed hypr-lua-proxy hypr-socat-proxy 2>/dev/null || true + +# Ensure proxy directory exists before socat tries to bind into it +mkdir -p "${XDG_RUNTIME_DIR}/hypr/lua_proxy" + +# Command socket — Python in its own persistent systemd unit +systemd-run --user --quiet --unit="hypr-lua-proxy" \ + -- python3 "${PROXY_SCRIPT}" 2>/dev/null || true + +# Event socket — socat in its own persistent systemd unit +systemd-run --user --quiet --unit="hypr-socat-proxy" \ + -- socat \ + "UNIX-LISTEN:${PROXY_EVT_SOCK},fork,unlink-early" \ + "UNIX-CONNECT:${REAL_DIR}/.socket2.sock" \ + 2>/dev/null || true + +for (( i = 0; i < 30; i++ )); do + [[ -S "${PROXY_CMD_SOCK}" && -S "${PROXY_EVT_SOCK}" ]] && break + sleep 0.1 +done +[[ -S "${PROXY_CMD_SOCK}" && -S "${PROXY_EVT_SOCK}" ]] \ + && log_success "Lua proxy sockets ready." \ + || log_err "Lua proxy socket(s) not ready — workspace clicks may be broken." + # --- Launch Sequence --- log_info "Starting ${APP_NAME}..." @@ -88,7 +139,9 @@ if command -v systemd-run >/dev/null 2>&1; then unit_name="${APP_NAME}-mgr-${EPOCHSECONDS}-$$" # '--' separates options from the command to prevent flag injection - if systemd-run --user --quiet --unit="${unit_name}" -- "${APP_NAME}" "$@" >/dev/null 2>&1; then + if systemd-run --user --quiet --unit="${unit_name}" \ + --setenv=HYPRLAND_INSTANCE_SIGNATURE="${PROXY_SIG}" \ + -- "${APP_NAME}" "$@" >/dev/null 2>&1; then log_success "${APP_NAME} launched via systemd unit: ${unit_name}" else log_err "systemd-run failed; attempting fallback." diff --git a/user_scripts/wlogout/dusky_session.sh b/user_scripts/wlogout/dusky_session.sh index 8aada693..cd3f70e8 100755 --- a/user_scripts/wlogout/dusky_session.sh +++ b/user_scripts/wlogout/dusky_session.sh @@ -26,7 +26,7 @@ if [[ -d "$STATE_DIR" ]]; then fi # 2. Reset workspace (visually cleaner for next boot, non-fatal) -hyprctl dispatch workspace 1 >/dev/null 2>&1 || : +hyprctl dispatch "hl.dsp.focus({workspace=1})" >/dev/null 2>&1 || : # 3. Smart teardown logic # Safely check if UWSM is installed, then ask UWSM if it is actively managing the session @@ -86,7 +86,7 @@ else # Execute final action if [[ "$ACTION" == "logout" ]]; then - exec hyprctl dispatch exit + exec hyprctl dispatch "hl.dsp.exit()" else exec systemctl "$ACTION" --no-wall fi