Skip to content

Personal dotfiles + UI setup for my Surface Laptop running archlinux

Notifications You must be signed in to change notification settings

snes19xx/surface-dots

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

surface-dots

Personal dotfiles + UI setup for my Surface Laptop 4 (AMD) running Hyprland. Also, please check out my calendar app: Evercal


Table of contents


SDDM: Lock Screen & Login Screen (hyprlock also looks just like this + with media information if playing when locked)


Dark Mode & Light Mode (Hub + Rofi)


Reading mode & Various other apps

Dependencies

Core & System

  • Hyprland
  • hypridle
  • hyprlock
  • hyprshade
  • hyprland-plugins
  • xdg-utils
  • xdg-desktop-portal-hyprland
  • xdg-desktop-portal-kde
  • xdg-desktop-portal-gtk
  • polkit-gnome
  • sddm
  • networkmanager
  • bluez, blueman

UI & Theming

  • dunst
  • swww
  • waypaper
  • rofi
  • kitty
  • firefox
  • colorreload-gtk-module
  • Everforest-Dark-theme
  • EVerforest-Light-theme
  • qt6ct
  • kvantum
  • papirus-icon-theme
  • ttf-manrope
  • ttf-nerd-fonts-symbols
  • inter-font

Utilities

  • grim, slurp, swappy, grimblast
  • pamixer, pipewire-pulse or pulseaudio
  • playerctl
  • brightnessctl
  • quickshell
  • vdirsyncer
  • khal
  • EverCal
  • xdg-utils
  • curl, jq
  • flutter, dart
  • linux-surface tools (Linux-surface only)
  • auto-cpufreq

Caution

Layout geometry is hardcoded for 3:2 high-resolution display. Deviation in aspect ratio or pixel density will result in misalignment or things looking too big or small. Please reconfigure values accordingly.

Hyprland

Main config is for Hyprland v0.53: ~/.config/hypr/hyprland.conf Old Config at ~/.config/hypr/hyprland_OLD.conf

Keybindings

Apps

  • SUPER + Q → terminal (kitty)
  • SUPER + E → file manager (thunar)
  • SUPER + R → rofi
  • SUPER + B → firefox
  • SUPER + D → reading mode
  • SUPER + S → my custom ocr app

Window actions

  • SUPER + SPACE → toggle hub on or off
  • SUPER + X → kill active window
  • SUPER + F → toggle floating (simple)
  • SUPER + ALT + F → toggle floating and set size 900x600 + center
  • SUPER + M → fullscreen
  • SUPER + P → pseudotile
  • SUPER + UP → togglesplit
  • SUPER + DOWN → togglesplit

Exit

  • ALT + F4 → Power menu
  • SUPER + ALT + F4 → exit Hyprland

Focus (arrow keys)

  • SUPER + Left/Right → move focus horizontally
  • SUPER + UP/Down → move focus vertically

Workspaces

  • SUPER + 1..0 → workspace 1..10
  • SUPER + SHIFT + 1..0 → move active window to workspace 1..10
  • SUPER + mouse wheel → next/prev workspace
  • SUPER + G → toggle group
  • SUPER+CTRL+LEFT/RIGHT → move across grouped windows

Scratchpad (“special workspace”)

  • SUPER + H → toggle special workspace magic
  • SUPER + SHIFT + S → move active window to special:magic

Mouse (window move/resize)

  • SUPER + LMB → move window
  • SUPER + RMB → resize window

Screenshots

  • Print → screenshot script mode s
  • SUPER + Print → mode p
  • SUPER + SHIFT + Print → mode sf
  • SUPER + O → mode m

Shaders

All shaders located at ~/.config/hypr/shaders/ and use hyprshade

activate with: hyprshade on <shader_name.glsl> deactivate with: hyprshade off

Reading Mode

A shader-based reading mode to mimic an e-ink reader.

  • Toggle with SUPER + D or ~/.config/hypr/shaders/reading_mode.sh
  • Automatically disables animations, shadows, and blur
  • Custom GLSL shader with e-ink-like color reproduction
  • Warm cream paper tone and soft charcoal blacks for reduced contrast
  • Fine paper grain -like texture

