foxygit / dotfiles Log in
commits tags

/install.sh · 14.6 KB

raw
#!/bin/bash
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SXWM_REPO="https://github.com/uint23/sxwm.git"
SXBAR_REPO="https://git.kristoffersson.info/repos/sxbar.git"
ST_REPO="https://git.suckless.org/st"
BUILD_DIR="/tmp/sxwm-sxbar-build"

echo "==> Installerar beroenden..."
sudo apt-get update -qq
sudo apt-get install -y \
    git \
    make \
    gcc \
    build-essential \
    pkg-config \
    libx11-dev \
    libxinerama-dev \
    libxrandr-dev \
    libxcursor-dev \
    libxft-dev \
    libfontconfig1-dev \
    libimlib2-dev \
    xorg \
    xinit \
    firefox-esr \
    pipewire-audio \
    alsa-utils \
    bluez \
    iwd \
    xinput \
    patch \
    wget \
    curl \
    unzip \
    fontconfig \
    wmctrl \
    xdotool \
    x11-utils \
    pipx \
    feh \
    dmenu \
    imagemagick \
    bc \
    geany \
    gocryptfs \
    fuse3 \

mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"

echo "==> Klonar sxwm..."
rm -rf sxwm
git clone --depth=1 "$SXWM_REPO" sxwm

echo "==> Applicerar sxwm-patchar..."
cd sxwm
patch -p1 < "$SCRIPT_DIR/cursor-dpi-fix.patch"
# Lägger till stöd för _NET_ACTIVE_WINDOW (behövs för sxbars taskbar-modul
# -- utan denna gör klick i taskbaren ingenting, sxwm har ingen annan
# extern mekanism för att fokusera ett specifikt fönster)
patch -p1 < "$SCRIPT_DIR/net-active-window.patch"
# Fixar _NET_WM_STRUT_PARTIAL-hantering vid monitorer av olika storlek --
# reservationer band tidigare bara till varje monitors x/y-spann, inte
# till panelfönstrets egen monitor, vilket kunde göra en monitors
# reserverade yta större än dess egen höjd/bredd (fönster öppnades då
# långt utanför synligt område, bara ram synlig)
patch -p1 < "$SCRIPT_DIR/multi-monitor-struts.patch"
# Windows tappar rätt monitor-koppling vid hotplug (t.ex. lid-display-watch
# som slår av/på eDP) -- client->mon är bara ett index i mons[], och blir
# meningslöst så fort monitor-antalet/ordningen ändras, vilket kan flytta
# fönster till fel skärm eller klämma in dem för litet. Räknar om mon-
# tillhörighet från varje fönsters faktiska position vid varje hotplug.
patch -p1 < "$SCRIPT_DIR/monitor-hotplug-remap.patch"
# apply_fullscreen() placerade fönstret på c->mon, som bara sätts en gång vid
# map-tid (till skärmen muspekaren råkade stå på) och aldrig hölls i synk med
# fönstrets verkliga position -- ett fönster flyttat av ett externt verktyg
# (xdotool, screensaver-launch) till en annan skärm innan det gjordes
# fullskärm hamnade då fullskärm på FEL skärm. Räknar om målskärmen från
# fönstrets faktiska geometri istället.
patch -p1 < "$SCRIPT_DIR/fullscreen-monitor-fix.patch"
# En bottom/right-panel (t.ex. sxbars secondary_bar) kunde hamna dold bakom
# vanliga fönster -- update_struts() räknar reserve_bottom/reserve_right som
# avstånd från *motsatt* skärmkant och behövde då hela skärmens bredd/höjd,
# men läste den ur scr_width/scr_height som bara uppdateras i update_mons()
# (start + monitor-hotplug). Blir de cachade värdena inaktuella räknas bara
# bottom/right fel (top/left beror aldrig på skärmstorleken, bara på
# monitorns egen x/y, och påverkades inte). Läser bredd/höjd direkt från
# X-servern i update_struts() istället för att lita på cachen.
patch -p1 < "$SCRIPT_DIR/strut-fresh-screen-size.patch"

