Skip to content

Input

Configure keyboard, pointer, touchpad, tablet, cursor, and focus behavior under [input].

[input]
middle_click_paste = false
client_window_drag = true
window_snapping = true
window_drag_toggle = "none"
mod_right_double_click = "none"

middle_click_paste = false disables primary-selection paste, including Shift+Insert. The regular Ctrl+C and Ctrl+V clipboard is unaffected. Applications started while primary selection is disabled must be restarted after it is re-enabled.

window_snapping = true (the default) enables edge and corner drop zones for floating windows in any layout, using title bar, client move, or Mod+drag. Set it to false to drop windows exactly where released. A preview shows the placement before release. Left, right, top, and bottom edges snap to the corresponding half of the screen. All four corners snap to quarters. Maximize remains available through the title bar button, double-click, or an action. The targets respect panels, layout struts, gaps, borders, title bars, and client size limits, all in logical coordinates.

Dragging a snapped or maximized window away restores its normal size under the pointer, keeping the title bar and content aligned while the application redraws. Snapping on another monitor maps the normal restore position to that monitor. Shared monitor edges require a 150 ms dwell before offering a zone, so dragging straight across monitors remains possible. Tiled, pinned, scratchpad, overview, data-device, and toplevel-transfer drags do not use these zones. Keyboard actions window-snap:<region> and window-unsnap work independently of the pointer setting. See Actions.

client_window_drag = false ignores move requests from applications, such as dragging a client-side title bar or the empty tab strip of Chromium, Firefox, or Electron apps. Ordinary window moves then use Mod+drag, keybinds, or an enabled Umbriel title bar. Resizing from client-side borders and tab tear-off operations using xdg-toplevel-drag-v1 are unaffected.

When the title bar is shown by [appearance.title_bar] mode or a window rule, dragging empty server-side title bar space moves a window without a modifier. Double-click it to maximize or restore. Floating windows resize by dragging the frame’s edges or corners with the left button without a modifier, whether or not the Umbriel title bar is shown. This also works for individually floated windows in tiling layouts. Tiled windows use Mod+right-drag for compositor resizing. Application content and client-side resize controls keep their normal pointer behavior. These compositor-owned interactions work with client_window_drag = false.

Title bar presses keep the normal cursor until the pointer crosses a threshold of 10 logical pixels from its position at the original button press. Umbriel then starts dragging and switches to the grabbing cursor. Movement before an application’s move request counts toward that threshold. If the pointer has already crossed it, dragging starts immediately without requiring another motion event or another threshold.

In tiled layouts, pressing a client-side or Umbriel title bar focuses and reveals the window while keeping it in the layout. It detaches only after the pointer crosses the drag threshold. Holding or releasing a stationary press preserves the spacing between windows, including while applications repaint.

Dropping a floating window settles it into the usable area with the move animation: however far out of frame it was dragged, at release it glides back until at least a quarter of the window (10 to 75 logical pixels) is visible. Nothing else moves a floating window that is already inside that margin, including focus changes.

Mod+right-click drags a window’s resize edge. mod_right_double_click gives a second Mod+right-click on the same window a job beyond resizing:

ValueBehavior
"none"(default) Mod+right-click only drags a resize edge.
"maximize"A second Mod+right-click on the same window within 300 ms and 8 px of the first toggles maximize, with the same target a client’s titlebar double-click picks: client_maximize decides between the column and the edges for a tiled window, and a floating window fills the usable area.

With "maximize", the first click starts resizing only once the pointer moves more than 8 px from the press, and then resizes the edge under the press. A Mod+MouseRight keybind overrides the built-in button entirely.

window_drag_toggle controls what pressing the other main mouse button does during a window drag:

ValueBehavior
"none"Leave the drag unchanged.
"floating"Toggle whether the dropped window is tiled or floating.
"pinned"Toggle whether the dropped window is pinned.

The state changes when the window is dropped. Unsupported transitions, such as pinning a fullscreen window, leave the window unchanged.

Umbriel supports xdg-toplevel-drag-v1 for native Wayland applications that implement it, including Chromium-based browsers. During a pointer drag, a detached window follows the pointer above ordinary windows and stays outside the tiling layout. Windows underneath it can receive the drop, allowing the application to merge a tab or dock a panel. If the application keeps the detached window after the drop, Umbriel places it using normal tiled or floating window-drag behavior. No additional configuration is needed.

[input.keyboard]
layout = "" # empty uses the system keymap
variant = ""
options = ""
model = ""
repeat_rate = 25
repeat_delay = 600
numlock_toggle = true
track_layout = "global"
KeyRange or valuesDescription
repeat_rate0 to 1000 HzKey repeats per second; 0 disables repeat.
repeat_delay0 to 10000 msDelay before a held key repeats.
numlock_toggleboolEnable NumLock when a keyboard connects.
track_layout"global" or "window"Choose session-wide or per-window layout tracking.

Use a comma-separated layout list to configure several layouts:

[input.keyboard]
layout = "us,de"
options = "grp:alt_shift_toggle"