Other shaders

Ranked from Useful to completely Useless:

  1. main.glslmy main shader to improve my display (I run it at startup)
  2. night.glslmy main night-light mode shader (script coming soon)
  3. outdoor.glsfor maximum outdoor useability
  4. cinema.glslfor media consumption
  5. soft.glslsoft, muted textures
  6. matte.glslanti-glare, matte
  7. IMB5151.glslsimulates vintage IBM 3278 / 5151 monitors
  8. fuji_acros.glslsimulates fujifilm acros
  9. crt_mode.glslsimulates a crt monitor/retro nostalgia
  10. vhs.glslsimulates vhs
  11. gameboy.glslsimulates a gameboy screen
  12. clarity_inefficient.glslan early version of my main shader
  13. focus.glslparty trick
  14. night_vision.glslsimulates night_vision

Quickshell Bar

The bar uses an Arch glyph icon (top left) as the launcher button:

  • Left click: launches rofi, choosing a different launcher script depending on the current theme mode.
  • Right click: toggles the bar’s isDarkMode and calls a theme script:
bash ~/config/quickshell/snes-hub/bar/theme-mode.sh dark|light
Expand for Bar components

Workspaces

Clicking a workspace pill runs: - hyprctl dispatch workspace <id>

Updates

Updates are shown using a poller, but it won’t run checkupdates while pacman is busy (to avoid lock-related crashes). When the pacman lock file exists, the bar displays the last cached update count instead. Polled with:

if [ -e /var/lib/pacman/db.lck ]; then
  cat /tmp/qs_updates_count 2>/dev/null || echo 0
else
  checkupdates 2>/dev/null | wc -l | tee /tmp/qs_updates_count
fi

Clicking the updates pill runs:

kitty -e bash -lc "sudo pacman -Syu"

Date and Clock

  • Pressing the clock triggers a requestHubToggle() signal (used to open/close the hub).
  • Esc closes the hub (or clicking anywhere outside it).

Quickshell Hub (snes-hub)

  • Toggled by clicking the date/clock module in the bar or SUPER+SPACE keybinding through hyprland
  • The hub window is an overlay (wlr-layershell) and is designed to get out of your way quickly:
  • Organized into reusable components, making it straightforward to add/remove cards or re-skin pieces without rewriting the whole hub.
  • If you want a lightweight fallback, use the early AGS version in .config/ags/ (works, but fewer features).
Components (click to expand) Hub comparison

Header

  • Profile icon,username + RAM/CPU usage chips.
  • Screenshot button (runs the capture script and then closes the hub).
  • Power button

Power options

  • Compact power grid that expands (click the power button or press p key) inside the header (no extra window):
  • Keyboard navigation: Arrow keys / Tab to move, Enter to trigger, Esc to close.

Buttons and Sliders

  • Wi‑Fi toggle + SSID readout (right‑click opens wifi module).
  • Bluetooth toggle + connected device status.
  • Performance profile button (cycle modes via auto-cpufreq, right click toggles battery health card).
  • DND toggle (dunst).
  • Volume + brightness sliders (pactl + brightnessctl).

Battery health

  • Polls: upower -i /org/freedesktop/UPower/devices/battery_BAT1
  • Shows: Health (capacity %) + current charge %, Charge cycles, Energy (full / design), Time remaining (to full/empty when available), State (charging/discharging/fully-charged)

[!NOTE] If your battery isn’t battery_BAT1, swap the device path in BatteryHealthCard.qml to match your system.s

Media card (MPRIS)

  • The hub includes an MPRIS-powered media card:
  • Clicking the media card launches the external now-playing widget and then toggles the hub off.
  • It tracks metadata changes and resets its internal timing state when tracks change. It's still finicky with some browser contents like youtube videos
  • Only appears when something is playing

Now Playing (Flutter)

  • This is a separate Flutter desktop widget (class rules are handled in Hyprland).
  • Resizable is disabled (setResizable(false) is used)
  • Esc closes the widget
  • Generates theme colors from album art using palette_generator

Calendar, Weather and Events

