# driftwm configuration # Copy to ~/.config/driftwm/config.toml and uncomment what you want to change. # Missing fields use built-in defaults. Invalid entries are logged and skipped. # Run `driftwm --check-config` to validate without starting the compositor. # Window manager modifier key: "super" (default) or "alt" # mod_key = "super" # Sloppy focus: keyboard focus follows the pointer to windows. # Moving to empty canvas keeps focus; click empty canvas to unfocus. focus_follows_mouse = true # Commands to run at startup (after WAYLAND_DISPLAY is set). # Each entry is passed to sh -c, so full shell syntax works (pipes, &&, env vars). autostart = [ "vicinae server", "waybar -c ~/.config/waybar/driftwm/config.jsonc", "hiddify", "gnome-keyring-daemon --start --components=secrets", "aw-qt --no-gui &" #"zen-browser --blank-window http://h2.kr0sh.ru:5120" ] #window_placement = "cursor" window_placement = "auto" # Environment variables set before any clients launch. # Child processes (autostart, exec bindings) inherit these. # These override the compositor's built-in toolkit defaults # (MOZ_ENABLE_WAYLAND, QT_QPA_PLATFORM, SDL_VIDEODRIVER, GDK_BACKEND, ELECTRON_OZONE_PLATFORM_HINT). [env] # Examples: # # QT_WAYLAND_DISABLE_WINDOWDECORATION = "1" # # MOZ_ENABLE_WAYLAND = "1" [input.keyboard] layout = "us,ru" # XKB layout (e.g., "us,ru" for multi-layout) # variant = "" # XKB variant (e.g., "dvorak", or "," for two defaults) options = "grp:win_space_toggle,ctrl:swap_lalt_lctl" # XKB options (e.g., "grp:win_space_toggle" for Super+Space layout switch) # model = "" # XKB model (e.g., "pc105") # repeat_rate = 25 # keys/sec # repeat_delay = 200 # ms before repeat starts # layout_independent = true # match bindings by physical key position across layouts # num_lock = true # num lock state on startup # caps_lock = false # caps lock state on startup [input.trackpad] # tap_to_click = true # enable tap-to-click natural_scroll = true # reverse scroll direction (content follows fingers) # tap_and_drag = true # double-tap-hold to drag # accel_speed = 0.0 # pointer acceleration (-1.0 to 1.0) # accel_profile = "adaptive" # "flat" or "adaptive" # click_method = "none" # none = device default; clickfinger = finger count (1=left, 2=right, 3=middle); button_areas = position on trackpad [input.mouse] accel_speed = 0.0 # pointer acceleration (-1.0 to 1.0) # accel_profile = "flat" # "flat" or "adaptive" natural_scroll = true # reverse scroll direction [cursor] theme = "Adwaita" # sets XCURSOR_THEME #theme = "Catppuccin-Mocha-Dark" # sets XCURSOR_THEME size = 24 # sets XCURSOR_SIZE inactive_opacity = 0.5 # cursor opacity on non-active outputs (0.0–1.0) [navigation] # trackpad_speed = 1.5 # trackpad (scroll/gestures) pan multiplier mouse_speed = 1.0 # mouse (drag) pan multiplier (1.0 = direct) # friction = 0.94 # momentum decay (0.90=snappy, 0.98=floaty) # animation_speed = 0.3 # camera lerp factor (higher = faster) # nudge_step = 20 # px per nudge-window action (mod-shift-arrow by default) # pan_step = 100.0 # px per pan-viewport action (mod-ctrl-arrow by default) # Anchors: canvas points discoverable by center-nearest (4-finger swipe / Mod+Arrow) # even when no window is there. Uses Y-up coordinate system. # anchors = [[0, 0]] # Example with 4 corners: # # anchors = [[0, 0], [-1750, 1750], [1750, 1750], [1750, -1750], [-1750, -1750]] [navigation.edge_pan] zone = 100.0 # activation zone width (px from viewport edge) # speed_min = 4.0 # px/frame at zone boundary # speed_max = 10.0 # px/frame at viewport edge [zoom] # step = 1.1 # multiplier per keypress (1.1 = 10% per press) # fit_padding = 100.0 # canvas px padding for zoom-to-fit reset_on_new_window = false # animate zoom to 1.0 when a new window is mapped # # (false = keep current zoom, pan only) reset_on_activation = false # animate zoom to 1.0 when an off-screen window # # requests focus # # (false = keep current zoom, pan only) [snap] enabled = true # magnetic edge snapping during window drag # gap = 12.0 # gap between snapped windows (canvas px) # distance = 24.0 # activation threshold (screen px from edge) # break_force = 32.0 # screen px past snap to break free # same_edge = false # also snap same edges (left-to-left, top-to-top) [decorations] # bg_color = "#303030" # title bar background (default: dark gray) # fg_color = "#FFFFFF" # close button × color (default: white) # corner_radius = 8 # clip window corners to this radius (no effect if client rounds more) [effects] # blur_radius = 2 # number of Kawase down+up passes (default: 2) # blur_strength = 1.1 # per-pass texel spread (default: 1.1) [backend] # Hardware stability quirks. All default to false (opt-in). # Enable these if you experience flickering, crashes, or rendering issues. # Particularly useful on NVIDIA GPUs with proprietary drivers. # Note: These flags must be set before launching driftwm. Changing them requires a restart. # For additional NVIDIA-specific settings, set these environment variables in your # session wrapper script or shell profile before starting driftwm: # export SMITHAY_USE_LEGACY=1 # Use legacy DRM API instead of atomic modesetting # export __GL_GSYNC_ALLOWED=0 # export __GL_VRR_ALLOWED=0 # export __GL_MaxFramesAllowed=1 # export NVD_BACKEND=direct # wait_for_frame_completion = false # Wait for GPU fences before page flip # disable_direct_scanout = false # Force EGL composition (disable direct scanout) [output] # Global output settings. Per-output scale/transform/mode/position # are configured in [[outputs]] sections below. [output.outline] # color = "#ffffff" # outline color for other monitors' viewports # thickness = 1 # pixels (0 to disable) # opacity = 0.5 # 0.0–1.0 [background] type = "tile" #mirror_tile = true #tile_path = "/home/krosh/Downloads/loop-pile-carpet-hexagonal-2400-mm-architextures.jpg" path = "/home/krosh/Downloads/loop-pile-carpet-hexagonal-2400-mm-architextures.jpg" #path = "/home/krosh/Pictures/Wallpapers/SFW/wallpaper20251127215007_3.png" #path = "/home/krosh/Pictures/Wallpapers/wallhaven-qr327r.png" #tile_path = "/home/krosh/Downloads/calacatta-vena-2200-mm-architextures-photoaidcom-invert.jpg" #tile_path = "/home/krosh/Pictures/Wallpapers/wallhaven-7pmkj3.png" #tile_path = "~/Pictures/Wallpapers/wallhaven-yx1zdk.png" # tiled image (mutually exclusive with shader) #tile_path = "~/.config/driftwm/tile.png" # tiled image (mutually exclusive with shader) # Examples: # # shader_path = "~/.config/driftwm/bg.glsl" # custom GLSL fragment shader #tile_path = "~/.config/driftwm/tile.png" # tiled image (mutually exclusive with shader) # # Custom shaders receive these uniforms: # - u_camera: vec2 - camera position in canvas coordinates # - u_time: float - time in seconds since compositor start (for animations) # - size: vec2 - viewport size in pixels # # Example animated shader: extras/wallpapers/animated_squares.glsl # Keyboard bindings: "Modifier+...+Keysym" = "action [arg]" # Merges with defaults. Use "none" to unbind a default binding. # "mod" expands to mod_key. Literal modifiers: alt, super, ctrl, shift. # Keysyms are XKB names (case-insensitive): return, tab, up, a, equal, etc. # # Actions: # exec — launch an app (shows loading cursor until window appears, exits fullscreen) # spawn — run a command without loading cursor and exiting fullscreen (toggles, OSD, screenshots) # close-window — close the focused window # nudge-window — move focused window by nudge_step px # pan-viewport — pan camera by pan_step px # center-window — center viewport on focused window + reset zoom # focus-center — focus + center on the window under the pointer + reset zoom # center-nearest — navigate to nearest window in direction # cycle-windows forward — Alt-Tab style window cycling # cycle-windows backward — reverse cycle # home-toggle — toggle between current position and origin # zoom-in / zoom-out — step zoom # zoom-reset — zoom to 1.0 # go-to — jump camera to canvas position (bookmarks, Y-up) # zoom-to-fit — fit all windows in viewport # toggle-fullscreen — toggle focused window fullscreen # fit-window — toggle maximize: centers + resets zoom + fills viewport; restore only resizes back # reload-config — hot-reload config file # quit — exit the compositor # send-to-output — move focused window to adjacent output # none — unbind this key combo # # Directions: up, down, left, right, up-left, up-right, down-left, down-right [keybindings] "mod+shift+s" = "exec grim -g \"$(slurp)\" - | wl-copy" "mod+shift+r" = "reload-config" "mod+return" = "exec kitty" "ctrl+return" = "exec kitty" "mod+w" = "exec zen-browser" "mod+h" = "exec /home/krosh/Apps/hermes-desktop" #"mod+]" = "exec hermes desktop" "ctrl+space" = "exec vicinae toggle" #"mod+d" = "exec vicinae toggle" "mod+e" = "exec nemo" "mod+s" = "exec spotify" "ctrl+5" = "exec Telegram" # "mod+d" = "exec " # "mod+q" = "close-window" # "mod+f" = "toggle-fullscreen" "mod+d" = "fit-window" # "mod+c" = "center-window" # "mod+x" = "focus-center" # "mod+a" = "home-toggle" # "mod+up" = "center-nearest up" # "mod+down" = "center-nearest down" # "mod+left" = "center-nearest left" # "mod+right" = "center-nearest right" # "mod+shift+up" = "nudge-window up" # "mod+shift+down" = "nudge-window down" # "mod+shift+left" = "nudge-window left" # "mod+shift+right" = "nudge-window right" # "mod+ctrl+up" = "pan-viewport up" # "mod+ctrl+down" = "pan-viewport down" # "mod+ctrl+left" = "pan-viewport left" # "mod+ctrl+right" = "pan-viewport right" # "alt+tab" = "cycle-windows forward" # "alt+shift+tab" = "cycle-windows backward" # "mod+equal" = "zoom-in" # "mod+minus" = "zoom-out" # "mod+0" = "zoom-reset" # "mod+z" = "zoom-reset" # "mod+w" = "zoom-to-fit" "mod+1" = "go-to -20000 20000" # top-left bookmark "mod+2" = "go-to 20000 20000" # top-right bookmark "mod+3" = "go-to 20000 -20000" # bottom-right bookmark "mod+4" = "go-to -20000 -20000" # bottom-left bookmark #"mod+1" = "go-to -1750 1750" # top-left bookmark #"mod+2" = "go-to 1750 1750" # top-right bookmark #"mod+3" = "go-to 1750 -1750" # bottom-right bookmark #"mod+4" = "go-to -1750 -1750" # bottom-left bookmark # "mod+alt+up" = "send-to-output up" # move window to output above # "mod+alt+down" = "send-to-output down" # "mod+alt+left" = "send-to-output left" # "mod+alt+right" = "send-to-output right" # "mod+l" = "spawn swaylock -f -c 000000 -kl" "mod+ctrl+shift+q" = "quit" # "XF86AudioRaiseVolume" = "spawn wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+" # "XF86AudioLowerVolume" = "spawn wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" # "XF86AudioMute" = "spawn wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" # "XF86MonBrightnessUp" = "spawn brightnessctl set +5%" # "XF86MonBrightnessDown" = "spawn brightnessctl set 5%-" "Print" = "exec mkdir -p ~/Pictures/Screenshots && grim ~/Pictures/Screenshots/ss-$(date +%Y-%m-%d_%H-%M-%S).png" # "shift+Print" = "spawn grim -g \"$(slurp -d)\" - | wl-copy" # Mouse bindings: "Modifier+...+Trigger" = "action" # Context-aware: on-window, on-canvas, anywhere. # Specific context checked first, then "anywhere" as fallback. # Click-to-focus and SSD decoration clicks are always hardcoded. # Triggers: left, right, middle (buttons), trackpad-scroll, wheel-scroll # Merges with defaults. Use "none" to unbind. # # Mouse actions: move-window, resize-window, pan-viewport, zoom, center-nearest # Any keyboard action also works for button triggers: exec, close-window, toggle-fullscreen, etc. [mouse.on-window] # "alt+left" = "move-window" # "alt+right" = "resize-window" # "alt+middle" = "fit-window" # "mod+middle" = "toggle-fullscreen" [mouse.on-canvas] # "left" = "pan-viewport" # unmodified left-click on empty canvas → pan # "trackpad-scroll" = "pan-viewport" # trackpad scroll on empty canvas → pan # "wheel-scroll" = "zoom" # mouse wheel on empty canvas → zoom [mouse.anywhere] # "mod+left" = "pan-viewport" # "mod+ctrl+left" = "center-nearest" # direction from drag delta # "mod+trackpad-scroll" = "pan-viewport" # "mod+wheel-scroll" = "zoom" # Gesture bindings: "Modifier+N-finger-" = "action" # Context-aware: on-window, on-canvas, anywhere. # Unbound gestures are forwarded to the focused app. # "none" unbinds (prevents anywhere fallback, still forwards). # # Gesture types: # N-finger-swipe — continuous OR threshold (action determines behavior) # N-finger-swipe-up/down/left/right — threshold only, checked before swipe fallback # 3-finger-doubletap-swipe — continuous OR threshold (3-finger tap then swipe) # N-finger-pinch — continuous only (use pinch-in/out for discrete) # N-finger-pinch-in/out — threshold only # N-finger-hold — threshold only (fires on release) # # Continuous actions: pan-viewport, zoom, move-window, resize-window # Threshold actions: center-nearest, center-window, home-toggle, zoom-to-fit, fit-window, exec , etc. # Gesture thresholds — tune for your touchpad size. [gestures] # swipe_threshold = 12.0 # px cumulative distance before directional swipe fires # pinch_in_threshold = 0.85 # scale below which pinch-in fires (1.0 = no pinch) # pinch_out_threshold = 1.15 # scale above which pinch-out fires (1.0 = no pinch) [gestures.on-window] # "alt+3-finger-swipe" = "resize-window" # "3-finger-doubletap-swipe" = "move-window" # "alt+2-finger-pinch-in" = "fit-window" # "alt+2-finger-pinch-out" = "fit-window" # "alt+3-finger-pinch-in" = "toggle-fullscreen" # "alt+3-finger-pinch-out" = "toggle-fullscreen" [gestures.on-canvas] # "2-finger-pinch" = "zoom" [gestures.anywhere] # "3-finger-swipe" = "pan-viewport" # continuous (per-frame dx/dy) # "4-finger-swipe" = "center-nearest" # threshold (accumulate, detect direction, fire once) # "mod+3-finger-swipe" = "center-nearest" # mod makes 3-finger swipe navigate too # Per-direction overrides examples (threshold only, checked before swipe fallback): # # "4-finger-swipe-up" = "exec brightnessctl set +5%" # # "4-finger-swipe-down" = "exec brightnessctl set 5%-" # "mod+2-finger-pinch" = "zoom" # mod overrides app forwarding # "3-finger-pinch" = "zoom" # continuous # "4-finger-pinch-in" = "zoom-to-fit" # threshold # "4-finger-pinch-out" = "home-toggle" # threshold # "mod+3-finger-pinch-in" = "zoom-to-fit" # "mod+3-finger-pinch-out" = "home-toggle" # "4-finger-hold" = "center-window" # fires on release # "mod+3-finger-hold" = "center-window" # Per-output configuration. Each [[outputs]] entry matches by connector name. # Find connector names with wlr-randr or check driftwm logs at startup. # Outputs without a matching entry default to scale 1.0. # Winit backend ignores [[outputs]] entries. # # Examples: # # [[outputs]] # # name = "eDP-1" # connector name (required) # # scale = 1.5 # fractional scale (default: 1.0) # # transform = "normal" # normal, 90, 180, 270, flipped, flipped-90, flipped-180, flipped-270 # # position = "auto" # "auto" (left-to-right) or [x, y] in layout coords # # mode = "preferred" # "preferred", "1920x1080", or "2560x1440@144" # # # # [[outputs]] # # name = "HDMI-A-1" # # scale = 1.0 # # mode = "1920x1080@60" [[outputs]] name = "HDMI-A-2" #scale = 1.0 #mode = "1920x1080@60" position = [0, 0] [[outputs]] name = "eDP-1" # connector name (required) position = [1920, 0] [[outputs]] name = "DP-2" #scale = 1.0 #mode = "1920x1080@60" position = [0, 0] [[outputs]] name = "DP-5" #scale = 1.0 #mode = "1920x1080@60" position = [0, 0] # Window rules: match windows by app_id and/or title and apply overrides. # At least one of app_id or title is required. Both support * glob. # To find an app's app_id: cat $XDG_RUNTIME_DIR/driftwm/state (see "windows=" line) # # Fields: # app_id — app_id to match (optional, supports * glob) # title — window title to match (optional, supports * glob) # position — [x, y] canvas coordinates to place the window # size — [width, height] to force window dimensions # widget — true: pinned (immovable), below normal windows, excluded from navigation (default: false) # decoration — "client" (default), "server", or "none" (borderless) # blur — true: blur background behind this window (default: false) # opacity — 0.0–1.0: window transparency (default: 1.0, fully opaque) # # Examples: # # [[window_rules]] # # app_id = "my-widget" # # position = [0, 0] # # widget = true # # decoration = "none" # # # Blurred terminal # # [[window_rules]] # # app_id = "Alacritty" # # opacity = 0.85 # # blur = true # # # Hide iced/libcosmic utility windows (same app_id as main window) # # [[window_rules]] # # title = "winit window" # # widget = true [[window_rules]] app_id = "kitty" opacity = 0.85 # blur = true [[window_rules]] app_id = "Firefox" position = [0, 0]