options accepts XKB options such as caps:escape or compose:ralt. Invalid layouts, variants, and models are reported in the log and fall back to the system default. Run xkbcli list to inspect available values.

When [input.keyboard] sets none of layout, variant, options, and model, Umbriel uses the X11 keymap configured with localectl set-x11-keymap, read from systemd-localed at startup and on every config reload. Run umbriel msg config-reload to apply a keymap changed with localectl. Without systemd-localed, the XKB_DEFAULT_* environment variables apply, then us. A [[input.device]] rule that sets any of these keys uses only its own and [input.keyboard]’s values.

Run umbriel keyboard-layouts to list the configured layouts. The active one is prefixed with *.

Bind keyboard-layout-next to cycle configured physical keyboard layouts:

[keybinds]
"Mod+Shift+K" = "keyboard-layout-next"

umbriel msg keyboard-layout-next provides the same action for scripts. Physical keyboards that provide the selected layout stay synchronized. Virtual keyboards retain their application-provided keymap.

When an input method removes its virtual keyboard, Umbriel restores the keyboard that supplied the input. Held shortcut modifiers stay active until they are released, even when another connected keyboard is idle.

Lock-key LEDs follow the active input source across physical keyboards, including newly connected devices. This keeps keyboard lights and LED-based lock-key OSDs working when an application forwards input through a uinput keyboard without LED feedback, such as a screen recorder’s global-hotkey helper.

track_layout accepts:

ValueBehavior
"global"Use one active layout for the session.
"window"Remember the active layout for each focused surface.

In window mode, a surface that has not been focused before starts with the first configured layout. Reloading keyboard configuration clears remembered surface layouts.

[input.touchpad]
# enabled = true
tap = true
# tap_and_drag = false
# drag_lock = "sticky"
natural_scroll = true
left_handed = false
# accel_profile = "adaptive"
# sensitivity = 0.5
# scroll_factor = 1.5
# disable_while_typing = true
# disable_on_external_mouse = true
# scroll_method = "edge"
# click_method = "clickfinger"
# tap_button_map = "left_middle_right"

Omitted values preserve the device’s libinput defaults. Explicit unsupported settings are reported in the log.

KeyDescription
enabledEnable or disable touchpad input.
tapEnable tap-to-click.
tap_and_dragKeep dragging after a tap when the finger stays down and moves.
drag_lockKeep dragging after the finger lifts during a tap-and-drag: "off" disables it, "timeout" ends the drag shortly after the finger lifts, "sticky" holds the drag until the next tap.
natural_scrollReverse scrolling and three-finger gesture direction.
left_handedSwap the primary and secondary buttons.
accel_profileUse "flat", "adaptive", or a custom acceleration curve.
sensitivityPointer speed from -1.0 to 1.0.
scroll_factorApplication scroll multiplier from 0.1 to 10.0.
disable_while_typingDisable the touchpad during keyboard input.
disable_on_external_mouseDisable the touchpad while an external mouse is connected.
scroll_methodScroll gesture for application content: "two_finger", "edge", or "none" to disable.
click_methodUse "button_areas" or "clickfinger".
tap_button_mapButtons for one-, two-, and three-finger taps: "left_right_middle" or "left_middle_right".

scroll_method selects the gesture a touchpad-style device uses to scroll applications. Devices support a subset (libinput list-devices reports them); an unsupported value is logged and ignored. An input.device rule that sets scroll_method replaces that device’s scroll_button scrolling, including its lock, and a rule that sets scroll_button takes the device’s scrolling away from the [input.touchpad] gesture. Mice and other device classes never inherit [input.touchpad] scroll_method.

scroll_factor also accepts per-axis values:

scroll_factor = { horizontal = 2.0, vertical = 1.5 }

This factor changes continuous two-finger application scrolling. Overview navigation uses the factors documented in Workspaces Overview.

[input.mouse]
natural_scroll = false
left_handed = false
# accel_profile = "flat"
sensitivity = 0.0
scroll_wheel_step = 60
# scroll_button = "MouseBack"
# scroll_button_lock = false

sensitivity ranges from -1.0 to 1.0. scroll_wheel_step accepts 1 to 1000 logical pixels per layout-scroll action. left_handed swaps the primary and secondary buttons; omit it to preserve the device default.

Omitting accel_profile preserves the device default. A custom libinput curve uses this form:

accel_profile = "custom 0.2 0.0 0.5 1.0 2.0"

scroll_button turns pointer motion into scrolling while the named button is held. Set scroll_button_lock = true to toggle that mode with a press instead. Accepted names are MouseLeft, MouseRight, MouseMiddle, MouseBack, and MouseForward.

scroll_wheel_step controls the distance used by layout scroll actions, not the scrolling sent to applications.

Use [[input.device]] for a device whose case-sensitive name exactly matches the Device value from libinput list-devices:

[[input.device]]
name = "Acme Split Keyboard"
layout = "us"
variant = "colemak_dh"
model = "pc104angle"
repeat_rate = 40
repeat_delay = 250
[[input.device]]
name = "Acme Precision Touchpad"
tap = true
natural_scroll = false
left_handed = false
scroll_method = "edge"
click_method = "clickfinger"
[[input.device]]
name = "Acme Gaming Mouse"
accel_profile = "flat"
sensitivity = 0.0
[[input.device]]
name = "Acme Controller Touchpad"
enabled = false