echo "==> Bygger och installerar sxwm..."
make
sudo make install
cd "$BUILD_DIR"

echo "==> Klonar sxbar..."
rm -rf sxbar
git clone --depth=1 "$SXBAR_REPO" sxbar

echo "==> Bygger och installerar sxbar..."
cd sxbar
make
sudo make install
cd "$BUILD_DIR"

echo "==> Klonar st..."
rm -rf st
git clone --depth=1 "$ST_REPO" st

echo "==> Applicerar st-patchar (delkey, scrollback, clipboard, boxdraw_v2, vertcenter, alpha, blinking_cursor, bold-is-not-bright, anysize, histsize-5000, kitty-graphics-protocol)..."
cd st
for p in "$SCRIPT_DIR"/st-patches/*.patch; do
    patch -p1 < "$p"
done
cp "$SCRIPT_DIR/config/st/config.def.h" config.def.h

echo "==> Bygger och installerar st..."
make
sudo make install

echo "==> Installerar icat (visa bilder i st via kitty graphics-protokollet)..."
mkdir -p "$HOME/.local/bin"
cp icat-mini.sh "$HOME/.local/bin/icat"
chmod +x "$HOME/.local/bin/icat"
echo "    icat-mini.sh -> ~/.local/bin/icat"

cd "$BUILD_DIR"

echo "==> Kopierar konfigfiler..."
mkdir -p "$HOME/.config/sxbar"

copy_config() {
    local src="$SCRIPT_DIR/config/$1"
    local dst="$HOME/.config/$2"
    mkdir -p "$(dirname "$dst")"
    if [ -f "$dst" ]; then
        cp "$dst" "$dst.bak"
        echo "    $2 -> backup sparad: ~/.config/$2.bak"
    fi
    cp "$src" "$dst"
    echo "    $2 -> ~/.config/$2"
}

copy_config sxwmrc sxwmrc
copy_config sxbarc sxbar/sxbarc
copy_config geany/geany.conf geany/geany.conf
copy_config geany/colorschemes/gruvbox.conf geany/colorschemes/gruvbox.conf

echo "==> Installerar Gruvbox GTK-tema (för Geanys gränssnitt, inte bara editorn)..."
mkdir -p "$HOME/.local/share/themes/Gruvbox-Dark/gtk-3.0"
cp "$SCRIPT_DIR/themes/Gruvbox-Dark/gtk-3.0/gtk.css" "$HOME/.local/share/themes/Gruvbox-Dark/gtk-3.0/gtk.css"
cp "$SCRIPT_DIR/themes/Gruvbox-Dark/index.theme" "$HOME/.local/share/themes/Gruvbox-Dark/index.theme"
echo "    Gruvbox-Dark -> ~/.local/share/themes/Gruvbox-Dark"

echo "==> Installerar geany-wrapper..."
# Sätter GTK_THEME=Gruvbox-Dark oavsett hur Geany startas. Ett bash-alias
# räcker inte -- dmenu/sxwm kör aldrig ~/.bashrc, men ärver PATH från
# ~/.xinitrc där ~/.local/bin ligger först, så denna skuggar /usr/bin/geany.
cp "$SCRIPT_DIR/bin/geany" "$HOME/.local/bin/geany"
chmod +x "$HOME/.local/bin/geany"
echo "    geany -> ~/.local/bin/geany"

echo "==> Installerar Geany .desktop-override (samma tema från app-startare)..."
mkdir -p "$HOME/.local/share/applications"
cp "$SCRIPT_DIR/applications/geany.desktop" "$HOME/.local/share/applications/geany.desktop"
echo "    geany.desktop -> ~/.local/share/applications/geany.desktop"

echo "==> Kopierar skrivbordsbakgrund..."
mkdir -p "$HOME/BG"
cp -n "$SCRIPT_DIR/BG/"* "$HOME/BG/"
echo "    BG/ -> ~/BG/"

echo ""
echo "==> Konfigurering av ~/.xinitrc"
echo ""

read -p "Vill du skriva över ~/.xinitrc? (j/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Jj]$ ]]; then
    if [ -f "$HOME/.xinitrc" ]; then
        cp "$HOME/.xinitrc" "$HOME/.xinitrc.bak"
        echo "    Backup skapad: ~/.xinitrc.bak"
    fi
    cat > "$HOME/.xinitrc" << 'EOF'
#!/bin/bash
# ~/.bash_profile sourcar inte ~/.profile/~/.bashrc, så PATH-tillägget för
# ~/.local/bin når annars aldrig sxwm eller dess "exec"-kommandon
# (mouse-settings, lid-display-watch m.fl. failar tyst utan denna rad)
export PATH="$HOME/.local/bin:$PATH"

# Stänga av skärmarna efter 5 min
xset s 300 300
xset dpms 300 300 300

# Stäng av pip-ljudet (bell)
xset b off

# Svenskt tangentbord
setxkbmap se

exec sxwm
EOF
    chmod +x "$HOME/.xinitrc"
    echo "    ~/.xinitrc skapad"
else
    echo "Lägg manuellt till i ~/.xinitrc:"
    echo ""
    echo "  xset s 300 300"
    echo "  xset dpms 300 300 300"
    echo "  setxkbmap se"
    echo "  exec sxwm"
fi

echo "==> Installerar lidsuspend..."
mkdir -p "$HOME/.local/bin"
cp "$SCRIPT_DIR/bin/lidsuspend" "$HOME/.local/bin/lidsuspend"
chmod +x "$HOME/.local/bin/lidsuspend"
echo "    lidsuspend -> ~/.local/bin/lidsuspend"

echo "==> Installerar mouse-settings..."
mkdir -p "$HOME/.local/bin"
cp "$SCRIPT_DIR/bin/mouse-settings" "$HOME/.local/bin/mouse-settings"
chmod +x "$HOME/.local/bin/mouse-settings"
echo "    mouse-settings -> ~/.local/bin/mouse-settings"

echo "==> Installerar status..."
mkdir -p "$HOME/.local/bin"
cp "$SCRIPT_DIR/bin/status" "$HOME/.local/bin/status"
chmod +x "$HOME/.local/bin/status"
echo "    status -> ~/.local/bin/status"

echo "==> Installerar gcfs (minimal gocryptfs-valvhanterare)..."
mkdir -p "$HOME/.local/bin"
cp "$SCRIPT_DIR/bin/gcfs" "$HOME/.local/bin/gcfs"
chmod +x "$HOME/.local/bin/gcfs"
# Lägg bara exempel-configen om ingen redan finns -- gcfs skapar en identisk
# vid första körning, och en riktig vaults.conf ska aldrig skrivas över.
if [ ! -f "$HOME/.config/gcfs/vaults.conf" ]; then
    mkdir -p "$HOME/.config/gcfs"
    cp "$SCRIPT_DIR/config/gcfs/vaults.conf" "$HOME/.config/gcfs/vaults.conf"
    echo "    gcfs -> ~/.local/bin/gcfs, vaults.conf -> ~/.config/gcfs/"
else
    echo "    gcfs -> ~/.local/bin/gcfs (behöll befintlig ~/.config/gcfs/vaults.conf)"
fi

echo "==> Installerar tte (terminaltexteffects) via pipx..."
pipx install terminaltexteffects
pipx ensurepath

echo "==> Installerar screensaver..."
mkdir -p "$HOME/.local/bin"
cp "$SCRIPT_DIR/bin/screensaver" "$SCRIPT_DIR/bin/screensaverd" "$SCRIPT_DIR/bin/screensaver-launch" "$SCRIPT_DIR/bin/screensaver-toggle" "$SCRIPT_DIR/bin/screensaver.txt" "$HOME/.local/bin/"
chmod +x "$HOME/.local/bin/screensaver" "$HOME/.local/bin/screensaverd" "$HOME/.local/bin/screensaver-launch" "$HOME/.local/bin/screensaver-toggle"
echo "    screensaver, screensaverd, screensaver-launch, screensaver-toggle, screensaver.txt -> ~/.local/bin/"

echo ""
echo "==> Automatisk avstängning av interna skärmen vid stängt lock"
echo ""
read -p "Installera lid-display-watch (stänger av interna skärmen när locket stängs, men bara om en extern skärm är ansluten)? (j/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Jj]$ ]]; then
    cp "$SCRIPT_DIR/bin/internal-display" "$HOME/.local/bin/internal-display"
    chmod +x "$HOME/.local/bin/internal-display"
    cp "$SCRIPT_DIR/bin/lid-display-watch" "$HOME/.local/bin/lid-display-watch"
    chmod +x "$HOME/.local/bin/lid-display-watch"
    echo "    internal-display, lid-display-watch -> ~/.local/bin/"

    if ! grep -qF 'exec : "lid-display-watch"' "$HOME/.config/sxwmrc" 2>/dev/null; then
        echo 'exec : "lid-display-watch"' >> "$HOME/.config/sxwmrc"
        echo "    lid-display-watch tillagd i ~/.config/sxwmrc"
    fi
else
    echo "    Hoppar över lid-display-watch"
fi

echo ""
echo "==> Stänga av locket ska inte göra något (ingen suspend/hibernate)"
echo ""
read -p "Sätta HandleLidSwitch=ignore i /etc/systemd/logind.conf? (j/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Jj]$ ]]; then
    LOGIND_CONF="/etc/systemd/logind.conf"
    if grep -q '^HandleLidSwitch=igonre$' "$LOGIND_CONF" 2>/dev/null; then
        # Stavfel som gjort att systemd-logind ignorerat raden och fallit
        # tillbaka på det inbyggda default-värdet ("suspend") istället
        sudo sed -i 's/^HandleLidSwitch=igonre$/HandleLidSwitch=ignore/' "$LOGIND_CONF"
        echo "    HandleLidSwitch=igonre -> ignore (rättade stavfel)"
    elif grep -q '^HandleLidSwitch=' "$LOGIND_CONF" 2>/dev/null; then
        echo "    HandleLidSwitch redan satt, rör inte: $(grep '^HandleLidSwitch=' "$LOGIND_CONF")"
    else
        echo 'HandleLidSwitch=ignore' | sudo tee -a "$LOGIND_CONF" > /dev/null
        echo "    HandleLidSwitch=ignore tillagd"
    fi
    echo "    Kräver omstart för att aktiveras. Kör INTE 'systemctl restart"
    echo "    systemd-logind' live -- på den här maskinen (X startas manuellt"
    echo "    via startx/.xinitrc, ingen display manager) har det hängt hela"
    echo "    skrivbordet och krävt en hård omstart."
else
    echo "    Hoppar över HandleLidSwitch"
fi

echo ""
echo "==> Förhindra att Bluetooth tappar anslutningar vid systeminaktivitet"
echo ""
read -p "Installera udev-regel som stänger av USB-autosuspend för Bluetooth-adaptern? (j/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Jj]$ ]]; then
    # Specifik för den här laptopens BT-chip (Qualcomm Atheros 0cf3:e500).
    # Annan hårdvara: hitta idVendor/idProduct via `lsusb`, matcha mot
    # /sys/class/bluetooth/hci0 -> realpath för att hitta rätt usb-enhet.
    sudo cp "$SCRIPT_DIR/udev/71-bluetooth-no-autosuspend.rules" /etc/udev/rules.d/71-bluetooth-no-autosuspend.rules
    sudo udevadm control --reload-rules
    sudo udevadm trigger --attr-match=idVendor=0cf3 --attr-match=idProduct=e500
    echo "    71-bluetooth-no-autosuspend.rules -> /etc/udev/rules.d/"
else
    echo "    Hoppar över Bluetooth-udev-regeln"
fi

echo "==> Konfigurerar skärmsläckning på TTY1 (innan inloggning/efter utloggning)..."
GRUB_FILE="/etc/default/grub"
if grep -q 'consoleblank=' "$GRUB_FILE" 2>/dev/null; then
    echo "    consoleblank redan konfigurerad i $GRUB_FILE, hoppar över"
else
    sudo sed -i '/^GRUB_CMDLINE_LINUX_DEFAULT=/ s/"$/ consoleblank=300"/' "$GRUB_FILE"
    sudo update-grub
    echo "    consoleblank=300 tillagt (5 min), kräver omstart för att aktiveras"
fi

echo "==> Stänger av PC-speaker beep..."
echo "blacklist pcspkr" | sudo tee /etc/modprobe.d/nobeep.conf > /dev/null
sudo rmmod pcspkr 2>/dev/null || true

echo ""
read -p "Installera Rust (rustup) och bygga/installera bluetui (bluetooth-hantering)? (j/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Jj]$ ]]; then
    echo "==> Tar bort ev. gammal rustc/cargo från apt (Debian har ofta för gammal version)..."
    RUST_APT_PKGS=$(dpkg-query -W -f='${Package}\n' 'rustc' 'cargo' 'libstd-rust-dev' 'rust-llvm' 'libstd-rust-*' 2>/dev/null || true)
    if [ -n "$RUST_APT_PKGS" ]; then
        sudo apt-get purge -y $RUST_APT_PKGS
        sudo apt-get autoremove --purge -y
    fi

    echo "==> Installerar rustup..."
    if ! command -v rustup >/dev/null 2>&1 && [ ! -x "$HOME/.cargo/bin/rustup" ]; then
        curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
    fi
    # shellcheck disable=SC1091
    source "$HOME/.cargo/env"

    echo "==> Bygger och installerar bluetui..."
    rm -rf "$BUILD_DIR/bluetui"
    git clone --depth=1 https://github.com/pythops/bluetui "$BUILD_DIR/bluetui"
    cd "$BUILD_DIR/bluetui"
    cargo build --release
    sudo cp target/release/bluetui /usr/local/bin/
    cd "$BUILD_DIR"
else
    echo "    Hoppar över Rust och bluetui"
fi

echo "==> Installerar JetBrainsMono Nerd Font..."
FONT_DIR="$HOME/.local/share/fonts/JetBrainsMono"
mkdir -p "$FONT_DIR"
FONT_URL="https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.zip"
wget -q --show-progress -O /tmp/JetBrainsMono.zip "$FONT_URL"
unzip -o /tmp/JetBrainsMono.zip -d "$FONT_DIR" '*.ttf'
rm /tmp/JetBrainsMono.zip
fc-cache -f
echo "    JetBrainsMono Nerd Font installerad"

echo ""
read -p "Lägga till automatisk start av X (sxwm) vid inloggning på TTY1? (j/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Jj]$ ]]; then
    echo "==> Konfigurerar autostart av X på TTY1..."
    BASH_PROFILE="$HOME/.bash_profile"
    AUTOSTART='if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then exec startx; fi'
    if grep -qF 'exec startx' "$BASH_PROFILE" 2>/dev/null; then
        echo "    ~/.bash_profile redan konfigurerad, hoppar över"
    else
        echo "" >> "$BASH_PROFILE"
        echo "$AUTOSTART" >> "$BASH_PROFILE"
        echo "    ~/.bash_profile uppdaterad"
    fi
else
    echo "    Hoppar över autostart av X"
fi

echo "==> Aktiverar PipeWire..."
systemctl --user enable --now pipewire pipewire-pulse wireplumber

echo ""
echo "Installation slutförd!"