A simple calendar with weather (json based script and events from my google calendar using khal+ vdirsyncer.

Google Calendar sync (vdirsyncer + khal)

Recommended approach (avoids system Python packaging issues):

sudo pacman -S --needed python-pipx
pipx install "vdirsyncer[google]"
  • If you have both a system and pipx vdirsyncer, remove the system one and make sure PATH prefers ~/.local/bin.
Config

Create folders:

mkdir -p ~/.config/vdirsyncer/status ~/.config/vdirsyncer/tokens
mkdir -p ~/.local/share/vdirsyncer/calendars

Example vdirsyncer config uses: token_file = "~/.config/vdirsyncer/tokens/google_calendar" type = "google_calendar" client_id / client_secret from Google Cloud OAuth ~/.local/share/vdirsyncer/calendars/* - Khal reads .ics files from here

Note:
  • You must enable CalDAV API in Google Cloud (not only the “Google Calendar API”).
  • If OAuth consent is in Testing mode, add yourself as a “Test user”.
  • If you get “token obtained but Not Found”, enable calendars at: https://calendar.google.com/calendar/syncselect
Run + test
vdirsyncer discover
vdirsyncer sync
khal list now 7d

Notifications

  • Clicking dismisses.
  • Uses dunst (dunstctl) as the notification backend.
  • Contracted by default when the media player card is active, but can be expanded via the expand button.

OSDs

  • custom OSDs for brightness and volume controls
  • custom OSD for various modes (Dark/Light/Reading Mode etc.)

[!NOTE] You may need to update the scripts in .config/hypr/scripts. Please review the contents of audiocontrol.sh and brightnesscontrol.sh. Newer versions of these scripts write cache for osd qmls to read

Power menu

Quickshell Power Menu screenshot (Dark) Quickshell Power Menu screenshot (Light)

wlr-layershell power menu overlay (separate from the hub header menu). Toggled with ALT+F4 Run

quickshell -p ~/.config/quickshell/snes-hub/bar/PowerMenu.qml

Wifi menu

Standalone network manager applet located at lib/WifiMenu.qml. With both (light/dark) theme.

  • Trigger: Right-click the Wi-Fi button in the Hub.
  • or run: quickshell -p ~/.config/quickshell/snes-hub/lib/Wifimenu.qml

Warning

You cannot connect to enterprise access points (for now), I haven't had the time to fix it yet

Pixel sddm theme

[Note: I am using qt5, please install qt5 dependencies]

sudo pacman -S qt6-5compat qt6-svg qqc2-desktop-style inter-font ttf-nerd-fonts-symbols

if you don't want windows hello like animation please use main.qml from the old directory

  • To install:

    • move the contents of sddm/theme folder to /usr/share/sddm/themes/ (create the dir if it doesn't exist yet)
    • Set "pixel" as the current theme by creating a config file in /etc/sddm.conf.d/:
    • make sure the directory exists:
    sudo mkdir -p /etc/sddm.conf.d
    • then create the config file:
    echo -e "[Theme]\nCurrent=pixel" | sudo tee /etc/sddm.conf.d/theme.conf

Firefox custom new-tab

Firefox doesn't really want you to use local html as a new tab page so

  • Move autoconfig.js to Firefox defaults/pref/ (e.g. /usr/lib/firefox/defaults/pref/)
  • Edit mozilla.cfg (repo path: .config/firefox/mozilla.cfg) and set your file path
  • Move mozilla.cfg to the Firefox install directory root (e.g. /usr/lib/firefox/)

Credits & acknowledgements

Media sources

  1. Photo by fffunction studio on Unsplash
  2. Photo by Brian McGowan on Unsplash
  3. Photo by Mimicry Hu on Unsplash
  4. Photo by Bailey Zindel on Unsplash
  5. Photo by on Jay Yu on Unsplash
  6. Photo by Ben Dutton on Unsplash
  7. Photo by Richard Rhee on Flickr
  8. Photo by Cedric Chambaz on Flickr

[OC]

[Reuse Note:]

Feel free to copy/steal whatever you want as long as you cite me and more importantly the listed media sources in the credits/references where applicable.

About

Personal dotfiles + UI setup for my Surface Laptop running archlinux

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages