-- ─────────────────────────────────────────────────────────────────────────────
-- Input
--
-- Deliberately GNOME-like: click-to-focus, no focus-follows-mouse, no mouse
-- acceleration changes. The goal is that muscle memory transfers untouched.
-- ─────────────────────────────────────────────────────────────────────────────

local prefs = require("prefs")

hl.config({
    input = {
        kb_layout  = prefs.get("keyboardLayout", "us"),
        kb_variant = prefs.get("keyboardVariant", ""),
        kb_model   = "",
        kb_options = prefs.get("keyboardOptions", "caps:escape_shifted_capslock"),
        kb_rules   = "",

        numlock_by_default = prefs.get("numlockByDefault", true),

        -- GNOME's defaults are 500ms delay / 33Hz repeat.
        repeat_delay = prefs.get("keyRepeatDelay", 500),
        repeat_rate  = prefs.get("keyRepeatRate", 33),

        -- 1 = FOLLOW. The window under the pointer takes focus. This comment
        -- previously claimed 1 was "click to focus, GNOME's behavior", which
        -- is the opposite of what Hyprland does -- `hyprctl descriptions` gives
        -- map: [{"separate":3},{"detached":2},{"follow":1},{"disabled":0}],
        -- so click-to-focus is 0. Changing the shipped value is a behavior
        -- decision rather than a correction, so the value is left alone and
        -- only the description is fixed; Settings exposes all four.
        follow_mouse = prefs.getInt("followMouse", 1),

        -- Softens follow_mouse: with this off, focus changes only when the
        -- pointer crosses a window boundary, not on every movement inside one.
        -- Still focus-follows-pointer, just less twitchy.
        mouse_refocus = false,

        -- 0 = NEXT, the compositor's own default: focus goes to the next window
        -- in the layout order. `hyprctl descriptions` publishes
        -- map: [{"mru":2},{"cursor":1},{"next":0}], and Settings offers all
        -- three; 0 is repeated here so nothing changes on a machine with no
        -- settings file.
        focus_on_close = prefs.getInt("focusOnClose", 0),

        -- Flat pointer response by default, no acceleration. Matters for
        -- gaming; Settings offers adaptive for people who want it back.
        sensitivity   = prefs.get("pointerSensitivity", 0),
        accel_profile = prefs.get("accelProfile", "flat"),

        natural_scroll = prefs.get("naturalScroll", false),
        scroll_factor  = prefs.get("scrollFactor", 1.0),
        left_handed    = prefs.get("leftHanded", false),

        -- Empty is a value, not an omission: it is what `hyprctl getoption`
        -- reports as "[[EMPTY]]" before anything writes the option, and it means
        -- "let libinput pick per device" -- two fingers on a touchpad, the wheel
        -- on a mouse. Writing it back explicitly is the same branch a stock
        -- Hyprland takes, and it keeps the setting reversible: without an empty
        -- choice in the schema there would be no way back from a scroll method
        -- once one was picked. Settings offers 2fg / edge / on_button_down /
        -- no_scroll alongside it, the four words the option's own description
        -- names (it publishes no map).
        scroll_method = prefs.get("scrollMethod", ""),

        -- Only consulted while scroll_method is on_button_down. 0 means the
        -- device's own middle button.
        scroll_button = prefs.get("scrollButton", 0),

        -- Clicking a floating window raises and focuses it.
        float_switch_override_focus = 2,

        -- Every touchpad preference Settings offers is read here as well as
        -- applied live: the live half (hyprctl eval) reaches a running
        -- compositor, and THIS half is what survives `hyprctl reload` and the
        -- gap before the shell starts. A schema `hypr:` entry without a
        -- prefs.get() here is a control that quietly reverts -- the whole
        -- Mouse & Touchpad page once had exactly that bug. Defaults must
        -- match PreferenceSchema's; the hypr-prefs-contract checks both.
        touchpad = {
            tap_to_click            = prefs.get("touchpadTapToClick", true),
            natural_scroll          = prefs.get("touchpadNaturalScroll", true),
            disable_while_typing    = prefs.get("touchpadDisableWhileTyping", true),
            scroll_factor           = prefs.get("touchpadScrollFactor", 1.0),
            drag_lock               = prefs.getInt("touchpadDragLock", 0),
            middle_button_emulation = prefs.get("touchpadMiddleButtonEmulation", false),
            clickfinger_behavior    = prefs.get("touchpadClickfinger", false),

            -- Underscores here, hyphens in the option name getoption answers to
            -- (input:touchpad:tap-and-drag) -- the same split tap_to_click has
            -- at the top of this table. Hyprland's own default is true; it is
            -- repeated rather than omitted so the schema, the Lua, and the
            -- compositor all state the same value.
            tap_and_drag            = prefs.get("touchpadTapAndDrag", true),
        },
    },

    -- Pointer BEHAVIOUR, as opposed to pointer appearance: how the cursor reacts
    -- to typing and to workspace switches. The cursor's looks -- theme, size,
    -- hardware cursors, the inactivity fade -- are a separate cursor table in
    -- looks.lua. hl.config calls are additive per option, so the two tables
    -- coexist; they are split by what a person would go looking for, and these
    -- two appear on Settings' Mouse & Touchpad page rather than in Appearance.
    cursor = {
        hide_on_key_press = prefs.get("cursorHideWhileTyping", false),

        -- An integer with three states, written from a switch: disable = 0,
        -- enable = 1, force = 2. Settings offers the first two, so getInt is
        -- what bridges a stored boolean to the number Hyprland wants -- the same
        -- pairing render.cm_auto_hdr uses in looks.lua.
        warp_on_change_workspace = prefs.getInt("cursorWarpOnWorkspaceChange", 0),
    },

    -- Tuning for the three-finger gestures registered below.
    gestures = {
        workspace_swipe_distance = prefs.getInt("swipeDistance", 300),
        workspace_swipe_invert   = prefs.get("swipeInvert", true),
    },
})

-- ── Touchpad gestures ───────────────────────────────────────────────────────
--
-- GNOME's gestures, reproduced: three fingers sideways moves between
-- workspaces, three fingers up opens the overview, three fingers down closes
-- it. That is the same muscle memory the keybinds were built to preserve.
--
-- Registered unconditionally rather than behind a preference. Hyprland 0.56
-- dropped `gestures:workspace_swipe` in favour of this `gesture` keyword, and a
-- registration is read at config time -- so a toggle would need a reload to
-- take effect, which is worse than the nothing these cost on a machine with no
-- touchpad. What IS tunable at runtime lives in Settings: how far a swipe has
-- to travel, and which way round it goes.
--
-- open and close rather than toggle twice: with a toggle on both directions,
-- swiping up from an already-open overview would close it, and swiping down
-- would reopen it. GNOME does not do that, and neither does this.
local overview = function(fn)
    return function() hl.exec_cmd("qs ipc call overview " .. fn) end
end

hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" })
hl.gesture({ fingers = 3, direction = "up",         action = overview("open") })
hl.gesture({ fingers = 3, direction = "down",       action = overview("close") })

return true