Each rule inherits its keyboard, touchpad, or mouse class settings and replaces only the keys it contains. enabled = false turns off a keyboard, touchpad, or mouse. Duplicate rules for the same device name are rejected.

[input.tablet]
enabled = true
map_to_output = "DP-1"
map_to_focused_output = false
map_to_focused_window = false
left_handed = false
calibration_matrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
KeyDescription
enabledEnable tablet and pad input.
map_to_outputConfine the tablet to a connector or monitor name.
map_to_focused_outputFollow the output holding keyboard focus.
map_to_focused_windowMap the tablet area to the focused window.
left_handedFlip the tablet orientation.
calibration_matrixPass a six-number calibration matrix to libinput.

Focused-window mapping takes precedence over focused-output mapping, which takes precedence over map_to_output.

[input.touch]
enabled = true
map_to_output = "eDP-1"
KeyDescription
enabledEnable or disable touch input.
map_to_outputConfine touch input to a connector or monitor name.

Without map_to_output, a touchscreen maps to the output its device reports, or else to the built-in panel (eDP-, LVDS-, or DSI-) when exactly one is enabled. Otherwise it spans the whole output layout.

[input.cursor]
theme = ""
size = 24
hardware_cursor = true
follows_focus = false
hide_when_typing = false
hide_timeout_ms = 0
KeyRange or valuesDescription
themestringXcursor theme; empty uses the environment default.
size1 to 512Cursor size in logical pixels.
hardware_cursorboolUse a hardware cursor plane when available.
follows_focusboolFollow keyboard-driven window focus.
hide_when_typingboolHide after a non-modifier key press.
hide_timeout_ms0 to 3600000Hide after inactivity; 0 disables the timeout.

Set hardware_cursor = false to work around hardware cursor flicker or disappearance. Set hide_timeout_ms to a value from 1 to 3600000 to hide an inactive cursor; 0 disables the timeout.

follows_focus = true moves the cursor to a newly focused window after keyboard-driven focus and transfer actions. Pointer-driven focus, gestures, and automatic replacement focus do not move it. window-focus-warp:<id> always moves the cursor regardless of this setting. Active-workspace output swaps keep the cursor and seat focus on the invoking output when this setting is false; when it is true, both follow the previously focused window to its new output.

[input.drag_edge_scroll]
enabled = true
trigger_zone = 30
delay_ms = 100
max_speed = 1500.0

While a drag-and-drop or a tiled window move (Mod+left-click or the tab bar) is held near either end of a scrolling layout, the layout scrolls so offscreen columns can be reached.

KeyRange or valuesDescription
enabledboolEnable edge scrolling during a data drag or a tiled window move.
trigger_zone1 to 1000Width of the zone at each end, in logical pixels.
delay_ms0 to 10000Time inside the zone before scrolling starts.
max_speed1.0 to 100000.0Peak scroll speed in logical pixels per second.

Speed rises from zero at the inner edge of the trigger zone to max_speed at the outer edge of the layout, so scrolling accelerates as the pointer pushes further in. The zone is clamped to half the viewport, so the two zones never overlap. delay_ms = 0 starts scrolling as soon as the pointer enters the zone. enabled = false turns the behavior off entirely.

[input.focus]
follows_mouse = false
follows_mouse_max_scroll = 0.5
hover_raises = true

follows_mouse = true focuses the window that the pointer enters through real pointer motion. Scrolling or dragging a layout beneath a stationary pointer does not change focus. After explicit layout scrolling settles, the next real pointer motion can focus the window beneath it without a border crossing. Pointer motion during scrolling does not change focus. Consume and expel commands also let the next pointer motion refresh focus after rearranging windows. This follows the actual seat focus across tiled, floating, and pinned windows, including pinned windows whose owning workspace is inactive.

hover_raises = false narrows hovering to focus alone: the entered window does not move above its neighbors, so sweeping the pointer across a larger window underneath cannot bury the window above it. Clicks, keybinds, and activation still raise. The key only matters with follows_mouse = true, and defaults to true.

While a client holds a pointer or keyboard grab, such as an open tray menu, hovering a window or crossing outputs preserves that grab and its keyboard focus. An outside click or explicit focus action can still dismiss the menu.

X11 windows that declare Input=False without WM_TAKE_FOCUS, including Steam’s on-screen keyboard, receive pointer input without taking keyboard focus. Hovering or clicking the keyboard leaves typing directed at the previously focused window. These windows are also skipped when Umbriel chooses replacement focus after a window closes.

follows_mouse_max_scroll limits how far Umbriel may scroll a layout to reveal that window, measured in viewport widths. 0.0 allows only fully visible windows. Omit the key for no limit.

Steam’s desktop controller mappings can control native Wayland windows through Umbriel’s X11 input emulation. Umbriel asks for permission on the first request and remembers the decision for the current session. See X11 desktop input for consent and lock-screen behavior.