From ed063ab1fee56721661e1487a13c4f27000fd386 Mon Sep 17 00:00:00 2001 From: Alex Blank Date: Mon, 24 Aug 2026 20:20:58 +0200 Subject: [PATCH] feat(desktop): consolidate declarative workstation profile Capture desktop-specific system, session, Noctalia, and Pi integration alongside shared laptop support. Retire obsolete X11 configuration and make package ownership explicit for repeatable Decman deployments. --- .Xmodmap | 9 - .Xresources##class.arch_desktop | 4 - .Xresources##class.arch_laptop | 1 - .Xresources##class.arch_laptop_work | 6 - .Xresources##class.arch_work_desktop | 5 - .config/alacritty/alacritty.yml | 881 ------ .../ashell/config.toml##class.arch_desktop | 14 - .config/i3status-rust/config.toml | 113 - .config/st/FUNDING.yml | 5 - .config/st/LICENSE | 34 - .config/st/Makefile | 64 - .config/st/PKGBUILD | 45 - .config/st/README.md | 82 - .config/st/arg.h | 50 - .config/st/boxdraw.c | 194 -- .config/st/boxdraw.o | Bin 7728 -> 0 bytes .config/st/boxdraw_data.h | 214 -- .config/st/config.h | 562 ---- .config/st/config.mk | 39 - .config/st/st | Bin 116008 -> 0 bytes .config/st/st-copyout | 13 - .config/st/st-urlhandler | 15 - .config/st/st.1 | 194 -- .config/st/st.c | 2780 ----------------- .config/st/st.h | 153 - .config/st/st.info | 222 -- .config/st/st.o | Bin 79456 -> 0 bytes .config/st/win.h | 40 - .config/st/x.c | 2208 ------------- .config/st/x.o | Bin 87648 -> 0 bytes .config/termite/config | 88 - .config/xmobar/launch.sh | 4 - .config/xmobar/xmobarrc | 96 - .gitignore | 19 + .../share/noctalia/plugins/pi-status-bridge | 1 - .../pi-permission-system/config.json | 2 + .xbindkeysrc | 15 - .xmonad/xmonad.hs | 570 ---- .xprofile##class.arch_desktop | 7 - .xprofile##class.arch_laptop | 15 - .xprofile##class.arch_laptop_work | 16 - .xprofile##class.arch_work_desktop | 12 - system-config/PACKAGE_AUDIT.md | 205 ++ system-config/README.md | 17 +- .../system/desktop/boot/mkinitcpio.conf | 81 + .../config/system/desktop/boot/refind.conf | 749 +++++ .../system/desktop/boot/refind_linux.conf | 3 + .../config/system/desktop/identity/hostname | 1 + .../config/system/desktop/input/50-zsa.rules | 24 + .../config/system/desktop/input/keyd.conf | 21 + .../desktop/network/NetworkManager.conf | 5 + .../system/desktop/nvidia/nvidia-pm.conf | 2 + .../config/system/desktop/sddm/10-theme.conf | 8 + .../config/system/desktop/storage/fstab | 12 + .../user/common/alacritty/alacritty.toml | 8 + .../common/alacritty/themes/noctalia.toml | 36 + .../user/common}/bin/idle-inhibitor-monitor | 0 .../config/user/common}/bin/pi-status-ui | 2 +- .../config/user/common/bin/wayshell-blanker | Bin 0 -> 17544 bytes .../environment.d/pi-status-bridge.conf | 2 +- .../config/user/common/hypr/hyprland.lua | 13 +- .../config/user/common/mime/mimeapps.list | 15 + .../config/user/common/noctalia/10-base.toml | 4 +- .../plugins/knowledge-lookup/.gitignore | 0 .../plugins/knowledge-lookup/create-entry.py | 0 .../knowledge-lookup/focus-obsidian.py | 0 .../plugins/knowledge-lookup/index.py | 0 .../plugins/knowledge-lookup/manage-entry.py | 0 .../plugins/knowledge-lookup/panel.luau | 0 .../plugins/knowledge-lookup/plugin.toml | 0 .../plugins/knowledge-lookup/vault-info.py | 0 .../plugins/knowledge-lookup/widget.luau | 0 .../plugins/pi-status-bridge/bridge.luau | 102 + .../plugins/pi-status-bridge/plugin.toml | 10 + .../plugins/system-status/battery-rate.luau | 0 .../noctalia/plugins/system-status/cpu.luau | 0 .../plugins/system-status/gpu-mode.luau | 0 .../system-status/inhibitors-panel.luau | 0 .../plugins/system-status/inhibitors.luau | 0 .../plugins/system-status/memory.luau | 0 .../plugins/system-status/network-rate.luau | 0 .../plugins/system-status/plugin.toml | 0 .../systemd/user/pi-status-bridge.service | 2 +- .../user/common/user-dirs}/user-dirs.dirs | 0 .../user/desktop/noctalia/90-machine.toml | 21 +- .../config/user/laptop/hypr/machine.lua | 1 + system-config/hosts.py | 5 +- .../manifests/desktop/hardware-system.txt | 3 + system-config/modules/host_system.py | 66 +- system-config/packages/common/core-repo.txt | 1 + .../packages/common/development-aur.txt | 1 - .../packages/common/hardware-aur.txt | 0 .../packages/common/hardware-repo.txt | 5 + .../packages/common/network-repo.txt | 1 - .../packages/common/productivity-aur.txt | 1 - .../packages/common/productivity-repo.txt | 1 + .../packages/common/services-repo.txt | 1 - system-config/packages/common/wayland-aur.txt | 1 - .../packages/common/wayland-repo.txt | 1 + system-config/packages/desktop/local-aur.txt | 5 + system-config/packages/desktop/local-repo.txt | 34 + .../packages/laptop/hardware-repo.txt | 5 - system-config/pyrightconfig.json | 7 +- system-config/scripts/split_packages.py | 21 +- system-config/source.py | 10 +- 105 files changed, 1479 insertions(+), 8826 deletions(-) delete mode 100644 .Xmodmap delete mode 100644 .Xresources##class.arch_desktop delete mode 100644 .Xresources##class.arch_laptop delete mode 100644 .Xresources##class.arch_laptop_work delete mode 100644 .Xresources##class.arch_work_desktop delete mode 100644 .config/alacritty/alacritty.yml delete mode 100644 .config/ashell/config.toml##class.arch_desktop delete mode 100644 .config/i3status-rust/config.toml delete mode 100644 .config/st/FUNDING.yml delete mode 100644 .config/st/LICENSE delete mode 100644 .config/st/Makefile delete mode 100644 .config/st/PKGBUILD delete mode 100644 .config/st/README.md delete mode 100644 .config/st/arg.h delete mode 100644 .config/st/boxdraw.c delete mode 100644 .config/st/boxdraw.o delete mode 100644 .config/st/boxdraw_data.h delete mode 100644 .config/st/config.h delete mode 100644 .config/st/config.mk delete mode 100755 .config/st/st delete mode 100755 .config/st/st-copyout delete mode 100755 .config/st/st-urlhandler delete mode 100644 .config/st/st.1 delete mode 100644 .config/st/st.c delete mode 100644 .config/st/st.h delete mode 100644 .config/st/st.info delete mode 100644 .config/st/st.o delete mode 100644 .config/st/win.h delete mode 100644 .config/st/x.c delete mode 100644 .config/st/x.o delete mode 100644 .config/termite/config delete mode 100755 .config/xmobar/launch.sh delete mode 100644 .config/xmobar/xmobarrc create mode 100644 .gitignore delete mode 120000 .local/share/noctalia/plugins/pi-status-bridge delete mode 100644 .xbindkeysrc delete mode 100644 .xmonad/xmonad.hs delete mode 100644 .xprofile##class.arch_desktop delete mode 100644 .xprofile##class.arch_laptop delete mode 100644 .xprofile##class.arch_laptop_work delete mode 100644 .xprofile##class.arch_work_desktop create mode 100644 system-config/PACKAGE_AUDIT.md create mode 100644 system-config/config/system/desktop/boot/mkinitcpio.conf create mode 100644 system-config/config/system/desktop/boot/refind.conf create mode 100644 system-config/config/system/desktop/boot/refind_linux.conf create mode 100644 system-config/config/system/desktop/identity/hostname create mode 100644 system-config/config/system/desktop/input/50-zsa.rules create mode 100644 system-config/config/system/desktop/input/keyd.conf create mode 100644 system-config/config/system/desktop/network/NetworkManager.conf create mode 100644 system-config/config/system/desktop/nvidia/nvidia-pm.conf create mode 100644 system-config/config/system/desktop/sddm/10-theme.conf create mode 100644 system-config/config/system/desktop/storage/fstab create mode 100644 system-config/config/user/common/alacritty/alacritty.toml create mode 100644 system-config/config/user/common/alacritty/themes/noctalia.toml rename {.local => system-config/config/user/common}/bin/idle-inhibitor-monitor (100%) rename {.local => system-config/config/user/common}/bin/pi-status-ui (55%) create mode 100755 system-config/config/user/common/bin/wayshell-blanker create mode 100644 system-config/config/user/common/mime/mimeapps.list rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/.gitignore (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/create-entry.py (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/focus-obsidian.py (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/index.py (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/manage-entry.py (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/panel.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/plugin.toml (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/vault-info.py (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/knowledge-lookup/widget.luau (100%) create mode 100644 system-config/config/user/common/noctalia/plugins/pi-status-bridge/bridge.luau create mode 100644 system-config/config/user/common/noctalia/plugins/pi-status-bridge/plugin.toml rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/battery-rate.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/cpu.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/gpu-mode.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/inhibitors-panel.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/inhibitors.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/memory.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/network-rate.luau (100%) rename {.local/share => system-config/config/user/common}/noctalia/plugins/system-status/plugin.toml (100%) rename {.config => system-config/config/user/common/user-dirs}/user-dirs.dirs (100%) create mode 100644 system-config/manifests/desktop/hardware-system.txt create mode 100644 system-config/packages/common/hardware-aur.txt create mode 100644 system-config/packages/common/hardware-repo.txt create mode 100644 system-config/packages/desktop/local-aur.txt create mode 100644 system-config/packages/desktop/local-repo.txt diff --git a/.Xmodmap b/.Xmodmap deleted file mode 100644 index 4044783..0000000 --- a/.Xmodmap +++ /dev/null @@ -1,9 +0,0 @@ -keycode 66 = Mode_switch NoSymbol Mode_switch -clear mod5 -add mod5 = ISO_Level3_Shift -keycode 30 = u U udiaeresis Udiaeresis -keycode 32 = o O odiaeresis Odiaeresis -keycode 38 = a A adiaeresis Adiaeresis -keycode 39 = s S ssharp ssharp -keycode 50 = Shift_L Shift_Lock Shift_L -keycode 62 = Shift_R Shift_Lock Shift_R diff --git a/.Xresources##class.arch_desktop b/.Xresources##class.arch_desktop deleted file mode 100644 index 34bfc83..0000000 --- a/.Xresources##class.arch_desktop +++ /dev/null @@ -1,4 +0,0 @@ -xterm*faceName: MesloLGS NF -xterm*faceSize: 13 - -Xft.dpi: 110 diff --git a/.Xresources##class.arch_laptop b/.Xresources##class.arch_laptop deleted file mode 100644 index 72a4471..0000000 --- a/.Xresources##class.arch_laptop +++ /dev/null @@ -1 +0,0 @@ -Xft.dpi: 192 diff --git a/.Xresources##class.arch_laptop_work b/.Xresources##class.arch_laptop_work deleted file mode 100644 index 4d72857..0000000 --- a/.Xresources##class.arch_laptop_work +++ /dev/null @@ -1,6 +0,0 @@ -xterm*faceName: MesloLGS NF -xterm*faceSize: 13 - -Xft.dpi: 115 - -xscreensaver.newLoginCommand: lxdm -c USER_SWITCH diff --git a/.Xresources##class.arch_work_desktop b/.Xresources##class.arch_work_desktop deleted file mode 100644 index ad8bb3c..0000000 --- a/.Xresources##class.arch_work_desktop +++ /dev/null @@ -1,5 +0,0 @@ -xterm*faceName: MesloLGS NF -xterm*faceSize: 13 - -Xft.dpi: 92 - diff --git a/.config/alacritty/alacritty.yml b/.config/alacritty/alacritty.yml deleted file mode 100644 index 4739510..0000000 --- a/.config/alacritty/alacritty.yml +++ /dev/null @@ -1,881 +0,0 @@ -# Configuration for Alacritty, the GPU enhanced terminal emulator. - -# Import additional configuration files -# -# Imports are loaded in order, skipping all missing files, with the importing -# file being loaded last. If a field is already present in a previous import, it -# will be replaced. -# -# All imports must either be absolute paths starting with `/`, or paths relative -# to the user's home directory starting with `~/`. -#import: -# - /path/to/alacritty.yml - -# Any items in the `env` entry below will be added as -# environment variables. Some entries may override variables -# set by alacritty itself. -#env: - # TERM variable - # - # This value is used to set the `$TERM` environment variable for - # each instance of Alacritty. If it is not present, alacritty will - # check the local terminfo database and use `alacritty` if it is - # available, otherwise `xterm-256color` is used. - #TERM: alacritty - -#window: - # Window dimensions (changes require restart) - # - # Number of lines/columns (not pixels) in the terminal. The number of columns - # must be at least `2`, while using a value of `0` for columns and lines will - # fall back to the window manager's recommended size. - #dimensions: - # columns: 0 - # lines: 0 - - # Window position (changes require restart) - # - # Specified in number of pixels. - # If the position is not set, the window manager will handle the placement. - #position: - # x: 0 - # y: 0 - - # Window padding (changes require restart) - # - # Blank space added around the window in pixels. This padding is scaled - # by DPI and the specified value is always added at both opposing sides. - #padding: - # x: 0 - # y: 0 - - # Spread additional padding evenly around the terminal content. - #dynamic_padding: false - - # Window decorations - # - # Values for `decorations`: - # - full: Borders and title bar - # - none: Neither borders nor title bar - # - # Values for `decorations` (macOS only): - # - transparent: Title bar, transparent background and title bar buttons - # - buttonless: Title bar, transparent background and no title bar buttons - #decorations: full - - # Startup Mode (changes require restart) - # - # Values for `startup_mode`: - # - Windowed - # - Maximized - # - Fullscreen - # - # Values for `startup_mode` (macOS only): - # - SimpleFullscreen - #startup_mode: Windowed - - # Window title - #title: Alacritty - - # Allow terminal applications to change Alacritty's window title. - #dynamic_title: true - - # Window class (Linux/BSD only): - #class: - # Application instance name - #instance: Alacritty - # General application class - #general: Alacritty - - # GTK theme variant (Linux/BSD only) - # - # Override the variant of the GTK theme. Commonly supported values are `dark` - # and `light`. Set this to `None` to use the default theme variant. - #gtk_theme_variant: None - -#scrolling: - # Maximum number of lines in the scrollback buffer. - # Specifying '0' will disable scrolling. - #history: 10000 - - # Scrolling distance multiplier. - #multiplier: 3 - -# Font configuration -font: - # Normal (roman) font face - normal: - # Font family - # - #Default: - # - (macOS) Menlo - # - (Linux/BSD) MesloLGS NF - # - (Windows) Consolas - family: MesloLGS NF - - # The `style` can be specified to pick a specific face. - #style: Regular - - # Bold font face - #bold: - # Font family - # - # If the bold family is not specified, it will fall back to the - # value specified for the normal font. - #family: monospace - - # The `style` can be specified to pick a specific face. - #style: Bold - - # Italic font face - #italic: - # Font family - # - # If the italic family is not specified, it will fall back to the - # value specified for the normal font. - #family: monospace - - # The `style` can be specified to pick a specific face. - #style: Italic - - # Bold italic font face - #bold_italic: - # Font family - # - # If the bold italic family is not specified, it will fall back to the - # value specified for the normal font. - #family: monospace - - # The `style` can be specified to pick a specific face. - #style: Bold Italic - - # Point size - size: 15.0 - - # Offset is the extra space around each character. `offset.y` can be thought - # of as modifying the line spacing, and `offset.x` as modifying the letter - # spacing. - #offset: - # x: 0 - # y: 0 - - # Glyph offset determines the locations of the glyphs within their cells with - # the default being at the bottom. Increasing `x` moves the glyph to the - # right, increasing `y` moves the glyph upward. - #glyph_offset: - # x: 0 - # y: 0 - - # Thin stroke font rendering (macOS only) - # - # Thin strokes are suitable for retina displays, but for non-retina screens - # it is recommended to set `use_thin_strokes` to `false`. - #use_thin_strokes: true - -# If `true`, bold text is drawn using the bright color variants. -#draw_bold_text_with_bright_colors: false - -# Colors (Monokai Pro) -colors: - # Default colors - primary: - background: '#2D2A2E' - foreground: '#FCFCFA' - - # Normal colors - normal: - black: '#403E41' - red: '#FF6188' - green: '#A9DC76' - yellow: '#FFD866' - blue: '#FC9867' - magenta: '#AB9DF2' - cyan: '#78DCE8' - white: '#FCFCFA' - - # Bright colors - bright: - black: '#727072' - red: '#FF6188' - green: '#A9DC76' - yellow: '#FFD866' - blue: '#FC9867' - magenta: '#AB9DF2' - cyan: '#78DCE8' - white: '#FCFCFA' - -# Colors (Tomorrow Night) -#colors: - # Default colors - #primary: - # background: '#1d1f21' - # foreground: '#c5c8c6' - - # Bright and dim foreground colors - # - # The dimmed foreground color is calculated automatically if it is not - # present. If the bright foreground color is not set, or - # `draw_bold_text_with_bright_colors` is `false`, the normal foreground - # color will be used. - #dim_foreground: '#828482' - #bright_foreground: '#eaeaea' - - # Cursor colors - # - # Colors which should be used to draw the terminal cursor. - # - # Allowed values are CellForeground/CellBackground, which reference the - # affected cell, or hexadecimal colors like #ff00ff. - #cursor: - # text: CellBackground - # cursor: CellForeground - - # Vi mode cursor colors - # - # Colors for the cursor when the vi mode is active. - # - # Allowed values are CellForeground/CellBackground, which reference the - # affected cell, or hexadecimal colors like #ff00ff. - #vi_mode_cursor: - # text: CellBackground - # cursor: CellForeground - - # Search colors - # - # Colors used for the search bar and match highlighting. - #search: - # Allowed values are CellForeground/CellBackground, which reference the - # affected cell, or hexadecimal colors like #ff00ff. - #matches: - # foreground: '#000000' - # background: '#ffffff' - #focused_match: - # foreground: '#ffffff' - # background: '#000000' - - #bar: - # background: '#c5c8c6' - # foreground: '#1d1f21' - - # Keyboard regex hints - #hints: - # Fist character in the hint label - # - # Allowed values are CellForeground/CellBackground, which reference the - # affected cell, or hexadecimal colors like #ff00ff. - #start: - # foreground: '#1d1f21' - # background: '#e9ff5e' - - # All characters after the first one in the hint label - # - # Allowed values are CellForeground/CellBackground, which reference the - # affected cell, or hexadecimal colors like #ff00ff. - #end: - # foreground: '#e9ff5e' - # background: '#1d1f21' - - # Line indicator - # - # Color used for the indicator displaying the position in history during - # search and vi mode. - # - # By default, these will use the opposing primary color. - #line_indicator: - # foreground: None - # background: None - - # Selection colors - # - # Colors which should be used to draw the selection area. - # - # Allowed values are CellForeground/CellBackground, which reference the - # affected cell, or hexadecimal colors like #ff00ff. - #selection: - # text: CellBackground - # background: CellForeground - - # Normal colors - #normal: - # black: '#1d1f21' - # red: '#cc6666' - # green: '#b5bd68' - # yellow: '#f0c674' - # blue: '#81a2be' - # magenta: '#b294bb' - # cyan: '#8abeb7' - # white: '#c5c8c6' - - # Bright colors - #bright: - # black: '#666666' - # red: '#d54e53' - # green: '#b9ca4a' - # yellow: '#e7c547' - # blue: '#7aa6da' - # magenta: '#c397d8' - # cyan: '#70c0b1' - # white: '#eaeaea' - - # Dim colors - # - # If the dim colors are not set, they will be calculated automatically based - # on the `normal` colors. - #dim: - # black: '#131415' - # red: '#864343' - # green: '#777c44' - # yellow: '#9e824c' - # blue: '#556a7d' - # magenta: '#75617b' - # cyan: '#5b7d78' - # white: '#828482' - - # Indexed Colors - # - # The indexed colors include all colors from 16 to 256. - # When these are not set, they're filled with sensible defaults. - # - # Example: - # `- { index: 16, color: '#ff00ff' }` - # - #indexed_colors: [] - -# Bell -# -# The bell is rung every time the BEL control character is received. -#bell: - # Visual Bell Animation - # - # Animation effect for flashing the screen when the visual bell is rung. - # - # Values for `animation`: - # - Ease - # - EaseOut - # - EaseOutSine - # - EaseOutQuad - # - EaseOutCubic - # - EaseOutQuart - # - EaseOutQuint - # - EaseOutExpo - # - EaseOutCirc - # - Linear - #animation: EaseOutExpo - - # Duration of the visual bell flash in milliseconds. A `duration` of `0` will - # disable the visual bell animation. - #duration: 0 - - # Visual bell animation color. - #color: '#ffffff' - - # Bell Command - # - # This program is executed whenever the bell is rung. - # - # When set to `command: None`, no command will be executed. - # - # Example: - # command: - # program: notify-send - # args: ["Hello, World!"] - # - #command: None - -# Background opacity -# -# Window opacity as a floating point number from `0.0` to `1.0`. -# The value `0.0` is completely transparent and `1.0` is opaque. -#background_opacity: 1.0 - -#selection: - # This string contains all characters that are used as separators for - # "semantic words" in Alacritty. - #semantic_escape_chars: ",│`|:\"' ()[]{}<>\t" - - # When set to `true`, selected text will be copied to the primary clipboard. - #save_to_clipboard: false - -#cursor: - # Cursor style - #style: - # Cursor shape - # - # Values for `shape`: - # - ▇ Block - # - _ Underline - # - | Beam - #shape: Block - - # Cursor blinking state - # - # Values for `blinking`: - # - Never: Prevent the cursor from ever blinking - # - Off: Disable blinking by default - # - On: Enable blinking by default - # - Always: Force the cursor to always blink - #blinking: Off - - # Vi mode cursor style - # - # If the vi mode cursor style is `None` or not specified, it will fall back to - # the style of the active value of the normal cursor. - # - # See `cursor.style` for available options. - #vi_mode_style: None - - # Cursor blinking interval in milliseconds. - #blink_interval: 750 - - # If this is `true`, the cursor will be rendered as a hollow box when the - # window is not focused. - #unfocused_hollow: true - - # Thickness of the cursor relative to the cell width as floating point number - # from `0.0` to `1.0`. - #thickness: 0.15 - -# Live config reload (changes require restart) -#live_config_reload: true - -# Shell -# -# You can set `shell.program` to the path of your favorite shell, e.g. -# `/bin/fish`. Entries in `shell.args` are passed unmodified as arguments to the -# shell. -# -# Default: -# - (macOS) /bin/bash --login -# - (Linux/BSD) user login shell -# - (Windows) powershell -#shell: -# program: /bin/bash -# args: -# - --login - -# Startup directory -# -# Directory the shell is started in. If this is unset, or `None`, the working -# directory of the parent process will be used. -#working_directory: None - -# Send ESC (\x1b) before characters when alt is pressed. -#alt_send_esc: true - -#mouse: - # Click settings - # - # The `double_click` and `triple_click` settings control the time - # alacritty should wait for accepting multiple clicks as one double - # or triple click. - #double_click: { threshold: 300 } - #triple_click: { threshold: 300 } - - # If this is `true`, the cursor is temporarily hidden when typing. - #hide_when_typing: false - -# Regex hints -# -# Terminal hints can be used to find text in the visible part of the terminal -# and pipe it to other applications. -#hints: - # Keys used for the hint labels. - #alphabet: "jfkdls;ahgurieowpq" - - # List with all available hints - # - # Each hint must have a `regex` and either an `action` or a `command` field. - # The fields `mouse`, `binding` and `post_processing` are optional. - # - # The fields `command`, `binding.key`, `binding.mods` and `mouse.mods` accept - # the same values as they do in the `key_bindings` section. - # - # The `mouse.enabled` field controls if the hint should be underlined while - # the mouse with all `mouse.mods` keys held or the vi mode cursor is above it. - # - # If the `post_processing` field is set to `true`, heuristics will be used to - # shorten the match if there are characters likely not to be part of the hint - # (e.g. a trailing `.`). This is most useful for URIs. - # - # Values for `action`: - # - Copy - # Copy the hint's text to the clipboard. - # - Paste - # Paste the hint's text to the terminal or search. - # - Select - # Select the hint's text. - # - MoveViModeCursor - # Move the vi mode cursor to the beginning of the hint. - #enabled: - # - regex: "(mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)\ - # [^\u0000-\u001F\u007F-\u009F<>\"\\s{-}\\^⟨⟩`]+" - # command: xdg-open - # post_processing: true - # mouse: - # enabled: true - # mods: None - # binding: - # key: U - # mods: Control|Shift - -# Mouse bindings -# -# Mouse bindings are specified as a list of objects, much like the key -# bindings further below. -# -# To trigger mouse bindings when an application running within Alacritty -# captures the mouse, the `Shift` modifier is automatically added as a -# requirement. -# -# Each mouse binding will specify a: -# -# - `mouse`: -# -# - Middle -# - Left -# - Right -# - Numeric identifier such as `5` -# -# - `action` (see key bindings) -# -# And optionally: -# -# - `mods` (see key bindings) -#mouse_bindings: -# - { mouse: Middle, action: PasteSelection } - -# Key bindings -# -# Key bindings are specified as a list of objects. For example, this is the -# default paste binding: -# -# `- { key: V, mods: Control|Shift, action: Paste }` -# -# Each key binding will specify a: -# -# - `key`: Identifier of the key pressed -# -# - A-Z -# - F1-F24 -# - Key0-Key9 -# -# A full list with available key codes can be found here: -# https://docs.rs/glutin/*/glutin/event/enum.VirtualKeyCode.html#variants -# -# Instead of using the name of the keys, the `key` field also supports using -# the scancode of the desired key. Scancodes have to be specified as a -# decimal number. This command will allow you to display the hex scancodes -# for certain keys: -# -# `showkey --scancodes`. -# -# Then exactly one of: -# -# - `chars`: Send a byte sequence to the running application -# -# The `chars` field writes the specified string to the terminal. This makes -# it possible to pass escape sequences. To find escape codes for bindings -# like `PageUp` (`"\x1b[5~"`), you can run the command `showkey -a` outside -# of tmux. Note that applications use terminfo to map escape sequences back -# to keys. It is therefore required to update the terminfo when changing an -# escape sequence. -# -# - `action`: Execute a predefined action -# -# - ToggleViMode -# - SearchForward -# Start searching toward the right of the search origin. -# - SearchBackward -# Start searching toward the left of the search origin. -# - Copy -# - Paste -# - IncreaseFontSize -# - DecreaseFontSize -# - ResetFontSize -# - ScrollPageUp -# - ScrollPageDown -# - ScrollHalfPageUp -# - ScrollHalfPageDown -# - ScrollLineUp -# - ScrollLineDown -# - ScrollToTop -# - ScrollToBottom -# - ClearHistory -# Remove the terminal's scrollback history. -# - Hide -# Hide the Alacritty window. -# - Minimize -# Minimize the Alacritty window. -# - Quit -# Quit Alacritty. -# - ToggleFullscreen -# - SpawnNewInstance -# Spawn a new instance of Alacritty. -# - ClearLogNotice -# Clear Alacritty's UI warning and error notice. -# - ClearSelection -# Remove the active selection. -# - ReceiveChar -# - None -# -# - Vi mode exclusive actions: -# -# - Open -# Perform the action of the first matching hint under the vi mode cursor -# with `mouse.enabled` set to `true`. -# - ToggleNormalSelection -# - ToggleLineSelection -# - ToggleBlockSelection -# - ToggleSemanticSelection -# Toggle semantic selection based on `selection.semantic_escape_chars`. -# -# - Vi mode exclusive cursor motion actions: -# -# - Up -# One line up. -# - Down -# One line down. -# - Left -# One character left. -# - Right -# One character right. -# - First -# First column, or beginning of the line when already at the first column. -# - Last -# Last column, or beginning of the line when already at the last column. -# - FirstOccupied -# First non-empty cell in this terminal row, or first non-empty cell of -# the line when already at the first cell of the row. -# - High -# Top of the screen. -# - Middle -# Center of the screen. -# - Low -# Bottom of the screen. -# - SemanticLeft -# Start of the previous semantically separated word. -# - SemanticRight -# Start of the next semantically separated word. -# - SemanticLeftEnd -# End of the previous semantically separated word. -# - SemanticRightEnd -# End of the next semantically separated word. -# - WordLeft -# Start of the previous whitespace separated word. -# - WordRight -# Start of the next whitespace separated word. -# - WordLeftEnd -# End of the previous whitespace separated word. -# - WordRightEnd -# End of the next whitespace separated word. -# - Bracket -# Character matching the bracket at the cursor's location. -# - SearchNext -# Beginning of the next match. -# - SearchPrevious -# Beginning of the previous match. -# - SearchStart -# Start of the match to the left of the vi mode cursor. -# - SearchEnd -# End of the match to the right of the vi mode cursor. -# -# - Search mode exclusive actions: -# - SearchFocusNext -# Move the focus to the next search match. -# - SearchFocusPrevious -# Move the focus to the previous search match. -# - SearchConfirm -# - SearchCancel -# - SearchClear -# Reset the search regex. -# - SearchDeleteWord -# Delete the last word in the search regex. -# - SearchHistoryPrevious -# Go to the previous regex in the search history. -# - SearchHistoryNext -# Go to the next regex in the search history. -# -# - macOS exclusive actions: -# - ToggleSimpleFullscreen -# Enter fullscreen without occupying another space. -# -# - Linux/BSD exclusive actions: -# -# - CopySelection -# Copy from the selection buffer. -# - PasteSelection -# Paste from the selection buffer. -# -# - `command`: Fork and execute a specified command plus arguments -# -# The `command` field must be a map containing a `program` string and an -# `args` array of command line parameter strings. For example: -# `{ program: "alacritty", args: ["-e", "vttest"] }` -# -# And optionally: -# -# - `mods`: Key modifiers to filter binding actions -# -# - Command -# - Control -# - Option -# - Super -# - Shift -# - Alt -# -# Multiple `mods` can be combined using `|` like this: -# `mods: Control|Shift`. -# Whitespace and capitalization are relevant and must match the example. -# -# - `mode`: Indicate a binding for only specific terminal reported modes -# -# This is mainly used to send applications the correct escape sequences -# when in different modes. -# -# - AppCursor -# - AppKeypad -# - Search -# - Alt -# - Vi -# -# A `~` operator can be used before a mode to apply the binding whenever -# the mode is *not* active, e.g. `~Alt`. -# -# Bindings are always filled by default, but will be replaced when a new -# binding with the same triggers is defined. To unset a default binding, it can -# be mapped to the `ReceiveChar` action. Alternatively, you can use `None` for -# a no-op if you do not wish to receive input characters for that binding. -# -# If the same trigger is assigned to multiple actions, all of them are executed -# in the order they were defined in. -#key_bindings: - #- { key: Paste, action: Paste } - #- { key: Copy, action: Copy } - #- { key: L, mods: Control, action: ClearLogNotice } - #- { key: L, mods: Control, mode: ~Vi|~Search, chars: "\x0c" } - #- { key: PageUp, mods: Shift, mode: ~Alt, action: ScrollPageUp, } - #- { key: PageDown, mods: Shift, mode: ~Alt, action: ScrollPageDown } - #- { key: Home, mods: Shift, mode: ~Alt, action: ScrollToTop, } - #- { key: End, mods: Shift, mode: ~Alt, action: ScrollToBottom } - - # Vi Mode - #- { key: Space, mods: Shift|Control, mode: Vi|~Search, action: ScrollToBottom } - #- { key: Space, mods: Shift|Control, mode: ~Search, action: ToggleViMode } - #- { key: Escape, mode: Vi|~Search, action: ClearSelection } - #- { key: I, mode: Vi|~Search, action: ScrollToBottom } - #- { key: I, mode: Vi|~Search, action: ToggleViMode } - #- { key: C, mods: Control, mode: Vi|~Search, action: ToggleViMode } - #- { key: Y, mods: Control, mode: Vi|~Search, action: ScrollLineUp } - #- { key: E, mods: Control, mode: Vi|~Search, action: ScrollLineDown } - #- { key: G, mode: Vi|~Search, action: ScrollToTop } - #- { key: G, mods: Shift, mode: Vi|~Search, action: ScrollToBottom } - #- { key: B, mods: Control, mode: Vi|~Search, action: ScrollPageUp } - #- { key: F, mods: Control, mode: Vi|~Search, action: ScrollPageDown } - #- { key: U, mods: Control, mode: Vi|~Search, action: ScrollHalfPageUp } - #- { key: D, mods: Control, mode: Vi|~Search, action: ScrollHalfPageDown } - #- { key: Y, mode: Vi|~Search, action: Copy } - #- { key: Y, mode: Vi|~Search, action: ClearSelection } - #- { key: Copy, mode: Vi|~Search, action: ClearSelection } - #- { key: V, mode: Vi|~Search, action: ToggleNormalSelection } - #- { key: V, mods: Shift, mode: Vi|~Search, action: ToggleLineSelection } - #- { key: V, mods: Control, mode: Vi|~Search, action: ToggleBlockSelection } - #- { key: V, mods: Alt, mode: Vi|~Search, action: ToggleSemanticSelection } - #- { key: Return, mode: Vi|~Search, action: Open } - #- { key: K, mode: Vi|~Search, action: Up } - #- { key: J, mode: Vi|~Search, action: Down } - #- { key: H, mode: Vi|~Search, action: Left } - #- { key: L, mode: Vi|~Search, action: Right } - #- { key: Up, mode: Vi|~Search, action: Up } - #- { key: Down, mode: Vi|~Search, action: Down } - #- { key: Left, mode: Vi|~Search, action: Left } - #- { key: Right, mode: Vi|~Search, action: Right } - #- { key: Key0, mode: Vi|~Search, action: First } - #- { key: Key4, mods: Shift, mode: Vi|~Search, action: Last } - #- { key: Key6, mods: Shift, mode: Vi|~Search, action: FirstOccupied } - #- { key: H, mods: Shift, mode: Vi|~Search, action: High } - #- { key: M, mods: Shift, mode: Vi|~Search, action: Middle } - #- { key: L, mods: Shift, mode: Vi|~Search, action: Low } - #- { key: B, mode: Vi|~Search, action: SemanticLeft } - #- { key: W, mode: Vi|~Search, action: SemanticRight } - #- { key: E, mode: Vi|~Search, action: SemanticRightEnd } - #- { key: B, mods: Shift, mode: Vi|~Search, action: WordLeft } - #- { key: W, mods: Shift, mode: Vi|~Search, action: WordRight } - #- { key: E, mods: Shift, mode: Vi|~Search, action: WordRightEnd } - #- { key: Key5, mods: Shift, mode: Vi|~Search, action: Bracket } - #- { key: Slash, mode: Vi|~Search, action: SearchForward } - #- { key: Slash, mods: Shift, mode: Vi|~Search, action: SearchBackward } - #- { key: N, mode: Vi|~Search, action: SearchNext } - #- { key: N, mods: Shift, mode: Vi|~Search, action: SearchPrevious } - - # Search Mode - #- { key: Return, mode: Search|Vi, action: SearchConfirm } - #- { key: Escape, mode: Search, action: SearchCancel } - #- { key: C, mods: Control, mode: Search, action: SearchCancel } - #- { key: U, mods: Control, mode: Search, action: SearchClear } - #- { key: W, mods: Control, mode: Search, action: SearchDeleteWord } - #- { key: P, mods: Control, mode: Search, action: SearchHistoryPrevious } - #- { key: N, mods: Control, mode: Search, action: SearchHistoryNext } - #- { key: Up, mode: Search, action: SearchHistoryPrevious } - #- { key: Down, mode: Search, action: SearchHistoryNext } - #- { key: Return, mode: Search|~Vi, action: SearchFocusNext } - #- { key: Return, mods: Shift, mode: Search|~Vi, action: SearchFocusPrevious } - - # (Windows, Linux, and BSD only) - #- { key: V, mods: Control|Shift, mode: ~Vi, action: Paste } - #- { key: C, mods: Control|Shift, action: Copy } - #- { key: F, mods: Control|Shift, mode: ~Search, action: SearchForward } - #- { key: B, mods: Control|Shift, mode: ~Search, action: SearchBackward } - #- { key: C, mods: Control|Shift, mode: Vi|~Search, action: ClearSelection } - #- { key: Insert, mods: Shift, action: PasteSelection } - #- { key: Key0, mods: Control, action: ResetFontSize } - #- { key: Equals, mods: Control, action: IncreaseFontSize } - #- { key: Plus, mods: Control, action: IncreaseFontSize } - #- { key: NumpadAdd, mods: Control, action: IncreaseFontSize } - #- { key: Minus, mods: Control, action: DecreaseFontSize } - #- { key: NumpadSubtract, mods: Control, action: DecreaseFontSize } - - # (Windows only) - #- { key: Return, mods: Alt, action: ToggleFullscreen } - - # (macOS only) - #- { key: K, mods: Command, mode: ~Vi|~Search, chars: "\x0c" } - #- { key: K, mods: Command, mode: ~Vi|~Search, action: ClearHistory } - #- { key: Key0, mods: Command, action: ResetFontSize } - #- { key: Equals, mods: Command, action: IncreaseFontSize } - #- { key: Plus, mods: Command, action: IncreaseFontSize } - #- { key: NumpadAdd, mods: Command, action: IncreaseFontSize } - #- { key: Minus, mods: Command, action: DecreaseFontSize } - #- { key: NumpadSubtract, mods: Command, action: DecreaseFontSize } - #- { key: V, mods: Command, action: Paste } - #- { key: C, mods: Command, action: Copy } - #- { key: C, mods: Command, mode: Vi|~Search, action: ClearSelection } - #- { key: H, mods: Command, action: Hide } - #- { key: H, mods: Command|Alt, action: HideOtherApplications } - #- { key: M, mods: Command, action: Minimize } - #- { key: Q, mods: Command, action: Quit } - #- { key: W, mods: Command, action: Quit } - #- { key: N, mods: Command, action: SpawnNewInstance } - #- { key: F, mods: Command|Control, action: ToggleFullscreen } - #- { key: F, mods: Command, mode: ~Search, action: SearchForward } - #- { key: B, mods: Command, mode: ~Search, action: SearchBackward } - -#debug: - # Display the time it takes to redraw each frame. - #render_timer: false - - # Keep the log file after quitting Alacritty. - #persistent_logging: false - - # Log level - # - # Values for `log_level`: - # - Off - # - Error - # - Warn - # - Info - # - Debug - # - Trace - #log_level: Warn - - # Print all received window events. - #print_events: false diff --git a/.config/ashell/config.toml##class.arch_desktop b/.config/ashell/config.toml##class.arch_desktop deleted file mode 100644 index 2401e44..0000000 --- a/.config/ashell/config.toml##class.arch_desktop +++ /dev/null @@ -1,14 +0,0 @@ -# Hyprland desktop status bar. Ashell reloads this file when it changes. -# Keep this intentionally lean while replacing the existing Waybar profile. - -position = "Bottom" -layer = "Top" - -[modules] -left = ["Workspaces", "KeyboardLayout"] -center = ["WindowTitle"] -right = ["SystemInfo", "MediaPlayer", ["Tray", "Tempo", "Settings"]] - -[workspaces] -visibility_mode = "MonitorSpecific" -disable_special_workspaces = true diff --git a/.config/i3status-rust/config.toml b/.config/i3status-rust/config.toml deleted file mode 100644 index 43e507d..0000000 --- a/.config/i3status-rust/config.toml +++ /dev/null @@ -1,113 +0,0 @@ -icons_format = "{icon}" - -[theme] -theme = "slick" -#[theme.overrides] -#idle_bg = "#222222" -#separator_bg = "#222222" - -[icons] -icons = "material-nf" - -[[block]] -block = "focused_window" -[[bloack.format]] -full = " $title.str(max_w:15) " -short = " $title.str(max_w:10) " - - -[[block]] -block = "cpu" -interval = 1 -format = " $icon $utilization" -format_alt = " $icon $frequency $boost" - -[[block]] -block = "temperature" -interval = 1 -format = " $icon $max" - - -[[block]] -block = "memory" -format = " $icon $mem_total_used_percents.eng(w:4)" -format_alt = " $icon $mem_total_used_percents.eng(w:2) S:$swap_used_percents.eng(w:2) " - -[[block]] -block = "disk_space" -path = "/" -info_type = "available" -alert_unit = "GB" -interval = 60 -warning = 20.0 -alert = 10.0 -format = " / $available.eng(w:2) " - -[[block]] -block = "custom" -command = '''echo iGPU: `sudo intel_gpu_top -l | head -n4 | tail -n1 | awk '{print $9 "%"}'`''' -interval = 5 - -[[block]] -block = "nvidia_gpu" -interval = 1 -format = "dGPU:$utilization $temperature $clocks" - - -[[block]] -block = "sound" -driver = "pulseaudio" -device_kind = "sink" -format = " $icon { $volume|} " -[[block.click]] -button = "left" -cmd = "pavucontrol" - -[[block]] -block = "sound" -driver = "pulseaudio" -device_kind = "source" -format= " $icon " - -[[block.click]] -button = "left" -cmd = "pactl set-source-mute @DEFAULT_SOURCE@ toggle" - - -[[block]] -block = "net" -format = " $icon {$signal_strength $ssid |Wired connection} ^icon_net_up$speed_up ^icon_net_down$speed_down " - -[[block]] -block = "vpn" -driver = "mullvad" -interval = 10 -format_connected = "VPN: $icon " -format_disconnected = "VPN: $icon " -state_connected = "good" -state_disconnected = "critical" - -[[block]] -block = "external_ip" -format = " $city.str(max_w:3):$country_code" -interval = 60 - -[[block]] -block = "battery" -device = "BAT0" -interval = 1 -format = " $icon $percentage {$power:$time|}" -full_format = " $icon $percentage" -charging_format = " $icon $percentage {$power:$time}" -missing_format = "" -good= 100 -warning= 40 -critical= 20 - - -[[block]] -block = "time" -interval = 1 -format = " $timestamp.datetime(f:'%a %d/%m %R:%S') " - - diff --git a/.config/st/FUNDING.yml b/.config/st/FUNDING.yml deleted file mode 100644 index 5b856dc..0000000 --- a/.config/st/FUNDING.yml +++ /dev/null @@ -1,5 +0,0 @@ -github: lukesmithxyz -custom: "https://lukesmith.xyz/donate" -custom: "https://paypal.me/lukemsmith" -patreon: lukesmith -custom: "https://lukesmith.xyz/crypto" diff --git a/.config/st/LICENSE b/.config/st/LICENSE deleted file mode 100644 index c356c39..0000000 --- a/.config/st/LICENSE +++ /dev/null @@ -1,34 +0,0 @@ -MIT/X Consortium License - -© 2014-2018 Hiltjo Posthuma -© 2018 Devin J. Pohly -© 2014-2017 Quentin Rameau -© 2009-2012 Aurélien APTEL -© 2008-2017 Anselm R Garbe -© 2012-2017 Roberto E. Vargas Caballero -© 2012-2016 Christoph Lohmann <20h at r-36 dot net> -© 2013 Eon S. Jeon -© 2013 Alexander Sedov -© 2013 Mark Edgar -© 2013-2014 Eric Pruitt -© 2013 Michael Forney -© 2013-2014 Markus Teich -© 2014-2015 Laslo Hunhold - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/.config/st/Makefile b/.config/st/Makefile deleted file mode 100644 index 2e05e4b..0000000 --- a/.config/st/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# st - simple terminal -# See LICENSE file for copyright and license details. -.POSIX: - -include config.mk - -SRC = st.c x.c boxdraw.c -OBJ = $(SRC:.c=.o) - -all: options st - -options: - @echo st build options: - @echo "CFLAGS = $(STCFLAGS)" - @echo "LDFLAGS = $(STLDFLAGS)" - @echo "CC = $(CC)" - -config.h: - cp config.def.h config.h - -.c.o: - $(CC) $(STCFLAGS) -c $< - -st.o: config.h st.h win.h -x.o: arg.h config.h st.h win.h -boxdraw.o: config.h st.h boxdraw_data.h - -$(OBJ): config.h config.mk - -st: $(OBJ) - $(CC) -o $@ $(OBJ) $(STLDFLAGS) - -clean: - rm -f st $(OBJ) st-$(VERSION).tar.gz *.o *.orig *.rej - -dist: clean - mkdir -p st-$(VERSION) - cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\ - config.def.h st.info st.1 arg.h st.h win.h $(SRC)\ - st-$(VERSION) - tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz - rm -rf st-$(VERSION) - -install: st - mkdir -p $(DESTDIR)$(PREFIX)/bin - cp -f st $(DESTDIR)$(PREFIX)/bin - cp -f st-copyout $(DESTDIR)$(PREFIX)/bin - cp -f st-urlhandler $(DESTDIR)$(PREFIX)/bin - chmod 755 $(DESTDIR)$(PREFIX)/bin/st - chmod 755 $(DESTDIR)$(PREFIX)/bin/st-copyout - chmod 755 $(DESTDIR)$(PREFIX)/bin/st-urlhandler - mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1 - tic -sx st.info - @echo Please see the README file regarding the terminfo entry of st. - -uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/st - rm -f $(DESTDIR)$(PREFIX)/bin/st-copyout - rm -f $(DESTDIR)$(PREFIX)/bin/st-urlhandler - rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1 - -.PHONY: all options clean dist install uninstall diff --git a/.config/st/PKGBUILD b/.config/st/PKGBUILD deleted file mode 100644 index 98a057d..0000000 --- a/.config/st/PKGBUILD +++ /dev/null @@ -1,45 +0,0 @@ -# Maintainer: - -pkgname=st-luke-git -_pkgname=st -pkgver=0.8.2.r1062.2087ab9 -pkgrel=1 -epoch=1 -pkgdesc="Luke's simple (suckless) terminal with vim-bindings, transparency, xresources, etc. " -url='https://github.com/LukeSmithxyz/st' -arch=('i686' 'x86_64') -license=('MIT') -options=('zipman') -depends=('libxft') -makedepends=('ncurses' 'libxext' 'git') -optdepends=('dmenu: feed urls to dmenu') -source=('git://github.com/LukeSmithxyz/st') -sha1sums=('SKIP') - -provides=("${_pkgname}") -conflicts=("${_pkgname}") - -pkgver() { - cd "${_pkgname}" - printf "%s.r%s.%s" "$(awk '/^VERSION =/ {print $3}' config.mk)" \ - "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" -} - -prepare() { - cd $srcdir/${_pkgname} - # skip terminfo which conflicts with ncurses - sed -i '/tic /d' Makefile -} - -build() { - cd "${_pkgname}" - make X11INC=/usr/include/X11 X11LIB=/usr/lib/X11 -} - -package() { - cd "${_pkgname}" - make PREFIX=/usr DESTDIR="${pkgdir}" install - install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" - install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md" - install -Dm644 .Xdefaults "${pkgdir}/usr/share/doc/${pkgname}/Xdefaults.example" -} diff --git a/.config/st/README.md b/.config/st/README.md deleted file mode 100644 index 811f446..0000000 --- a/.config/st/README.md +++ /dev/null @@ -1,82 +0,0 @@ -# Luke's build of st - the simple (suckless) terminal - -The [suckless terminal (st)](https://st.suckless.org/) with some additional features that make it literally the best terminal emulator ever: - -## Unique features (using dmenu) - -+ **follow urls** by pressing `alt-l` -+ **copy urls** in the same way with `alt-y` -+ **copy the output of commands** with `alt-o` - -## Bindings for - -+ **scrollback** with `alt-↑/↓` or `alt-pageup/down` or `shift` while scrolling the mouse -+ OR **vim-bindings**: scroll up/down in history with `alt-k` and `alt-j`. Faster with `alt-u`/`alt-d`. -+ **zoom/change font size**: same bindings as above, but holding down shift as well. `alt-home` returns to default -+ **copy text** with `alt-c`, **paste** is `alt-v` or `shift-insert` - -## Pretty stuff - -+ Compatibility with `Xresources` and `pywal` for dynamic colors. -+ Default [gruvbox](https://github.com/morhetz/gruvbox) colors otherwise. -+ Transparency/alpha, which is also adjustable from your `Xresources`. -+ Default font is system "mono" at 14pt, meaning the font will match your system font. - -## Other st patches - -+ Vertcenter -+ Scrollback -+ font2 -+ updated to latest version 0.8.2 - -## Installation for newbs - -``` -git clone https://github.com/LukeSmithxyz/st -cd st -sudo make install -``` - -Users of Arch-based distros can also install it from the AUR as [st-luke-git](https://aur.archlinux.org/packages/st-luke-git/). - -Obviously, `make` is required to build. `fontconfig` is required for the default build, since it asks `fontconfig` for your system monospace font. It might be obvious, but `libX11` and `libXft` are required as well. Chances are, you have all of this installed already. - -On OpenBSD, be sure to edit `config.mk` first and remove `-lrt` from the `$LIBS` before compiling. - -Be sure to have a composite manager (`xcompmgr`, `picom`, etc.) running if you want transparency. - -## How to configure dynamically with Xresources - -For many key variables, this build of `st` will look for X settings set in either `~/.Xdefaults` or `~/.Xresources`. You must run `xrdb` on one of these files to load the settings. - -For example, you can define your desired fonts, transparency or colors: - -``` -*.font: Liberation Mono:pixelsize=12:antialias=true:autohint=true; -*.alpha: 0.9 -*.color0: #111 -... -``` - -The `alpha` value (for transparency) goes from `0` (transparent) to `1` (opaque). - -### Colors - -To be clear about the color settings: - -- This build will use gruvbox colors by default and as a fallback. -- If there are Xresources colors defined, those will take priority. -- But if `wal` has run in your session, its colors will take priority. - -Note that when you run `wal`, it will negate the transparency of existing windows, but new windows will continue with the previously defined transparency. - -## Notes on Emojis and Special Characters - -If st crashes when viewing emojis, install [libxft-bgra](https://aur.archlinux.org/packages/libxft-bgra/) from the AUR. - -Note that some special characters may appear truncated if too wide. You might want to manually set your prefered emoji/special character font to a lower size in the `config.h` file to avoid this. By default, JoyPixels is used at a smaller size than the usual text. - -## Contact - -- Luke Smith -- [https://lukesmith.xyz](https://lukesmith.xyz) diff --git a/.config/st/arg.h b/.config/st/arg.h deleted file mode 100644 index a22e019..0000000 --- a/.config/st/arg.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copy me if you can. - * by 20h - */ - -#ifndef ARG_H__ -#define ARG_H__ - -extern char *argv0; - -/* use main(int argc, char *argv[]) */ -#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ - argv[0] && argv[0][0] == '-'\ - && argv[0][1];\ - argc--, argv++) {\ - char argc_;\ - char **argv_;\ - int brk_;\ - if (argv[0][1] == '-' && argv[0][2] == '\0') {\ - argv++;\ - argc--;\ - break;\ - }\ - int i_;\ - for (i_ = 1, brk_ = 0, argv_ = argv;\ - argv[0][i_] && !brk_;\ - i_++) {\ - if (argv_ != argv)\ - break;\ - argc_ = argv[0][i_];\ - switch (argc_) - -#define ARGEND }\ - } - -#define ARGC() argc_ - -#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ - ((x), abort(), (char *)0) :\ - (brk_ = 1, (argv[0][i_+1] != '\0')?\ - (&argv[0][i_+1]) :\ - (argc--, argv++, argv[0]))) - -#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ - (char *)0 :\ - (brk_ = 1, (argv[0][i_+1] != '\0')?\ - (&argv[0][i_+1]) :\ - (argc--, argv++, argv[0]))) - -#endif diff --git a/.config/st/boxdraw.c b/.config/st/boxdraw.c deleted file mode 100644 index 28a92d0..0000000 --- a/.config/st/boxdraw.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih - * MIT/X Consortium License - */ - -#include -#include "st.h" -#include "boxdraw_data.h" - -/* Rounded non-negative integers division of n / d */ -#define DIV(n, d) (((n) + (d) / 2) / (d)) - -static Display *xdpy; -static Colormap xcmap; -static XftDraw *xd; -static Visual *xvis; - -static void drawbox(int, int, int, int, XftColor *, XftColor *, ushort); -static void drawboxlines(int, int, int, int, XftColor *, ushort); - -/* public API */ - -void -boxdraw_xinit(Display *dpy, Colormap cmap, XftDraw *draw, Visual *vis) -{ - xdpy = dpy; xcmap = cmap; xd = draw, xvis = vis; -} - -int -isboxdraw(Rune u) -{ - Rune block = u & ~0xff; - return (boxdraw && block == 0x2500 && boxdata[(uint8_t)u]) || - (boxdraw_braille && block == 0x2800); -} - -/* the "index" is actually the entire shape data encoded as ushort */ -ushort -boxdrawindex(const Glyph *g) -{ - if (boxdraw_braille && (g->u & ~0xff) == 0x2800) - return BRL | (uint8_t)g->u; - if (boxdraw_bold && (g->mode & ATTR_BOLD)) - return BDB | boxdata[(uint8_t)g->u]; - return boxdata[(uint8_t)g->u]; -} - -void -drawboxes(int x, int y, int cw, int ch, XftColor *fg, XftColor *bg, - const XftGlyphFontSpec *specs, int len) -{ - for ( ; len-- > 0; x += cw, specs++) - drawbox(x, y, cw, ch, fg, bg, (ushort)specs->glyph); -} - -/* implementation */ - -void -drawbox(int x, int y, int w, int h, XftColor *fg, XftColor *bg, ushort bd) -{ - ushort cat = bd & ~(BDB | 0xff); /* mask out bold and data */ - if (bd & (BDL | BDA)) { - /* lines (light/double/heavy/arcs) */ - drawboxlines(x, y, w, h, fg, bd); - - } else if (cat == BBD) { - /* lower (8-X)/8 block */ - int d = DIV((uint8_t)bd * h, 8); - XftDrawRect(xd, fg, x, y + d, w, h - d); - - } else if (cat == BBU) { - /* upper X/8 block */ - XftDrawRect(xd, fg, x, y, w, DIV((uint8_t)bd * h, 8)); - - } else if (cat == BBL) { - /* left X/8 block */ - XftDrawRect(xd, fg, x, y, DIV((uint8_t)bd * w, 8), h); - - } else if (cat == BBR) { - /* right (8-X)/8 block */ - int d = DIV((uint8_t)bd * w, 8); - XftDrawRect(xd, fg, x + d, y, w - d, h); - - } else if (cat == BBQ) { - /* Quadrants */ - int w2 = DIV(w, 2), h2 = DIV(h, 2); - if (bd & TL) - XftDrawRect(xd, fg, x, y, w2, h2); - if (bd & TR) - XftDrawRect(xd, fg, x + w2, y, w - w2, h2); - if (bd & BL) - XftDrawRect(xd, fg, x, y + h2, w2, h - h2); - if (bd & BR) - XftDrawRect(xd, fg, x + w2, y + h2, w - w2, h - h2); - - } else if (bd & BBS) { - /* Shades - data is 1/2/3 for 25%/50%/75% alpha, respectively */ - int d = (uint8_t)bd; - XftColor xfc; - XRenderColor xrc = { .alpha = 0xffff }; - - xrc.red = DIV(fg->color.red * d + bg->color.red * (4 - d), 4); - xrc.green = DIV(fg->color.green * d + bg->color.green * (4 - d), 4); - xrc.blue = DIV(fg->color.blue * d + bg->color.blue * (4 - d), 4); - - XftColorAllocValue(xdpy, xvis, xcmap, &xrc, &xfc); - XftDrawRect(xd, &xfc, x, y, w, h); - XftColorFree(xdpy, xvis, xcmap, &xfc); - - } else if (cat == BRL) { - /* braille, each data bit corresponds to one dot at 2x4 grid */ - int w1 = DIV(w, 2); - int h1 = DIV(h, 4), h2 = DIV(h, 2), h3 = DIV(3 * h, 4); - - if (bd & 1) XftDrawRect(xd, fg, x, y, w1, h1); - if (bd & 2) XftDrawRect(xd, fg, x, y + h1, w1, h2 - h1); - if (bd & 4) XftDrawRect(xd, fg, x, y + h2, w1, h3 - h2); - if (bd & 8) XftDrawRect(xd, fg, x + w1, y, w - w1, h1); - if (bd & 16) XftDrawRect(xd, fg, x + w1, y + h1, w - w1, h2 - h1); - if (bd & 32) XftDrawRect(xd, fg, x + w1, y + h2, w - w1, h3 - h2); - if (bd & 64) XftDrawRect(xd, fg, x, y + h3, w1, h - h3); - if (bd & 128) XftDrawRect(xd, fg, x + w1, y + h3, w - w1, h - h3); - - } -} - -void -drawboxlines(int x, int y, int w, int h, XftColor *fg, ushort bd) -{ - /* s: stem thickness. width/8 roughly matches underscore thickness. */ - /* We draw bold as 1.5 * normal-stem and at least 1px thicker. */ - /* doubles draw at least 3px, even when w or h < 3. bold needs 6px. */ - int mwh = MIN(w, h); - int base_s = MAX(1, DIV(mwh, 8)); - int bold = (bd & BDB) && mwh >= 6; /* possibly ignore boldness */ - int s = bold ? MAX(base_s + 1, DIV(3 * base_s, 2)) : base_s; - int w2 = DIV(w - s, 2), h2 = DIV(h - s, 2); - /* the s-by-s square (x + w2, y + h2, s, s) is the center texel. */ - /* The base length (per direction till edge) includes this square. */ - - int light = bd & (LL | LU | LR | LD); - int double_ = bd & (DL | DU | DR | DD); - - if (light) { - /* d: additional (negative) length to not-draw the center */ - /* texel - at arcs and avoid drawing inside (some) doubles */ - int arc = bd & BDA; - int multi_light = light & (light - 1); - int multi_double = double_ & (double_ - 1); - /* light crosses double only at DH+LV, DV+LH (ref. shapes) */ - int d = arc || (multi_double && !multi_light) ? -s : 0; - - if (bd & LL) - XftDrawRect(xd, fg, x, y + h2, w2 + s + d, s); - if (bd & LU) - XftDrawRect(xd, fg, x + w2, y, s, h2 + s + d); - if (bd & LR) - XftDrawRect(xd, fg, x + w2 - d, y + h2, w - w2 + d, s); - if (bd & LD) - XftDrawRect(xd, fg, x + w2, y + h2 - d, s, h - h2 + d); - } - - /* double lines - also align with light to form heavy when combined */ - if (double_) { - /* - * going clockwise, for each double-ray: p is additional length - * to the single-ray nearer to the previous direction, and n to - * the next. p and n adjust from the base length to lengths - * which consider other doubles - shorter to avoid intersections - * (p, n), or longer to draw the far-corner texel (n). - */ - int dl = bd & DL, du = bd & DU, dr = bd & DR, dd = bd & DD; - if (dl) { - int p = dd ? -s : 0, n = du ? -s : dd ? s : 0; - XftDrawRect(xd, fg, x, y + h2 + s, w2 + s + p, s); - XftDrawRect(xd, fg, x, y + h2 - s, w2 + s + n, s); - } - if (du) { - int p = dl ? -s : 0, n = dr ? -s : dl ? s : 0; - XftDrawRect(xd, fg, x + w2 - s, y, s, h2 + s + p); - XftDrawRect(xd, fg, x + w2 + s, y, s, h2 + s + n); - } - if (dr) { - int p = du ? -s : 0, n = dd ? -s : du ? s : 0; - XftDrawRect(xd, fg, x + w2 - p, y + h2 - s, w - w2 + p, s); - XftDrawRect(xd, fg, x + w2 - n, y + h2 + s, w - w2 + n, s); - } - if (dd) { - int p = dr ? -s : 0, n = dl ? -s : dr ? s : 0; - XftDrawRect(xd, fg, x + w2 + s, y + h2 - p, s, h - h2 + p); - XftDrawRect(xd, fg, x + w2 - s, y + h2 - n, s, h - h2 + n); - } - } -} diff --git a/.config/st/boxdraw.o b/.config/st/boxdraw.o deleted file mode 100644 index 10c3d9d3bfbf1417ea5c1dffe3f408255ad9ccf5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7728 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 cursor */ - "#555555", /* 257 -> rev cursor*/ - "#232323", /* 258 -> bg */ - "#ebdbb2", /* 259 -> fg */ -}; - - -/* - * Default colors (colorname index) - * foreground, background, cursor, reverse cursor - */ -unsigned int defaultfg = 259; -unsigned int defaultbg = 258; -unsigned int defaultcs = 256; -unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 2; - -/* - * Default columns and rows numbers - */ - -static unsigned int cols = 80; -static unsigned int rows = 24; - -/* - * Default colour and shape of the mouse cursor - */ -static unsigned int mouseshape = XC_xterm; -static unsigned int mousefg = 7; -static unsigned int mousebg = 0; - -/* - * Color used to display font attributes when fontconfig selected a font which - * doesn't match the ones requested. - */ -static unsigned int defaultattr = 11; - -/* - * Xresources preferences to load at startup - */ -ResourcePref resources[] = { - { "font", STRING, &font }, - { "fontalt0", STRING, &font2[0] }, - { "color0", STRING, &colorname[0] }, - { "color1", STRING, &colorname[1] }, - { "color2", STRING, &colorname[2] }, - { "color3", STRING, &colorname[3] }, - { "color4", STRING, &colorname[4] }, - { "color5", STRING, &colorname[5] }, - { "color6", STRING, &colorname[6] }, - { "color7", STRING, &colorname[7] }, - { "color8", STRING, &colorname[8] }, - { "color9", STRING, &colorname[9] }, - { "color10", STRING, &colorname[10] }, - { "color11", STRING, &colorname[11] }, - { "color12", STRING, &colorname[12] }, - { "color13", STRING, &colorname[13] }, - { "color14", STRING, &colorname[14] }, - { "color15", STRING, &colorname[15] }, - { "background", STRING, &colorname[258] }, - { "foreground", STRING, &colorname[259] }, - { "cursorColor", STRING, &colorname[256] }, - { "termname", STRING, &termname }, - { "shell", STRING, &shell }, - { "blinktimeout", INTEGER, &blinktimeout }, - { "bellvolume", INTEGER, &bellvolume }, - { "tabspaces", INTEGER, &tabspaces }, - { "borderpx", INTEGER, &borderpx }, - { "cwscale", FLOAT, &cwscale }, - { "chscale", FLOAT, &chscale }, - { "alpha", FLOAT, &alpha }, - { "ximspot_update_interval", INTEGER, &ximspot_update_interval }, -}; - -/* - * Internal mouse shortcuts. - * Beware that overloading Button1 will disable the selection. - */ -static MouseShortcut mshortcuts[] = { - /* button mask string */ - { Button4, XK_NO_MOD, "\031" }, - { Button5, XK_NO_MOD, "\005" }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (Mod1Mask|ShiftMask) - -MouseKey mkeys[] = { - /* button mask function argument */ - { Button4, ShiftMask, kscrollup, {.i = 1} }, - { Button5, ShiftMask, kscrolldown, {.i = 1} }, - { Button4, MODKEY, kscrollup, {.i = 1} }, - { Button5, MODKEY, kscrolldown, {.i = 1} }, - { Button4, TERMMOD, zoom, {.f = +1} }, - { Button5, TERMMOD, zoom, {.f = -1} }, -}; - -static char *openurlcmd[] = { "/bin/sh", "-c", "st-urlhandler", "externalpipe", NULL }; - -static char *copyurlcmd[] = { "/bin/sh", "-c", - "tmp=$(sed 's/.*│//g' | tr -d '\n' | grep -aEo '(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./@$&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)' | uniq | sed 's/^www./http:\\/\\/www\\./g' ); IFS=; [ ! -z $tmp ] && echo $tmp | dmenu -i -p 'Copy which url?' -l 10 | tr -d '\n' | xclip -selection clipboard", - "externalpipe", NULL }; - -static char *copyoutput[] = { "/bin/sh", "-c", "st-copyout", "externalpipe", NULL }; - -static Shortcut shortcuts[] = { - /* mask keysym function argument */ - { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, - { ControlMask, XK_Print, toggleprinter, {.i = 0} }, - { ShiftMask, XK_Print, printscreen, {.i = 0} }, - { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, - { TERMMOD, XK_Prior, zoom, {.f = +1} }, - { TERMMOD, XK_Next, zoom, {.f = -1} }, - { MODKEY, XK_Home, zoomreset, {.f = 0} }, - { MODKEY, XK_c, clipcopy, {.i = 0} }, - { ShiftMask, XK_Insert, clippaste, {.i = 0} }, - { MODKEY, XK_v, clippaste, {.i = 0} }, - { XK_ANY_MOD, Button2, selpaste, {.i = 0} }, - { MODKEY, XK_Num_Lock, numlock, {.i = 0} }, - { MODKEY, XK_Control_L, iso14755, {.i = 0} }, - { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, - { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, - { MODKEY, XK_Page_Up, kscrollup, {.i = -1} }, - { MODKEY, XK_Page_Down, kscrolldown, {.i = -1} }, - { MODKEY, XK_k, kscrollup, {.i = 1} }, - { MODKEY, XK_j, kscrolldown, {.i = 1} }, - { MODKEY, XK_Up, kscrollup, {.i = 1} }, - { MODKEY, XK_Down, kscrolldown, {.i = 1} }, - { MODKEY, XK_u, kscrollup, {.i = -1} }, - { MODKEY, XK_d, kscrolldown, {.i = -1} }, - { TERMMOD, XK_Up, zoom, {.f = +1} }, - { TERMMOD, XK_Down, zoom, {.f = -1} }, - { TERMMOD, XK_K, zoom, {.f = +1} }, - { TERMMOD, XK_J, zoom, {.f = -1} }, - { TERMMOD, XK_U, zoom, {.f = +2} }, - { TERMMOD, XK_D, zoom, {.f = -2} }, - { MODKEY, XK_l, externalpipe, {.v = openurlcmd } }, - { MODKEY, XK_y, externalpipe, {.v = copyurlcmd } }, - { MODKEY, XK_o, externalpipe, {.v = copyoutput } }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * crlf value - * * 0: no value - * * > 0: crlf mode is enabled - * * < 0: crlf mode is disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * Override mouse-select while mask is active (when MODE_MOUSE is set). - * Note that if you want to use ShiftMask with selmasks, set this to an other - * modifier, set to 0 to not use it. - */ -static uint forceselmod = ShiftMask; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/.config/st/config.mk b/.config/st/config.mk deleted file mode 100644 index 1635264..0000000 --- a/.config/st/config.mk +++ /dev/null @@ -1,39 +0,0 @@ -# st version -VERSION = 0.8.2 - -# Customize below to fit your system - -# paths -PREFIX ?= /usr/local -MANPREFIX = $(PREFIX)/share/man - -X11INC = /usr/X11R6/include -X11LIB = /usr/X11R6/lib - -# include X11 in Ubuntu -# X11INC = /usr/include/X11R6 -# X11LIB = /usr/lib/X11R6 - -PKG_CONFIG = pkg-config - -# includes and libs -INCS = -I$(X11INC) \ - `$(PKG_CONFIG) --cflags fontconfig` \ - `$(PKG_CONFIG) --cflags freetype2` -LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft -lXrender \ - `$(PKG_CONFIG) --libs fontconfig` \ - `$(PKG_CONFIG) --libs freetype2` - -# flags -STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) -STLDFLAGS = $(LIBS) $(LDFLAGS) - -# OpenBSD: -#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ -# `pkg-config --libs fontconfig` \ -# `pkg-config --libs freetype2` - -# compiler and linker -# CC = c99 diff --git a/.config/st/st b/.config/st/st deleted file mode 100755 index 355625122f6ee4d672fd7e2e9d4d655180497a65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116008 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/dev/null 2>&1 & diff --git a/.config/st/st.1 b/.config/st/st.1 deleted file mode 100644 index 57c35f4..0000000 --- a/.config/st/st.1 +++ /dev/null @@ -1,194 +0,0 @@ -.TH ST 1 st\-VERSION -.SH NAME -st \- simple terminal (Luke Smith (https://lukesmith.xyz)'s build) -.SH SYNOPSIS -.B st -.RB [ \-aiv ] -.RB [ \-c -.IR class ] -.RB [ \-f -.IR font ] -.RB [ \-g -.IR geometry ] -.RB [ \-n -.IR name ] -.RB [ \-o -.IR iofile ] -.RB [ \-T -.IR title ] -.RB [ \-t -.IR title ] -.RB [ \-l -.IR line ] -.RB [ \-w -.IR windowid ] -.RB [[ \-e ] -.IR command -.RI [ arguments ...]] -.PP -.B st -.RB [ \-aiv ] -.RB [ \-c -.IR class ] -.RB [ \-f -.IR font ] -.RB [ \-g -.IR geometry ] -.RB [ \-n -.IR name ] -.RB [ \-o -.IR iofile ] -.RB [ \-T -.IR title ] -.RB [ \-t -.IR title ] -.RB [ \-w -.IR windowid ] -.RB \-l -.IR line -.RI [ stty_args ...] -.SH DESCRIPTION -.B st -is a simple terminal emulator. -.SH OPTIONS -.TP -.B \-a -disable alternate screens in terminal -.TP -.BI \-c " class" -defines the window class (default $TERM). -.TP -.BI \-f " font" -defines the -.I font -to use when st is run. -.TP -.BI \-g " geometry" -defines the X11 geometry string. -The form is [=][{xX}][{+-}{+-}]. See -.BR XParseGeometry (3) -for further details. -.TP -.B \-i -will fixate the position given with the -g option. -.TP -.BI \-n " name" -defines the window instance name (default $TERM). -.TP -.BI \-o " iofile" -writes all the I/O to -.I iofile. -This feature is useful when recording st sessions. A value of "-" means -standard output. -.TP -.BI \-T " title" -defines the window title (default 'st'). -.TP -.BI \-t " title" -defines the window title (default 'st'). -.TP -.BI \-w " windowid" -embeds st within the window identified by -.I windowid -.TP -.BI \-l " line" -use a tty -.I line -instead of a pseudo terminal. -.I line -should be a (pseudo-)serial device (e.g. /dev/ttyS0 on Linux for serial port -0). -When this flag is given -remaining arguments are used as flags for -.BR stty(1). -By default st initializes the serial line to 8 bits, no parity, 1 stop bit -and a 38400 baud rate. The speed is set by appending it as last argument -(e.g. 'st -l /dev/ttyS0 115200'). Arguments before the last one are -.BR stty(1) -flags. If you want to set odd parity on 115200 baud use for example 'st -l -/dev/ttyS0 parenb parodd 115200'. Set the number of bits by using for -example 'st -l /dev/ttyS0 cs7 115200'. See -.BR stty(1) -for more arguments and cases. -.TP -.B \-v -prints version information to stderr, then exits. -.TP -.BI \-e " command " [ " arguments " "... ]" -st executes -.I command -instead of the shell. If this is used it -.B must be the last option -on the command line, as in xterm / rxvt. -This option is only intended for compatibility, -and all the remaining arguments are used as a command -even without it. -.SH SHORTCUTS -.TP -.B Alt-j/k or Alt-Up/Down or Alt-Mouse Wheel -Scroll up/down one line at a time. -.TP -.B Alt-u/d or Alt-Page Up/Page Down -Scroll up/down one screen at a time. -.TP -.B Alt-Shift-k/j or Alt-Shift-Page Up/Page Down or Alt-Shift-Mouse Wheel -Increase or decrease font size. -.TP -.B Alt-Home -Reset to default font size. -.TP -.B Shift-Insert or Alt-v -Paste from clipboard. -.TP -.B Alt-c -Copy to clipboard. -.TP -.B Alt-p -Paste/input primary selection. -.TP -.B Alt-l -Show dmenu menu of all URLs on screen and choose one to open. -.TP -.B Alt-y -Show dmenu menu of all URLs on screen and choose one to copy. -.TP -.B Alt-o -Show dmenu menu of all recently run commands and copy the output of the chosen command to the clipboard. -.I xclip -required. -.TP -.B Break -Send a break in the serial line. -Break key is obtained in PC keyboards -pressing at the same time control and pause. -.TP -.B Ctrl-Print Screen -Toggle if st should print to the -.I iofile. -.TP -.B Shift-Print Screen -Print the full screen to the -.I iofile. -.TP -.B Print Screen -Print the selection to the -.I iofile. -.TP -.B Alt-Ctrl -Launch dmenu to enter a unicode codepoint and send the corresponding glyph -to st. -.SH CUSTOMIZATION -.B st -can be customized by creating a custom config.h and (re)compiling the source -code. This keeps it fast, secure and simple. -.SH AUTHORS -See the LICENSE file for the authors. -.SH LICENSE -See the LICENSE file for the terms of redistribution. -.SH SEE ALSO -.BR tabbed (1), -.BR utmp (1), -.BR stty (1) -.SH BUGS -See the TODO file in the distribution. - diff --git a/.config/st/st.c b/.config/st/st.c deleted file mode 100644 index 0e5e3f5..0000000 --- a/.config/st/st.c +++ /dev/null @@ -1,2780 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "st.h" -#include "win.h" - -#if defined(__linux) - #include -#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) - #include -#elif defined(__FreeBSD__) || defined(__DragonFly__) - #include -#endif - -/* Arbitrary sizes */ -#define UTF_INVALID 0xFFFD -#define UTF_SIZ 4 -#define ESC_BUF_SIZ (128*UTF_SIZ) -#define ESC_ARG_SIZ 16 -#define STR_BUF_SIZ ESC_BUF_SIZ -#define STR_ARG_SIZ ESC_ARG_SIZ -#define HISTSIZE 2000 - -/* macros */ -#define IS_SET(flag) ((term.mode & (flag)) != 0) -#define NUMMAXLEN(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) -#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') -#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) -#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) -#define ISDELIM(u) (u && wcschr(worddelimiters, u)) -#define TLINE(y) ((y) < term.scr ? term.hist[((y) + term.histi - \ - term.scr + HISTSIZE + 1) % HISTSIZE] : \ - term.line[(y) - term.scr]) - -#define TLINE_HIST(y) ((y) <= HISTSIZE-term.row+2 ? term.hist[(y)] : term.line[(y-HISTSIZE+term.row-3)]) - -/* constants */ -#define ISO14755CMD "dmenu -w \"$WINDOWID\" -p codepoint: ] [;]] []] */ -typedef struct { - char buf[ESC_BUF_SIZ]; /* raw string */ - int len; /* raw string length */ - char priv; - int arg[ESC_ARG_SIZ]; - int narg; /* nb of args */ - char mode[2]; -} CSIEscape; - -/* STR Escape sequence structs */ -/* ESC type [[ [] [;]] ] ESC '\' */ -typedef struct { - char type; /* ESC type ... */ - char buf[STR_BUF_SIZ]; /* raw string */ - int len; /* raw string length */ - char *args[STR_ARG_SIZ]; - int narg; /* nb of args */ -} STREscape; - -static void execsh(char *, char **); -static void stty(char **); -static void sigchld(int); -static void ttywriteraw(const char *, size_t); - -static void csidump(void); -static void csihandle(void); -static void csiparse(void); -static void csireset(void); -static int eschandle(uchar); -static void strdump(void); -static void strhandle(void); -static void strparse(void); -static void strreset(void); - -static void tprinter(char *, size_t); -static void tdumpsel(void); -static void tdumpline(int); -static void tdump(void); -static void tclearregion(int, int, int, int); -static void tcursor(int); -static void tdeletechar(int); -static void tdeleteline(int); -static void tinsertblank(int); -static void tinsertblankline(int); -static int tlinelen(int); -static void tmoveto(int, int); -static void tmoveato(int, int); -static void tnewline(int); -static void tputtab(int); -static void tputc(Rune); -static void treset(void); -static void tscrollup(int, int, int); -static void tscrolldown(int, int, int); -static void tsetattr(int *, int); -static void tsetchar(Rune, Glyph *, int, int); -static void tsetdirt(int, int); -static void tsetscroll(int, int); -static void tswapscreen(void); -static void tsetmode(int, int, int *, int); -static int twrite(const char *, int, int); -static void tfulldirt(void); -static void tcontrolcode(uchar ); -static void tdectest(char ); -static void tdefutf8(char); -static int32_t tdefcolor(int *, int *, int); -static void tdeftran(char); -static void tstrsequence(uchar); - -static void drawregion(int, int, int, int); - -static void selnormalize(void); -static void selscroll(int, int); -static void selsnap(int *, int *, int); - -static size_t utf8decode(const char *, Rune *, size_t); -static Rune utf8decodebyte(char, size_t *); -static char utf8encodebyte(Rune, size_t); -static size_t utf8validate(Rune *, size_t); - -static char *base64dec(const char *); -static char base64dec_getc(const char **); - -static ssize_t xwrite(int, const char *, size_t); - -/* Globals */ -static Term term; -static Selection sel; -static CSIEscape csiescseq; -static STREscape strescseq; -static int iofd = 1; -static int cmdfd; -static pid_t pid; - -static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; -static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; -static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; -static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; - -ssize_t -xwrite(int fd, const char *s, size_t len) -{ - size_t aux = len; - ssize_t r; - - while (len > 0) { - r = write(fd, s, len); - if (r < 0) - return r; - len -= r; - s += r; - } - - return aux; -} - -void * -xmalloc(size_t len) -{ - void *p; - - if (!(p = malloc(len))) - die("malloc: %s\n", strerror(errno)); - - return p; -} - -void * -xrealloc(void *p, size_t len) -{ - if ((p = realloc(p, len)) == NULL) - die("realloc: %s\n", strerror(errno)); - - return p; -} - -char * -xstrdup(char *s) -{ - if ((s = strdup(s)) == NULL) - die("strdup: %s\n", strerror(errno)); - - return s; -} - -size_t -utf8decode(const char *c, Rune *u, size_t clen) -{ - size_t i, j, len, type; - Rune udecoded; - - *u = UTF_INVALID; - if (!clen) - return 0; - udecoded = utf8decodebyte(c[0], &len); - if (!BETWEEN(len, 1, UTF_SIZ)) - return 1; - for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { - udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); - if (type != 0) - return j; - } - if (j < len) - return 0; - *u = udecoded; - utf8validate(u, len); - - return len; -} - -Rune -utf8decodebyte(char c, size_t *i) -{ - for (*i = 0; *i < LEN(utfmask); ++(*i)) - if (((uchar)c & utfmask[*i]) == utfbyte[*i]) - return (uchar)c & ~utfmask[*i]; - - return 0; -} - -size_t -utf8encode(Rune u, char *c) -{ - size_t len, i; - - len = utf8validate(&u, 0); - if (len > UTF_SIZ) - return 0; - - for (i = len - 1; i != 0; --i) { - c[i] = utf8encodebyte(u, 0); - u >>= 6; - } - c[0] = utf8encodebyte(u, len); - - return len; -} - -char -utf8encodebyte(Rune u, size_t i) -{ - return utfbyte[i] | (u & ~utfmask[i]); -} - -size_t -utf8validate(Rune *u, size_t i) -{ - if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) - *u = UTF_INVALID; - for (i = 1; *u > utfmax[i]; ++i) - ; - - return i; -} - -static const char base64_digits[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, - 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -char -base64dec_getc(const char **src) -{ - while (**src && !isprint(**src)) (*src)++; - return *((*src)++); -} - -char * -base64dec(const char *src) -{ - size_t in_len = strlen(src); - char *result, *dst; - - if (in_len % 4) - in_len += 4 - (in_len % 4); - result = dst = xmalloc(in_len / 4 * 3 + 1); - while (*src) { - int a = base64_digits[(unsigned char) base64dec_getc(&src)]; - int b = base64_digits[(unsigned char) base64dec_getc(&src)]; - int c = base64_digits[(unsigned char) base64dec_getc(&src)]; - int d = base64_digits[(unsigned char) base64dec_getc(&src)]; - - *dst++ = (a << 2) | ((b & 0x30) >> 4); - if (c == -1) - break; - *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); - if (d == -1) - break; - *dst++ = ((c & 0x03) << 6) | d; - } - *dst = '\0'; - return result; -} - -void -selinit(void) -{ - sel.mode = SEL_IDLE; - sel.snap = 0; - sel.ob.x = -1; -} - -int -tlinelen(int y) -{ - int i = term.col; - - if (TLINE(y)[i - 1].mode & ATTR_WRAP) - return i; - - while (i > 0 && TLINE(y)[i - 1].u == ' ') - --i; - - return i; -} - -int -tlinehistlen(int y) -{ - int i = term.col; - - if (TLINE_HIST(y)[i - 1].mode & ATTR_WRAP) - return i; - - while (i > 0 && TLINE_HIST(y)[i - 1].u == ' ') - --i; - - return i; -} - -void -selstart(int col, int row, int snap) -{ - selclear(); - sel.mode = SEL_EMPTY; - sel.type = SEL_REGULAR; - sel.alt = IS_SET(MODE_ALTSCREEN); - sel.snap = snap; - sel.oe.x = sel.ob.x = col; - sel.oe.y = sel.ob.y = row; - selnormalize(); - - if (sel.snap != 0) - sel.mode = SEL_READY; - tsetdirt(sel.nb.y, sel.ne.y); -} - -void -selextend(int col, int row, int type, int done) -{ - int oldey, oldex, oldsby, oldsey, oldtype; - - if (sel.mode == SEL_IDLE) - return; - if (done && sel.mode == SEL_EMPTY) { - selclear(); - return; - } - - oldey = sel.oe.y; - oldex = sel.oe.x; - oldsby = sel.nb.y; - oldsey = sel.ne.y; - oldtype = sel.type; - - sel.oe.x = col; - sel.oe.y = row; - selnormalize(); - sel.type = type; - - if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY) - tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); - - sel.mode = done ? SEL_IDLE : SEL_READY; -} - -void -selnormalize(void) -{ - int i; - - if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) { - sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x; - sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x; - } else { - sel.nb.x = MIN(sel.ob.x, sel.oe.x); - sel.ne.x = MAX(sel.ob.x, sel.oe.x); - } - sel.nb.y = MIN(sel.ob.y, sel.oe.y); - sel.ne.y = MAX(sel.ob.y, sel.oe.y); - - selsnap(&sel.nb.x, &sel.nb.y, -1); - selsnap(&sel.ne.x, &sel.ne.y, +1); - - /* expand selection over line breaks */ - if (sel.type == SEL_RECTANGULAR) - return; - i = tlinelen(sel.nb.y); - if (i < sel.nb.x) - sel.nb.x = i; - if (tlinelen(sel.ne.y) <= sel.ne.x) - sel.ne.x = term.col - 1; -} - -int -selected(int x, int y) -{ - if (sel.mode == SEL_EMPTY || sel.ob.x == -1 || - sel.alt != IS_SET(MODE_ALTSCREEN)) - return 0; - - if (sel.type == SEL_RECTANGULAR) - return BETWEEN(y, sel.nb.y, sel.ne.y) - && BETWEEN(x, sel.nb.x, sel.ne.x); - - return BETWEEN(y, sel.nb.y, sel.ne.y) - && (y != sel.nb.y || x >= sel.nb.x) - && (y != sel.ne.y || x <= sel.ne.x); -} - -void -selsnap(int *x, int *y, int direction) -{ - int newx, newy, xt, yt; - int delim, prevdelim; - Glyph *gp, *prevgp; - - switch (sel.snap) { - case SNAP_WORD: - /* - * Snap around if the word wraps around at the end or - * beginning of a line. - */ - prevgp = &TLINE(*y)[*x]; - prevdelim = ISDELIM(prevgp->u); - for (;;) { - newx = *x + direction; - newy = *y; - if (!BETWEEN(newx, 0, term.col - 1)) { - newy += direction; - newx = (newx + term.col) % term.col; - if (!BETWEEN(newy, 0, term.row - 1)) - break; - - if (direction > 0) - yt = *y, xt = *x; - else - yt = newy, xt = newx; - if (!(TLINE(yt)[xt].mode & ATTR_WRAP)) - break; - } - - if (newx >= tlinelen(newy)) - break; - - gp = &TLINE(newy)[newx]; - delim = ISDELIM(gp->u); - if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim - || (delim && gp->u != prevgp->u))) - break; - - *x = newx; - *y = newy; - prevgp = gp; - prevdelim = delim; - } - break; - case SNAP_LINE: - /* - * Snap around if the the previous line or the current one - * has set ATTR_WRAP at its end. Then the whole next or - * previous line will be selected. - */ - *x = (direction < 0) ? 0 : term.col - 1; - if (direction < 0) { - for (; *y > 0; *y += direction) { - if (!(TLINE(*y-1)[term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } else if (direction > 0) { - for (; *y < term.row-1; *y += direction) { - if (!(TLINE(*y)[term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } - break; - } -} - -char * -getsel(void) -{ - char *str, *ptr; - int y, bufsize, lastx, linelen; - Glyph *gp, *last; - - if (sel.ob.x == -1) - return NULL; - - bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ; - ptr = str = xmalloc(bufsize); - - /* append every set & selected glyph to the selection */ - for (y = sel.nb.y; y <= sel.ne.y; y++) { - if ((linelen = tlinelen(y)) == 0) { - *ptr++ = '\n'; - continue; - } - - if (sel.type == SEL_RECTANGULAR) { - gp = &TLINE(y)[sel.nb.x]; - lastx = sel.ne.x; - } else { - gp = &TLINE(y)[sel.nb.y == y ? sel.nb.x : 0]; - lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; - } - last = &TLINE(y)[MIN(lastx, linelen-1)]; - while (last >= gp && last->u == ' ') - --last; - - for ( ; gp <= last; ++gp) { - if (gp->mode & ATTR_WDUMMY) - continue; - - ptr += utf8encode(gp->u, ptr); - } - - /* - * Copy and pasting of line endings is inconsistent - * in the inconsistent terminal and GUI world. - * The best solution seems like to produce '\n' when - * something is copied from st and convert '\n' to - * '\r', when something to be pasted is received by - * st. - * FIXME: Fix the computer world. - */ - if ((y < sel.ne.y || lastx >= linelen) && !(last->mode & ATTR_WRAP)) - *ptr++ = '\n'; - } - *ptr = 0; - return str; -} - -void -selclear(void) -{ - if (sel.ob.x == -1) - return; - sel.mode = SEL_IDLE; - sel.ob.x = -1; - tsetdirt(sel.nb.y, sel.ne.y); -} - -void -die(const char *errstr, ...) -{ - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(1); -} - -void -execsh(char *cmd, char **args) -{ - char *sh, *prog; - const struct passwd *pw; - - errno = 0; - if ((pw = getpwuid(getuid())) == NULL) { - if (errno) - die("getpwuid: %s\n", strerror(errno)); - else - die("who are you?\n"); - } - - if ((sh = getenv("SHELL")) == NULL) - sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd; - - if (args) - prog = args[0]; - else if (utmp) - prog = utmp; - else - prog = sh; - DEFAULT(args, ((char *[]) {prog, NULL})); - - unsetenv("COLUMNS"); - unsetenv("LINES"); - unsetenv("TERMCAP"); - setenv("LOGNAME", pw->pw_name, 1); - setenv("USER", pw->pw_name, 1); - setenv("SHELL", sh, 1); - setenv("HOME", pw->pw_dir, 1); - setenv("TERM", termname, 1); - - signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGALRM, SIG_DFL); - - execvp(prog, args); - _exit(1); -} - -void -sigchld(int a) -{ - int stat; - pid_t p; - - if ((p = waitpid(pid, &stat, WNOHANG)) < 0) - die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); - - if (pid != p) - return; - - if (WIFEXITED(stat) && WEXITSTATUS(stat)) - die("child exited with status %d\n", WEXITSTATUS(stat)); - else if (WIFSIGNALED(stat)) - die("child terminated due to signal %d\n", WTERMSIG(stat)); - exit(0); -} - -void -stty(char **args) -{ - char cmd[_POSIX_ARG_MAX], **p, *q, *s; - size_t n, siz; - - if ((n = strlen(stty_args)) > sizeof(cmd)-1) - die("incorrect stty parameters\n"); - memcpy(cmd, stty_args, n); - q = cmd + n; - siz = sizeof(cmd) - n; - for (p = args; p && (s = *p); ++p) { - if ((n = strlen(s)) > siz-1) - die("stty parameter length too long\n"); - *q++ = ' '; - memcpy(q, s, n); - q += n; - siz -= n + 1; - } - *q = '\0'; - if (system(cmd) != 0) - perror("Couldn't call stty"); -} - -int -ttynew(char *line, char *cmd, char *out, char **args) -{ - int m, s; - - if (out) { - term.mode |= MODE_PRINT; - iofd = (!strcmp(out, "-")) ? - 1 : open(out, O_WRONLY | O_CREAT, 0666); - if (iofd < 0) { - fprintf(stderr, "Error opening %s:%s\n", - out, strerror(errno)); - } - } - - if (line) { - if ((cmdfd = open(line, O_RDWR)) < 0) - die("open line '%s' failed: %s\n", - line, strerror(errno)); - dup2(cmdfd, 0); - stty(args); - return cmdfd; - } - - /* seems to work fine on linux, openbsd and freebsd */ - if (openpty(&m, &s, NULL, NULL, NULL) < 0) - die("openpty failed: %s\n", strerror(errno)); - - switch (pid = fork()) { - case -1: - die("fork failed: %s\n", strerror(errno)); - break; - case 0: - close(iofd); - setsid(); /* create a new process group */ - dup2(s, 0); - dup2(s, 1); - dup2(s, 2); - if (ioctl(s, TIOCSCTTY, NULL) < 0) - die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); - close(s); - close(m); -#ifdef __OpenBSD__ - if (pledge("stdio getpw proc exec", NULL) == -1) - die("pledge\n"); -#endif - execsh(cmd, args); - break; - default: -#ifdef __OpenBSD__ - if (pledge("stdio rpath tty proc", NULL) == -1) - die("pledge\n"); -#endif - close(s); - cmdfd = m; - signal(SIGCHLD, sigchld); - break; - } - return cmdfd; -} - -size_t -ttyread(void) -{ - static char buf[BUFSIZ]; - static int buflen = 0; - int written; - int ret; - - /* append read bytes to unprocessed bytes */ - if ((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0) - die("couldn't read from shell: %s\n", strerror(errno)); - buflen += ret; - - written = twrite(buf, buflen, 0); - buflen -= written; - /* keep any uncomplete utf8 char for the next call */ - if (buflen > 0) - memmove(buf, buf + written, buflen); - - return ret; -} - -void -ttywrite(const char *s, size_t n, int may_echo) -{ - const char *next; - Arg arg = (Arg) { .i = term.scr }; - - kscrolldown(&arg); - - if (may_echo && IS_SET(MODE_ECHO)) - twrite(s, n, 1); - - if (!IS_SET(MODE_CRLF)) { - ttywriteraw(s, n); - return; - } - - /* This is similar to how the kernel handles ONLCR for ttys */ - while (n > 0) { - if (*s == '\r') { - next = s + 1; - ttywriteraw("\r\n", 2); - } else { - next = memchr(s, '\r', n); - DEFAULT(next, s + n); - ttywriteraw(s, next - s); - } - n -= next - s; - s = next; - } -} - -void -ttywriteraw(const char *s, size_t n) -{ - fd_set wfd, rfd; - ssize_t r; - size_t lim = 256; - - /* - * Remember that we are using a pty, which might be a modem line. - * Writing too much will clog the line. That's why we are doing this - * dance. - * FIXME: Migrate the world to Plan 9. - */ - while (n > 0) { - FD_ZERO(&wfd); - FD_ZERO(&rfd); - FD_SET(cmdfd, &wfd); - FD_SET(cmdfd, &rfd); - - /* Check if we can write. */ - if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) { - if (errno == EINTR) - continue; - die("select failed: %s\n", strerror(errno)); - } - if (FD_ISSET(cmdfd, &wfd)) { - /* - * Only write the bytes written by ttywrite() or the - * default of 256. This seems to be a reasonable value - * for a serial line. Bigger values might clog the I/O. - */ - if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0) - goto write_error; - if (r < n) { - /* - * We weren't able to write out everything. - * This means the buffer is getting full - * again. Empty it. - */ - if (n < lim) - lim = ttyread(); - n -= r; - s += r; - } else { - /* All bytes have been written. */ - break; - } - } - if (FD_ISSET(cmdfd, &rfd)) - lim = ttyread(); - } - return; - -write_error: - die("write error on tty: %s\n", strerror(errno)); -} - -void -ttyresize(int tw, int th) -{ - struct winsize w; - - w.ws_row = term.row; - w.ws_col = term.col; - w.ws_xpixel = tw; - w.ws_ypixel = th; - if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0) - fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno)); -} - -void -ttyhangup() -{ - /* Send SIGHUP to shell */ - kill(pid, SIGHUP); -} - -int -tattrset(int attr) -{ - int i, j; - - for (i = 0; i < term.row-1; i++) { - for (j = 0; j < term.col-1; j++) { - if (term.line[i][j].mode & attr) - return 1; - } - } - - return 0; -} - -void -tsetdirt(int top, int bot) -{ - int i; - - LIMIT(top, 0, term.row-1); - LIMIT(bot, 0, term.row-1); - - for (i = top; i <= bot; i++) - term.dirty[i] = 1; -} - -void -tsetdirtattr(int attr) -{ - int i, j; - - for (i = 0; i < term.row-1; i++) { - for (j = 0; j < term.col-1; j++) { - if (term.line[i][j].mode & attr) { - tsetdirt(i, i); - break; - } - } - } -} - -void -tfulldirt(void) -{ - tsetdirt(0, term.row-1); -} - -void -tcursor(int mode) -{ - static TCursor c[2]; - int alt = IS_SET(MODE_ALTSCREEN); - - if (mode == CURSOR_SAVE) { - c[alt] = term.c; - } else if (mode == CURSOR_LOAD) { - term.c = c[alt]; - tmoveto(c[alt].x, c[alt].y); - } -} - -void -treset(void) -{ - uint i; - - term.c = (TCursor){{ - .mode = ATTR_NULL, - .fg = defaultfg, - .bg = defaultbg - }, .x = 0, .y = 0, .state = CURSOR_DEFAULT}; - - memset(term.tabs, 0, term.col * sizeof(*term.tabs)); - for (i = tabspaces; i < term.col; i += tabspaces) - term.tabs[i] = 1; - term.top = 0; - term.bot = term.row - 1; - term.mode = MODE_WRAP|MODE_UTF8; - memset(term.trantbl, CS_USA, sizeof(term.trantbl)); - term.charset = 0; - - for (i = 0; i < 2; i++) { - tmoveto(0, 0); - tcursor(CURSOR_SAVE); - tclearregion(0, 0, term.col-1, term.row-1); - tswapscreen(); - } -} - -void -tnew(int col, int row) -{ - term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } }; - clock_gettime(CLOCK_MONOTONIC, &term.last_ximspot_update); - tresize(col, row); - treset(); -} - -void -tswapscreen(void) -{ - Line *tmp = term.line; - - term.line = term.alt; - term.alt = tmp; - term.mode ^= MODE_ALTSCREEN; - tfulldirt(); -} - -void -kscrolldown(const Arg* a) -{ - int n = a->i; - - if (n < 0) - n = term.row + n; - - if (n > term.scr) - n = term.scr; - - if (term.scr > 0) { - term.scr -= n; - selscroll(0, -n); - tfulldirt(); - } -} - -void -kscrollup(const Arg* a) -{ - int n = a->i; - - if (n < 0) - n = term.row + n; - - if (term.scr <= HISTSIZE-n) { - term.scr += n; - selscroll(0, n); - tfulldirt(); - } -} - -void -tscrolldown(int orig, int n, int copyhist) -{ - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - - if (copyhist) { - term.histi = (term.histi - 1 + HISTSIZE) % HISTSIZE; - temp = term.hist[term.histi]; - term.hist[term.histi] = term.line[term.bot]; - term.line[term.bot] = temp; - } - - tsetdirt(orig, term.bot-n); - tclearregion(0, term.bot-n+1, term.col-1, term.bot); - - for (i = term.bot; i >= orig+n; i--) { - temp = term.line[i]; - term.line[i] = term.line[i-n]; - term.line[i-n] = temp; - } - - selscroll(orig, n); -} - -void -tscrollup(int orig, int n, int copyhist) -{ - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - - if (copyhist) { - term.histi = (term.histi + 1) % HISTSIZE; - temp = term.hist[term.histi]; - term.hist[term.histi] = term.line[orig]; - term.line[orig] = temp; - } - - if (term.scr > 0 && term.scr < HISTSIZE) - term.scr = MIN(term.scr + n, HISTSIZE-1); - - tclearregion(0, orig, term.col-1, orig+n-1); - tsetdirt(orig+n, term.bot); - - for (i = orig; i <= term.bot-n; i++) { - temp = term.line[i]; - term.line[i] = term.line[i+n]; - term.line[i+n] = temp; - } - - selscroll(orig, -n); -} - -void -selscroll(int orig, int n) -{ - if (sel.ob.x == -1) - return; - - if (BETWEEN(sel.ob.y, orig, term.bot) || BETWEEN(sel.oe.y, orig, term.bot)) { - if ((sel.ob.y += n) > term.bot || (sel.oe.y += n) < term.top) { - selclear(); - return; - } - if (sel.type == SEL_RECTANGULAR) { - if (sel.ob.y < term.top) - sel.ob.y = term.top; - if (sel.oe.y > term.bot) - sel.oe.y = term.bot; - } else { - if (sel.ob.y < term.top) { - sel.ob.y = term.top; - sel.ob.x = 0; - } - if (sel.oe.y > term.bot) { - sel.oe.y = term.bot; - sel.oe.x = term.col; - } - } - selnormalize(); - } -} - -void -tnewline(int first_col) -{ - int y = term.c.y; - - if (y == term.bot) { - tscrollup(term.top, 1, 1); - } else { - y++; - } - tmoveto(first_col ? 0 : term.c.x, y); -} - -void -csiparse(void) -{ - char *p = csiescseq.buf, *np; - long int v; - - csiescseq.narg = 0; - if (*p == '?') { - csiescseq.priv = 1; - p++; - } - - csiescseq.buf[csiescseq.len] = '\0'; - while (p < csiescseq.buf+csiescseq.len) { - np = NULL; - v = strtol(p, &np, 10); - if (np == p) - v = 0; - if (v == LONG_MAX || v == LONG_MIN) - v = -1; - csiescseq.arg[csiescseq.narg++] = v; - p = np; - if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ) - break; - p++; - } - csiescseq.mode[0] = *p++; - csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0'; -} - -/* for absolute user moves, when decom is set */ -void -tmoveato(int x, int y) -{ - tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0)); -} - -void -tmoveto(int x, int y) -{ - int miny, maxy; - - if (term.c.state & CURSOR_ORIGIN) { - miny = term.top; - maxy = term.bot; - } else { - miny = 0; - maxy = term.row - 1; - } - term.c.state &= ~CURSOR_WRAPNEXT; - term.c.x = LIMIT(x, 0, term.col-1); - term.c.y = LIMIT(y, miny, maxy); -} - -void -tsetchar(Rune u, Glyph *attr, int x, int y) -{ - static char *vt100_0[62] = { /* 0x41 - 0x7e */ - "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ - 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ - 0, 0, 0, 0, 0, 0, 0, 0, /* P - W */ - 0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */ - "◆", "▒", "␉", "␌", "␍", "␊", "°", "±", /* ` - g */ - "␤", "␋", "┘", "┐", "┌", "└", "┼", "⎺", /* h - o */ - "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */ - "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */ - }; - - /* - * The table is proudly stolen from rxvt. - */ - if (term.trantbl[term.charset] == CS_GRAPHIC0 && - BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41]) - utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ); - - if (term.line[y][x].mode & ATTR_WIDE) { - if (x+1 < term.col) { - term.line[y][x+1].u = ' '; - term.line[y][x+1].mode &= ~ATTR_WDUMMY; - } - } else if (term.line[y][x].mode & ATTR_WDUMMY) { - term.line[y][x-1].u = ' '; - term.line[y][x-1].mode &= ~ATTR_WIDE; - } - - term.dirty[y] = 1; - term.line[y][x] = *attr; - term.line[y][x].u = u; - - if (isboxdraw(u)) - term.line[y][x].mode |= ATTR_BOXDRAW; -} - -void -tclearregion(int x1, int y1, int x2, int y2) -{ - int x, y, temp; - Glyph *gp; - - if (x1 > x2) - temp = x1, x1 = x2, x2 = temp; - if (y1 > y2) - temp = y1, y1 = y2, y2 = temp; - - LIMIT(x1, 0, term.col-1); - LIMIT(x2, 0, term.col-1); - LIMIT(y1, 0, term.row-1); - LIMIT(y2, 0, term.row-1); - - for (y = y1; y <= y2; y++) { - term.dirty[y] = 1; - for (x = x1; x <= x2; x++) { - gp = &term.line[y][x]; - if (selected(x, y)) - selclear(); - gp->fg = term.c.attr.fg; - gp->bg = term.c.attr.bg; - gp->mode = 0; - gp->u = ' '; - } - } -} - -void -tdeletechar(int n) -{ - int dst, src, size; - Glyph *line; - - LIMIT(n, 0, term.col - term.c.x); - - dst = term.c.x; - src = term.c.x + n; - size = term.col - src; - line = term.line[term.c.y]; - - memmove(&line[dst], &line[src], size * sizeof(Glyph)); - tclearregion(term.col-n, term.c.y, term.col-1, term.c.y); -} - -void -tinsertblank(int n) -{ - int dst, src, size; - Glyph *line; - - LIMIT(n, 0, term.col - term.c.x); - - dst = term.c.x + n; - src = term.c.x; - size = term.col - dst; - line = term.line[term.c.y]; - - memmove(&line[dst], &line[src], size * sizeof(Glyph)); - tclearregion(src, term.c.y, dst - 1, term.c.y); -} - -void -tinsertblankline(int n) -{ - if (BETWEEN(term.c.y, term.top, term.bot)) - tscrolldown(term.c.y, n, 0); -} - -void -tdeleteline(int n) -{ - if (BETWEEN(term.c.y, term.top, term.bot)) - tscrollup(term.c.y, n, 0); -} - -int32_t -tdefcolor(int *attr, int *npar, int l) -{ - int32_t idx = -1; - uint r, g, b; - - switch (attr[*npar + 1]) { - case 2: /* direct color in RGB space */ - if (*npar + 4 >= l) { - fprintf(stderr, - "erresc(38): Incorrect number of parameters (%d)\n", - *npar); - break; - } - r = attr[*npar + 2]; - g = attr[*npar + 3]; - b = attr[*npar + 4]; - *npar += 4; - if (!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255)) - fprintf(stderr, "erresc: bad rgb color (%u,%u,%u)\n", - r, g, b); - else - idx = TRUECOLOR(r, g, b); - break; - case 5: /* indexed color */ - if (*npar + 2 >= l) { - fprintf(stderr, - "erresc(38): Incorrect number of parameters (%d)\n", - *npar); - break; - } - *npar += 2; - if (!BETWEEN(attr[*npar], 0, 255)) - fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]); - else - idx = attr[*npar]; - break; - case 0: /* implemented defined (only foreground) */ - case 1: /* transparent */ - case 3: /* direct color in CMY space */ - case 4: /* direct color in CMYK space */ - default: - fprintf(stderr, - "erresc(38): gfx attr %d unknown\n", attr[*npar]); - break; - } - - return idx; -} - -void -tsetattr(int *attr, int l) -{ - int i; - int32_t idx; - - for (i = 0; i < l; i++) { - switch (attr[i]) { - case 0: - term.c.attr.mode &= ~( - ATTR_BOLD | - ATTR_FAINT | - ATTR_ITALIC | - ATTR_UNDERLINE | - ATTR_BLINK | - ATTR_REVERSE | - ATTR_INVISIBLE | - ATTR_STRUCK ); - term.c.attr.fg = defaultfg; - term.c.attr.bg = defaultbg; - break; - case 1: - term.c.attr.mode |= ATTR_BOLD; - break; - case 2: - term.c.attr.mode |= ATTR_FAINT; - break; - case 3: - term.c.attr.mode |= ATTR_ITALIC; - break; - case 4: - term.c.attr.mode |= ATTR_UNDERLINE; - break; - case 5: /* slow blink */ - /* FALLTHROUGH */ - case 6: /* rapid blink */ - term.c.attr.mode |= ATTR_BLINK; - break; - case 7: - term.c.attr.mode |= ATTR_REVERSE; - break; - case 8: - term.c.attr.mode |= ATTR_INVISIBLE; - break; - case 9: - term.c.attr.mode |= ATTR_STRUCK; - break; - case 22: - term.c.attr.mode &= ~(ATTR_BOLD | ATTR_FAINT); - break; - case 23: - term.c.attr.mode &= ~ATTR_ITALIC; - break; - case 24: - term.c.attr.mode &= ~ATTR_UNDERLINE; - break; - case 25: - term.c.attr.mode &= ~ATTR_BLINK; - break; - case 27: - term.c.attr.mode &= ~ATTR_REVERSE; - break; - case 28: - term.c.attr.mode &= ~ATTR_INVISIBLE; - break; - case 29: - term.c.attr.mode &= ~ATTR_STRUCK; - break; - case 38: - if ((idx = tdefcolor(attr, &i, l)) >= 0) - term.c.attr.fg = idx; - break; - case 39: - term.c.attr.fg = defaultfg; - break; - case 48: - if ((idx = tdefcolor(attr, &i, l)) >= 0) - term.c.attr.bg = idx; - break; - case 49: - term.c.attr.bg = defaultbg; - break; - default: - if (BETWEEN(attr[i], 30, 37)) { - term.c.attr.fg = attr[i] - 30; - } else if (BETWEEN(attr[i], 40, 47)) { - term.c.attr.bg = attr[i] - 40; - } else if (BETWEEN(attr[i], 90, 97)) { - term.c.attr.fg = attr[i] - 90 + 8; - } else if (BETWEEN(attr[i], 100, 107)) { - term.c.attr.bg = attr[i] - 100 + 8; - } else { - fprintf(stderr, - "erresc(default): gfx attr %d unknown\n", - attr[i]); - csidump(); - } - break; - } - } -} - -void -tsetscroll(int t, int b) -{ - int temp; - - LIMIT(t, 0, term.row-1); - LIMIT(b, 0, term.row-1); - if (t > b) { - temp = t; - t = b; - b = temp; - } - term.top = t; - term.bot = b; -} - -void -tsetmode(int priv, int set, int *args, int narg) -{ - int alt, *lim; - - for (lim = args + narg; args < lim; ++args) { - if (priv) { - switch (*args) { - case 1: /* DECCKM -- Cursor key */ - xsetmode(set, MODE_APPCURSOR); - break; - case 5: /* DECSCNM -- Reverse video */ - xsetmode(set, MODE_REVERSE); - break; - case 6: /* DECOM -- Origin */ - MODBIT(term.c.state, set, CURSOR_ORIGIN); - tmoveato(0, 0); - break; - case 7: /* DECAWM -- Auto wrap */ - MODBIT(term.mode, set, MODE_WRAP); - break; - case 0: /* Error (IGNORED) */ - case 2: /* DECANM -- ANSI/VT52 (IGNORED) */ - case 3: /* DECCOLM -- Column (IGNORED) */ - case 4: /* DECSCLM -- Scroll (IGNORED) */ - case 8: /* DECARM -- Auto repeat (IGNORED) */ - case 18: /* DECPFF -- Printer feed (IGNORED) */ - case 19: /* DECPEX -- Printer extent (IGNORED) */ - case 42: /* DECNRCM -- National characters (IGNORED) */ - case 12: /* att610 -- Start blinking cursor (IGNORED) */ - break; - case 25: /* DECTCEM -- Text Cursor Enable Mode */ - xsetmode(!set, MODE_HIDE); - break; - case 9: /* X10 mouse compatibility mode */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEX10); - break; - case 1000: /* 1000: report button press */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEBTN); - break; - case 1002: /* 1002: report motion on button press */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEMOTION); - break; - case 1003: /* 1003: enable all mouse motions */ - xsetpointermotion(set); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEMANY); - break; - case 1004: /* 1004: send focus events to tty */ - xsetmode(set, MODE_FOCUS); - break; - case 1006: /* 1006: extended reporting mode */ - xsetmode(set, MODE_MOUSESGR); - break; - case 1034: - xsetmode(set, MODE_8BIT); - break; - case 1049: /* swap screen & set/restore cursor as xterm */ - if (!allowaltscreen) - break; - tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); - /* FALLTHROUGH */ - case 47: /* swap screen */ - case 1047: - if (!allowaltscreen) - break; - alt = IS_SET(MODE_ALTSCREEN); - if (alt) { - tclearregion(0, 0, term.col-1, - term.row-1); - } - if (set ^ alt) /* set is always 1 or 0 */ - tswapscreen(); - if (*args != 1049) - break; - /* FALLTHROUGH */ - case 1048: - tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); - break; - case 2004: /* 2004: bracketed paste mode */ - xsetmode(set, MODE_BRCKTPASTE); - break; - /* Not implemented mouse modes. See comments there. */ - case 1001: /* mouse highlight mode; can hang the - terminal by design when implemented. */ - case 1005: /* UTF-8 mouse mode; will confuse - applications not supporting UTF-8 - and luit. */ - case 1015: /* urxvt mangled mouse mode; incompatible - and can be mistaken for other control - codes. */ - break; - default: - fprintf(stderr, - "erresc: unknown private set/reset mode %d\n", - *args); - break; - } - } else { - switch (*args) { - case 0: /* Error (IGNORED) */ - break; - case 2: - xsetmode(set, MODE_KBDLOCK); - break; - case 4: /* IRM -- Insertion-replacement */ - MODBIT(term.mode, set, MODE_INSERT); - break; - case 12: /* SRM -- Send/Receive */ - MODBIT(term.mode, !set, MODE_ECHO); - break; - case 20: /* LNM -- Linefeed/new line */ - MODBIT(term.mode, set, MODE_CRLF); - break; - default: - fprintf(stderr, - "erresc: unknown set/reset mode %d\n", - *args); - break; - } - } - } -} - -void -csihandle(void) -{ - char buf[40]; - int len; - - switch (csiescseq.mode[0]) { - default: - unknown: - fprintf(stderr, "erresc: unknown csi "); - csidump(); - /* die(""); */ - break; - case '@': /* ICH -- Insert blank char */ - DEFAULT(csiescseq.arg[0], 1); - tinsertblank(csiescseq.arg[0]); - break; - case 'A': /* CUU -- Cursor Up */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x, term.c.y-csiescseq.arg[0]); - break; - case 'B': /* CUD -- Cursor Down */ - case 'e': /* VPR --Cursor Down */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x, term.c.y+csiescseq.arg[0]); - break; - case 'i': /* MC -- Media Copy */ - switch (csiescseq.arg[0]) { - case 0: - tdump(); - break; - case 1: - tdumpline(term.c.y); - break; - case 2: - tdumpsel(); - break; - case 4: - term.mode &= ~MODE_PRINT; - break; - case 5: - term.mode |= MODE_PRINT; - break; - } - break; - case 'c': /* DA -- Device Attributes */ - if (csiescseq.arg[0] == 0) - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 'C': /* CUF -- Cursor Forward */ - case 'a': /* HPR -- Cursor Forward */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x+csiescseq.arg[0], term.c.y); - break; - case 'D': /* CUB -- Cursor Backward */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x-csiescseq.arg[0], term.c.y); - break; - case 'E': /* CNL -- Cursor Down and first col */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(0, term.c.y+csiescseq.arg[0]); - break; - case 'F': /* CPL -- Cursor Up and first col */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(0, term.c.y-csiescseq.arg[0]); - break; - case 'g': /* TBC -- Tabulation clear */ - switch (csiescseq.arg[0]) { - case 0: /* clear current tab stop */ - term.tabs[term.c.x] = 0; - break; - case 3: /* clear all the tabs */ - memset(term.tabs, 0, term.col * sizeof(*term.tabs)); - break; - default: - goto unknown; - } - break; - case 'G': /* CHA -- Move to */ - case '`': /* HPA */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(csiescseq.arg[0]-1, term.c.y); - break; - case 'H': /* CUP -- Move to */ - case 'f': /* HVP */ - DEFAULT(csiescseq.arg[0], 1); - DEFAULT(csiescseq.arg[1], 1); - tmoveato(csiescseq.arg[1]-1, csiescseq.arg[0]-1); - break; - case 'I': /* CHT -- Cursor Forward Tabulation tab stops */ - DEFAULT(csiescseq.arg[0], 1); - tputtab(csiescseq.arg[0]); - break; - case 'J': /* ED -- Clear screen */ - switch (csiescseq.arg[0]) { - case 0: /* below */ - tclearregion(term.c.x, term.c.y, term.col-1, term.c.y); - if (term.c.y < term.row-1) { - tclearregion(0, term.c.y+1, term.col-1, - term.row-1); - } - break; - case 1: /* above */ - if (term.c.y > 1) - tclearregion(0, 0, term.col-1, term.c.y-1); - tclearregion(0, term.c.y, term.c.x, term.c.y); - break; - case 2: /* all */ - tclearregion(0, 0, term.col-1, term.row-1); - break; - default: - goto unknown; - } - break; - case 'K': /* EL -- Clear line */ - switch (csiescseq.arg[0]) { - case 0: /* right */ - tclearregion(term.c.x, term.c.y, term.col-1, - term.c.y); - break; - case 1: /* left */ - tclearregion(0, term.c.y, term.c.x, term.c.y); - break; - case 2: /* all */ - tclearregion(0, term.c.y, term.col-1, term.c.y); - break; - } - break; - case 'S': /* SU -- Scroll line up */ - DEFAULT(csiescseq.arg[0], 1); - tscrollup(term.top, csiescseq.arg[0], 0); - break; - case 'T': /* SD -- Scroll line down */ - DEFAULT(csiescseq.arg[0], 1); - tscrolldown(term.top, csiescseq.arg[0], 0); - break; - case 'L': /* IL -- Insert blank lines */ - DEFAULT(csiescseq.arg[0], 1); - tinsertblankline(csiescseq.arg[0]); - break; - case 'l': /* RM -- Reset Mode */ - tsetmode(csiescseq.priv, 0, csiescseq.arg, csiescseq.narg); - break; - case 'M': /* DL -- Delete lines */ - DEFAULT(csiescseq.arg[0], 1); - tdeleteline(csiescseq.arg[0]); - break; - case 'X': /* ECH -- Erase char */ - DEFAULT(csiescseq.arg[0], 1); - tclearregion(term.c.x, term.c.y, - term.c.x + csiescseq.arg[0] - 1, term.c.y); - break; - case 'P': /* DCH -- Delete char */ - DEFAULT(csiescseq.arg[0], 1); - tdeletechar(csiescseq.arg[0]); - break; - case 'Z': /* CBT -- Cursor Backward Tabulation tab stops */ - DEFAULT(csiescseq.arg[0], 1); - tputtab(-csiescseq.arg[0]); - break; - case 'd': /* VPA -- Move to */ - DEFAULT(csiescseq.arg[0], 1); - tmoveato(term.c.x, csiescseq.arg[0]-1); - break; - case 'h': /* SM -- Set terminal mode */ - tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg); - break; - case 'm': /* SGR -- Terminal attribute (color) */ - tsetattr(csiescseq.arg, csiescseq.narg); - break; - case 'n': /* DSR – Device Status Report (cursor position) */ - if (csiescseq.arg[0] == 6) { - len = snprintf(buf, sizeof(buf),"\033[%i;%iR", - term.c.y+1, term.c.x+1); - ttywrite(buf, len, 0); - } - break; - case 'r': /* DECSTBM -- Set Scrolling Region */ - if (csiescseq.priv) { - goto unknown; - } else { - DEFAULT(csiescseq.arg[0], 1); - DEFAULT(csiescseq.arg[1], term.row); - tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1); - tmoveato(0, 0); - } - break; - case 's': /* DECSC -- Save cursor position (ANSI.SYS) */ - tcursor(CURSOR_SAVE); - break; - case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ - tcursor(CURSOR_LOAD); - break; - case ' ': - switch (csiescseq.mode[1]) { - case 'q': /* DECSCUSR -- Set Cursor Style */ - if (xsetcursor(csiescseq.arg[0])) - goto unknown; - break; - default: - goto unknown; - } - break; - } -} - -void -csidump(void) -{ - int i; - uint c; - - fprintf(stderr, "ESC["); - for (i = 0; i < csiescseq.len; i++) { - c = csiescseq.buf[i] & 0xff; - if (isprint(c)) { - putc(c, stderr); - } else if (c == '\n') { - fprintf(stderr, "(\\n)"); - } else if (c == '\r') { - fprintf(stderr, "(\\r)"); - } else if (c == 0x1b) { - fprintf(stderr, "(\\e)"); - } else { - fprintf(stderr, "(%02x)", c); - } - } - putc('\n', stderr); -} - -void -csireset(void) -{ - memset(&csiescseq, 0, sizeof(csiescseq)); -} - -void -strhandle(void) -{ - char *p = NULL, *dec; - int j, narg, par; - - term.esc &= ~(ESC_STR_END|ESC_STR); - strparse(); - par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0; - - switch (strescseq.type) { - case ']': /* OSC -- Operating System Command */ - switch (par) { - case 0: - case 1: - case 2: - if (narg > 1) - xsettitle(strescseq.args[1]); - return; - case 52: - if (narg > 2) { - dec = base64dec(strescseq.args[2]); - if (dec) { - xsetsel(dec); - xclipcopy(); - } else { - fprintf(stderr, "erresc: invalid base64\n"); - } - } - return; - case 4: /* color set */ - case 10: /* foreground set */ - case 11: /* background set */ - case 12: /* cursor color */ - if ((par == 4 && narg < 3) || narg < 2) - break; - p = strescseq.args[((par == 4) ? 2 : 1)]; - /* FALLTHROUGH */ - case 104: /* color reset, here p = NULL */ - if (par == 10) - j = defaultfg; - else if (par == 11) - j = defaultbg; - else if (par == 12) - j = defaultcs; - else - j = (narg > 1) ? atoi(strescseq.args[1]) : -1; - - if (xsetcolorname(j, p)) { - if (par == 104 && narg <= 1) - return; /* color reset without parameter */ - fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", - j, p ? p : "(null)"); - } else { - /* - * TODO if defaultbg color is changed, borders - * are dirty - */ - if (j == defaultbg) - xclearwin(); - redraw(); - } - return; - } - break; - case 'k': /* old title set compatibility */ - xsettitle(strescseq.args[0]); - return; - case 'P': /* DCS -- Device Control String */ - term.mode |= ESC_DCS; - case '_': /* APC -- Application Program Command */ - case '^': /* PM -- Privacy Message */ - return; - } - - fprintf(stderr, "erresc: unknown str "); - strdump(); -} - -void -strparse(void) -{ - int c; - char *p = strescseq.buf; - - strescseq.narg = 0; - strescseq.buf[strescseq.len] = '\0'; - - if (*p == '\0') - return; - - while (strescseq.narg < STR_ARG_SIZ) { - strescseq.args[strescseq.narg++] = p; - while ((c = *p) != ';' && c != '\0') - ++p; - if (c == '\0') - return; - *p++ = '\0'; - } -} - -void -strdump(void) -{ - int i; - uint c; - - fprintf(stderr, "ESC%c", strescseq.type); - for (i = 0; i < strescseq.len; i++) { - c = strescseq.buf[i] & 0xff; - if (c == '\0') { - putc('\n', stderr); - return; - } else if (isprint(c)) { - putc(c, stderr); - } else if (c == '\n') { - fprintf(stderr, "(\\n)"); - } else if (c == '\r') { - fprintf(stderr, "(\\r)"); - } else if (c == 0x1b) { - fprintf(stderr, "(\\e)"); - } else { - fprintf(stderr, "(%02x)", c); - } - } - fprintf(stderr, "ESC\\\n"); -} - -void -strreset(void) -{ - memset(&strescseq, 0, sizeof(strescseq)); -} - -void -sendbreak(const Arg *arg) -{ - if (tcsendbreak(cmdfd, 0)) - perror("Error sending break"); -} - -void -tprinter(char *s, size_t len) -{ - if (iofd != -1 && xwrite(iofd, s, len) < 0) { - perror("Error writing to output file"); - close(iofd); - iofd = -1; - } -} - -void -externalpipe(const Arg *arg) -{ - int to[2]; - char buf[UTF_SIZ]; - void (*oldsigpipe)(int); - Glyph *bp, *end; - int lastpos, n, newline; - - if (pipe(to) == -1) - return; - - switch (fork()) { - case -1: - close(to[0]); - close(to[1]); - return; - case 0: - dup2(to[0], STDIN_FILENO); - close(to[0]); - close(to[1]); - execvp(((char **)arg->v)[0], (char **)arg->v); - fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]); - perror("failed"); - exit(0); - } - - close(to[0]); - /* ignore sigpipe for now, in case child exists early */ - oldsigpipe = signal(SIGPIPE, SIG_IGN); - newline = 0; - /* modify externalpipe patch to pipe history too */ - for (n = 0; n <= HISTSIZE + 2; n++) { - bp = TLINE_HIST(n); - lastpos = MIN(tlinehistlen(n) +1, term.col) - 1; - if (lastpos < 0) - break; - if (lastpos == 0) - continue; - end = &bp[lastpos + 1]; - for (; bp < end; ++bp) - if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) - break; - if ((newline = TLINE_HIST(n)[lastpos].mode & ATTR_WRAP)) - continue; - if (xwrite(to[1], "\n", 1) < 0) - break; - newline = 0; - } - if (newline) - (void)xwrite(to[1], "\n", 1); - close(to[1]); - /* restore */ - signal(SIGPIPE, oldsigpipe); -} - -void -iso14755(const Arg *arg) -{ - FILE *p; - char *us, *e, codepoint[9], uc[UTF_SIZ]; - unsigned long utf32; - - if (!(p = popen(ISO14755CMD, "r"))) - return; - - us = fgets(codepoint, sizeof(codepoint), p); - pclose(p); - - if (!us || *us == '\0' || *us == '-' || strlen(us) > 7) - return; - if ((utf32 = strtoul(us, &e, 16)) == ULONG_MAX || - (*e != '\n' && *e != '\0')) - return; - - ttywrite(uc, utf8encode(utf32, uc), 1); -} - -void -toggleprinter(const Arg *arg) -{ - term.mode ^= MODE_PRINT; -} - -void -printscreen(const Arg *arg) -{ - tdump(); -} - -void -printsel(const Arg *arg) -{ - tdumpsel(); -} - -void -tdumpsel(void) -{ - char *ptr; - - if ((ptr = getsel())) { - tprinter(ptr, strlen(ptr)); - free(ptr); - } -} - -void -tdumpline(int n) -{ - char buf[UTF_SIZ]; - Glyph *bp, *end; - - bp = &term.line[n][0]; - end = &bp[MIN(tlinelen(n), term.col) - 1]; - if (bp != end || bp->u != ' ') { - for ( ;bp <= end; ++bp) - tprinter(buf, utf8encode(bp->u, buf)); - } - tprinter("\n", 1); -} - -void -tdump(void) -{ - int i; - - for (i = 0; i < term.row; ++i) - tdumpline(i); -} - -void -tputtab(int n) -{ - uint x = term.c.x; - - if (n > 0) { - while (x < term.col && n--) - for (++x; x < term.col && !term.tabs[x]; ++x) - /* nothing */ ; - } else if (n < 0) { - while (x > 0 && n++) - for (--x; x > 0 && !term.tabs[x]; --x) - /* nothing */ ; - } - term.c.x = LIMIT(x, 0, term.col-1); -} - -void -tdefutf8(char ascii) -{ - if (ascii == 'G') - term.mode |= MODE_UTF8; - else if (ascii == '@') - term.mode &= ~MODE_UTF8; -} - -void -tdeftran(char ascii) -{ - static char cs[] = "0B"; - static int vcs[] = {CS_GRAPHIC0, CS_USA}; - char *p; - - if ((p = strchr(cs, ascii)) == NULL) { - fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii); - } else { - term.trantbl[term.icharset] = vcs[p - cs]; - } -} - -void -tdectest(char c) -{ - int x, y; - - if (c == '8') { /* DEC screen alignment test. */ - for (x = 0; x < term.col; ++x) { - for (y = 0; y < term.row; ++y) - tsetchar('E', &term.c.attr, x, y); - } - } -} - -void -tstrsequence(uchar c) -{ - strreset(); - - switch (c) { - case 0x90: /* DCS -- Device Control String */ - c = 'P'; - term.esc |= ESC_DCS; - break; - case 0x9f: /* APC -- Application Program Command */ - c = '_'; - break; - case 0x9e: /* PM -- Privacy Message */ - c = '^'; - break; - case 0x9d: /* OSC -- Operating System Command */ - c = ']'; - break; - } - strescseq.type = c; - term.esc |= ESC_STR; -} - -void -tcontrolcode(uchar ascii) -{ - switch (ascii) { - case '\t': /* HT */ - tputtab(1); - return; - case '\b': /* BS */ - tmoveto(term.c.x-1, term.c.y); - return; - case '\r': /* CR */ - tmoveto(0, term.c.y); - return; - case '\f': /* LF */ - case '\v': /* VT */ - case '\n': /* LF */ - /* go to first col if the mode is set */ - tnewline(IS_SET(MODE_CRLF)); - return; - case '\a': /* BEL */ - if (term.esc & ESC_STR_END) { - /* backwards compatibility to xterm */ - strhandle(); - } else { - xbell(); - } - break; - case '\033': /* ESC */ - csireset(); - term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST); - term.esc |= ESC_START; - return; - case '\016': /* SO (LS1 -- Locking shift 1) */ - case '\017': /* SI (LS0 -- Locking shift 0) */ - term.charset = 1 - (ascii - '\016'); - return; - case '\032': /* SUB */ - tsetchar('?', &term.c.attr, term.c.x, term.c.y); - case '\030': /* CAN */ - csireset(); - break; - case '\005': /* ENQ (IGNORED) */ - case '\000': /* NUL (IGNORED) */ - case '\021': /* XON (IGNORED) */ - case '\023': /* XOFF (IGNORED) */ - case 0177: /* DEL (IGNORED) */ - return; - case 0x80: /* TODO: PAD */ - case 0x81: /* TODO: HOP */ - case 0x82: /* TODO: BPH */ - case 0x83: /* TODO: NBH */ - case 0x84: /* TODO: IND */ - break; - case 0x85: /* NEL -- Next line */ - tnewline(1); /* always go to first col */ - break; - case 0x86: /* TODO: SSA */ - case 0x87: /* TODO: ESA */ - break; - case 0x88: /* HTS -- Horizontal tab stop */ - term.tabs[term.c.x] = 1; - break; - case 0x89: /* TODO: HTJ */ - case 0x8a: /* TODO: VTS */ - case 0x8b: /* TODO: PLD */ - case 0x8c: /* TODO: PLU */ - case 0x8d: /* TODO: RI */ - case 0x8e: /* TODO: SS2 */ - case 0x8f: /* TODO: SS3 */ - case 0x91: /* TODO: PU1 */ - case 0x92: /* TODO: PU2 */ - case 0x93: /* TODO: STS */ - case 0x94: /* TODO: CCH */ - case 0x95: /* TODO: MW */ - case 0x96: /* TODO: SPA */ - case 0x97: /* TODO: EPA */ - case 0x98: /* TODO: SOS */ - case 0x99: /* TODO: SGCI */ - break; - case 0x9a: /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 0x9b: /* TODO: CSI */ - case 0x9c: /* TODO: ST */ - break; - case 0x90: /* DCS -- Device Control String */ - case 0x9d: /* OSC -- Operating System Command */ - case 0x9e: /* PM -- Privacy Message */ - case 0x9f: /* APC -- Application Program Command */ - tstrsequence(ascii); - return; - } - /* only CAN, SUB, \a and C1 chars interrupt a sequence */ - term.esc &= ~(ESC_STR_END|ESC_STR); -} - -/* - * returns 1 when the sequence is finished and it hasn't to read - * more characters for this sequence, otherwise 0 - */ -int -eschandle(uchar ascii) -{ - switch (ascii) { - case '[': - term.esc |= ESC_CSI; - return 0; - case '#': - term.esc |= ESC_TEST; - return 0; - case '%': - term.esc |= ESC_UTF8; - return 0; - case 'P': /* DCS -- Device Control String */ - case '_': /* APC -- Application Program Command */ - case '^': /* PM -- Privacy Message */ - case ']': /* OSC -- Operating System Command */ - case 'k': /* old title set compatibility */ - tstrsequence(ascii); - return 0; - case 'n': /* LS2 -- Locking shift 2 */ - case 'o': /* LS3 -- Locking shift 3 */ - term.charset = 2 + (ascii - 'n'); - break; - case '(': /* GZD4 -- set primary charset G0 */ - case ')': /* G1D4 -- set secondary charset G1 */ - case '*': /* G2D4 -- set tertiary charset G2 */ - case '+': /* G3D4 -- set quaternary charset G3 */ - term.icharset = ascii - '('; - term.esc |= ESC_ALTCHARSET; - return 0; - case 'D': /* IND -- Linefeed */ - if (term.c.y == term.bot) { - tscrollup(term.top, 1, 1); - } else { - tmoveto(term.c.x, term.c.y+1); - } - break; - case 'E': /* NEL -- Next line */ - tnewline(1); /* always go to first col */ - break; - case 'H': /* HTS -- Horizontal tab stop */ - term.tabs[term.c.x] = 1; - break; - case 'M': /* RI -- Reverse index */ - if (term.c.y == term.top) { - tscrolldown(term.top, 1, 1); - } else { - tmoveto(term.c.x, term.c.y-1); - } - break; - case 'Z': /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 'c': /* RIS -- Reset to initial state */ - treset(); - resettitle(); - xloadcols(); - break; - case '=': /* DECPAM -- Application keypad */ - xsetmode(1, MODE_APPKEYPAD); - break; - case '>': /* DECPNM -- Normal keypad */ - xsetmode(0, MODE_APPKEYPAD); - break; - case '7': /* DECSC -- Save Cursor */ - tcursor(CURSOR_SAVE); - break; - case '8': /* DECRC -- Restore Cursor */ - tcursor(CURSOR_LOAD); - break; - case '\\': /* ST -- String Terminator */ - if (term.esc & ESC_STR_END) - strhandle(); - break; - default: - fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", - (uchar) ascii, isprint(ascii)? ascii:'.'); - break; - } - return 1; -} - -void -tputc(Rune u) -{ - char c[UTF_SIZ]; - int control; - int width, len; - Glyph *gp; - - control = ISCONTROL(u); - if (!IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { - c[0] = u; - width = len = 1; - } else { - len = utf8encode(u, c); - if (!control && (width = wcwidth(u)) == -1) { - memcpy(c, "\357\277\275", 4); /* UTF_INVALID */ - width = 1; - } - } - - if (IS_SET(MODE_PRINT)) - tprinter(c, len); - - /* - * STR sequence must be checked before anything else - * because it uses all following characters until it - * receives a ESC, a SUB, a ST or any other C1 control - * character. - */ - if (term.esc & ESC_STR) { - if (u == '\a' || u == 030 || u == 032 || u == 033 || - ISCONTROLC1(u)) { - term.esc &= ~(ESC_START|ESC_STR|ESC_DCS); - if (IS_SET(MODE_SIXEL)) { - /* TODO: render sixel */; - term.mode &= ~MODE_SIXEL; - return; - } - term.esc |= ESC_STR_END; - goto check_control_code; - } - - if (IS_SET(MODE_SIXEL)) { - /* TODO: implement sixel mode */ - return; - } - if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') - term.mode |= MODE_SIXEL; - - if (strescseq.len+len >= sizeof(strescseq.buf)-1) { - /* - * Here is a bug in terminals. If the user never sends - * some code to stop the str or esc command, then st - * will stop responding. But this is better than - * silently failing with unknown characters. At least - * then users will report back. - * - * In the case users ever get fixed, here is the code: - */ - /* - * term.esc = 0; - * strhandle(); - */ - return; - } - - memmove(&strescseq.buf[strescseq.len], c, len); - strescseq.len += len; - return; - } - -check_control_code: - /* - * Actions of control codes must be performed as soon they arrive - * because they can be embedded inside a control sequence, and - * they must not cause conflicts with sequences. - */ - if (control) { - tcontrolcode(u); - /* - * control codes are not shown ever - */ - return; - } else if (term.esc & ESC_START) { - if (term.esc & ESC_CSI) { - csiescseq.buf[csiescseq.len++] = u; - if (BETWEEN(u, 0x40, 0x7E) - || csiescseq.len >= \ - sizeof(csiescseq.buf)-1) { - term.esc = 0; - csiparse(); - csihandle(); - } - return; - } else if (term.esc & ESC_UTF8) { - tdefutf8(u); - } else if (term.esc & ESC_ALTCHARSET) { - tdeftran(u); - } else if (term.esc & ESC_TEST) { - tdectest(u); - } else { - if (!eschandle(u)) - return; - /* sequence already finished */ - } - term.esc = 0; - /* - * All characters which form part of a sequence are not - * printed - */ - return; - } - if (sel.ob.x != -1 && BETWEEN(term.c.y, sel.ob.y, sel.oe.y)) - selclear(); - - gp = &term.line[term.c.y][term.c.x]; - if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) { - gp->mode |= ATTR_WRAP; - tnewline(1); - gp = &term.line[term.c.y][term.c.x]; - } - - if (IS_SET(MODE_INSERT) && term.c.x+width < term.col) - memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph)); - - if (term.c.x+width > term.col) { - tnewline(1); - gp = &term.line[term.c.y][term.c.x]; - } - - tsetchar(u, &term.c.attr, term.c.x, term.c.y); - - if (width == 2) { - gp->mode |= ATTR_WIDE; - if (term.c.x+1 < term.col) { - gp[1].u = '\0'; - gp[1].mode = ATTR_WDUMMY; - } - } - if (term.c.x+width < term.col) { - tmoveto(term.c.x+width, term.c.y); - } else { - term.c.state |= CURSOR_WRAPNEXT; - } -} - -int -twrite(const char *buf, int buflen, int show_ctrl) -{ - int charsize; - Rune u; - int n; - - for (n = 0; n < buflen; n += charsize) { - if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { - /* process a complete utf8 char */ - charsize = utf8decode(buf + n, &u, buflen - n); - if (charsize == 0) - break; - } else { - u = buf[n] & 0xFF; - charsize = 1; - } - if (show_ctrl && ISCONTROL(u)) { - if (u & 0x80) { - u &= 0x7f; - tputc('^'); - tputc('['); - } else if (u != '\n' && u != '\r' && u != '\t') { - u ^= 0x40; - tputc('^'); - } - } - tputc(u); - } - return n; -} - -void -tresize(int col, int row) -{ - int i, j; - int minrow = MIN(row, term.row); - int mincol = MIN(col, term.col); - int *bp; - TCursor c; - - if (col < 1 || row < 1) { - fprintf(stderr, - "tresize: error resizing to %dx%d\n", col, row); - return; - } - - /* - * slide screen to keep cursor where we expect it - - * tscrollup would work here, but we can optimize to - * memmove because we're freeing the earlier lines - */ - for (i = 0; i <= term.c.y - row; i++) { - free(term.line[i]); - free(term.alt[i]); - } - /* ensure that both src and dst are not NULL */ - if (i > 0) { - memmove(term.line, term.line + i, row * sizeof(Line)); - memmove(term.alt, term.alt + i, row * sizeof(Line)); - } - for (i += row; i < term.row; i++) { - free(term.line[i]); - free(term.alt[i]); - } - - /* resize to new height */ - term.line = xrealloc(term.line, row * sizeof(Line)); - term.alt = xrealloc(term.alt, row * sizeof(Line)); - term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); - term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); - - for (i = 0; i < HISTSIZE; i++) { - term.hist[i] = xrealloc(term.hist[i], col * sizeof(Glyph)); - for (j = mincol; j < col; j++) { - term.hist[i][j] = term.c.attr; - term.hist[i][j].u = ' '; - } - } - - /* resize each row to new width, zero-pad if needed */ - for (i = 0; i < minrow; i++) { - term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); - term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph)); - } - - /* allocate any new rows */ - for (/* i = minrow */; i < row; i++) { - term.line[i] = xmalloc(col * sizeof(Glyph)); - term.alt[i] = xmalloc(col * sizeof(Glyph)); - } - if (col > term.col) { - bp = term.tabs + term.col; - - memset(bp, 0, sizeof(*term.tabs) * (col - term.col)); - while (--bp > term.tabs && !*bp) - /* nothing */ ; - for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces) - *bp = 1; - } - /* update terminal size */ - term.col = col; - term.row = row; - /* reset scrolling region */ - tsetscroll(0, row-1); - /* make use of the LIMIT in tmoveto */ - tmoveto(term.c.x, term.c.y); - /* Clearing both screens (it makes dirty all lines) */ - c = term.c; - for (i = 0; i < 2; i++) { - if (mincol < col && 0 < minrow) { - tclearregion(mincol, 0, col - 1, minrow - 1); - } - if (0 < col && minrow < row) { - tclearregion(0, minrow, col - 1, row - 1); - } - tswapscreen(); - tcursor(CURSOR_LOAD); - } - term.c = c; -} - -void -resettitle(void) -{ - xsettitle(NULL); -} - -void -drawregion(int x1, int y1, int x2, int y2) -{ - int y; - for (y = y1; y < y2; y++) { - if (!term.dirty[y]) - continue; - - term.dirty[y] = 0; - xdrawline(TLINE(y), x1, y, x2); - } -} - -void -draw(void) -{ - int cx = term.c.x; - - if (!xstartdraw()) - return; - - /* adjust cursor position */ - LIMIT(term.ocx, 0, term.col-1); - LIMIT(term.ocy, 0, term.row-1); - if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY) - term.ocx--; - if (term.line[term.c.y][cx].mode & ATTR_WDUMMY) - cx--; - - drawregion(0, 0, term.col, term.row); - if (term.scr == 0) - xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], - term.ocx, term.ocy, term.line[term.ocy][term.ocx]); - term.ocx = cx, term.ocy = term.c.y; - xfinishdraw(); - - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - if (ximspot_update_interval && TIMEDIFF(now, term.last_ximspot_update) > ximspot_update_interval) { - xximspot(term.ocx, term.ocy); - term.last_ximspot_update = now; - } -} - -void -redraw(void) -{ - tfulldirt(); - draw(); -} diff --git a/.config/st/st.h b/.config/st/st.h deleted file mode 100644 index b85474b..0000000 --- a/.config/st/st.h +++ /dev/null @@ -1,153 +0,0 @@ -/* See LICENSE for license details. */ - -#include -#include - -/* macros */ -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a) / sizeof(a)[0]) -#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) -#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) -#define DEFAULT(a, b) (a) = (a) ? (a) : (b) -#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) -#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ - (a).bg != (b).bg) -#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ - (t1.tv_nsec-t2.tv_nsec)/1E6) -#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) - -#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) -#define IS_TRUECOL(x) (1 << 24 & (x)) - -enum glyph_attribute { - ATTR_NULL = 0, - ATTR_BOLD = 1 << 0, - ATTR_FAINT = 1 << 1, - ATTR_ITALIC = 1 << 2, - ATTR_UNDERLINE = 1 << 3, - ATTR_BLINK = 1 << 4, - ATTR_REVERSE = 1 << 5, - ATTR_INVISIBLE = 1 << 6, - ATTR_STRUCK = 1 << 7, - ATTR_WRAP = 1 << 8, - ATTR_WIDE = 1 << 9, - ATTR_WDUMMY = 1 << 10, - ATTR_BOXDRAW = 1 << 11, - ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, -}; - -enum drawing_mode { - DRAW_NONE = 0, - DRAW_BG = 1 << 0, - DRAW_FG = 1 << 1, -}; - -enum selection_mode { - SEL_IDLE = 0, - SEL_EMPTY = 1, - SEL_READY = 2 -}; - -enum selection_type { - SEL_REGULAR = 1, - SEL_RECTANGULAR = 2 -}; - -enum selection_snap { - SNAP_WORD = 1, - SNAP_LINE = 2 -}; - -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned long ulong; -typedef unsigned short ushort; - -typedef uint_least32_t Rune; - -#define Glyph Glyph_ -typedef struct { - Rune u; /* character code */ - ushort mode; /* attribute flags */ - uint32_t fg; /* foreground */ - uint32_t bg; /* background */ -} Glyph; - -typedef Glyph *Line; - -typedef union { - int i; - uint ui; - float f; - const void *v; -} Arg; - -typedef struct { - uint b; - uint mask; - void (*func)(const Arg *); - const Arg arg; -} MouseKey; - -void die(const char *, ...); -void redraw(void); -void draw(void); - -void externalpipe(const Arg *); -void iso14755(const Arg *); -void kscrolldown(const Arg *); -void kscrollup(const Arg *); -void printscreen(const Arg *); -void printsel(const Arg *); -void sendbreak(const Arg *); -void toggleprinter(const Arg *); - -int tattrset(int); -void tnew(int, int); -void tresize(int, int); -void tsetdirtattr(int); -void ttyhangup(void); -int ttynew(char *, char *, char *, char **); -size_t ttyread(void); -void ttyresize(int, int); -void ttywrite(const char *, size_t, int); - -void resettitle(void); - -void selclear(void); -void selinit(void); -void selstart(int, int, int); -void selextend(int, int, int, int); -int selected(int, int); -char *getsel(void); - -size_t utf8encode(Rune, char *); - -void *xmalloc(size_t); -void *xrealloc(void *, size_t); -char *xstrdup(char *); - -int isboxdraw(Rune); -ushort boxdrawindex(const Glyph *); -#ifdef XFT_VERSION -/* only exposed to x.c, otherwise we'll need Xft.h for the types */ -void boxdraw_xinit(Display *, Colormap, XftDraw *, Visual *); -void drawboxes(int, int, int, int, XftColor *, XftColor *, const XftGlyphFontSpec *, int); -#endif - -/* config.h globals */ -extern char *utmp; -extern char *stty_args; -extern char *vtiden; -extern wchar_t *worddelimiters; -extern int allowaltscreen; -extern char *termname; -extern unsigned int tabspaces; -extern unsigned int defaultfg; -extern unsigned int defaultbg; -extern unsigned int defaultcs; -extern const int boxdraw, boxdraw_bold, boxdraw_braille; -extern float alpha; -extern MouseKey mkeys[]; -extern int ximspot_update_interval; diff --git a/.config/st/st.info b/.config/st/st.info deleted file mode 100644 index 78ffd30..0000000 --- a/.config/st/st.info +++ /dev/null @@ -1,222 +0,0 @@ -st| simpleterm, - acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, - am, - bce, - bel=^G, - blink=\E[5m, - bold=\E[1m, - cbt=\E[Z, - cvvis=\E[?25h, - civis=\E[?25l, - clear=\E[H\E[2J, - cnorm=\E[?12l\E[?25h, - colors#8, - cols#80, - cr=^M, - csr=\E[%i%p1%d;%p2%dr, - cub=\E[%p1%dD, - cub1=^H, - cud1=^J, - cud=\E[%p1%dB, - cuf1=\E[C, - cuf=\E[%p1%dC, - cup=\E[%i%p1%d;%p2%dH, - cuu1=\E[A, - cuu=\E[%p1%dA, - dch=\E[%p1%dP, - dch1=\E[P, - dim=\E[2m, - dl=\E[%p1%dM, - dl1=\E[M, - ech=\E[%p1%dX, - ed=\E[J, - el=\E[K, - el1=\E[1K, - enacs=\E)0, - flash=\E[?5h$<80/>\E[?5l, - fsl=^G, - home=\E[H, - hpa=\E[%i%p1%dG, - hs, - ht=^I, - hts=\EH, - ich=\E[%p1%d@, - il1=\E[L, - il=\E[%p1%dL, - ind=^J, - indn=\E[%p1%dS, - invis=\E[8m, - is2=\E[4l\E>\E[?1034l, - it#8, - kel=\E[1;2F, - ked=\E[1;5F, - ka1=\E[1~, - ka3=\E[5~, - kc1=\E[4~, - kc3=\E[6~, - kbs=\177, - kcbt=\E[Z, - kb2=\EOu, - kcub1=\EOD, - kcud1=\EOB, - kcuf1=\EOC, - kcuu1=\EOA, - kDC=\E[3;2~, - kent=\EOM, - kEND=\E[1;2F, - kIC=\E[2;2~, - kNXT=\E[6;2~, - kPRV=\E[5;2~, - kHOM=\E[1;2H, - kLFT=\E[1;2D, - kRIT=\E[1;2C, - kind=\E[1;2B, - kri=\E[1;2A, - kclr=\E[3;5~, - kdl1=\E[3;2~, - kdch1=\E[3~, - kich1=\E[2~, - kend=\E[4~, - kf1=\EOP, - kf2=\EOQ, - kf3=\EOR, - kf4=\EOS, - kf5=\E[15~, - kf6=\E[17~, - kf7=\E[18~, - kf8=\E[19~, - kf9=\E[20~, - kf10=\E[21~, - kf11=\E[23~, - kf12=\E[24~, - kf13=\E[1;2P, - kf14=\E[1;2Q, - kf15=\E[1;2R, - kf16=\E[1;2S, - kf17=\E[15;2~, - kf18=\E[17;2~, - kf19=\E[18;2~, - kf20=\E[19;2~, - kf21=\E[20;2~, - kf22=\E[21;2~, - kf23=\E[23;2~, - kf24=\E[24;2~, - kf25=\E[1;5P, - kf26=\E[1;5Q, - kf27=\E[1;5R, - kf28=\E[1;5S, - kf29=\E[15;5~, - kf30=\E[17;5~, - kf31=\E[18;5~, - kf32=\E[19;5~, - kf33=\E[20;5~, - kf34=\E[21;5~, - kf35=\E[23;5~, - kf36=\E[24;5~, - kf37=\E[1;6P, - kf38=\E[1;6Q, - kf39=\E[1;6R, - kf40=\E[1;6S, - kf41=\E[15;6~, - kf42=\E[17;6~, - kf43=\E[18;6~, - kf44=\E[19;6~, - kf45=\E[20;6~, - kf46=\E[21;6~, - kf47=\E[23;6~, - kf48=\E[24;6~, - kf49=\E[1;3P, - kf50=\E[1;3Q, - kf51=\E[1;3R, - kf52=\E[1;3S, - kf53=\E[15;3~, - kf54=\E[17;3~, - kf55=\E[18;3~, - kf56=\E[19;3~, - kf57=\E[20;3~, - kf58=\E[21;3~, - kf59=\E[23;3~, - kf60=\E[24;3~, - kf61=\E[1;4P, - kf62=\E[1;4Q, - kf63=\E[1;4R, - khome=\E[1~, - kil1=\E[2;5~, - krmir=\E[2;2~, - knp=\E[6~, - kmous=\E[M, - kpp=\E[5~, - lines#24, - mir, - msgr, - npc, - op=\E[39;49m, - pairs#64, - mc0=\E[i, - mc4=\E[4i, - mc5=\E[5i, - rc=\E8, - rev=\E[7m, - ri=\EM, - ritm=\E[23m, - rmacs=\E(B, - rmcup=\E[?1049l, - rmir=\E[4l, - rmkx=\E[?1l\E>, - rmso=\E[27m, - rmul=\E[24m, - rs1=\Ec, - rs2=\E[4l\E>\E[?1034l, - sc=\E7, - setab=\E[4%p1%dm, - setaf=\E[3%p1%dm, - setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, - setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, - sgr0=\E[0m, - sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m, - sitm=\E[3m, - smacs=\E(0, - smcup=\E[?1049h, - smir=\E[4h, - smkx=\E[?1h\E=, - smso=\E[7m, - smul=\E[4m, - tbc=\E[3g, - tsl=\E]0;, - xenl, - vpa=\E[%i%p1%dd, -# XTerm extensions - rmxx=\E[29m, - smxx=\E[9m, -# tmux extensions, see TERMINFO EXTENSIONS in tmux(1) - Tc, - Ms=\E]52;%p1%s;%p2%s\007, - Se=\E[2 q, - Ss=\E[%p1%d q, - -st-256color| simpleterm with 256 colors, - use=st, - ccc, - colors#256, - oc=\E]104\007, - pairs#32767, -# Nicked from xterm-256color - initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, - setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, - setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, - -st-meta| simpleterm with meta key, - use=st, - km, - rmm=\E[?1034l, - smm=\E[?1034h, - rs2=\E[4l\E>\E[?1034h, - is2=\E[4l\E>\E[?1034h, - -st-meta-256color| simpleterm with meta key and 256 colors, - use=st-256color, - km, - rmm=\E[?1034l, - smm=\E[?1034h, - rs2=\E[4l\E>\E[?1034h, - is2=\E[4l\E>\E[?1034h, diff --git a/.config/st/st.o b/.config/st/st.o deleted file mode 100644 index 38b856f571b53d4ec804717d09ec3caf2ab98a7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79456 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 KH*|A|>Hh;QG)qwc diff --git a/.config/st/win.h b/.config/st/win.h deleted file mode 100644 index d7b4980..0000000 --- a/.config/st/win.h +++ /dev/null @@ -1,40 +0,0 @@ -/* See LICENSE for license details. */ - -enum win_mode { - MODE_VISIBLE = 1 << 0, - MODE_FOCUSED = 1 << 1, - MODE_APPKEYPAD = 1 << 2, - MODE_MOUSEBTN = 1 << 3, - MODE_MOUSEMOTION = 1 << 4, - MODE_REVERSE = 1 << 5, - MODE_KBDLOCK = 1 << 6, - MODE_HIDE = 1 << 7, - MODE_APPCURSOR = 1 << 8, - MODE_MOUSESGR = 1 << 9, - MODE_8BIT = 1 << 10, - MODE_BLINK = 1 << 11, - MODE_FBLINK = 1 << 12, - MODE_FOCUS = 1 << 13, - MODE_MOUSEX10 = 1 << 14, - MODE_MOUSEMANY = 1 << 15, - MODE_BRCKTPASTE = 1 << 16, - MODE_NUMLOCK = 1 << 17, - MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ - |MODE_MOUSEMANY, -}; - -void xbell(void); -void xclipcopy(void); -void xdrawcursor(int, int, Glyph, int, int, Glyph); -void xdrawline(Line, int, int, int); -void xfinishdraw(void); -void xloadcols(void); -int xsetcolorname(int, const char *); -void xsettitle(char *); -int xsetcursor(int); -void xsetmode(int, unsigned int); -void xsetpointermotion(int); -void xsetsel(char *); -int xstartdraw(void); -void xximspot(int, int); -void xclearwin(void); diff --git a/.config/st/x.c b/.config/st/x.c deleted file mode 100644 index c1f050b..0000000 --- a/.config/st/x.c +++ /dev/null @@ -1,2208 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static char *argv0; -#include "arg.h" -#include "st.h" -#include "win.h" - -/* types used in config.h */ -typedef struct { - uint mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Shortcut; - -typedef struct { - uint b; - uint mask; - char *s; -} MouseShortcut; - -typedef struct { - KeySym k; - uint mask; - char *s; - /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ - signed char appkey; /* application keypad */ - signed char appcursor; /* application cursor */ -} Key; - -/* Xresources preferences */ -enum resource_type { - STRING = 0, - INTEGER = 1, - FLOAT = 2 -}; - -typedef struct { - char *name; - enum resource_type type; - void *dst; -} ResourcePref; - -/* X modifiers */ -#define XK_ANY_MOD UINT_MAX -#define XK_NO_MOD 0 -#define XK_SWITCH_MOD (1<<13) - -/* function definitions used in config.h */ -static void clipcopy(const Arg *); -static void clippaste(const Arg *); -static void numlock(const Arg *); -static void selpaste(const Arg *); -static void zoom(const Arg *); -static void zoomabs(const Arg *); -static void zoomreset(const Arg *); - -/* config.h for applying patches and the configuration. */ -#include "config.h" - -/* XEMBED messages */ -#define XEMBED_FOCUS_IN 4 -#define XEMBED_FOCUS_OUT 5 - -/* macros */ -#define IS_SET(flag) ((win.mode & (flag)) != 0) -#define TRUERED(x) (((x) & 0xff0000) >> 8) -#define TRUEGREEN(x) (((x) & 0xff00)) -#define TRUEBLUE(x) (((x) & 0xff) << 8) - -typedef XftDraw *Draw; -typedef XftColor Color; -typedef XftGlyphFontSpec GlyphFontSpec; - -/* Purely graphic info */ -typedef struct { - int tw, th; /* tty width and height */ - int w, h; /* window width and height */ - int hborderpx, vborderpx; - int ch; /* char height */ - int cw; /* char width */ - int cyo; /* char y offset */ - int mode; /* window state/mode flags */ - int cursor; /* cursor style */ -} TermWindow; - -typedef struct { - Display *dpy; - Colormap cmap; - Window win; - Drawable buf; - GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ - Atom xembed, wmdeletewin, netwmname, netwmpid; - XIM xim; - XIC xic; - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; - int scr; - int isfixed; /* is fixed geometry? */ - int depth; /* bit depth */ - int l, t; /* left and top offset */ - int gm; /* geometry mask */ -} XWindow; - -typedef struct { - Atom xtarget; - char *primary, *clipboard; - struct timespec tclick1; - struct timespec tclick2; -} XSelection; - -/* Font structure */ -#define Font Font_ -typedef struct { - int height; - int width; - int ascent; - int descent; - int badslant; - int badweight; - short lbearing; - short rbearing; - XftFont *match; - FcFontSet *set; - FcPattern *pattern; -} Font; - -/* Drawing Context */ -typedef struct { - Color *col; - size_t collen; - Font font, bfont, ifont, ibfont; - GC gc; -} DC; - -static inline ushort sixd_to_16bit(int); -static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); -static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int); -static void xdrawglyph(Glyph, int, int); -static void xclear(int, int, int, int); -static int xgeommasktogravity(int); -static void ximopen(Display *); -static void ximinstantiate(Display *, XPointer, XPointer); -static void ximdestroy(XIM, XPointer, XPointer); -static void xinit(int, int); -static void cresize(int, int); -static void xresize(int, int); -static void xhints(void); -static int xloadcolor(int, const char *, Color *); -static int xloadfont(Font *, FcPattern *); -static void xloadfonts(char *, double); -static int xloadsparefont(FcPattern *, int); -static void xloadsparefonts(void); -static void xunloadfont(Font *); -static void xunloadfonts(void); -static void xsetenv(void); -static void xseturgency(int); -static int evcol(XEvent *); -static int evrow(XEvent *); - -static void expose(XEvent *); -static void visibility(XEvent *); -static void unmap(XEvent *); -static void kpress(XEvent *); -static void cmessage(XEvent *); -static void resize(XEvent *); -static void focus(XEvent *); -static void brelease(XEvent *); -static void bpress(XEvent *); -static void bmotion(XEvent *); -static void propnotify(XEvent *); -static void selnotify(XEvent *); -static void selclear_(XEvent *); -static void selrequest(XEvent *); -static void setsel(char *, Time); -static void mousesel(XEvent *, int); -static void mousereport(XEvent *); -static char *kmap(KeySym, uint); -static int match(uint, uint); - -static void run(void); -static void usage(void); - -static void (*handler[LASTEvent])(XEvent *) = { - [KeyPress] = kpress, - [ClientMessage] = cmessage, - [ConfigureNotify] = resize, - [VisibilityNotify] = visibility, - [UnmapNotify] = unmap, - [Expose] = expose, - [FocusIn] = focus, - [FocusOut] = focus, - [MotionNotify] = bmotion, - [ButtonPress] = bpress, - [ButtonRelease] = brelease, -/* - * Uncomment if you want the selection to disappear when you select something - * different in another window. - */ -/* [SelectionClear] = selclear_, */ - [SelectionNotify] = selnotify, -/* - * PropertyNotify is only turned on when there is some INCR transfer happening - * for the selection retrieval. - */ - [PropertyNotify] = propnotify, - [SelectionRequest] = selrequest, -}; - -/* Globals */ -static DC dc; -static XWindow xw; -static XSelection xsel; -static TermWindow win; - -/* Font Ring Cache */ -enum { - FRC_NORMAL, - FRC_ITALIC, - FRC_BOLD, - FRC_ITALICBOLD -}; - -typedef struct { - XftFont *font; - int flags; - Rune unicodep; -} Fontcache; - -/* Fontcache is an array now. A new font will be appended to the array. */ -static Fontcache *frc = NULL; -static int frclen = 0; -static int frccap = 0; -static char *usedfont = NULL; -static double usedfontsize = 0; -static double defaultfontsize = 0; - -static char *opt_alpha = NULL; -static char *opt_class = NULL; -static char **opt_cmd = NULL; -static char *opt_embed = NULL; -static char *opt_font = NULL; -static char *opt_io = NULL; -static char *opt_line = NULL; -static char *opt_name = NULL; -static char *opt_title = NULL; - -static int oldbutton = 3; /* button event on startup: 3 = release */ - -void -clipcopy(const Arg *dummy) -{ - Atom clipboard; - - free(xsel.clipboard); - xsel.clipboard = NULL; - - if (xsel.primary != NULL) { - xsel.clipboard = xstrdup(xsel.primary); - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); - } -} - -void -clippaste(const Arg *dummy) -{ - Atom clipboard; - - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard, - xw.win, CurrentTime); -} - -void -selpaste(const Arg *dummy) -{ - XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, - xw.win, CurrentTime); -} - -void -numlock(const Arg *dummy) -{ - win.mode ^= MODE_NUMLOCK; -} - -void -zoom(const Arg *arg) -{ - Arg larg; - - larg.f = usedfontsize + arg->f; - zoomabs(&larg); -} - -void -zoomabs(const Arg *arg) -{ - xunloadfonts(); - xloadfonts(usedfont, arg->f); - xloadsparefonts(); - cresize(0, 0); - redraw(); - xhints(); -} - -void -zoomreset(const Arg *arg) -{ - Arg larg; - - if (defaultfontsize > 0) { - larg.f = defaultfontsize; - zoomabs(&larg); - } -} - -int -evcol(XEvent *e) -{ - int x = e->xbutton.x - win.hborderpx; - LIMIT(x, 0, win.tw - 1); - return x / win.cw; -} - -int -evrow(XEvent *e) -{ - int y = e->xbutton.y - win.vborderpx; - LIMIT(y, 0, win.th - 1); - return y / win.ch; -} - -void -mousesel(XEvent *e, int done) -{ - int type, seltype = SEL_REGULAR; - uint state = e->xbutton.state & ~(Button1Mask | forceselmod); - - for (type = 1; type < LEN(selmasks); ++type) { - if (match(selmasks[type], state)) { - seltype = type; - break; - } - } - selextend(evcol(e), evrow(e), seltype, done); - if (done) - setsel(getsel(), e->xbutton.time); -} - -void -mousereport(XEvent *e) -{ - int len, x = evcol(e), y = evrow(e), - button = e->xbutton.button, state = e->xbutton.state; - char buf[40]; - static int ox, oy; - - /* from urxvt */ - if (e->xbutton.type == MotionNotify) { - if (x == ox && y == oy) - return; - if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) - return; - /* MOUSE_MOTION: no reporting if no button is pressed */ - if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3) - return; - - button = oldbutton + 32; - ox = x; - oy = y; - } else { - if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) { - button = 3; - } else { - button -= Button1; - if (button >= 3) - button += 64 - 3; - } - if (e->xbutton.type == ButtonPress) { - oldbutton = button; - ox = x; - oy = y; - } else if (e->xbutton.type == ButtonRelease) { - oldbutton = 3; - /* MODE_MOUSEX10: no button release reporting */ - if (IS_SET(MODE_MOUSEX10)) - return; - if (button == 64 || button == 65) - return; - } - } - - if (!IS_SET(MODE_MOUSEX10)) { - button += ((state & ShiftMask ) ? 4 : 0) - + ((state & Mod4Mask ) ? 8 : 0) - + ((state & ControlMask) ? 16 : 0); - } - - if (IS_SET(MODE_MOUSESGR)) { - len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", - button, x+1, y+1, - e->xbutton.type == ButtonRelease ? 'm' : 'M'); - } else if (x < 223 && y < 223) { - len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", - 32+button, 32+x+1, 32+y+1); - } else { - return; - } - - ttywrite(buf, len, 0); -} - -void -bpress(XEvent *e) -{ - struct timespec now; - MouseShortcut *ms; - MouseKey *mk; - int snap; - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { - mousereport(e); - return; - } - - for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { - if (e->xbutton.button == ms->b - && match(ms->mask, e->xbutton.state)) { - ttywrite(ms->s, strlen(ms->s), 1); - return; - } - } - - for (mk = mkeys; mk < mkeys + LEN(mkeys); mk++) { - if (e->xbutton.button == mk->b - && match(mk->mask, e->xbutton.state)) { - mk->func(&mk->arg); - return; - } - } - - if (e->xbutton.button == Button1) { - /* - * If the user clicks below predefined timeouts specific - * snapping behaviour is exposed. - */ - clock_gettime(CLOCK_MONOTONIC, &now); - if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { - snap = SNAP_LINE; - } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { - snap = SNAP_WORD; - } else { - snap = 0; - } - xsel.tclick2 = xsel.tclick1; - xsel.tclick1 = now; - - selstart(evcol(e), evrow(e), snap); - } -} - -void -propnotify(XEvent *e) -{ - XPropertyEvent *xpev; - Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - - xpev = &e->xproperty; - if (xpev->state == PropertyNewValue && - (xpev->atom == XA_PRIMARY || - xpev->atom == clipboard)) { - selnotify(e); - } -} - -void -selnotify(XEvent *e) -{ - ulong nitems, ofs, rem; - int format; - uchar *data, *last, *repl; - Atom type, incratom, property = None; - - incratom = XInternAtom(xw.dpy, "INCR", 0); - - ofs = 0; - if (e->type == SelectionNotify) - property = e->xselection.property; - else if (e->type == PropertyNotify) - property = e->xproperty.atom; - - if (property == None) - return; - - do { - if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, - BUFSIZ/4, False, AnyPropertyType, - &type, &format, &nitems, &rem, - &data)) { - fprintf(stderr, "Clipboard allocation failed\n"); - return; - } - - if (e->type == PropertyNotify && nitems == 0 && rem == 0) { - /* - * If there is some PropertyNotify with no data, then - * this is the signal of the selection owner that all - * data has been transferred. We won't need to receive - * PropertyNotify events anymore. - */ - MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - } - - if (type == incratom) { - /* - * Activate the PropertyNotify events so we receive - * when the selection owner does send us the next - * chunk of data. - */ - MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - - /* - * Deleting the property is the transfer start signal. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); - continue; - } - - /* - * As seen in getsel: - * Line endings are inconsistent in the terminal and GUI world - * copy and pasting. When receiving some selection data, - * replace all '\n' with '\r'. - * FIXME: Fix the computer world. - */ - repl = data; - last = data + nitems * format / 8; - while ((repl = memchr(repl, '\n', last - repl))) { - *repl++ = '\r'; - } - - if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) - ttywrite("\033[200~", 6, 0); - ttywrite((char *)data, nitems * format / 8, 1); - if (IS_SET(MODE_BRCKTPASTE) && rem == 0) - ttywrite("\033[201~", 6, 0); - XFree(data); - /* number of 32-bit chunks returned */ - ofs += nitems * format / 32; - } while (rem > 0); - - /* - * Deleting the property again tells the selection owner to send the - * next data chunk in the property. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); -} - -void -xclipcopy(void) -{ - clipcopy(NULL); -} - -void -selclear_(XEvent *e) -{ - selclear(); -} - -void -selrequest(XEvent *e) -{ - XSelectionRequestEvent *xsre; - XSelectionEvent xev; - Atom xa_targets, string, clipboard; - char *seltext; - - xsre = (XSelectionRequestEvent *) e; - xev.type = SelectionNotify; - xev.requestor = xsre->requestor; - xev.selection = xsre->selection; - xev.target = xsre->target; - xev.time = xsre->time; - if (xsre->property == None) - xsre->property = xsre->target; - - /* reject */ - xev.property = None; - - xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); - if (xsre->target == xa_targets) { - /* respond with the supported type */ - string = xsel.xtarget; - XChangeProperty(xsre->display, xsre->requestor, xsre->property, - XA_ATOM, 32, PropModeReplace, - (uchar *) &string, 1); - xev.property = xsre->property; - } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { - /* - * xith XA_STRING non ascii characters may be incorrect in the - * requestor. It is not our problem, use utf8. - */ - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - if (xsre->selection == XA_PRIMARY) { - seltext = xsel.primary; - } else if (xsre->selection == clipboard) { - seltext = xsel.clipboard; - } else { - fprintf(stderr, - "Unhandled clipboard selection 0x%lx\n", - xsre->selection); - return; - } - if (seltext != NULL) { - XChangeProperty(xsre->display, xsre->requestor, - xsre->property, xsre->target, - 8, PropModeReplace, - (uchar *)seltext, strlen(seltext)); - xev.property = xsre->property; - } - } - - /* all done, send a notification to the listener */ - if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev)) - fprintf(stderr, "Error sending SelectionNotify event\n"); -} - -void -setsel(char *str, Time t) -{ - if (!str) - return; - - free(xsel.primary); - xsel.primary = str; - - XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); - if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) - selclear(); -} - -void -xsetsel(char *str) -{ - setsel(str, CurrentTime); -} - -void -brelease(XEvent *e) -{ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { - mousereport(e); - return; - } - - if (e->xbutton.button == Button2) - selpaste(NULL); - else if (e->xbutton.button == Button1) - mousesel(e, 1); -} - -void -bmotion(XEvent *e) -{ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) { - mousereport(e); - return; - } - - mousesel(e, 0); -} - -void -cresize(int width, int height) -{ - int col, row; - - if (width != 0) - win.w = width; - if (height != 0) - win.h = height; - - col = (win.w - 2 * borderpx) / win.cw; - row = (win.h - 2 * borderpx) / win.ch; - col = MAX(1, col); - row = MAX(1, row); - - win.hborderpx = (win.w - col * win.cw) / 2; - win.vborderpx = (win.h - row * win.ch) / 2; - - tresize(col, row); - xresize(col, row); - ttyresize(win.tw, win.th); -} - -void -xresize(int col, int row) -{ - win.tw = col * win.cw; - win.th = row * win.ch; - - XFreePixmap(xw.dpy, xw.buf); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - xw.depth); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, win.w, win.h); - - /* resize to new width */ - xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); -} - -ushort -sixd_to_16bit(int x) -{ - return x == 0 ? 0 : 0x3737 + 0x2828 * x; -} - -int -xloadcolor(int i, const char *name, Color *ncolor) -{ - XRenderColor color = { .alpha = 0xffff }; - - if (!name) { - if (BETWEEN(i, 16, 255)) { /* 256 color */ - if (i < 6*6*6+16) { /* same colors as xterm */ - color.red = sixd_to_16bit( ((i-16)/36)%6 ); - color.green = sixd_to_16bit( ((i-16)/6) %6 ); - color.blue = sixd_to_16bit( ((i-16)/1) %6 ); - } else { /* greyscale */ - color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16)); - color.green = color.blue = color.red; - } - return XftColorAllocValue(xw.dpy, xw.vis, - xw.cmap, &color, ncolor); - } else - name = colorname[i]; - } - - return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); -} - -void -xloadcols(void) -{ - int i; - static int loaded; - Color *cp; - - if (loaded) { - for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) - XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); - } else { - dc.collen = MAX(LEN(colorname), 256); - dc.col = xmalloc(dc.collen * sizeof(Color)); - } - - for (i = 0; i < dc.collen; i++) - if (!xloadcolor(i, NULL, &dc.col[i])) { - if (colorname[i]) - die("could not allocate color '%s'\n", colorname[i]); - else - die("could not allocate color %d\n", i); - } - - /* set alpha value of bg color */ - if (opt_alpha) - alpha = strtof(opt_alpha, NULL); - dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); - dc.col[defaultbg].color.red = - ((unsigned short)(dc.col[defaultbg].color.red * alpha)) & 0xff00; - dc.col[defaultbg].color.green = - ((unsigned short)(dc.col[defaultbg].color.green * alpha)) & 0xff00; - dc.col[defaultbg].color.blue = - ((unsigned short)(dc.col[defaultbg].color.blue * alpha)) & 0xff00; - dc.col[defaultbg].pixel &= 0x00FFFFFF; - dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; - loaded = 1; -} - -int -xsetcolorname(int x, const char *name) -{ - Color ncolor; - - if (!BETWEEN(x, 0, dc.collen)) - return 1; - - if (!xloadcolor(x, name, &ncolor)) - return 1; - - XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); - dc.col[x] = ncolor; - if (x == defaultbg) - dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); - - return 0; -} - -/* - * Absolute coordinates. - */ -void -xclear(int x1, int y1, int x2, int y2) -{ - XftDrawRect(xw.draw, - &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg], - x1, y1, x2-x1, y2-y1); -} - -void -xclearwin(void) -{ - xclear(0, 0, win.w, win.h); -} - - -void -xhints(void) -{ - XClassHint class = {opt_name ? opt_name : "st", - opt_class ? opt_class : "St"}; - XWMHints wm = {.flags = InputHint, .input = 1}; - XSizeHints *sizeh; - - sizeh = XAllocSizeHints(); - - sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; - sizeh->height = win.h; - sizeh->width = win.w; - sizeh->height_inc = 1; - sizeh->width_inc = 1; - sizeh->base_height = 2 * borderpx; - sizeh->base_width = 2 * borderpx; - sizeh->min_height = win.ch + 2 * borderpx; - sizeh->min_width = win.cw + 2 * borderpx; - if (xw.isfixed) { - sizeh->flags |= PMaxSize; - sizeh->min_width = sizeh->max_width = win.w; - sizeh->min_height = sizeh->max_height = win.h; - } - if (xw.gm & (XValue|YValue)) { - sizeh->flags |= USPosition | PWinGravity; - sizeh->x = xw.l; - sizeh->y = xw.t; - sizeh->win_gravity = xgeommasktogravity(xw.gm); - } - - XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, - &class); - XFree(sizeh); -} - -int -xgeommasktogravity(int mask) -{ - switch (mask & (XNegative|YNegative)) { - case 0: - return NorthWestGravity; - case XNegative: - return NorthEastGravity; - case YNegative: - return SouthWestGravity; - } - - return SouthEastGravity; -} - -int -xloadfont(Font *f, FcPattern *pattern) -{ - FcPattern *configured; - FcPattern *match; - FcResult result; - XGlyphInfo extents; - int wantattr, haveattr; - - /* - * Manually configure instead of calling XftMatchFont - * so that we can use the configured pattern for - * "missing glyph" lookups. - */ - configured = FcPatternDuplicate(pattern); - if (!configured) - return 1; - - FcConfigSubstitute(NULL, configured, FcMatchPattern); - XftDefaultSubstitute(xw.dpy, xw.scr, configured); - - match = FcFontMatch(NULL, configured, &result); - if (!match) { - FcPatternDestroy(configured); - return 1; - } - - if (!(f->match = XftFontOpenPattern(xw.dpy, match))) { - FcPatternDestroy(configured); - FcPatternDestroy(match); - return 1; - } - - if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) == - XftResultMatch)) { - /* - * Check if xft was unable to find a font with the appropriate - * slant but gave us one anyway. Try to mitigate. - */ - if ((XftPatternGetInteger(f->match->pattern, "slant", 0, - &haveattr) != XftResultMatch) || haveattr < wantattr) { - f->badslant = 1; - fputs("font slant does not match\n", stderr); - } - } - - if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) == - XftResultMatch)) { - if ((XftPatternGetInteger(f->match->pattern, "weight", 0, - &haveattr) != XftResultMatch) || haveattr != wantattr) { - f->badweight = 1; - fputs("font weight does not match\n", stderr); - } - } - - XftTextExtentsUtf8(xw.dpy, f->match, - (const FcChar8 *) ascii_printable, - strlen(ascii_printable), &extents); - - f->set = NULL; - f->pattern = configured; - - f->ascent = f->match->ascent; - f->descent = f->match->descent; - f->lbearing = 0; - f->rbearing = f->match->max_advance_width; - - f->height = f->ascent + f->descent; - f->width = DIVCEIL(extents.xOff, strlen(ascii_printable)); - - return 0; -} - -void -xloadfonts(char *fontstr, double fontsize) -{ - FcPattern *pattern; - double fontval; - - if (fontstr[0] == '-') - pattern = XftXlfdParse(fontstr, False, False); - else - pattern = FcNameParse((FcChar8 *)fontstr); - - if (!pattern) - die("can't open font %s\n", fontstr); - - if (fontsize > 1) { - FcPatternDel(pattern, FC_PIXEL_SIZE); - FcPatternDel(pattern, FC_SIZE); - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); - usedfontsize = fontsize; - } else { - if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = fontval; - } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = -1; - } else { - /* - * Default font size is 12, if none given. This is to - * have a known usedfontsize value. - */ - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); - usedfontsize = 12; - } - defaultfontsize = usedfontsize; - } - - if (xloadfont(&dc.font, pattern)) - die("can't open font %s\n", fontstr); - - if (usedfontsize < 0) { - FcPatternGetDouble(dc.font.match->pattern, - FC_PIXEL_SIZE, 0, &fontval); - usedfontsize = fontval; - if (fontsize == 0) - defaultfontsize = fontval; - } - - /* Setting character width and height. */ - win.cw = ceilf(dc.font.width * cwscale); - win.ch = ceilf(dc.font.height * chscale); - win.cyo = ceilf(dc.font.height * (chscale - 1) / 2); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); - if (xloadfont(&dc.ifont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); - if (xloadfont(&dc.ibfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); - if (xloadfont(&dc.bfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDestroy(pattern); -} - -int -xloadsparefont(FcPattern *pattern, int flags) -{ - FcPattern *match; - FcResult result; - - match = FcFontMatch(NULL, pattern, &result); - if (!match) { - return 1; - } - - if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) { - FcPatternDestroy(match); - return 1; - } - - frc[frclen].flags = flags; - /* Believe U+0000 glyph will present in each default font */ - frc[frclen].unicodep = 0; - frclen++; - - return 0; -} - -void -xloadsparefonts(void) -{ - FcPattern *pattern; - double sizeshift, fontval; - int fc; - char **fp; - - if (frclen != 0) - die("can't embed spare fonts. cache isn't empty"); - - /* Calculate count of spare fonts */ - fc = sizeof(font2) / sizeof(*font2); - if (fc == 0) - return; - - /* Allocate memory for cache entries. */ - if (frccap < 4 * fc) { - frccap += 4 * fc - frccap; - frc = xrealloc(frc, frccap * sizeof(Fontcache)); - } - - for (fp = font2; fp - font2 < fc; ++fp) { - - if (**fp == '-') - pattern = XftXlfdParse(*fp, False, False); - else - pattern = FcNameParse((FcChar8 *)*fp); - - if (!pattern) - die("can't open spare font %s\n", *fp); - - if (defaultfontsize > 0) { - sizeshift = usedfontsize - defaultfontsize; - if (sizeshift != 0 && - FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == - FcResultMatch) { - fontval += sizeshift; - FcPatternDel(pattern, FC_PIXEL_SIZE); - FcPatternDel(pattern, FC_SIZE); - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval); - } - } - - FcPatternAddBool(pattern, FC_SCALABLE, 1); - - FcConfigSubstitute(NULL, pattern, FcMatchPattern); - XftDefaultSubstitute(xw.dpy, xw.scr, pattern); - - if (xloadsparefont(pattern, FRC_NORMAL)) - die("can't open spare font %s\n", *fp); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); - if (xloadsparefont(pattern, FRC_ITALIC)) - die("can't open spare font %s\n", *fp); - - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); - if (xloadsparefont(pattern, FRC_ITALICBOLD)) - die("can't open spare font %s\n", *fp); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); - if (xloadsparefont(pattern, FRC_BOLD)) - die("can't open spare font %s\n", *fp); - - FcPatternDestroy(pattern); - } -} - -void -xunloadfont(Font *f) -{ - XftFontClose(xw.dpy, f->match); - FcPatternDestroy(f->pattern); - if (f->set) - FcFontSetDestroy(f->set); -} - -void -xunloadfonts(void) -{ - /* Free the loaded fonts in the font cache. */ - while (frclen > 0) - XftFontClose(xw.dpy, frc[--frclen].font); - - xunloadfont(&dc.font); - xunloadfont(&dc.bfont); - xunloadfont(&dc.ifont); - xunloadfont(&dc.ibfont); -} - -void -ximopen(Display *dpy) -{ - XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy }; - - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { - XSetLocaleModifiers("@im=local"); - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) { - XSetLocaleModifiers("@im="); - if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) - die("XOpenIM failed. Could not open input device.\n"); - } - } - if (XSetIMValues(xw.xim, XNDestroyCallback, &destroy, NULL) != NULL) - die("XSetIMValues failed. Could not set input method value.\n"); - xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL); - if (xw.xic == NULL) - die("XCreateIC failed. Could not obtain input method.\n"); -} - -void -ximinstantiate(Display *dpy, XPointer client, XPointer call) -{ - ximopen(dpy); - XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); -} - -void -ximdestroy(XIM xim, XPointer client, XPointer call) -{ - xw.xim = NULL; - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); -} - -void -xinit(int cols, int rows) -{ - XGCValues gcvalues; - Cursor cursor; - Window parent; - pid_t thispid = getpid(); - XColor xmousefg, xmousebg; - XWindowAttributes attr; - XVisualInfo vis; - - xw.scr = XDefaultScreen(xw.dpy); - - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) { - parent = XRootWindow(xw.dpy, xw.scr); - xw.depth = 32; - } else { - XGetWindowAttributes(xw.dpy, parent, &attr); - xw.depth = attr.depth; - } - - XMatchVisualInfo(xw.dpy, xw.scr, xw.depth, TrueColor, &vis); - xw.vis = vis.visual; - - /* font */ - if (!FcInit()) - die("could not init fontconfig.\n"); - - usedfont = (opt_font == NULL)? font : opt_font; - xloadfonts(usedfont, 0); - - /* spare fonts */ - xloadsparefonts(); - - /* colors */ - xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); - xloadcols(); - - /* adjust fixed window geometry */ - win.w = 2 * win.hborderpx + cols * win.cw; - win.h = 2 * win.vborderpx + rows * win.ch; - if (xw.gm & XNegative) - xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; - if (xw.gm & YNegative) - xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2; - - /* Events */ - xw.attrs.background_pixel = dc.col[defaultbg].pixel; - xw.attrs.border_pixel = dc.col[defaultbg].pixel; - xw.attrs.bit_gravity = NorthWestGravity; - xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask - | ExposureMask | VisibilityChangeMask | StructureNotifyMask - | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; - xw.attrs.colormap = xw.cmap; - - xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, - win.w, win.h, 0, xw.depth, InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, xw.depth); - dc.gc = XCreateGC(xw.dpy, xw.buf, GCGraphicsExposures, &gcvalues); - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); - - /* font spec buffer */ - xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); - - /* Xft rendering context */ - xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); - - /* input methods */ - ximopen(xw.dpy); - - /* white cursor, black outline */ - cursor = XCreateFontCursor(xw.dpy, mouseshape); - XDefineCursor(xw.dpy, xw.win, cursor); - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { - xmousefg.red = 0xffff; - xmousefg.green = 0xffff; - xmousefg.blue = 0xffff; - } - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { - xmousebg.red = 0x0000; - xmousebg.green = 0x0000; - xmousebg.blue = 0x0000; - } - - XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); - xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); - XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); - - xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); - XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, - PropModeReplace, (uchar *)&thispid, 1); - - win.mode = MODE_NUMLOCK; - resettitle(); - XMapWindow(xw.dpy, xw.win); - xhints(); - XSync(xw.dpy, False); - - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); - xsel.primary = NULL; - xsel.clipboard = NULL; - xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); - if (xsel.xtarget == None) - xsel.xtarget = XA_STRING; - - boxdraw_xinit(xw.dpy, xw.cmap, xw.draw, xw.vis); -} - -int -xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) -{ - float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; - ushort mode, prevmode = USHRT_MAX; - Font *font = &dc.font; - int frcflags = FRC_NORMAL; - float runewidth = win.cw; - Rune rune; - FT_UInt glyphidx; - FcResult fcres; - FcPattern *fcpattern, *fontpattern; - FcFontSet *fcsets[] = { NULL }; - FcCharSet *fccharset; - int i, f, numspecs = 0; - - for (i = 0, xp = winx, yp = winy + font->ascent + win.cyo; i < len; ++i) { - /* Fetch rune and mode for current glyph. */ - rune = glyphs[i].u; - mode = glyphs[i].mode; - - /* Skip dummy wide-character spacing. */ - if (mode == ATTR_WDUMMY) - continue; - - /* Determine font for glyph if different from previous glyph. */ - if (prevmode != mode) { - prevmode = mode; - font = &dc.font; - frcflags = FRC_NORMAL; - runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f); - if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) { - font = &dc.ibfont; - frcflags = FRC_ITALICBOLD; - } else if (mode & ATTR_ITALIC) { - font = &dc.ifont; - frcflags = FRC_ITALIC; - } else if (mode & ATTR_BOLD) { - font = &dc.bfont; - frcflags = FRC_BOLD; - } - yp = winy + font->ascent + win.cyo; - } - - if (mode & ATTR_BOXDRAW) { - /* minor shoehorning: boxdraw uses only this ushort */ - glyphidx = boxdrawindex(&glyphs[i]); - } else { - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - } - if (glyphidx) { - specs[numspecs].font = font->match; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - continue; - } - - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); - /* Everything correct. */ - if (glyphidx && frc[f].flags == frcflags) - break; - /* We got a default font for a not found glyph. */ - if (!glyphidx && frc[f].flags == frcflags - && frc[f].unicodep == rune) { - break; - } - } - - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; - - /* - * Nothing was found in the cache. Now use - * some dozen of Fontconfig calls to get the - * font for one single character. - * - * Xft and fontconfig are design failures. - */ - fcpattern = FcPatternDuplicate(font->pattern); - fccharset = FcCharSetCreate(); - - FcCharSetAddChar(fccharset, rune); - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); - - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); - - fontpattern = FcFontSetMatch(0, fcsets, 1, - fcpattern, &fcres); - - /* Allocate memory for the new cache entry. */ - if (frclen >= frccap) { - frccap += 16; - frc = xrealloc(frc, frccap * sizeof(Fontcache)); - } - - frc[frclen].font = XftFontOpenPattern(xw.dpy, - fontpattern); - if (!frc[frclen].font) - die("XftFontOpenPattern failed seeking fallback font: %s\n", - strerror(errno)); - frc[frclen].flags = frcflags; - frc[frclen].unicodep = rune; - - glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune); - - f = frclen; - frclen++; - - FcPatternDestroy(fcpattern); - FcCharSetDestroy(fccharset); - } - - specs[numspecs].font = frc[f].font; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - } - - return numspecs; -} - -void -xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y, int dmode) -{ - int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); - int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, - width = charlen * win.cw; - Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; - XRenderColor colfg, colbg; - - /* Fallback on color display for attributes not supported by the font */ - if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) { - if (dc.ibfont.badslant || dc.ibfont.badweight) - base.fg = defaultattr; - } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) || - (base.mode & ATTR_BOLD && dc.bfont.badweight)) { - base.fg = defaultattr; - } - - if (IS_TRUECOL(base.fg)) { - colfg.alpha = 0xffff; - colfg.red = TRUERED(base.fg); - colfg.green = TRUEGREEN(base.fg); - colfg.blue = TRUEBLUE(base.fg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg); - fg = &truefg; - } else { - fg = &dc.col[base.fg]; - } - - if (IS_TRUECOL(base.bg)) { - colbg.alpha = 0xffff; - colbg.green = TRUEGREEN(base.bg); - colbg.red = TRUERED(base.bg); - colbg.blue = TRUEBLUE(base.bg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg); - bg = &truebg; - } else { - bg = &dc.col[base.bg]; - } - - if (IS_SET(MODE_REVERSE)) { - if (fg == &dc.col[defaultfg]) { - fg = &dc.col[defaultbg]; - } else { - colfg.red = ~fg->color.red; - colfg.green = ~fg->color.green; - colfg.blue = ~fg->color.blue; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, - &revfg); - fg = &revfg; - } - - if (bg == &dc.col[defaultbg]) { - bg = &dc.col[defaultfg]; - } else { - colbg.red = ~bg->color.red; - colbg.green = ~bg->color.green; - colbg.blue = ~bg->color.blue; - colbg.alpha = bg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, - &revbg); - bg = &revbg; - } - } - - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { - colfg.red = fg->color.red / 2; - colfg.green = fg->color.green / 2; - colfg.blue = fg->color.blue / 2; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); - fg = &revfg; - } - - if (base.mode & ATTR_REVERSE) { - temp = fg; - fg = bg; - bg = temp; - } - - if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK) - fg = bg; - - if (base.mode & ATTR_INVISIBLE) - fg = bg; - - if (dmode & DRAW_BG) { - /* Intelligent cleaning up of the borders. */ - if (x == 0) { - xclear(0, (y == 0)? 0 : winy, win.vborderpx, - winy + win.ch + - ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); - } - if (winx + width >= win.hborderpx + win.tw) { - xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); - } - if (y == 0) - xclear(winx, 0, winx + width, win.hborderpx); - if (winy + win.ch >= win.vborderpx + win.th) - xclear(winx, winy + win.ch, winx + width, win.h); - - /* Fill the background */ - XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); - } - - if (dmode & DRAW_FG) { - if (base.mode & ATTR_BOXDRAW) { - drawboxes(winx, winy, width / len, win.ch, fg, bg, specs, len); - } else { - /* Render the glyphs. */ - XftDrawGlyphFontSpec(xw.draw, fg, specs, len); - } - - /* Render underline and strikethrough. */ - if (base.mode & ATTR_UNDERLINE) { - XftDrawRect(xw.draw, fg, winx, winy + win.cyo + dc.font.ascent + 1, - width, 1); - } - - if (base.mode & ATTR_STRUCK) { - XftDrawRect(xw.draw, fg, winx, winy + win.cyo + 2 * dc.font.ascent / 3, - width, 1); - } - } -} - -void -xdrawglyph(Glyph g, int x, int y) -{ - int numspecs; - XftGlyphFontSpec spec; - - numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); - xdrawglyphfontspecs(&spec, g, numspecs, x, y, DRAW_BG | DRAW_FG); -} - -void -xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) -{ - Color drawcol; - - /* remove the old cursor */ - if (selected(ox, oy)) - og.mode ^= ATTR_REVERSE; - xdrawglyph(og, ox, oy); - - if (IS_SET(MODE_HIDE)) - return; - - /* - * Select the right color for the right mode. - */ - g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE|ATTR_BOXDRAW; - - if (IS_SET(MODE_REVERSE)) { - g.mode |= ATTR_REVERSE; - g.bg = defaultfg; - if (selected(cx, cy)) { - drawcol = dc.col[defaultcs]; - g.fg = defaultrcs; - } else { - drawcol = dc.col[defaultrcs]; - g.fg = defaultcs; - } - } else { - if (selected(cx, cy)) { - g.fg = defaultfg; - g.bg = defaultrcs; - } else { - g.fg = defaultbg; - g.bg = defaultcs; - } - drawcol = dc.col[g.bg]; - } - - /* draw the new one */ - if (IS_SET(MODE_FOCUSED)) { - switch (win.cursor) { - case 7: /* st extension: snowman (U+2603) */ - g.u = 0x2603; - case 0: /* Blinking Block */ - case 1: /* Blinking Block (Default) */ - case 2: /* Steady Block */ - xdrawglyph(g, cx, cy); - break; - case 3: /* Blinking Underline */ - case 4: /* Steady Underline */ - XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + (cy + 1) * win.ch - \ - cursorthickness, - win.cw, cursorthickness); - break; - case 5: /* Blinking bar */ - case 6: /* Steady bar */ - XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + cy * win.ch, - cursorthickness, win.ch); - break; - } - } else { - XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + cy * win.ch, - win.cw - 1, 1); - XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - win.hborderpx + (cx + 1) * win.cw - 1, - win.vborderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - win.hborderpx + cx * win.cw, - win.vborderpx + (cy + 1) * win.ch - 1, - win.cw, 1); - } -} - -void -xsetenv(void) -{ - char buf[sizeof(long) * 8 + 1]; - - snprintf(buf, sizeof(buf), "%lu", xw.win); - setenv("WINDOWID", buf, 1); -} - -void -xsettitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop); - XSetWMName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); - XFree(prop.value); -} - -int -xstartdraw(void) -{ - return IS_SET(MODE_VISIBLE); -} - -void -xdrawline(Line line, int x1, int y1, int x2) -{ - int i, x, ox, numspecs, numspecs_cached; - Glyph base, new; - XftGlyphFontSpec *specs; - - numspecs_cached = xmakeglyphfontspecs(xw.specbuf, &line[x1], x2 - x1, x1, y1); - - /* Draw line in 2 passes: background and foreground. This way wide glyphs - won't get truncated (#223) */ - for (int dmode = DRAW_BG; dmode <= DRAW_FG; dmode <<= 1) { - specs = xw.specbuf; - numspecs = numspecs_cached; - i = ox = 0; - for (x = x1; x < x2 && i < numspecs; x++) { - new = line[x]; - if (new.mode == ATTR_WDUMMY) - continue; - if (selected(x, y1)) - new.mode ^= ATTR_REVERSE; - if (i > 0 && ATTRCMP(base, new)) { - xdrawglyphfontspecs(specs, base, i, ox, y1, dmode); - specs += i; - numspecs -= i; - i = 0; - } - if (i == 0) { - ox = x; - base = new; - } - i++; - } - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y1, dmode); - } -} - -void -xfinishdraw(void) -{ - XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, - win.h, 0, 0); - XSetForeground(xw.dpy, dc.gc, - dc.col[IS_SET(MODE_REVERSE)? - defaultfg : defaultbg].pixel); -} - -void -xximspot(int x, int y) -{ - XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch }; - XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); - - XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL); - XFree(attr); -} - -void -expose(XEvent *ev) -{ - redraw(); -} - -void -visibility(XEvent *ev) -{ - XVisibilityEvent *e = &ev->xvisibility; - - MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); -} - -void -unmap(XEvent *ev) -{ - win.mode &= ~MODE_VISIBLE; -} - -void -xsetpointermotion(int set) -{ - MODBIT(xw.attrs.event_mask, set, PointerMotionMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); -} - -void -xsetmode(int set, unsigned int flags) -{ - int mode = win.mode; - MODBIT(win.mode, set, flags); - if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) - redraw(); -} - -int -xsetcursor(int cursor) -{ - DEFAULT(cursor, 1); - if (!BETWEEN(cursor, 0, 6)) - return 1; - win.cursor = cursor; - return 0; -} - -void -xseturgency(int add) -{ - XWMHints *h = XGetWMHints(xw.dpy, xw.win); - - MODBIT(h->flags, add, XUrgencyHint); - XSetWMHints(xw.dpy, xw.win, h); - XFree(h); -} - -void -xbell(void) -{ - if (!(IS_SET(MODE_FOCUSED))) - xseturgency(1); - if (bellvolume) - XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); -} - -void -focus(XEvent *ev) -{ - XFocusChangeEvent *e = &ev->xfocus; - - if (e->mode == NotifyGrab) - return; - - if (ev->type == FocusIn) { - XSetICFocus(xw.xic); - win.mode |= MODE_FOCUSED; - xseturgency(0); - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[I", 3, 0); - } else { - XUnsetICFocus(xw.xic); - win.mode &= ~MODE_FOCUSED; - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[O", 3, 0); - } -} - -int -match(uint mask, uint state) -{ - return mask == XK_ANY_MOD || mask == (state & ~ignoremod); -} - -char* -kmap(KeySym k, uint state) -{ - Key *kp; - int i; - - /* Check for mapped keys out of X11 function keys. */ - for (i = 0; i < LEN(mappedkeys); i++) { - if (mappedkeys[i] == k) - break; - } - if (i == LEN(mappedkeys)) { - if ((k & 0xFFFF) < 0xFD00) - return NULL; - } - - for (kp = key; kp < key + LEN(key); kp++) { - if (kp->k != k) - continue; - - if (!match(kp->mask, state)) - continue; - - if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) - continue; - if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) - continue; - - if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) - continue; - - return kp->s; - } - - return NULL; -} - -void -kpress(XEvent *ev) -{ - XKeyEvent *e = &ev->xkey; - KeySym ksym; - char buf[32], *customkey; - int len; - Rune c; - Status status; - Shortcut *bp; - - if (IS_SET(MODE_KBDLOCK)) - return; - - len = XmbLookupString(xw.xic, e, buf, sizeof buf, &ksym, &status); - /* 1. shortcuts */ - for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { - if (ksym == bp->keysym && match(bp->mod, e->state)) { - bp->func(&(bp->arg)); - return; - } - } - - /* 2. custom keys from config.h */ - if ((customkey = kmap(ksym, e->state))) { - ttywrite(customkey, strlen(customkey), 1); - return; - } - - /* 3. composed string from input method */ - if (len == 0) - return; - if (len == 1 && e->state & Mod1Mask) { - if (IS_SET(MODE_8BIT)) { - if (*buf < 0177) { - c = *buf | 0x80; - len = utf8encode(c, buf); - } - } else { - buf[1] = buf[0]; - buf[0] = '\033'; - len = 2; - } - } - ttywrite(buf, len, 1); -} - -void -cmessage(XEvent *e) -{ - /* - * See xembed specs - * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html - */ - if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { - if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { - win.mode |= MODE_FOCUSED; - xseturgency(0); - } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { - win.mode &= ~MODE_FOCUSED; - } - } else if (e->xclient.data.l[0] == xw.wmdeletewin) { - ttyhangup(); - exit(0); - } -} - -void -resize(XEvent *e) -{ - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) - return; - - cresize(e->xconfigure.width, e->xconfigure.height); -} - -void -run(void) -{ - XEvent ev; - int w = win.w, h = win.h; - fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; - struct timespec seltv, *tv, now, lastblink, trigger; - double timeout; - - /* Waiting for window mapping */ - do { - XNextEvent(xw.dpy, &ev); - /* - * This XFilterEvent call is required because of XOpenIM. It - * does filter out the key event and some client message for - * the input method too. - */ - if (XFilterEvent(&ev, None)) - continue; - if (ev.type == ConfigureNotify) { - w = ev.xconfigure.width; - h = ev.xconfigure.height; - } - } while (ev.type != MapNotify); - - ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); - cresize(w, h); - - for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) { - FD_ZERO(&rfd); - FD_SET(ttyfd, &rfd); - FD_SET(xfd, &rfd); - - if (XPending(xw.dpy)) - timeout = 0; /* existing events might not set xfd */ - - seltv.tv_sec = timeout / 1E3; - seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec); - tv = timeout >= 0 ? &seltv : NULL; - - if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { - if (errno == EINTR) - continue; - die("select failed: %s\n", strerror(errno)); - } - clock_gettime(CLOCK_MONOTONIC, &now); - - if (FD_ISSET(ttyfd, &rfd)) - ttyread(); - - xev = 0; - while (XPending(xw.dpy)) { - xev = 1; - XNextEvent(xw.dpy, &ev); - if (XFilterEvent(&ev, None)) - continue; - if (handler[ev.type]) - (handler[ev.type])(&ev); - } - - /* - * To reduce flicker and tearing, when new content or event - * triggers drawing, we first wait a bit to ensure we got - * everything, and if nothing new arrives - we draw. - * We start with trying to wait minlatency ms. If more content - * arrives sooner, we retry with shorter and shorter preiods, - * and eventually draw even without idle after maxlatency ms. - * Typically this results in low latency while interacting, - * maximum latency intervals during `cat huge.txt`, and perfect - * sync with periodic updates from animations/key-repeats/etc. - */ - if (FD_ISSET(ttyfd, &rfd) || xev) { - if (!drawing) { - trigger = now; - drawing = 1; - } - timeout = (maxlatency - TIMEDIFF(now, trigger)) \ - / maxlatency * minlatency; - if (timeout > 0) - continue; /* we have time, try to find idle */ - } - - /* idle detected or maxlatency exhausted -> draw */ - timeout = -1; - if (blinktimeout && tattrset(ATTR_BLINK)) { - timeout = blinktimeout - TIMEDIFF(now, lastblink); - if (timeout <= 0) { - if (-timeout > blinktimeout) /* start visible */ - win.mode |= MODE_BLINK; - win.mode ^= MODE_BLINK; - tsetdirtattr(ATTR_BLINK); - lastblink = now; - timeout = blinktimeout; - } - } - - draw(); - XFlush(xw.dpy); - drawing = 0; - } -} - -int -resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst) -{ - char **sdst = dst; - int *idst = dst; - float *fdst = dst; - - char fullname[256]; - char fullclass[256]; - char *type; - XrmValue ret; - - snprintf(fullname, sizeof(fullname), "%s.%s", - opt_name ? opt_name : "st", name); - snprintf(fullclass, sizeof(fullclass), "%s.%s", - opt_class ? opt_class : "St", name); - fullname[sizeof(fullname) - 1] = fullclass[sizeof(fullclass) - 1] = '\0'; - - XrmGetResource(db, fullname, fullclass, &type, &ret); - if (ret.addr == NULL || strncmp("String", type, 64)) - return 1; - - switch (rtype) { - case STRING: - *sdst = ret.addr; - break; - case INTEGER: - *idst = strtoul(ret.addr, NULL, 10); - break; - case FLOAT: - *fdst = strtof(ret.addr, NULL); - break; - } - return 0; -} - -void -config_init(void) -{ - char *resm; - XrmDatabase db; - ResourcePref *p; - - XrmInitialize(); - resm = XResourceManagerString(xw.dpy); - if (!resm) - return; - - db = XrmGetStringDatabase(resm); - for (p = resources; p < resources + LEN(resources); p++) - resource_load(db, p->name, p->type, p->dst); -} - -void -usage(void) -{ - die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid]" - " [[-e] command [args ...]]\n" - " %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid] -l line" - " [stty_args ...]\n", argv0, argv0); -} - -int -main(int argc, char *argv[]) -{ - xw.l = xw.t = 0; - xw.isfixed = False; - win.cursor = cursorshape; - - ARGBEGIN { - case 'a': - allowaltscreen = 0; - break; - case 'A': - opt_alpha = EARGF(usage()); - break; - case 'c': - opt_class = EARGF(usage()); - break; - case 'e': - if (argc > 0) - --argc, ++argv; - goto run; - case 'f': - opt_font = EARGF(usage()); - break; - case 'g': - xw.gm = XParseGeometry(EARGF(usage()), - &xw.l, &xw.t, &cols, &rows); - break; - case 'i': - xw.isfixed = 1; - break; - case 'o': - opt_io = EARGF(usage()); - break; - case 'l': - opt_line = EARGF(usage()); - break; - case 'n': - opt_name = EARGF(usage()); - break; - case 't': - case 'T': - opt_title = EARGF(usage()); - break; - case 'w': - opt_embed = EARGF(usage()); - break; - case 'v': - die("%s " VERSION "\n", argv0); - break; - default: - usage(); - } ARGEND; - -run: - if (argc > 0) /* eat all remaining arguments */ - opt_cmd = argv; - - if (!opt_title) - opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0]; - - setlocale(LC_CTYPE, ""); - XSetLocaleModifiers(""); - - if(!(xw.dpy = XOpenDisplay(NULL))) - die("Can't open display\n"); - - config_init(); - cols = MAX(cols, 1); - rows = MAX(rows, 1); - tnew(cols, rows); - xinit(cols, rows); - xsetenv(); - selinit(); - run(); - - return 0; -} diff --git a/.config/st/x.o b/.config/st/x.o deleted file mode 100644 index 4574cb305bccc3f641dcebbf4190c5f6cceec3d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87648 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 wiFd`Z2><{9 diff --git a/.config/termite/config b/.config/termite/config deleted file mode 100644 index 3917d40..0000000 --- a/.config/termite/config +++ /dev/null @@ -1,88 +0,0 @@ -[options] -allow_bold = true -#audible_bell = false -bold_is_bright = true -#cell_height_scale = 1.0 -#cell_width_scale = 1.0 -clickable_url = true -dynamic_title = true -font = MesloLGS NF 15 -#fullscreen = true -#icon_name = terminal -#mouse_autohide = false -#scroll_on_output = false -#scroll_on_keystroke = true -# Length of the scrollback buffer, 0 disabled the scrollback buffer -# and setting it to a negative value means "infinite scrollback" -scrollback_lines = 10000 -#search_wrap = true -#urgent_on_bell = true -#hyperlinks = false - -# $BROWSER is used by default if set, with xdg-open as a fallback -#browser = xdg-open - -# "system", "on" or "off" -#cursor_blink = system - -# "block", "underline" or "ibeam" -#cursor_shape = block - -# Hide links that are no longer valid in url select overlay mode -#filter_unmatched_urls = true - -# Emit escape sequences for extra modified keys -#modify_other_keys = false - -# set size hints for the window -#size_hints = false - -# "off", "left" or "right" -#scrollbar = off - -[colors] -# If both of these are unset, cursor falls back to the foreground color, -# and cursor_foreground falls back to the background color. -#cursor = #dcdccc -#cursor_foreground = #dcdccc - -foreground = #dcdccc -foreground_bold = #ffffff -background = #222222 - -# 20% background transparency (requires a compositor) -#background = rgba(63, 63, 63, 0.8) - -# If unset, will reverse foreground and background -highlight = #2f2f2f - -# Colors from color0 to color254 can be set -color0 = #3f3f3f -color1 = #705050 -color2 = #60b48a -color3 = #dfaf8f -color4 = #506070 -color5 = #dc8cc3 -color6 = #8cd0d3 -color7 = #dcdccc -color8 = #709080 -color9 = #dca3a3 -color10 = #c3bf9f -color11 = #f0dfaf -color12 = #94bff3 -color13 = #ec93d3 -color14 = #93e0e3 -color15 = #ffffff - -[hints] -#font = Monospace 12 -#foreground = #dcdccc -#background = #3f3f3f -#active_foreground = #e68080 -#active_background = #3f3f3f -#padding = 2 -#border = #3f3f3f -#border_width = 0.5 -#roundness = 2.0 - -# vim: ft=dosini cms=#%s diff --git a/.config/xmobar/launch.sh b/.config/xmobar/launch.sh deleted file mode 100755 index 8df0fce..0000000 --- a/.config/xmobar/launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -killall xmobar; -/usr/bin/xmobar /home/arch/.config/xmobar/xmobarrc & diff --git a/.config/xmobar/xmobarrc b/.config/xmobar/xmobarrc deleted file mode 100644 index bd6ae9b..0000000 --- a/.config/xmobar/xmobarrc +++ /dev/null @@ -1,96 +0,0 @@ -Config { - - -- appearance - font = "xft:Bitstream Vera Sans Mono:size=11:bold:antialias=true" - , bgColor = "black" - , fgColor = "#bbbbbb" - , position = Top - , border = BottomB - , borderColor = "#646464" - - -- layout - , sepChar = "%" -- delineator between plugin names and straight text - , alignSep = "}{" -- separator between left-right alignment - , template = "%battery% | %multicpu% | %coretemp% | %memory% | %dynnetwork% }{ %date%" - - -- general behavior - , lowerOnStart = True -- send to bottom of window stack on start - , hideOnStart = False -- start with window unmapped (hidden) - , allDesktops = True -- show on all desktops - , overrideRedirect = True -- set the Override Redirect flag (Xlib) - , pickBroadest = False -- choose widest display (multi-monitor) - , persistent = True -- enable/disable hiding (True = disabled) - - -- plugins - -- Numbers can be automatically colored according to their value. xmobar - -- decides color based on a three-tier/two-cutoff system, controlled by - -- command options: - -- --Low sets the low cutoff - -- --High sets the high cutoff - -- - -- --low sets the color below --Low cutoff - -- --normal sets the color between --Low and --High cutoffs - -- --High sets the color above --High cutoff - -- - -- The --template option controls how the plugin is displayed. Text - -- color can be set by enclosing in tags. For more details - -- see http://projects.haskell.org/xmobar/#system-monitor-plugins. - , commands = - -- network activity monitor (dynamic interface resolution) - [ Run DynNetwork [ "--template" , ": kB/s|kB/s" - , "--Low" , "1000" -- units: B/s - , "--High" , "5000" -- units: B/s - , "--low" , "darkgreen" - , "--normal" , "darkorange" - , "--high" , "darkred" - ] 10 - - -- cpu activity monitor - , Run MultiCpu [ "--template" , "CPU: %" - , "--Low" , "50" -- units: % - , "--High" , "85" -- units: % - , "--low" , "darkgreen" - , "--normal" , "darkorange" - , "--high" , "darkred" - ] 10 - - -- cpu core temperature monitor - , Run CoreTemp [ "--template" , "Temp: °C" - , "--Low" , "70" -- units: °C - , "--High" , "80" -- units: °C - , "--low" , "darkgreen" - , "--normal" , "darkorange" - , "--high" , "darkred" - ] 50 - - -- memory usage monitor - , Run Memory [ "--template" ,"Mem: %" - , "--Low" , "25" -- units: % - , "--High" , "90" -- units: % - , "--low" , "darkgreen" - , "--normal" , "darkorange" - , "--high" , "darkred" - ] 10 - - -- battery monitor - , Run Battery [ "--template" , "Bat: " - , "--Low" , "10" -- units: % - , "--High" , "80" -- units: % - , "--low" , "darkred" - , "--normal" , "darkorange" - , "--high" , "darkgreen" - - , "--" -- battery specific options - -- discharging status - , "-o" , "% () W" - -- AC "on" status - , "-O" , "Charging" - -- charged status - , "-i" , "Charged" - ] 50 - - -- time and date indicator - , Run Date "%a %0d.%b.%Y %H:%M:%S" "date" 10 - ] - } - diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8b747ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# Home-directory targets owned by system-config/Decman. +.config/alacritty/ +.config/environment.d/pi-status-bridge.conf +.config/fish/config.fish +.config/hypr/ +.config/kitty/ +.config/mimeapps.list +.config/noctalia/ +.config/systemd/user/idle-inhibitor-monitor.service +.config/systemd/user/pi-status-bridge.service +.config/systemd/user/ssh-agent.service +.config/user-dirs.dirs +.config/yazi/ +.local/bin/idle-inhibitor-monitor +.local/bin/pi-status-ui +.local/bin/wayshell-blanker +.local/share/noctalia/plugins/knowledge-lookup/ +.local/share/noctalia/plugins/pi-status-bridge/ +.local/share/noctalia/plugins/system-status/ diff --git a/.local/share/noctalia/plugins/pi-status-bridge b/.local/share/noctalia/plugins/pi-status-bridge deleted file mode 120000 index d0b4ee1..0000000 --- a/.local/share/noctalia/plugins/pi-status-bridge +++ /dev/null @@ -1 +0,0 @@ -../../../../projects/pi-status-bridge/noctalia-v5-plugin/pi-status-bridge \ No newline at end of file diff --git a/.pi/agent/extensions/pi-permission-system/config.json b/.pi/agent/extensions/pi-permission-system/config.json index 3f84ca1..d698fbd 100644 --- a/.pi/agent/extensions/pi-permission-system/config.json +++ b/.pi/agent/extensions/pi-permission-system/config.json @@ -84,6 +84,8 @@ "echo *": "allow", "which *": "allow", "command -v *": "allow", + "find *": "allow", + "hypa *": "allow", "git status": "allow", "git status *": "allow", diff --git a/.xbindkeysrc b/.xbindkeysrc deleted file mode 100644 index 36e3902..0000000 --- a/.xbindkeysrc +++ /dev/null @@ -1,15 +0,0 @@ -# forward button => next song -"xte 'key XF86AudioPlay'" - b:9 - -# thumb wheel up => increase volume -"pamixer -i 2" -Mod4 + b:7 - -# thumb wheel down => lower volume -"pamixer -d 2" -Mod4 + b:6 - -# set reload page to pressing the mouse wheel -#"xte 'keydown ctrl' 'keydown r' 'keyup ctrl' 'keyup r'" -# b:2 diff --git a/.xmonad/xmonad.hs b/.xmonad/xmonad.hs deleted file mode 100644 index 032b571..0000000 --- a/.xmonad/xmonad.hs +++ /dev/null @@ -1,570 +0,0 @@ --- IMPORTS -- - -import System.IO -import System.Exit --- import System.Taffybar.Hooks.PagerHints (pagerHints) - -import qualified Data.List as L - -import XMonad -import XMonad.Actions.Navigation2D -import XMonad.Actions.SpawnOn -import XMonad.Actions.UpdatePointer - -import XMonad.Hooks.DynamicLog -import XMonad.Hooks.ManageDocks -import XMonad.Hooks.ManageHelpers -import XMonad.Hooks.SetWMName -import XMonad.Hooks.EwmhDesktops (ewmh) - -import XMonad.Layout.Gaps -import XMonad.Layout.Fullscreen -import XMonad.Layout.BinarySpacePartition as BSP -import XMonad.Layout.NoBorders -import XMonad.Layout.Tabbed -import XMonad.Layout.ThreeColumns -import XMonad.Layout.Spacing -import XMonad.Layout.MultiToggle -import XMonad.Layout.MultiToggle.Instances -import XMonad.Layout.NoFrillsDecoration -import XMonad.Layout.Renamed -import XMonad.Layout.Simplest -import XMonad.Layout.SubLayouts -import XMonad.Layout.WindowNavigation -import XMonad.Layout.ZoomRow - -import XMonad.Util.Run(spawnPipe) -import XMonad.Util.SpawnOnce -import XMonad.Util.EZConfig(additionalKeys) -import XMonad.Util.Cursor - -import Graphics.X11.ExtraTypes.XF86 -import qualified XMonad.StackSet as W -import qualified Data.Map as M - --- The preferred terminal program, which is used in a binding below and by --- certain contrib modules. --- -myTerminal = "alacritty" - --- The command to take a fullscreen screenshot. -myScreenshotFull = "flameshot full -c" -myScreenshotSelective = "flameshot gui" - -myScreensaver = "light-locker-command -l" - -myLauncher = "rofi -combi-mode drun,window -show combi -modi combi" - --- A tagging example: --- --- > workspaces = ["web", "irc", "code" ] ++ map show [4..9] --- -myWorkspaces = ["1: term","2: web","3: message","4: code", "5: vm", "6", "7", "8", "9: mail"] - ------------------------------------------------------------------------- --- Colors and borders - --- Color of current window title in xmobar. -xmobarTitleColor = "#C678DD" - --- Color of current workspace in xmobar. -xmobarCurrentWorkspaceColor = "#51AFEF" - --- Width of the window border in pixels. -myBorderWidth = 0 - -myNormalBorderColor = "#000000" -myFocusedBorderColor = active - -base03 = "#002b36" -base02 = "#073642" -base01 = "#586e75" -base00 = "#657b83" -base0 = "#839496" -base1 = "#93a1a1" -base2 = "#eee8d5" -base3 = "#fdf6e3" -yellow = "#b58900" -orange = "#cb4b16" -red = "#dc322f" -magenta = "#d33682" -violet = "#6c71c4" -blue = "#268bd2" -cyan = "#2aa198" -green = "#859900" - --- sizes -gap = 10 -topbar = 5 -border = 5 -prompt = 5 -status = 5 - -active = orange -activeWarn = red -inactive = orange -focusColor = orange -unfocusColor = base02 - --- myFont = "-*-Zekton-medium-*-*-*-*-160-*-*-*-*-*-*" --- myBigFont = "-*-Zekton-medium-*-*-*-*-240-*-*-*-*-*-*" -myFont = "xft:Zekton:size=9:bold:antialias=true" -myBigFont = "xft:Zekton:size=9:bold:antialias=true" -myWideFont = "xft:Eurostar Black Extended:" - ++ "style=Regular:pixelsize=180:hinting=true" - --- this is a "fake title" used as a highlight bar in lieu of full borders --- (I find this a cleaner and less visually intrusive solution) -topBarTheme = def - { - fontName = myFont - , inactiveBorderColor = base03 - , inactiveColor = base03 - , inactiveTextColor = base03 - , activeBorderColor = active - , activeColor = active - , activeTextColor = active - , urgentBorderColor = red - , urgentTextColor = yellow - , decoHeight = topbar - } - -addTopBar = noFrillsDeco shrinkText topBarTheme - -myTabTheme = def - { fontName = myFont - , activeColor = active - , inactiveColor = base02 - , activeBorderColor = active - , inactiveBorderColor = base02 - , activeTextColor = base03 - , inactiveTextColor = base00 - } - ------------------------------------------------------------------------- --- Key bindings --- --- modMask lets you specify which modkey you want to use. The default --- is mod1Mask ("left alt"). You may also consider using mod3Mask --- ("right alt"), which does not conflict with emacs keybindings. The --- "windows key" is usually mod4Mask. --- -myModMask = mod4Mask -altMask = mod1Mask - -myKeys conf@(XConfig {XMonad.modMask = modMask}) = M.fromList $ - ---------------------------------------------------------------------- - -- Custom key bindings - -- - - -- Start a terminal. Terminal to start is specified by myTerminal variable. - [ ((modMask .|. shiftMask, xK_Return), - spawn $ XMonad.terminal conf) - - -- Lock the screen using command specified by myScreensaver. - , ((modMask .|. shiftMask, xK_0), - spawn myScreensaver) - - -- go into sleep then hibernate - , ((modMask .|. shiftMask .|. controlMask, xK_0), - spawn "systemctl suspend-then-hibernate") - - -- Spawn the launcher using command specified by myLauncher. - -- Use this to launch programs without a key binding. - , ((modMask, xK_p), - spawn myLauncher) - - -- Take a full screenshot using the command specified by myScreenshot. - , ((modMask, xK_Print), - spawn myScreenshotFull) - - -- Take a full screenshot using the command specified by myScreenshot. - , ((modMask .|. controlMask, xK_Print), - spawn myScreenshotSelective) - - -- run autorandr to switch configuration - , ((modMask, xK_Home), - spawn "autorandr -c") - - -- Toggle current focus window to fullscreen - , ((modMask, xK_f), sendMessage $ Toggle FULL) - - -- Mute volume. - , ((0, xF86XK_AudioMute), - spawn "pamixer -t") - - -- Mute standard input device - , ((modMask, xF86XK_AudioMute), - spawn "pactl set-source-mute @DEFAULT_SOURCE@ toggle") - - -- Decrease volume. - , ((0, xF86XK_AudioLowerVolume), - spawn "pamixer --decrease 5") - - -- Increase volume. - , ((0, xF86XK_AudioRaiseVolume), - spawn "pamixer --increase 5") - - -- Audio previous. - , ((modMask, xF86XK_AudioLowerVolume), - spawn "playerctl previous") - , ((0, xF86XK_AudioPrev), - spawn "playerctl previous") - - - -- Play/pause. - , ((0, xF86XK_AudioPlay), - spawn "playerctl play-pause") - - -- Audio next. - , ((modMask, xF86XK_AudioRaiseVolume), - spawn "playerctl next") - , ((0, xF86XK_AudioNext), - spawn "playerctl next") - - - -- Increase brigthness - , ((0, xF86XK_MonBrightnessUp), - spawn "light -A 5") - - -- Increase brigthness - , ((modMask, xF86XK_MonBrightnessUp), - spawn "light -S 100") - - , ((0, xF86XK_MonBrightnessDown), - spawn "light -U 5") - - , ((modMask, xF86XK_MonBrightnessDown), - spawn "light -S 0.2") - -------------------------------------------------------------------- - -- "Standard" xmonad key bindings - -- - - -- Close focused window. - , ((modMask .|. shiftMask, xK_c), - kill) - - -- Cycle through the available layout algorithms. - , ((modMask, xK_space), - sendMessage NextLayout) - - -- Reset the layouts on the current workspace to default. - , ((modMask .|. shiftMask, xK_space), - setLayout $ XMonad.layoutHook conf) - - -- Resize viewed windows to the correct size. - , ((modMask, xK_n), - refresh) - - -- Move focus to the next window. - , ((modMask, xK_j), - windows W.focusDown) - - -- Move focus to the previous window. - , ((modMask, xK_k), - windows W.focusUp ) - - -- Move focus to the master window. - , ((modMask, xK_m), - windows W.focusMaster ) - - -- Swap the focused window and the master window. - , ((modMask, xK_Return), - windows W.swapMaster) - - -- Swap the focused window with the next window. - , ((modMask .|. shiftMask, xK_j), - windows W.swapDown ) - - -- Swap the focused window with the previous window. - , ((modMask .|. shiftMask, xK_k), - windows W.swapUp ) - - -- Shrink the master area. - , ((modMask, xK_h), - sendMessage Shrink) - - -- Expand the master area. - , ((modMask, xK_l), - sendMessage Expand) - - -- Push window back into tiling. - , ((modMask, xK_t), - withFocused $ windows . W.sink) - - -- Increment the number of windows in the master area. - , ((modMask, xK_comma), - sendMessage (IncMasterN 1)) - - -- Decrement the number of windows in the master area. - , ((modMask, xK_period), - sendMessage (IncMasterN (-1))) - - -- Toggle polybar - , ((modMask .|. shiftMask, xK_f), - spawn "polybar-msg cmd toggle") - - -- lock screen - , ((modMask .|. shiftMask, xK_0), - spawn "light-locker-command -l") - - -- Quit xmonad. - , ((modMask .|. shiftMask, xK_q), - io (exitWith ExitSuccess)) - - -- Restart xmonad. - , ((modMask, xK_q), - spawn "xmonad --recompile && xmonad --restart") - ] - ++ - - -- mod-[1..9], Switch to workspace N - -- mod-shift-[1..9], Move client to workspace N - [((m .|. modMask, k), windows $ f i) - | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9] - , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]] - ++ - - -- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3 - -- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3 - [((m .|. modMask, key), screenWorkspace sc >>= flip whenJust (windows . f)) - | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..] - , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]] - - - ++ - -- Bindings for manage sub tabs in layouts please checkout the link below for reference - -- https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Layout-SubLayouts.html - [ - -- Tab current focused window with the window to the left - ((modMask .|. controlMask, xK_h), sendMessage $ pullGroup L) - -- Tab current focused window with the window to the right - , ((modMask .|. controlMask, xK_l), sendMessage $ pullGroup R) - -- Tab current focused window with the window above - , ((modMask .|. controlMask, xK_k), sendMessage $ pullGroup U) - -- Tab current focused window with the window below - , ((modMask .|. controlMask, xK_j), sendMessage $ pullGroup D) - - -- Tab all windows in the current workspace with current window as the focus - , ((modMask .|. controlMask, xK_m), withFocused (sendMessage . MergeAll)) - -- Group the current tabbed windows - , ((modMask .|. controlMask, xK_u), withFocused (sendMessage . UnMerge)) - - -- Toggle through tabes from the right - , ((modMask, xK_Tab), onGroup W.focusDown') - ] - - ++ - -- Some bindings for BinarySpacePartition - -- https://github.com/benweitzman/BinarySpacePartition - [ - ((modMask .|. controlMask, xK_Right ), sendMessage $ ExpandTowards R) - , ((modMask .|. controlMask .|. shiftMask, xK_Right ), sendMessage $ ShrinkFrom R) - , ((modMask .|. controlMask, xK_Left ), sendMessage $ ExpandTowards L) - , ((modMask .|. controlMask .|. shiftMask, xK_Left ), sendMessage $ ShrinkFrom L) - , ((modMask .|. controlMask, xK_Down ), sendMessage $ ExpandTowards D) - , ((modMask .|. controlMask .|. shiftMask, xK_Down ), sendMessage $ ShrinkFrom D) - , ((modMask .|. controlMask, xK_Up ), sendMessage $ ExpandTowards U) - , ((modMask .|. controlMask .|. shiftMask, xK_Up ), sendMessage $ ShrinkFrom U) - , ((modMask, xK_r ), sendMessage BSP.Rotate) - , ((modMask, xK_s ), sendMessage BSP.Swap) - -- , ((modMask, xK_n ), sendMessage BSP.FocusParent) - -- , ((modMask .|. controlMask, xK_n ), sendMessage BSP.SelectNode) - -- , ((modMask .|. shiftMask, xK_n ), sendMessage BSP.MoveNode) - ] - - ------------------------------------------------------------------------- --- Mouse bindings --- --- Focus rules --- True if your focus should follow your mouse cursor. -myFocusFollowsMouse :: Bool -myFocusFollowsMouse = True - -myMouseBindings (XConfig {XMonad.modMask = modMask}) = M.fromList $ - [ - -- mod-button1, Set the window to floating mode and move by dragging - ((modMask, button1), - (\w -> focus w >> mouseMoveWindow w)) - - -- mod-button2, Raise the window to the top of the stack - , ((modMask, button2), - (\w -> focus w >> windows W.swapMaster)) - - -- mod-button3, Set the window to floating mode and resize by dragging - , ((modMask, button3), - (\w -> focus w >> mouseResizeWindow w)) - - -- you may also bind events to the mouse scroll wheel (button4 and button5) - ] - ------------------------------------------------------------------------- --- Layouts: - --- You can specify and transform your layouts by modifying these values. --- If you change layout bindings be sure to use 'mod-shift-space' after --- restarting (with 'mod-q') to reset your layout state to the new --- defaults, as xmonad preserves your old layout settings by default. --- --- The available layouts. Note that each layout is separated by |||, --- which denotes layout choice. --- - - -outerGaps = 10 -myGaps = gaps [(U, outerGaps), (R, outerGaps), (L, outerGaps), (D, outerGaps)] -addSpace = renamed [CutWordsLeft 2] . spacing gap -tab = avoidStruts - $ renamed [Replace "Tabbed"] - $ addTopBar - $ myGaps - $ tabbed shrinkText myTabTheme - -layouts = avoidStruts ( - ( - renamed [CutWordsLeft 1] - $ addTopBar - $ windowNavigation - $ renamed [Replace "BSP"] - $ addTabs shrinkText myTabTheme - $ subLayout [] Simplest - $ myGaps - $ addSpace (BSP.emptyBSP) - ) - ||| tab - ) - -myLayout = smartBorders - $ mkToggle (NOBORDERS ?? FULL ?? EOT) - $ layouts - -myNav2DConf = def - { defaultTiledNavigation = centerNavigation - , floatNavigation = centerNavigation - , screenNavigation = lineNavigation - , layoutNavigation = [("Full", centerNavigation) - -- line/center same results ,("Tabs", lineNavigation) - -- ,("Tabs", centerNavigation) - ] - , unmappedWindowRect = [("Full", singleWindowRect) - -- works but breaks tab deco ,("Tabs", singleWindowRect) - -- doesn't work but deco ok ,("Tabs", fullScreenRect) - ] - } - ------------------------------------------------------------------------- --- Window rules: - --- Execute arbitrary actions and WindowSet manipulations when managing --- a new window. You can use this to, for example, always float a --- particular program, or have a client always appear on a particular --- workspace. --- --- To find the property name associated with a program, use --- > xprop | grep WM_CLASS --- and click on the client you're interested in. --- --- To match on the WM_NAME, you can use 'title' in the same way that --- 'className' and 'resource' are used below. --- -myManageHook = composeAll - [ className =? "MPlayer" --> doFloat - , className =? "Gimp" --> doFloat - , className =? "firefox" --> doShift "2: web" - , className =? "thunderbird" --> doShift "9: mail" - , resource =? "desktop_window" --> doIgnore - , resource =? "kdesktop" --> doIgnore - , className =? "VirtualBox" --> doShift "5: vm" - , className =? "pycharm" --> doShift "4" - , isFullscreen --> (doF W.focusDown <+> doFullFloat) - ] - - ------------------------------------------------------------------------- --- Event handling - --- * EwmhDesktops users should change this to ewmhDesktopsEventHook --- --- Defines a custom handler function for X Events. The function should --- return (All True) if the default handler is to be run afterwards. To --- combine event hooks use mappend or mconcat from Data.Monoid. --- --- myEventHook = empty - ------------------------------------------------------------------------- --- Status bars and logging - --- Perform an arbitrary action on each internal state change or X event. --- See the 'XMonad.Hooks.DynamicLog' extension for examples. --- --- myLogHook = return () - ------------------------------------------------------------------------- --- Startup hook - --- Perform an arbitrary action each time xmonad starts or is restarted --- with mod-q. Used by, e.g., XMonad.Layout.PerWorkspace to initialize --- per-workspace layout choices. --- --- By default, do nothing. -myStartupHook = do - -- spawn once not necessary here, since the launch script takes care of multiple instances - spawn "~/.config/polybar/launch.sh" - spawnOnce "redshift ~/.config/redshift/redshift.conf &" - spawnOnce "mullvad-vpn &" - spawnOnce "sleep 2 && nextcloud &" - --spawnOnce "xscreensaver -nosplash &" - spawnOnce "flameshot &" - - -- spawn startup programs at specific workspaces - ------------------------------------------------------------------------- --- Now run xmonad with all the defaults we set up. - --- Run xmonad with the settings you specify. No need to modify this. --- -main = do - --xmproc <- spawnPipe "/home/arch/.config/xmobar/launch.sh" - -- xmproc <- spawnPipe "sleep 2 && sudo torguard &" - xmonad $ docks - $ withNavigation2DConfig myNav2DConf - $ additionalNav2DKeys (xK_Up, xK_Left, xK_Down, xK_Right) - [ - (mod4Mask, windowGo ) - , (mod4Mask .|. shiftMask, windowSwap) - ] - False - $ ewmh - -- $ pagerHints -- uncomment to use taffybar - $ defaults - - - --- A structure containing your configuration settings, overriding --- fields in the default config. Any you don't override, will --- use the defaults defined in xmonad/XMonad/Config.hs --- --- No need to modify this. --- -defaults = def { - -- simple stuff - terminal = myTerminal, - focusFollowsMouse = myFocusFollowsMouse, - borderWidth = myBorderWidth, - modMask = myModMask, - workspaces = myWorkspaces, - normalBorderColor = myNormalBorderColor, - focusedBorderColor = myFocusedBorderColor, - - -- key bindings - keys = myKeys, - mouseBindings = myMouseBindings, - - -- hooks, layouts - layoutHook = myLayout, - -- handleEventHook = E.fullscreenEventHook, - handleEventHook = fullscreenEventHook, - manageHook = manageDocks <+> myManageHook, - startupHook = myStartupHook -} diff --git a/.xprofile##class.arch_desktop b/.xprofile##class.arch_desktop deleted file mode 100644 index db62bbc..0000000 --- a/.xprofile##class.arch_desktop +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -export AWT_TOOLKIT=MToolkit -export LUTRIS_RUNTIME=0 - -xrandr --dpi 110 & -xrdb -merge ~/.Xresources & diff --git a/.xprofile##class.arch_laptop b/.xprofile##class.arch_laptop deleted file mode 100644 index c0397b1..0000000 --- a/.xprofile##class.arch_laptop +++ /dev/null @@ -1,15 +0,0 @@ -xrdb -merge ~/.Xresources -xrandr --dpi 192 -export GDK_SCALE=1 -export ELM_SCALE=1 -export QT_AUTO_SCREEN_SCALE_FACTOR=1 -exoprt MOZ_USE_XINPUT2=1 -export MESA_LOADER_DRIVER_OVERRIDE=i965 - -(sleep 5 && xset dpms 300 300 300) & - -xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/logind-handle-lid-switch -n -t bool -s true & -xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/logind-handle-power-key -n -t bool -s true & -export ESPIDF=/opt/esp-idf & - -[[ -f ~/.Xmodmap ]] && xmodmap ~/.Xmodmap & diff --git a/.xprofile##class.arch_laptop_work b/.xprofile##class.arch_laptop_work deleted file mode 100644 index 05916ac..0000000 --- a/.xprofile##class.arch_laptop_work +++ /dev/null @@ -1,16 +0,0 @@ -export AWT_TOOLKIT=MToolkit -export _JAVA_AWT_WM_NONREPARENTING=1 - -blueman-applet & -xbindkeys & -optimus-manager-qt & -light-locker & -xrdb -merge ~/.Xresources - -xrandr --dpi 115 & - -(sleep 5 && xset dpms 300 300 300) & - -xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/logind-handle-lid-switch -n -t bool -s true -xfconf-query -c xfce4-power-manager -p /xfce4-power-manager/logind-handle-power-key -n -t bool -s true - diff --git a/.xprofile##class.arch_work_desktop b/.xprofile##class.arch_work_desktop deleted file mode 100644 index 18ef7cb..0000000 --- a/.xprofile##class.arch_work_desktop +++ /dev/null @@ -1,12 +0,0 @@ -export AWT_TOOLKIT=MToolkit - -xrandr --dpi 92 & -xrdb -merge ~/.Xresources & - -xset s 300 0 & -xset s blank & -xset +dpms & -xsetroot -solid black & -xset-root -solid black & - -powerline-config tmux setup & diff --git a/system-config/PACKAGE_AUDIT.md b/system-config/PACKAGE_AUDIT.md new file mode 100644 index 0000000..294ade6 --- /dev/null +++ b/system-config/PACKAGE_AUDIT.md @@ -0,0 +1,205 @@ +# Desktop Package Audit + +Generated from `pacman -Qen` (official repository, explicitly installed) and `pacman -Qem` (AUR/foreign, explicitly installed). Package versions are included so this is an exact inventory. + +## Decision key + +- **KEEP**: already declared by a shared desktop concern. +- **REVIEW**: currently installed but not proven necessary by a configuration. The newly created `desktop/local` lists are provisional protection against an over-broad first Decman run; remove a package from those lists only after deciding to retire it. +- **RETIRE**: selected from the approved legacy non-Wayland cleanup or the NetworkManager-only decision. These will be omitted from the desktop profile. + +## Official repository packages (124) + +| Package | Version | Proposed status | +| --- | --- | --- | +| `alacritty` | `0.17.0-1` | KEEP — declared common desktop concern | +| `audacity` | `1:3.7.8-2` | KEEP — declared common desktop concern | +| `base` | `3-3` | KEEP — declared common desktop concern | +| `base-devel` | `1-2` | KEEP — declared common desktop concern | +| `biber` | `1:2.21-3` | KEEP — declared common desktop concern | +| `blueman` | `2.4.6-2` | KEEP — declared common desktop concern | +| `bun` | `1.3.14-1` | REVIEW — provisional desktop/local retention candidate | +| `chromium` | `150.0.7871.186-1` | KEEP — declared common desktop concern | +| `code` | `1.130.0-2` | REVIEW — provisional desktop/local retention candidate | +| `cryptsetup` | `2.8.7-1` | KEEP — declared common desktop concern | +| `cudnn` | `9.24.0.43-1` | KEEP — declared common desktop concern | +| `dhcpcd` | `10.3.2-1` | RETIRE — legacy X11 or superseded network/colour tool | +| `docker` | `1:29.6.2-1` | KEEP — declared common desktop concern | +| `docker-compose` | `5.3.1-1` | KEEP — declared common desktop concern | +| `evince` | `1:48.4-1` | KEEP — declared common desktop concern | +| `ex-vi-compat` | `2-1` | KEEP — declared common desktop concern | +| `fakeroot` | `1:1.37.2-3` | REVIEW — provisional desktop/local retention candidate | +| `fish` | `4.8.1-1` | KEEP — declared common desktop concern | +| `flameshot` | `14.0.0-1` | KEEP — declared common desktop concern | +| `gammastep` | `2.0.11-2` | RETIRE — legacy X11 or superseded network/colour tool | +| `geoclue` | `2.8.2-1` | REVIEW — provisional desktop/local retention candidate | +| `git` | `2.55.0-1` | KEEP — declared common desktop concern | +| `github-cli` | `2.96.0-1` | REVIEW — provisional desktop/local retention candidate | +| `glances` | `4.5.5-1` | KEEP — declared common desktop concern | +| `gnome-font-viewer` | `50.0-1` | REVIEW — provisional desktop/local retention candidate | +| `gtk4-layer-shell` | `1.3.0-1` | REVIEW — provisional desktop/local retention candidate | +| `hypridle` | `0.1.8-1` | KEEP — declared common desktop concern | +| `hyprland` | `0.56.1-2` | KEEP — declared common desktop concern | +| `i3-wm` | `4.25.1-1` | RETIRE — legacy X11 or superseded network/colour tool | +| `jq` | `1.8.2-1` | KEEP — declared common desktop concern | +| `jre-openjdk` | `26.0.2.u10-1` | REVIEW — provisional desktop/local retention candidate | +| `keyd` | `2.6.0-5` | KEEP — declared common desktop concern | +| `lib32-libpulse` | `17.0+r98+gb096704c0-1` | REVIEW — provisional desktop/local retention candidate | +| `lib32-vkd3d` | `1.19-1` | REVIEW — provisional desktop/local retention candidate | +| `libreoffice-fresh` | `26.2.5-1` | KEEP — declared common desktop concern | +| `lightdm` | `1:1.32.0-9` | RETIRE — legacy X11 or superseded network/colour tool | +| `linux` | `7.1.5.arch1-2` | KEEP — declared common desktop concern | +| `linux-firmware` | `20260622-1` | KEEP — declared common desktop concern | +| `linux-headers` | `7.1.5.arch1-2` | KEEP — declared common desktop concern | +| `lsof` | `4.99.7-1` | REVIEW — provisional desktop/local retention candidate | +| `lvm2` | `2.03.41-1` | REVIEW — provisional desktop/local retention candidate | +| `man-db` | `2.13.1-2` | KEEP — declared common desktop concern | +| `mpv` | `1:0.41.0-3` | REVIEW — provisional desktop/local retention candidate | +| `neovim` | `0.12.4-1` | KEEP — declared common desktop concern | +| `networkmanager` | `1.58.0-1` | KEEP — declared common desktop concern | +| `nextcloud-client` | `2:33.0.7-1` | KEEP — declared common desktop concern | +| `npm` | `12.0.1-1` | KEEP — declared common desktop concern | +| `ntfs-3g` | `2026.7.7-1` | KEEP — declared common desktop concern | +| `numlockx` | `1.2-6` | REVIEW — provisional desktop/local retention candidate | +| `nvidia-container-toolkit` | `1.19.1-1` | REVIEW — provisional desktop/local retention candidate | +| `nvidia-open` | `610.43.03-9` | KEEP — declared common desktop concern | +| `nvidia-settings` | `610.43.03-1` | REVIEW — provisional desktop/local retention candidate | +| `nvtop` | `3.3.2-1` | KEEP — declared common desktop concern | +| `obsidian` | `1.12.7-3` | KEEP — declared common desktop concern | +| `ollama-cuda` | `0.32.5-1` | REVIEW — provisional desktop/local retention candidate | +| `opencode` | `1.18.8-1` | REVIEW — provisional desktop/local retention candidate | +| `os-prober` | `1.84-1` | KEEP — declared common desktop concern | +| `pavucontrol` | `1:6.2-1` | KEEP — declared common desktop concern | +| `perl-yaml-tiny` | `1.76-3` | REVIEW — provisional desktop/local retention candidate | +| `pipewire` | `1:1.6.8-1` | REVIEW — provisional desktop/local retention candidate | +| `pipewire-pulse` | `1:1.6.8-1` | KEEP — declared common desktop concern | +| `polybar` | `3.7.2-2` | RETIRE — legacy X11 or superseded network/colour tool | +| `powerline` | `2.8.4-4` | REVIEW — provisional desktop/local retention candidate | +| `pyenv` | `1:2.8.1-1` | KEEP — declared common desktop concern | +| `qalculate-qt` | `5.12.0-1` | KEEP — declared common desktop concern | +| `qbittorrent` | `5.2.3-3` | KEEP — declared common desktop concern | +| `qpwgraph` | `1.0.3-1` | REVIEW — provisional desktop/local retention candidate | +| `r` | `4.6.1-1` | KEEP — declared common desktop concern | +| `ranger` | `1.9.4-5` | REVIEW — provisional desktop/local retention candidate | +| `refind` | `0.14.2-3` | KEEP — declared common desktop concern | +| `retry` | `1.0.6-1` | REVIEW — provisional desktop/local retention candidate | +| `rofi` | `2.0.0-1` | KEEP — declared common desktop concern | +| `rpi-imager` | `2.0.9-1` | REVIEW — provisional desktop/local retention candidate | +| `rsync` | `3.4.4-1` | KEEP — declared common desktop concern | +| `rustup` | `1.29.0-2` | REVIEW — provisional desktop/local retention candidate | +| `screengrab` | `3.2.0-1` | REVIEW — provisional desktop/local retention candidate | +| `sddm` | `0.21.0-7` | KEEP — declared common desktop concern | +| `seahorse` | `1:47.0.1-6` | REVIEW — provisional desktop/local retention candidate | +| `signal-desktop` | `8.20.0-1` | KEEP — declared common desktop concern | +| `smplayer` | `25.6.0-2` | KEEP — declared common desktop concern | +| `starship` | `1.26.0-1` | KEEP — declared common desktop concern | +| `steam` | `1.0.0.87-1` | KEEP — declared common desktop concern | +| `sudo` | `1.9.17.p2-6` | REVIEW — provisional desktop/local retention candidate | +| `sway` | `1:1.12-4` | REVIEW — provisional desktop/local retention candidate | +| `teamspeak3` | `3.6.2-6` | KEEP — declared common desktop concern | +| `texlive-basic` | `2026.1-1` | KEEP — declared common desktop concern | +| `texlive-bin` | `2026.0-2` | REVIEW — provisional desktop/local retention candidate | +| `texlive-fontsrecommended` | `2026.1-1` | KEEP — declared common desktop concern | +| `texlive-latex` | `2026.1-1` | KEEP — declared common desktop concern | +| `texlive-latexextra` | `2026.1-1` | KEEP — declared common desktop concern | +| `texlive-latexrecommended` | `2026.1-1` | KEEP — declared common desktop concern | +| `texlive-meta` | `2026.1-1` | REVIEW — provisional desktop/local retention candidate | +| `thunderbird` | `153.0-1` | KEEP — declared common desktop concern | +| `tmux` | `3.7_b-1` | KEEP — declared common desktop concern | +| `tree` | `2.3.2-1` | REVIEW — provisional desktop/local retention candidate | +| `ttf-jetbrains-mono-nerd` | `3.4.0-2` | KEEP — declared common desktop concern | +| `ttf-meslo-nerd` | `3.4.0-2` | REVIEW — provisional desktop/local retention candidate | +| `ueberzug` | `18.3.1-5` | REVIEW — provisional desktop/local retention candidate | +| `unrar` | `1:7.2.7-1` | REVIEW — provisional desktop/local retention candidate | +| `vim` | `9.2.0849-1` | KEEP — declared common desktop concern | +| `virtualbox` | `7.2.14-1` | KEEP — declared common desktop concern | +| `vkd3d` | `1.19-1` | REVIEW — provisional desktop/local retention candidate | +| `vlc` | `3.0.23_2-9` | KEEP — declared common desktop concern | +| `vlc-plugins-all` | `3.0.23_2-9` | REVIEW — provisional desktop/local retention candidate | +| `vulkan-mesa-layers` | `1:26.1.5-1` | REVIEW — provisional desktop/local retention candidate | +| `vulkan-radeon` | `1:26.1.5-1` | REVIEW — provisional desktop/local retention candidate | +| `vulkan-tools` | `1.4.350.1-1` | KEEP — declared common desktop concern | +| `waybar` | `0.15.0-2` | KEEP — declared common desktop concern | +| `wdisplays` | `1.1.3-2` | REVIEW — provisional desktop/local retention candidate | +| `wget` | `1.25.0-6` | REVIEW — provisional desktop/local retention candidate | +| `wine` | `11.14-2` | REVIEW — provisional desktop/local retention candidate | +| `winetricks` | `20260125-2` | REVIEW — provisional desktop/local retention candidate | +| `wl-clipboard` | `1:2.3.0-1` | KEEP — declared common desktop concern | +| `xclip` | `0.13-6` | RETIRE — legacy X11 or superseded network/colour tool | +| `xorg-server` | `21.1.24-1` | RETIRE — legacy X11 or superseded network/colour tool | +| `xorg-xauth` | `1.1.5-1` | RETIRE — legacy X11 or superseded network/colour tool | +| `xorg-xinit` | `1.4.4-1` | RETIRE — legacy X11 or superseded network/colour tool | +| `xorg-xkill` | `1.0.7-1` | RETIRE — legacy X11 or superseded network/colour tool | +| `xorg-xsetroot` | `1.1.4-1` | RETIRE — legacy X11 or superseded network/colour tool | +| `xorg-xwayland` | `24.1.13-1` | KEEP — declared common desktop concern | +| `xournalpp` | `1.3.5-1` | REVIEW — provisional desktop/local retention candidate | +| `xsel` | `1.2.1-2` | RETIRE — legacy X11 or superseded network/colour tool | +| `yadm` | `3.5.0-1` | KEEP — declared common desktop concern | +| `zellij` | `0.44.3-1` | KEEP — declared common desktop concern | + +## AUR / foreign packages (19) + +| Package | Version | Proposed status | +| --- | --- | --- | +| `ashell-bin` | `0.9.0-1` | REVIEW — provisional desktop/local retention candidate | +| `ausweisapp2` | `2.4.0-1` | REVIEW — provisional desktop/local retention candidate | +| `beads` | `1.0.3-1` | REVIEW — provisional desktop/local retention candidate | +| `brave-bin` | `1:1.92.140-1` | KEEP — declared common desktop concern | +| `decman` | `1.2.2-2` | KEEP — declared common desktop concern | +| `downgrade` | `12.0.2-1` | REVIEW — provisional desktop/local retention candidate | +| `lutris-git` | `0.5.22.r394.g1b0f116-1` | REVIEW — provisional desktop/local retention candidate | +| `mongodb-compass-bin` | `1.49.11-2` | KEEP — declared common desktop concern | +| `mullvad-vpn-beta-bin` | `2026.3.stable-1` | KEEP — declared common desktop concern | +| `noctalia` | `5.0.0_beta.3-2` | REVIEW — provisional desktop/local retention candidate | +| `nomacs-git` | `3.23.2.r0.gccb6ff42-1` | REVIEW — provisional desktop/local retention candidate | +| `pycharm-professional` | `2025.2.2-1` | REVIEW — provisional desktop/local retention candidate | +| `rustrover` | `2026.1.3-1` | REVIEW — provisional desktop/local retention candidate | +| `spotify` | `1:1.2.92.147-1` | KEEP — declared common desktop concern | +| `xclicker` | `1.5.1-1` | REVIEW — provisional desktop/local retention candidate | +| `yay` | `13.0.1-1` | KEEP — declared common desktop concern | +| `yay-debug` | `12.5.0-1` | REVIEW — undeclared explicit package | +| `zotero-bin` | `9.0.6-1` | KEEP — declared common desktop concern | +| `zsa-keymapp-bin` | `1.3.7-1` | REVIEW — provisional desktop/local retention candidate | + +## Initial retirement set + +```text +dhcpcd +gammastep +i3-wm +lightdm +polybar +xclip +xorg-server +xorg-xauth +xorg-xinit +xorg-xkill +xorg-xsetroot +xsel +``` + +## Approved follow-up retirement + +In addition to the initial set, remove these selected groups from the desktop profile: + +```text +ashell-bin +ausweisapp2 +code +gammastep +gnome-font-viewer +lib32-libpulse +lib32-vkd3d +lutris-git +pycharm-professional +rpi-imager +rustrover +ueberzug +vkd3d +vulkan-mesa-layers +wine +winetricks +xclicker +``` + +Keep `nomacs-git` (the current PNG default), `zsa-keymapp-bin` (matches the managed ZSA rules), and the declared TeX Live stack. The desktop package lists now reflect these decisions; a Decman dry run must confirm the exact removal closure before applying it. diff --git a/system-config/README.md b/system-config/README.md index b1d455d..bba5ca5 100644 --- a/system-config/README.md +++ b/system-config/README.md @@ -6,16 +6,18 @@ A small, declarative Arch configuration managed by Decman. - **Concerns live in `packages/`**: each concern has a native (`*-repo.txt`) and AUR (`*-aur.txt`) list. -- **Hosts live in `hosts.py`**: a host composes concerns. `laptop()` contains - every explicit package. `desktop()` begins with shared concerns only. +- **Hosts live in `hosts.py`**: a host composes package concerns and explicit + system state. `desktop()` owns this desktop's boot, storage, NVIDIA, input, + SDDM, network-policy, and user-session configuration. - **System files live in `config/system/`**: shared files go in `common/`; hardware, sleep/logind, and boot policy go in the relevant host directory. - **State lives in `manifests/`**: units follow the same concern and host scopes as packages. - **Python glue lives in `modules/`**: package and system-state adapters only. -No yadm migration, user-home dotfiles, or application state is managed here. -Those can be added later as small, explicit modules. +Decman owns the listed system files and selected durable home configuration. +yadm owns remaining portable dotfiles; application state, browser profiles, +NetworkManager connection profiles, and project build output remain unmanaged. ## System policy @@ -29,8 +31,9 @@ Those can be added later as small, explicit modules. remains in `config/system/laptop/systemd/`. - `config/system/laptop/power/tlp.conf` owns laptop power policy. TLP reads `/etc/tlp.conf` after drop-ins, so a whole-file policy is required here. -- `config/system/laptop/boot/mkinitcpio.conf` owns encrypted-root and resume - initramfs hooks; its module rebuilds the initramfs after a change. +- `config/system/{laptop,desktop}/boot/mkinitcpio.conf` owns encrypted-root + and resume initramfs hooks for each host; its module rebuilds the initramfs + after a change. - `config/system/laptop/refind/` owns the laptop ESP rEFInd configuration and encrypted-root kernel options. It is intentionally laptop-only. - `config/system/laptop/iwlwifi.conf` retains the Wi-Fi 6 stability workaround; @@ -49,7 +52,7 @@ remove those explicitly in a separate reviewed package change. | --- | --- | | Shared | core, wayland, fonts, development, productivity, media, research, network, services | | Laptop | hardware, legacy; hardware units | -| Desktop | shared concerns now; add `packages/desktop/-{repo,aur}.txt` when hardware/software differs | +| Desktop | shared concerns, `common/hardware`, and a reviewable `desktop/local` set; host state is in `config/system/desktop/` | Every package must have a named purpose. Add a new concern when an existing one does not explain a package. System and user units use the same naming: diff --git a/system-config/config/system/desktop/boot/mkinitcpio.conf b/system-config/config/system/desktop/boot/mkinitcpio.conf new file mode 100644 index 0000000..6ee461b --- /dev/null +++ b/system-config/config/system/desktop/boot/mkinitcpio.conf @@ -0,0 +1,81 @@ +# vim:set ft=sh +# MODULES +# The following modules are loaded before any boot hooks are +# run. Advanced users may wish to specify all system modules +# in this array. For instance: +# MODULES=(usbhid xhci_hcd) +MODULES=() + +# BINARIES +# This setting includes any additional binaries a given user may +# wish into the CPIO image. This is run last, so it may be used to +# override the actual binaries included by a given hook +# BINARIES are dependency parsed, so you may safely ignore libraries +BINARIES=() + +# FILES +# This setting is similar to BINARIES above, however, files are added +# as-is and are not parsed in any way. This is useful for config files. +FILES=() + +# HOOKS +# This is the most important setting in this file. The HOOKS control the +# modules and scripts added to the image, and what happens at boot time. +# Order is important, and it is recommended that you do not change the +# order in which HOOKS are added. Run 'mkinitcpio -H ' for +# help on a given hook. +# 'base' is _required_ unless you know precisely what you are doing. +# 'udev' is _required_ in order to automatically load modules +# 'filesystems' is _required_ unless you specify your fs modules in MODULES +# Examples: +## This setup specifies all modules in the MODULES setting above. +## No RAID, lvm2, or encrypted root is needed. +# HOOKS=(base) +# +## This setup will autodetect all modules for your system and should +## work as a sane default +# HOOKS=(base udev autodetect modconf block filesystems fsck) +# +## This setup will generate a 'full' image which supports most systems. +## No autodetection is done. +# HOOKS=(base udev modconf block filesystems fsck) +# +## This setup assembles a mdadm array with an encrypted root file system. +## Note: See 'mkinitcpio -H mdadm_udev' for more information on RAID devices. +# HOOKS=(base udev modconf keyboard keymap consolefont block mdadm_udev encrypt filesystems fsck) +# +## This setup loads an lvm2 volume group. +# HOOKS=(base udev modconf block lvm2 filesystems fsck) +# +## This will create a systemd based initramfs which loads an encrypted root filesystem. +# HOOKS=(base systemd autodetect modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck) +# +## NOTE: If you have /usr on a separate partition, you MUST include the +# usr and fsck hooks. +HOOKS=(base udev autodetect microcode modconf kms keyboard keymap encrypt lvm2 consolefont block filesystems resume fsck) + +# COMPRESSION +# Use this to compress the initramfs image. By default, zstd compression +# is used for Linux ≥ 5.9 and gzip compression is used for Linux < 5.9. +# Use 'cat' to create an uncompressed image. +#COMPRESSION="zstd" +#COMPRESSION="gzip" +#COMPRESSION="bzip2" +#COMPRESSION="lzma" +#COMPRESSION="xz" +#COMPRESSION="lzop" +#COMPRESSION="lz4" + +# COMPRESSION_OPTIONS +# Additional options for the compressor +#COMPRESSION_OPTIONS=() + +# MODULES_DECOMPRESS +# Decompress loadable kernel modules and their firmware during initramfs +# creation. Switch (yes/no). +# Enable to allow further decreasing image size when using high compression +# (e.g. xz -9e or zstd --long --ultra -22) at the expense of increased RAM usage +# at early boot. +# Note that any compressed files will be placed in the uncompressed early CPIO +# to avoid double compression. +#MODULES_DECOMPRESS="no" diff --git a/system-config/config/system/desktop/boot/refind.conf b/system-config/config/system/desktop/boot/refind.conf new file mode 100644 index 0000000..2ef1fea --- /dev/null +++ b/system-config/config/system/desktop/boot/refind.conf @@ -0,0 +1,749 @@ +# +# refind.conf +# Configuration file for the rEFInd boot menu +# + +# Timeout in seconds for the main menu screen. Setting the timeout to 0 +# disables automatic booting (i.e., no timeout). Setting it to -1 causes +# an immediate boot to the default OS *UNLESS* a keypress is in the buffer +# when rEFInd launches, in which case that keypress is interpreted as a +# shortcut key. If no matching shortcut is found, rEFInd displays its +# menu with no timeout. +# +timeout 20 + +# Set the logging level. When set to 0, rEFInd does not log its actions. +# When set to 1 or above, rEFInd creates a file called refind.log in +# its home directory on the ESP and records information about what it's +# doing. Higher values record more information, up to a maximum of 4. +# This token should be left at the default of 0 except when debugging +# problems. +# Default value is 0 +# +#log_level 1 + +# Normally, when the timeout period has passed, rEFInd boots the +# default_selection. If the following option is uncommented, though, +# rEFInd will instead attempt to shut down the computer. +# CAUTION: MANY COMPUTERS WILL INSTEAD HANG OR REBOOT! Macs and more +# recent UEFI-based PCs are most likely to work with this feature. +# Default value is true +# +#shutdown_after_timeout + +# Whether to store rEFInd's rEFInd-specific variables in NVRAM (1, true, +# or on) or in files in the "vars" subdirectory of rEFInd's directory on +# disk (0, false, or off). Using NVRAM works well with most computers; +# however, it increases wear on the motherboard's NVRAM, and if the EFI +# is buggy or the NVRAM is old and worn out, it may not work at all. +# Storing variables on disk is a viable alternative in such cases, or +# if you want to minimize wear and tear on the NVRAM; however, it won't +# work if rEFInd is stored on a filesystem that's read-only to the EFI +# (such as an HFS+ volume), and it increases the risk of filesystem +# damage. Note that this option affects ONLY rEFInd's own variables, +# such as the PreviousBoot, HiddenTags, HiddenTools, and HiddenLegacy +# variables. It does NOT affect Secure Boot or other non-rEFInd +# variables. +# Default is true +# +use_nvram false + +# Screen saver timeout; the screen blanks after the specified number of +# seconds with no keyboard input. The screen returns after most keypresses +# (unfortunately, not including modifier keys such as Shift, Control, Alt, +# or Option). Setting a value of "-1" causes rEFInd to start up with its +# screen saver active. The default is 0, which disables the screen saver. +# +#screensaver 300 + +# Hide user interface elements for personal preference or to increase +# security: +# banner - the rEFInd title banner (built-in or loaded via "banner") +# label - boot option text label in the menu +# singleuser - remove the submenu options to boot macOS in single-user +# or verbose modes; affects ONLY macOS +# safemode - remove the submenu option to boot macOS in "safe mode" +# hwtest - the submenu option to run Apple's hardware test +# arrows - scroll arrows on the OS selection tag line +# hints - brief command summary in the menu +# editor - the options editor (+, F2, or Insert on boot options menu) +# badges - device-type badges for boot options +# all - all of the above +# Default is none of these (all elements active) +# +#hideui singleuser +#hideui all + +# Set the name of a subdirectory in which icons are stored. Icons must +# have the same names they have in the standard directory. The directory +# name is specified relative to the main rEFInd binary's directory. If +# an icon can't be found in the specified directory, an attempt is made +# to load it from the default directory; thus, you can replace just some +# icons in your own directory and rely on the default for others. +# Icon files may be in any supported format -- ICNS (*.icns), BMP (*.bmp), +# PNG (*.png), or JPEG (*.jpg or *.jpeg); however, rEFInd's BMP and JPEG +# implementations do not support transparency, which is highly desirable +# in icons. +# Default is "icons". +# +#icons_dir myicons +#icons_dir icons/snowy + +# Use a custom title banner instead of the rEFInd icon and name. The file +# path is relative to the directory where refind.efi is located. The color +# in the top left corner of the image is used as the background color +# for the menu screens. Currently uncompressed BMP images with color +# depths of 24, 8, 4 or 1 bits are supported, as well as PNG and JPEG +# images. (ICNS images can also be used, but ICNS has limitations that +# make it a poor choice for this purpose.) PNG and JPEG support is +# limited by the underlying libraries; some files, like progressive JPEGs, +# will not work. +# +#banner hostname.bmp +#banner mybanner.jpg +#banner icons/snowy/banner-snowy.png + +# Specify how to handle banners that aren't exactly the same as the screen +# size: +# noscale - Crop if too big, show with border if too small +# fillscreen - Fill the screen +# Default is noscale +# +#banner_scale fillscreen + +# Icon sizes. All icons are square, so just one value is specified. The +# big icons are used for OS selectors in the first row and the small +# icons are used for tools on the second row. Drive-type badges are 1/4 +# the size of the big icons. Legal values are 32 and above. If the icon +# files do not hold icons of the proper size, the icons are scaled to +# the specified size. The default values are 48 and 128 for small and +# big icons, respectively. +# +#small_icon_size 96 +#big_icon_size 256 + +# Custom images for the selection background. There is a big one (144 x 144) +# for the OS icons, and a small one (64 x 64) for the function icons in the +# second row. If only a small image is given, that one is also used for +# the big icons by stretching it in the middle. If only a big one is given, +# the built-in default will be used for the small icons. If an image other +# than the optimal size is specified, it will be scaled in a way that may +# be ugly. +# +# Like the banner option above, these options take a filename of an +# uncompressed BMP, PNG, JPEG, or ICNS image file with a color depth of +# 24, 8, 4, or 1 bits. The PNG or ICNS format is required if you need +# transparency support (to let you "see through" to a full-screen banner). +# +#selection_big selection-big.bmp +#selection_small selection-small.bmp + +# Set the font to be used for all textual displays in graphics mode. +# For best results, the font must be a PNG file with alpha channel +# transparency. It must contain ASCII characters 32-126 (space through +# tilde), inclusive, plus a glyph to be displayed in place of characters +# outside of this range, for a total of 96 glyphs. Only monospaced fonts +# are supported. Fonts may be of any size, although large fonts can +# produce display irregularities. +# The default is rEFInd's built-in font, Luxi Mono Regular 12 point. +# +#font myfont.png + +# Use text mode only. When enabled, this option forces rEFInd into text mode. +# Passing this option a "0" value causes graphics mode to be used. Pasing +# it no value or any non-0 value causes text mode to be used. +# Default is to use graphics mode. +# +#textonly + +# Set the EFI text mode to be used for textual displays. This option +# takes a single digit that refers to a mode number. Mode 0 is normally +# 80x25, 1 is sometimes 80x50, and higher numbers are system-specific +# modes. Mode 1024 is a special code that tells rEFInd to not set the +# text mode; it uses whatever was in use when the program was launched. +# If you specify an invalid mode, rEFInd pauses during boot to inform +# you of valid modes. +# CAUTION: On VirtualBox, and perhaps on some real computers, specifying +# a text mode and uncommenting the "textonly" option while NOT specifying +# a resolution can result in an unusable display in the booted OS. +# Default is 1024 (no change) +# +#textmode 2 + +# Set the screen's video resolution. Pass this option one of the following: +# * two integer values, corresponding to the X and Y resolutions +# * one integer value, corresponding to a GOP (UEFI) video mode +# * the string "max", which sets the maximum available resolution +# Note that not all resolutions are supported. On UEFI systems, passing +# an incorrect value results in a message being shown on the screen to +# that effect, along with a list of supported modes. On EFI 1.x systems +# (e.g., Macintoshes), setting an incorrect mode silently fails. On both +# types of systems, setting an incorrect resolution results in the default +# resolution being used. A resolution of 1024x768 usually works, but higher +# values often don't. +# Default is "0 0" (use the system default resolution, usually 800x600). +# +#resolution 1024 768 +#resolution 1440 900 +#resolution 3 +#resolution max + +# Enable touch screen support. If active, this feature enables use of +# touch screen controls (as on tablets). Note, however, that not all +# tablets' EFIs provide the necessary underlying support, so this +# feature may not work for you. If it does work, you should be able +# to launch an OS or tool by touching it. In a submenu, touching +# anywhere launches the currently-selection item; there is, at present, +# no way to select a specific submenu item. This feature is mutually +# exclusive with the enable_mouse feature. If both are uncommented, +# the one read most recently takes precedence. +# +#enable_touch + +# Enable mouse support. If active, this feature enables use of the +# computer's mouse. Note, however, that not all computers' EFIs +# provide the necessary underlying support, so this feature may not +# work for you. If it does work, you should be able to launch an +# OS or tool by clicking it with the mouse pointer. This feature +# is mutually exclusive with the enable_touch feature. If both +# are uncommented, the one read most recently takes precedence. +# +#enable_mouse + +# Size of the mouse pointer, in pixels, per side. +# Default is 16 +# +#mouse_size 16 + +# Speed of mouse tracking. Higher numbers equate to faster +# mouse movement. This option requires that enable_mouse be +# uncommented. +# Legal values are between 1 and 32. Default is 4. +# +#mouse_speed 4 + +# Launch specified OSes in graphics mode. By default, rEFInd switches +# to text mode and displays basic pre-launch information when launching +# all OSes except macOS. Using graphics mode can produce a more seamless +# transition, but displays no information, which can make matters +# difficult if you must debug a problem. Also, on at least one known +# computer, using graphics mode prevents a crash when using the Linux +# kernel's EFI stub loader. You can specify an empty list to boot all +# OSes in text mode. +# Valid options: +# osx - macOS +# linux - A Linux kernel with EFI stub loader +# elilo - The ELILO boot loader +# grub - The GRUB (Legacy or 2) boot loader +# windows - Microsoft Windows +# Default value: osx +# +#use_graphics_for osx,linux + +# Which non-bootloader tools to show on the tools line, and in what +# order to display them: +# shell - the EFI shell (requires external program; see rEFInd +# documentation for details) +# memtest - the memtest86 program, in EFI/tools, EFI/memtest86, +# EFI/memtest, EFI/tools/memtest86, EFI/tools/memtest, +# or a boot loader's directory +# gptsync - the (dangerous) gptsync.efi utility (requires external +# program; see rEFInd documentation for details) +# gdisk - the gdisk partitioning program +# apple_recovery - boots the Apple Recovery HD partition, if present +# windows_recovery - boots an OEM Windows recovery tool, if present +# (see also the windows_recovery_files option) +# mok_tool - makes available the Machine Owner Key (MOK) maintenance +# tool, MokManager.efi, used on Secure Boot systems +# csr_rotate - adjusts Apple System Integrity Protection (SIP) +# policy. Requires "csr_values" to be set. +# install - an option to install rEFInd from the current location +# to another ESP +# bootorder - adjust the EFI's (NOT rEFInd's) boot order +# about - an "about this program" option +# hidden_tags - manage hidden tags +# exit - a tag to exit from rEFInd +# shutdown - shuts down the computer (a bug causes this to reboot +# many UEFI systems) +# reboot - a tag to reboot the computer +# firmware - a tag to reboot the computer into the firmware's +# user interface (ignored on older computers) +# fwupdate - a tag to update the firmware; launches the fwupx64.efi +# (or similar) program +# netboot - launch the ipxe.efi tool for network (PXE) booting +# Default is shell,memtest,gdisk,apple_recovery,windows_recovery,mok_tool,about,hidden_tags,shutdown,reboot,firmware,fwupdate +# To completely disable scanning for all tools, provide a showtools line +# with no options. +# +#showtools shell, bootorder, gdisk, memtest, mok_tool, apple_recovery, windows_recovery, about, hidden_tags, reboot, exit, firmware, fwupdate + +# Additional directories to scan for tools. You may specify a directory +# alone or a volume identifier plus pathname. The default is to scan no +# extra directories, beyond EFI/tools and any directory in which an EFI +# loader is found. +# +#also_scan_tool_dirs EFI/memtest,ESP2:/EFI/tools/memtest86 + +# Tool binaries to be excluded from the tools line, even if the +# general class is specified in showtools. This enables trimming an +# overabundance of tools, as when you see multiple mok_tool entries +# after installing multiple Linux distributions. +# Just as with dont_scan_files, you can specify a filename alone, a +# full pathname, or a volume identifier (filesystem label, partition +# name, or partition GUID) and a full pathname. +# Default is an empty list (nothing is excluded) +# +#dont_scan_tools ESP2:/EFI/ubuntu/mmx64.efi,gptsync_x64.efi + +# Boot loaders that can launch a Windows restore or emergency system. +# These tend to be OEM-specific. +# Default is LRS_ESP:/EFI/Microsoft/Boot/LrsBootmgr.efi +# +#windows_recovery_files LRS_ESP:/EFI/Microsoft/Boot/LrsBootmgr.efi + +# Directories in which to search for EFI drivers. These drivers can +# provide filesystem support, give access to hard disks on plug-in +# controllers, etc. In most cases none are needed, but if you add +# EFI drivers and you want rEFInd to automatically load them, you +# should specify one or more paths here. rEFInd always scans the +# "drivers" and "drivers_{arch}" subdirectories of its own installation +# directory (where "{arch}" is your architecture code); this option +# specifies ADDITIONAL directories to scan. +# Default is to scan no additional directories for EFI drivers +# +#scan_driver_dirs EFI/tools/drivers,drivers + +# Which types of boot loaders to search, and in what order to display them: +# internal - internal EFI disk-based boot loaders +# external - external EFI disk-based boot loaders +# optical - EFI optical discs (CD, DVD, etc.) +# netboot - EFI network (PXE) boot options +# hdbios - BIOS disk-based boot loaders +# biosexternal - BIOS external boot loaders (USB, eSATA, etc.) +# cd - BIOS optical-disc boot loaders +# manual - use stanzas later in this configuration file +# firmware - boot EFI programs set in the firmware's NVRAM +# Note that the legacy BIOS options require firmware support, which is +# not present on all computers. +# The netboot option is experimental and relies on the ipxe.efi and +# ipxe_discover.efi program files. +# On UEFI PCs, default is internal,external,optical,manual +# On Macs, default is internal,hdbios,external,biosexternal,optical,cd,manual +# +#scanfor internal,external,optical,manual,firmware + +# By default, rEFInd relies on the UEFI firmware to detect BIOS-mode boot +# devices. This sometimes doesn't detect all the available devices, though. +# For these cases, uefi_deep_legacy_scan results in a forced scan and +# modification of NVRAM variables on each boot. Adding "0", "off", or +# "false" resets to the default value. This token has no effect on Macs or +# when no BIOS-mode options are set via scanfor. +# Default is unset (or "uefi_deep_legacy_scan false") +# +#uefi_deep_legacy_scan + +# Delay for the specified number of seconds before scanning disks. +# This can help some users who find that some of their disks +# (usually external or optical discs) aren't detected initially, +# but are detected after pressing Esc. +# The default is 0. +# +#scan_delay 5 + +# When scanning volumes for EFI boot loaders, rEFInd always looks for +# macOS's and Microsoft Windows' boot loaders in their normal locations, +# and scans the root directory and every subdirectory of the /EFI directory +# for additional boot loaders, but it doesn't recurse into these directories. +# The also_scan_dirs token adds more directories to the scan list. +# Directories are specified relative to the volume's root directory. This +# option applies to ALL the volumes that rEFInd scans UNLESS you include +# a volume name and colon before the directory name, as in "myvol:/somedir" +# to scan the somedir directory only on the filesystem named myvol. If a +# specified directory doesn't exist, it's ignored (no error condition +# results). The "+" symbol denotes appending to the list of scanned +# directories rather than overwriting that list. +# The default is to scan the "boot" and "@/boot" directories in addition +# to various hard-coded directories. +# +#also_scan_dirs boot,ESP2:EFI/linux/kernels +#also_scan_dirs boot,@/boot +#also_scan_dirs +,@/kernels + +# Partitions (or whole disks, for legacy-mode boots) to omit from scans. +# For EFI-mode scans, you normally specify a volume by its label, which you +# can obtain in an EFI shell by typing "vol", from Linux by typing +# "blkid /dev/{devicename}", or by examining the disk's label in various +# OSes' file browsers. It's also possible to identify a partition by its +# unique GUID (aka its "PARTUUID" in Linux parlance). (Note that this is +# NOT the partition TYPE CODE GUID.) This identifier can be obtained via +# "blkid" in Linux or "diskutil info {partition-id}" in macOS. +# For legacy-mode scans, you can specify any subset of the boot loader +# description shown when you highlight the option in rEFInd. +# The default is "LRS_ESP". +# +#dont_scan_volumes "Recovery HD" + +# Directories that should NOT be scanned for boot loaders. By default, +# rEFInd doesn't scan its own directory, the EFI/tools directory, the +# EFI/memtest directory, the EFI/memtest86 directory, or the +# com.apple.recovery.boot directory. Using the dont_scan_dirs option +# enables you to "blacklist" other directories; but be sure to use "+" +# as the first element if you want to continue blacklisting existing +# directories. You might use this token to keep EFI/boot/bootx64.efi out +# of the menu if that's a duplicate of another boot loader or to exclude +# a directory that holds drivers or non-bootloader utilities provided by +# a hardware manufacturer. If a directory is listed both here and in +# also_scan_dirs, dont_scan_dirs takes precedence. Note that this +# blacklist applies to ALL the filesystems that rEFInd scans, not just +# the ESP, unless you precede the directory name by a filesystem name or +# partition unique GUID, as in "myvol:EFI/somedir" to exclude EFI/somedir +# from the scan on the myvol volume but not on other volumes. +# +#dont_scan_dirs ESP:/EFI/boot,EFI/Dell,EFI/memtest86 + +# Files that should NOT be included as EFI boot loaders (on the +# first line of the display). If you're using a boot loader that +# relies on support programs or drivers that are installed alongside +# the main binary or if you want to "blacklist" certain loaders by +# name rather than location, use this option. Note that this will +# NOT prevent certain binaries from showing up in the second-row +# set of tools. Most notably, various Secure Boot and recovery +# tools are present in this list, but may appear as second-row +# items. +# The file may be specified as a bare name (e.g., "notme.efi"), as +# a complete pathname (e.g., "/EFI/somedir/notme.efi"), or as a +# complete pathname with volume (e.g., "SOMEDISK:/EFI/somedir/notme.efi" +# or 2C17D5ED-850D-4F76-BA31-47A561740082:/EFI/somedir/notme.efi"). +# OS tags hidden via the Delete or '-' key in the rEFInd menu are +# added to this list, but stored in NVRAM. +# The default is shim.efi,shim-fedora.efi,shimx64.efi,PreLoader.efi, +# TextMode.efi,ebounce.efi,GraphicsConsole.efi,MokManager.efi,HashTool.efi, +# HashTool-signed.efi,bootmgr.efi,fb{arch}.efi +# (where "{arch}" is the architecture code, like "x64"). +# If you want to keep these defaults but add to them, be sure to +# specify "+" as the first item in the new list; if you don't, then +# items from the default list are likely to appear. +# +#dont_scan_files shim.efi,MokManager.efi + +# EFI NVRAM Boot#### variables that should NOT be presented as loaders +# when "firmware" is an option to "scanfor". The comma-separated list +# presented here contains strings that are matched against the +# description field -- if a value here is a case-insensitive substring +# of the boot option description, then it will be excluded from the +# boot list. To specify a string that includes a space, enclose it +# in quotes. Specifying "shell" will counteract the automatic +# inclusion of built-in EFI shells. +# +#dont_scan_firmware HARDDISK,shell,"Removable Device" + +# Scan for Linux kernels that lack a ".efi" filename extension. This is +# useful for better integration with Linux distributions that provide +# kernels with EFI stub loaders but that don't give those kernels filenames +# that end in ".efi", particularly if the kernels are stored on a +# filesystem that the EFI can read. When set to "1", "true", or "on", this +# option causes all files in scanned directories with names that begin with +# "vmlinuz", "bzImage", or "kernel" to be included as loaders, even if they +# lack ".efi" extensions. Passing this option a "0", "false", or "off" value +# causes kernels without ".efi" extensions to NOT be scanned. +# Default is "true" -- to scan for kernels without ".efi" extensions. +# +#scan_all_linux_kernels false + +# Support loaders that have been compressed with gzip. +# On x86 and x86-64 platforms, Linux kernels are self-decompressing. +# On ARM64, Linux kernel files are typically compressed with gzip, +# including the EFI stub loader. This makes them unloadable in rEFInd +# unless rEFInd itself uncompresses them. This option enables rEFInd +# to do this. This feature is unnecessary on x86 and x86-64 systems. +# Default is "false" on x86 and x86-64; "true" on ARM64. +# +#support_gzipped_loaders true + +# Combine all Linux kernels in a given directory into a single entry. +# When so set, the kernel with the most recent time stamp will be launched +# by default, and its filename will appear in the entry's description. +# To launch other kernels, the user must press F2 or Insert; alternate +# kernels then appear as options on the sub-menu. +# Default is "true" -- kernels are "folded" into a single menu entry. +# +#fold_linux_kernels false + +# Filename prefixes that indicate a file is a Linux kernel. Files that +# begin with any of these strings are treated as Linux kernels, if they +# are also EFI boot loaders. To include the default string, use "+" +# Default is "vmlinuz,bzImage,kernel", except on ARM64, where it is +# "vmlinuz,Image,kernel". +# +#linux_prefixes vmlinuz,bzImage,kernel +#linux_prefixes +,zImage + +# Comma-delimited list of strings to treat as if they were numbers for the +# purpose of kernel version number detection. These strings are matched on a +# first-found basis; that is, if you want to treat both "linux-lts" and +# "linux" as version strings, they MUST be specified as "linux-lts,linux", +# since if you specify it the other way, both vmlinuz-linux and +# vmlinuz-linux-lts will return with "linux" as the "version string," which +# is not what you'd want. Also, if the kernel or initrd file includes both a +# specified string and digits, the "version string" includes both. For +# instance, "vmlinuz-linux-4.8" would yield a version string of "linux-4.8". +# This option is intended for Arch and other distributions that don't include +# version numbers in their kernel filenames, but may provide other uniquely +# identifying strings for multiple kernels. If this feature causes problems +# (say, if your kernel filename includes "linux" but the initrd filename +# doesn't), be sure this is set to an empty string +# (extra_kernel_version_strings "") or comment out the option to disable it. +# Default is no extra version strings +# +#extra_kernel_version_strings linux-lts,linux + +# Write to systemd EFI variables (currently only LoaderDevicePartUUID) when +# launching Linux via an EFI stub loader, ELILO, or GRUB. This variable, +# when present, causes systemd to mount the ESP at /boot or /efi *IF* either +# directory is empty and nothing else is mounted there. +# Default is "false" +# +#write_systemd_vars true + +# Symlinked loaders will be processed when this setting is set to true. +# These are ignored by default as they may result in undesirable outcomes. +# This token may, however, be useful on Linux setups that provide symbolic +# links in scanned locations that point to kernels in unscanned locations, +# such as some openSUSE installations. +# +#follow_symlinks true + +# Set the maximum number of tags that can be displayed on the screen at +# any time. If more loaders are discovered than this value, rEFInd shows +# a subset in a scrolling list. If this value is set too high for the +# screen to handle, it's reduced to the value that the screen can manage. +# If this value is set to 0 (the default), it's adjusted to the number +# that the screen can handle. +# +#max_tags 0 + +# Set the default menu selection. The available arguments match the +# keyboard accelerators available within rEFInd. You may select the +# default loader using: +# - A digit between 1 and 9, in which case the Nth loader in the menu +# will be the default. +# - A "+" symbol at the start of the string, which refers to the most +# recently booted loader. +# - Any substring that corresponds to a portion of the loader's title +# (usually the OS's name, boot loader's path, or a volume or +# filesystem title). +# You may also specify multiple selectors by separating them with commas +# and enclosing the list in quotes. (The "+" option is only meaningful in +# this context.) +# If you follow the selector(s) with two times, in 24-hour format, the +# default will apply only between those times. The times are in the +# motherboard's time standard, whether that's UTC or local time, so if +# you use UTC, you'll need to adjust this from local time manually. +# Times may span midnight as in "23:30 00:30", which applies to 11:30 PM +# to 12:30 AM. You may specify multiple default_selection lines, in which +# case the last one to match takes precedence. Thus, you can set a main +# option without a time followed by one or more that include times to +# set different defaults for different times of day. +# The default behavior is to boot the previously-booted OS. +# +#default_selection 1 +#default_selection Microsoft +#default_selection "+,bzImage,vmlinuz" +#default_selection Maintenance 23:30 2:00 +#default_selection "Maintenance,macOS" 1:00 2:30 + +# Enable VMX bit and lock the CPU MSR if unlocked. +# On some Intel Apple computers, the firmware does not lock the MSR 0x3A. +# The symptom on Windows is Hyper-V not working even if the CPU +# meets the minimum requirements (HW assisted virtualization and SLAT) +# DO NOT SET THIS EXCEPT ON INTEL CPUs THAT SUPPORT VMX! See +# http://www.thomas-krenn.com/en/wiki/Activating_the_Intel_VT_Virtualization_Feature +# for more on this subject. +# The default is false: Don't try to enable and lock the MSR. +# +#enable_and_lock_vmx false + +# Tell a Mac's EFI that macOS is about to be launched, even when it's not. +# This option causes some Macs to initialize their hardware differently than +# when a third-party OS is launched normally. In some cases (particularly on +# Macs with multiple video cards), using this option can cause hardware to +# work that would not otherwise work. On the other hand, using this option +# when it is not necessary can cause hardware (such as keyboards and mice) to +# become inaccessible. Therefore, you should not enable this option if your +# non-Apple OSes work correctly; enable it only if you have problems with +# some hardware devices. When needed, a value of "10.9" usually works, but +# you can experiment with other values. This feature has no effect on +# non-Apple computers. +# The default is inactive (no macOS spoofing is done). +# +#spoof_osx_version 10.9 + +# Set the CSR values for Apple's System Integrity Protection (SIP) feature. +# Values are two-byte (four-character) hexadecimal numbers. These values +# define which specific security features are enabled. Below are the codes +# for what the values mean. Add them up (in hexadecimal!) to set new values. +# Apple's "csrutil enable" and "csrutil disable" commands set values of 10 +# and 877, respectively. (Prior to OS 11, 77 was used rather than 877; 877 +# is required for OS 11, and should work for OS X 10.x, too.) +# CSR_ALLOW_UNTRUSTED_KEXTS 0x0001 +# CSR_ALLOW_UNRESTRICTED_FS 0x0002 +# CSR_ALLOW_TASK_FOR_PID 0x0004 +# CSR_ALLOW_KERNEL_DEBUGGER 0x0008 +# CSR_ALLOW_APPLE_INTERNAL 0x0010 +# CSR_ALLOW_UNRESTRICTED_DTRACE 0x0020 +# CSR_ALLOW_UNRESTRICTED_NVRAM 0x0040 +# CSR_ALLOW_DEVICE_CONFIGURATION 0x0080 +# CSR_ALLOW_ANY_RECOVERY_OS 0x0100 +# CSR_ALLOW_UNAPPROVED_KEXTS 0x0200 +# CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE 0x0400 +# CSR_ALLOW_UNAUTHENTICATED_ROOT 0x0800 +#csr_values 10,877 + +# Include a secondary configuration file within this one. This secondary +# file is loaded as if its options appeared at the point of the "include" +# token itself, so if you want to override a setting in the main file, +# the secondary file must be referenced AFTER the setting you want to +# override. Note that the secondary file may NOT load a tertiary file. +# +#include manual.conf + +# Sample manual configuration stanzas. Each begins with the "menuentry" +# keyword followed by a name that's to appear in the menu (use quotes +# if you want the name to contain a space) and an open curly brace +# ("{"). Each entry ends with a close curly brace ("}"). Common +# keywords within each stanza include: +# +# volume - identifies the filesystem from which subsequent files +# are loaded. You can specify the volume by filesystem +# label, by partition label, or by partition GUID number +# (but NOT yet by filesystem UUID number). +# loader - identifies the boot loader file +# initrd - Specifies an initial RAM disk file +# icon - specifies a custom boot loader icon +# ostype - OS type code to determine boot options available by +# pressing Insert. Valid values are "MacOS", "Linux", +# "Windows", and "XOM". Case-sensitive. +# graphics - set to "on" to enable graphics-mode boot (useful +# mainly for MacOS) or "off" for text-mode boot. +# Default is auto-detected from loader filename. +# options - sets options to be passed to the boot loader; use +# quotes if more than one option should be passed or +# if any options use characters that might be changed +# by rEFInd parsing procedures (=, /, #, or tab). +# disabled - use alone or set to "yes" to disable this entry. +# +# Note that you can use either DOS/Windows/EFI-style backslashes (\) +# or Unix-style forward slashes (/) as directory separators. Either +# way, all file references are on the ESP from which rEFInd was +# launched. +# Use of quotes around parameters causes them to be interpreted as +# one keyword, and for parsing of special characters (spaces, =, /, +# and #) to be disabled. This is useful mainly with the "options" +# keyword. Use of quotes around parameters that specify filenames is +# permissible, but you must then use backslashes instead of slashes, +# except when you must pass a forward slash to the loader, as when +# passing a root= option to a Linux kernel. + +# Below are several sample boot stanzas. All are disabled by default. +# Find one similar to what you need, copy it, remove the "disabled" line, +# and adjust the entries to suit your needs. + +# A sample entry for a Linux 3.13 kernel with EFI boot stub support +# on a partition with a GUID of 904404F8-B481-440C-A1E3-11A5A954E601. +# This entry includes Linux-specific boot options and specification +# of an initial RAM disk. Note uses of Linux-style forward slashes. +# Also note that a leading slash is optional in file specifications. +menuentry Linux { + icon EFI/refind/icons/os_linux.png + volume 904404F8-B481-440C-A1E3-11A5A954E601 + loader bzImage-3.3.0-rc7 + initrd initrd-3.3.0.img + options "ro root=UUID=5f96cafa-e0a7-4057-b18f-fa709db5b837" + disabled +} + +# Below is a more complex Linux example, specifically for Arch Linux. +# This example MUST be modified for your specific installation; if nothing +# else, the PARTUUID code must be changed for your disk. Because Arch Linux +# does not include version numbers in its kernel and initrd filenames, you +# may need to use manual boot stanzas when using fallback initrds or +# multiple kernels with Arch. This example is modified from one in the Arch +# wiki page on rEFInd (https://wiki.archlinux.org/index.php/rEFInd). +menuentry "Arch Linux" { + icon /EFI/refind/icons/os_arch.png + volume "Arch Linux" + loader /boot/vmlinuz-linux + initrd /boot/initramfs-linux.img + options "root=PARTUUID=5028fa50-0079-4c40-b240-abfaf28693ea rw add_efi_memmap" + submenuentry "Boot using fallback initramfs" { + initrd /boot/initramfs-linux-fallback.img + } + submenuentry "Boot to terminal" { + add_options "systemd.unit=multi-user.target" + } + disabled +} + +# A sample entry for loading Ubuntu using its standard name for +# its GRUB 2 boot loader. Note uses of Linux-style forward slashes +menuentry Ubuntu { + loader /EFI/ubuntu/grubx64.efi + icon /EFI/refind/icons/os_linux.png + disabled +} + +# A minimal ELILO entry, which probably offers nothing that +# auto-detection can't accomplish. +menuentry "ELILO" { + loader \EFI\elilo\elilo.efi + disabled +} + +# Like the ELILO entry, this one offers nothing that auto-detection +# can't do; but you might use it if you want to disable auto-detection +# but still boot Windows.... +menuentry "Windows 7" { + loader \EFI\Microsoft\Boot\bootmgfw.efi + disabled +} + +# EFI shells are programs just like boot loaders, and can be +# launched in the same way. You can pass a shell the name of a +# script that it's to run on the "options" line. The script +# could initialize hardware and then launch an OS, or it could +# do something entirely different. +menuentry "Windows via shell script" { + icon \EFI\refind\icons\os_win.png + loader \EFI\tools\shell.efi + options "fs0:\EFI\tools\launch_windows.nsh" + disabled +} + +# MacOS is normally detected and run automatically; however, +# if you want to do something unusual, a manual boot stanza may +# be the way to do it. This one does nothing very unusual, but +# it may serve as a starting point. Note that you'll almost +# certainly need to change the "volume" line for this example +# to work. +menuentry "My macOS" { + icon \EFI\refind\icons\os_mac.png + volume "macOS boot" + loader \System\Library\CoreServices\boot.efi + disabled +} + +# The firmware_bootnum token takes a HEXADECIMAL value as an option +# and sets that value using the EFI's BootNext variable and then +# reboots the computer. This then causes a one-time boot of the +# computer using this EFI boot option. It can be used for various +# purposes, but one that's likely to interest some rEFInd users is +# that some Macs with HiDPI displays produce lower-resolution +# desktops when booted through rEFInd than when booted via Apple's +# own boot manager. Booting using the firmware_bootnum option +# produces the better resolution. Note that no loader option is +# used in this type of configuration. +menuentry "macOS via BootNext" { + icon /EFI/refind/icons/os_mac.png + firmware_bootnum 80 + disabled +} diff --git a/system-config/config/system/desktop/boot/refind_linux.conf b/system-config/config/system/desktop/boot/refind_linux.conf new file mode 100644 index 0000000..9f6362d --- /dev/null +++ b/system-config/config/system/desktop/boot/refind_linux.conf @@ -0,0 +1,3 @@ +"Boot with standard options" "rw cryptdevice=UUID=58ae6681-79a6-418e-94e1-8ed298b19e7c:cryptroot root=/dev/vg0/arch quiet resume=UUID=33876d89-a80d-4422-b852-d308fec68d4a" +"Boot to single-user mode" "rw cryptdevice=UUID=58ae6681-79a6-418e-94e1-8ed298b19e7c:cryptroot root=/dev/vg0/arch quiet single resume=UUID=33876d89-a80d-4422-b852-d308fec68d4a" +"Boot with minimal options" "rw cryptdevice=UUID=58ae6681-79a6-418e-94e1-8ed298b19e7c:cryptroot root=/dev/vg0/arch options quiet resume=UUID=33875d89-a80d-4422-b852-d308fec68d4a" diff --git a/system-config/config/system/desktop/identity/hostname b/system-config/config/system/desktop/identity/hostname new file mode 100644 index 0000000..f6cfe3a --- /dev/null +++ b/system-config/config/system/desktop/identity/hostname @@ -0,0 +1 @@ +alex-desktop diff --git a/system-config/config/system/desktop/input/50-zsa.rules b/system-config/config/system/desktop/input/50-zsa.rules new file mode 100644 index 0000000..3f40cce --- /dev/null +++ b/system-config/config/system/desktop/input/50-zsa.rules @@ -0,0 +1,24 @@ +# Rules for Oryx web flashing and live training +KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev" +KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev" + +# Legacy rules for live training over webusb (Not needed for firmware v21+) + # Rule for all ZSA keyboards + SUBSYSTEM=="usb", ATTR{idVendor}=="3297", GROUP="plugdev" + # Rule for the Moonlander + SUBSYSTEM=="usb", ATTR{idVendor}=="3297", ATTR{idProduct}=="1969", GROUP="plugdev" + # Rule for the Ergodox EZ + SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="1307", GROUP="plugdev" + # Rule for the Planck EZ + SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="6060", GROUP="plugdev" + +# Wally Flashing rules for the Ergodox EZ +ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1" +ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1" +SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666" +KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666" + +# Keymapp / Wally Flashing rules for the Moonlander and Planck EZ +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666", SYMLINK+="stm32_dfu" +# Keymapp Flashing rules for the Voyager +SUBSYSTEMS=="usb", ATTRS{idVendor}=="3297", MODE:="0666", SYMLINK+="ignition_dfu" diff --git a/system-config/config/system/desktop/input/keyd.conf b/system-config/config/system/desktop/input/keyd.conf new file mode 100644 index 0000000..20e2601 --- /dev/null +++ b/system-config/config/system/desktop/input/keyd.conf @@ -0,0 +1,21 @@ +[ids] + +* + +[main] +capslock = layer(capslayer) +rightcontrol = rightcontrol +' = G-' + +[capslayer] +# arrow keys vimlike +j = down +h = left +k = up +l = right +# german special keys +a = G-q +o = G-p +u = G-y +s = G-s +e = G-5 diff --git a/system-config/config/system/desktop/network/NetworkManager.conf b/system-config/config/system/desktop/network/NetworkManager.conf new file mode 100644 index 0000000..66a0a9c --- /dev/null +++ b/system-config/config/system/desktop/network/NetworkManager.conf @@ -0,0 +1,5 @@ +# Configuration file for NetworkManager. +# See "man 5 NetworkManager.conf" for details. +[main] +dns=none +rc-manager=unmanaged diff --git a/system-config/config/system/desktop/nvidia/nvidia-pm.conf b/system-config/config/system/desktop/nvidia/nvidia-pm.conf new file mode 100644 index 0000000..bf1eabe --- /dev/null +++ b/system-config/config/system/desktop/nvidia/nvidia-pm.conf @@ -0,0 +1,2 @@ + +options nvidia NVreg_EnableGpuFirmware=0 diff --git a/system-config/config/system/desktop/sddm/10-theme.conf b/system-config/config/system/desktop/sddm/10-theme.conf new file mode 100644 index 0000000..bf66c73 --- /dev/null +++ b/system-config/config/system/desktop/sddm/10-theme.conf @@ -0,0 +1,8 @@ +[Theme] +ThemeDir=/usr/share/sddm/themes +Current=maya +EnableAvatars=false + +[Users] +RememberLastUser=true +RememberLastSession=true diff --git a/system-config/config/system/desktop/storage/fstab b/system-config/config/system/desktop/storage/fstab new file mode 100644 index 0000000..aa9867d --- /dev/null +++ b/system-config/config/system/desktop/storage/fstab @@ -0,0 +1,12 @@ +# Static information about the filesystems. +# See fstab(5) for details. + +# +# /dev/mapper/vg0-arch +UUID=91fb6a1e-90ce-4a62-b27f-0f5e3b356a9a / ext4 rw,relatime 0 1 + +# /dev/nvme0n1p1 +UUID=8D94-3117 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2 + +# /dev/nvme0n1p2 +UUID=33876d89-a80d-4422-b852-d308fec68d4a none swap defaults 0 0 diff --git a/system-config/config/user/common/alacritty/alacritty.toml b/system-config/config/user/common/alacritty/alacritty.toml new file mode 100644 index 0000000..8e066bc --- /dev/null +++ b/system-config/config/user/common/alacritty/alacritty.toml @@ -0,0 +1,8 @@ +[general] +import = ["~/.config/alacritty/themes/noctalia.toml"] + +[font] +size = 11.0 + +[font.normal] +family = "MesloLGS Nerd Font" diff --git a/system-config/config/user/common/alacritty/themes/noctalia.toml b/system-config/config/user/common/alacritty/themes/noctalia.toml new file mode 100644 index 0000000..317f017 --- /dev/null +++ b/system-config/config/user/common/alacritty/themes/noctalia.toml @@ -0,0 +1,36 @@ +# Generated from Noctalia's custom "Ember OLED" palette. +[colors.primary] +background = "#050403" +foreground = "#fff1e6" + +[colors.cursor] +cursor = "#fff1e6" +text = "#050403" + +[colors.vi_mode_cursor] +cursor = "#ffb05c" +text = "#2b1600" + +[colors.selection] +background = "#3b220f" +text = "#fff1e6" + +[colors.normal] +black = "#050403" +red = "#ff6b4a" +green = "#c98a45" +yellow = "#ffb05c" +blue = "#c97c45" +magenta = "#d98a5c" +cyan = "#e8a76a" +white = "#fff1e6" + +[colors.bright] +black = "#6e4a31" +red = "#ff8f72" +green = "#e8ad68" +yellow = "#ffca80" +blue = "#e8a06a" +magenta = "#f0ad82" +cyan = "#ffd0a0" +white = "#ffffff" diff --git a/.local/bin/idle-inhibitor-monitor b/system-config/config/user/common/bin/idle-inhibitor-monitor similarity index 100% rename from .local/bin/idle-inhibitor-monitor rename to system-config/config/user/common/bin/idle-inhibitor-monitor diff --git a/.local/bin/pi-status-ui b/system-config/config/user/common/bin/pi-status-ui similarity index 55% rename from .local/bin/pi-status-ui rename to system-config/config/user/common/bin/pi-status-ui index 39aab7c..e9b2a00 100755 --- a/.local/bin/pi-status-ui +++ b/system-config/config/user/common/bin/pi-status-ui @@ -1,4 +1,4 @@ #!/bin/sh # The opaque release window runs natively on Wayland; disable WebKit DMABUF, # which is unreliable with this NVIDIA desktop's compositor path. -exec env WEBKIT_DISABLE_DMABUF_RENDERER=1 "$HOME/projects/pi-status-bridge/ui/src-tauri/target/release/pi-status-ui" "$@" +exec env WEBKIT_DISABLE_DMABUF_RENDERER=1 "$HOME/projects/pi-gui/ui/src-tauri/target/release/pi-status-ui" "$@" diff --git a/system-config/config/user/common/bin/wayshell-blanker b/system-config/config/user/common/bin/wayshell-blanker new file mode 100755 index 0000000000000000000000000000000000000000..4ba6c8d289c95e0680554cad5f6aca1f52f04215 GIT binary patch literal 17544 zcmeHPe{3Apoqx6oF+UPJX#yd%$&!XD1iZ0L;!)WxVxv5ETY7ut|;-(fT#Lxw2 zKdCbyhPX|%;ksNb6PJU(Ok%3sPz0qanJu-nRpSJc-oNPbF#WKWW6BW{CB3K=Yf~jm zMZ4ljZw_TOAEq}@MUa?sx$iF~i-ic$ShK>J2KC6~^ew7E=0ZZ zm{R|uMDZ@d9~E!C`(E+-$;Y#g zbd22A)6ugwUdY9}<(MT~Y!BHFlzxQ%w6Kokn-TcOAseeB{~wU&E)Xmp15?lbClP2p zd@4eIC<1>h!p?P&kKr$z7DmV)im2~9Fik;4N9D zd+yql$z`2Ac7MiEWpztZ-d<~8I-AVxv+}M}aIzlk7SgG#ov{+RY?kaNZO;}Yh=3f| zDj+183t;JN+Or07uC^5@A?dx&Xn)Rjlh#l!>4eJcY+^9yhCpW|ktr6^!;ZBdbwEUR zKA%Y^Y%h)aQwt_gak3(wYezH&}&6!YYug zJ*1i@SXDL^#Pr?bqJ3#u+Zo$vfr2-hK{Tj@GvZlPA;0Eyk96OXq0b5u_sXw~=uPSU;Tz@_v$(T#C#}SwgN93I(Y3P)uy%oZJAQK#y0;J6 z>8t>c`@6P7cD|0npp(haFHom0=#alhUBu<>Y$}(q({8S#E8gh~Nw@|XwB3RJ;{N@< z2#vjbdZfQN(9s>xRJKxTz^R`-ijF+^+;B0o*Ul0vV@SDne$dG}HU3iRT#a3Au@-~n z8X!S7d&Jfq+cs{py5qO5^|Rgabu&*nJbr%9q+Se~M6;NWmjQmC_~zrs@fy-1mT0WF zG<}7D%tz^k0g2xy`MqV5A7=dCsKmsW#-|Jgusri8Hz=ImdGsra1jYlnb}8|*0sKm( zDzB3PTu&h+em;ON4aiRg@EZcSFcdQv1U~_OYBf}r@L*fF2XOhGuf)WX03Ljwiv@79 z#c7qHa)fak5z=YURS3dy1N?NGp|XTu<)e6C4&YY@a5I3<3*b8g`1}BVe*o808(I2b z0O!6!1%m-x-*SRQK7fBnBI+^{!0G*y)0m-hRIkMhf<9^}hVW}tR$h-8iXr@3m6g{o z8;T)(iOS0BlZIjlr*}0@&loC4`1K5eo-hRWbEb;V6shp7f*NCS_N##k&KSewZ z*~&4=KS4YV)ykOUzeGIUmP%goe@8qG&B}w4|2*+DBr7{5zn}Oki8mzg5>G?3(kb~* z6Hi035|eyC@iY`G?UMg%;%Nw0gyeS--$wj}O8{=%PCN~{%9P|c5>Jo1%B19PCw?LE z71gP>+fVE?xqtoIu;3nX?u^(*qMT@gfdG49xIkuabi7y|A$xJ=-)(2Tq!$;)(JLXb!V9 zVIJ-S|5CYGvaeD0l45%Q<0+Y->j0QCq0zDOF7c%C}`Y3l8SF0VmZ z`HC78qEhy)-vlj?8M5#bjrt~!K$+v4G>&iI^UBTAwRv>iwaWJS-cwYe-jgcSb7tuxxmrQG zN2M;gLPN<2-g}RopEpZq%+e3a6%t&joJ?saj_>3&h9cCb>O1)^td&P(^yFkpJ2@_$ zOqA!(a{n1wA}jY0`TdUM`^wtyFIIEq?pA)w_5Jpd-xI!HuG}(djUp-Q%3Vz|N9W9i zwbQD7UMk-&^(M;sS^BSCq{flay+v8wzvja1G4t>P(=Sg@H$^Xvl@7d#PC5nC-@voW zH~p`wI@7rGH&fk@uKQ;c!_IW?DRQrFlFZUQ`YfE3UzScO=xN=2pOVN6Xp^bKeQ(lT z`tS0sz)F2@E2)>tNjN&(_x8&ZFzWv%_`d?=s*xHk&}e~13p84w(E^PYXtY411^yIT zfYuu+t&Tk$>$ekoQ*N%9O?D)5nVfrjtUm+jj@SW#1?dj@G*NJpf~i`67g_o^kjM?i zGg$1+#G#ViizRzI;iZRd&w=fx>s#(v1xl0t@BDAI`Zu7T`Bk-wX`m?nU$sgz&kw&- ztv&r5Rq7{V~X7-mX?3 z2Nk_qrum30C+PLpTIRHfX}Ly9ixlLaQYZet|4W)4R;v^kEkH1T0&&p<-n*d6W&Ge( z%eS;%h8%@1TG}rcElZlk0$ToUX}t;nNkx~bHYMM*fI{Dmo5#fXWynh%NtJyw|4VKBfO7196*om4_h?7PtyTShc!K<>2Xb;*7P|| z&uIFprf+EaYfUfLn}M#;^kbU#Xu3ty`!pTUbXe0vnjY8mX-%Kg^o*vjYRdJTGE{Es zrcJlUR$+#FQ>?2e-WBhPb$536boO+wW6AoI?(b#dSJiMSZ8&HW_^iJ|mBh3FedwFg+$M9Ot zJ-}lu6rg)azImSioaLg2fa|WqkfcXQz6MduQxW({;O*E!b>65|`ge)X^b;;U7h&g( z2>jg${5m{$+tCj%g#0c89%E+#+5x;?y*5YS4@TezBJh8Vz`qHc+K0yrhxF|T`8Oi) zcO&pcc)-`I7ri&s!?#D^0}=Qb;m!E9)X!0l|4@Yd6A?IVREgE;Ctr_{|1R(tI}6Ys z0H<*=WduNEe->fqVg!CIe)sFOPbcsNV!rQOzaEGU5%Rku@Kgl;NCYl+CtR;9p2Lo3 zyFYDtc1i%~$3Fh-ZlE(;`Ymq=Tg*Tu;KY-x8##ej=_=T@>fG&Bm80EgY!*wP;q-Di)=J=Yz2ojslq*p2Tm zwj*XIo1};>Ys;?QyZWrYyEo&Qg0*$WJsW#>Sodt%vb%4OwWoLEjy|B9|LX4EyS8nD zFn$@WK2z(Mn|BGh*}Hbn|L@!@j^hsO@BPj}Q2pUDxGUY@ebuy?I{NH`-e(^;Re%=8 z!3ecM9X9)Mz(5|&ko)Rqj!Fa$ID`*cV5|PD{r7>R1-L~?7!Do!2%ZI~*?s?hyY*+n z2_LOM3^m*K>mH4$k&qkv9sf|s2R&?1bB4n|tP!kD=w!pJrkSZNHtE+pAX9rrW%j8P zeGfw?JY-LoH!T6@53@*+?0%rp?()jJrXDic1eGwY;bZ&zaxRLsbMUXxlYC=1)a;| z&=V};Tu+=%vWU1GzHv7vJ73%x)DNt|By^cWpz<*$;(mBI!IF1eZ&X9Q8@F}PQ&yT* zk2qzT^N7G6N+%Fr4o-22%Se=0jB^pklXi&CO8p@c&39>zh@W|x9>wn#C8jGC>tFFR zQj=%{D}G{q{iyTItVFWG)C1<%m@~3}o<}p~`8NCI`77HnkfEt3>z8%>OglAC^K$ad z`aIt?fsqL7^SqrY&(k3yQ#k&eKxt0Q`aBP2x>@US{4B@x0hH4mn|YpRGwsy+;rKNy zGRTl^*5`RXQ=aFu|8V_>wf;tJkk<{E@;U?QQ=5hL$AD3r@H&V8zNX*Xcs&IoGI1Qt zKa5OJKc@AVj)xjt7yE7wh4guT!n7;okoDRBk&r&G3o+&OB9;%C6JOH$-2Nh_B{l8W zEE8@&=AS@@s>u30uVZ=(3u+qn|4c~#SWF2reNwUhHSGUcl;E?!-~Ynr#PhzU%7pcw z2ONBUgwN9(zeE4OLi+yXaD`Hgh4jPq|1rw(*6gp7@j4!#Ll4KxJk$SyZd*X#Uq`^+ zdrB;)xEY@Dw@^TRUq5F2`8xj}1O9&nG=3?u9{0oF0HgcQ`g|VkmGV-j)^vaMv&!^9KDn*Wy&9ENx?a(KT_o zzlin2&kxoQQXV_LGBT}Qn$r)akAS5$DvpPr|FoXPv1<)UTIs+)(m#Yc9Q#$JG-s=? P|MVS7Vp&Kb#ESn1yd5>a literal 0 HcmV?d00001 diff --git a/system-config/config/user/common/environment.d/pi-status-bridge.conf b/system-config/config/user/common/environment.d/pi-status-bridge.conf index f35a284..8c884c5 100644 --- a/system-config/config/user/common/environment.d/pi-status-bridge.conf +++ b/system-config/config/user/common/environment.d/pi-status-bridge.conf @@ -1,3 +1,3 @@ # Used by the Noctalia Pi Status Bridge adapter and the Hyprland launcher. -PI_STATUS_BRIDGE_CLIENT=/home/alex/.npm-global/bin/pi-status-bridge-client +PI_STATUS_BRIDGE_CLIENT=/home/alex/.local/bin/pi-status-bridge-client PI_STATUS_UI_BINARY=/home/alex/.local/bin/pi-status-ui diff --git a/system-config/config/user/common/hypr/hyprland.lua b/system-config/config/user/common/hypr/hyprland.lua index 2505a8b..84bdce5 100644 --- a/system-config/config/user/common/hypr/hyprland.lua +++ b/system-config/config/user/common/hypr/hyprland.lua @@ -78,7 +78,6 @@ hl.bind(main_mod .. " + CTRL + L", hl.dsp.exec_cmd("command -v hyprlock >/dev/nu hl.bind(main_mod .. " + CTRL + SHIFT + ALT + S", hl.dsp.exec_cmd("systemctl suspend")) hl.bind(main_mod .. " + CTRL + SHIFT + ALT + H", hl.dsp.exec_cmd("systemctl hibernate")) hl.bind(main_mod .. " + SHIFT + C", hl.dsp.window.close()) -hl.bind(main_mod .. " + CTRL + SHIFT + F", hl.dsp.exec_cmd("/home/alex/.local/bin/screenshot-select")) -- Audio, media, brightness, and calculator keys. hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true }) @@ -90,10 +89,12 @@ hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true }) hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true }) hl.bind(main_mod .. " + XF86AudioRaiseVolume", hl.dsp.exec_cmd("playerctl next"), { locked = true }) hl.bind(main_mod .. " + XF86AudioLowerVolume", hl.dsp.exec_cmd("playerctl previous"), { locked = true }) -hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd('light -A 5'), { locked = true }) -hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd('light -U 5'), { locked = true }) -hl.bind(main_mod .. " + XF86MonBrightnessDown", hl.dsp.exec_cmd('light -S 0.0'), { locked = true }) -hl.bind(main_mod .. " + XF86MonBrightnessUp", hl.dsp.exec_cmd('light -S 100'), { locked = true }) +if machine.is_laptop then + hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd('light -A 5'), { locked = true }) + hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd('light -U 5'), { locked = true }) + hl.bind(main_mod .. " + XF86MonBrightnessDown", hl.dsp.exec_cmd('light -S 0.0'), { locked = true }) + hl.bind(main_mod .. " + XF86MonBrightnessUp", hl.dsp.exec_cmd('light -S 100'), { locked = true }) +end hl.bind("XF86Calculator", hl.dsp.exec_cmd("qalculate-qt"), { locked = true }) -- Retain i3's hjkl and arrow-key directional workflow. @@ -145,8 +146,6 @@ hl.window_rule({ name = "thunderbird-workspace", match = { class = "^Thunderbird float_rule("pi-status-ui", { class = "^(pi-status-ui|Pi-status-ui)$" }, 1) float_rule("alsamixer", { title = "^alsamixer$" }, 1) float_rule("qalculate", { title = "^Qalculate!$" }) -float_rule("psensor", { class = "^Psensor$" }) -float_rule("lxrandr", { title = "^lxrandr$" }) float_rule("blueman", { class = "^Blueman-manager$" }) float_rule("gparted", { class = "^GParted$" }) float_rule("pavucontrol", { class = "^pavucontrol$" }) diff --git a/system-config/config/user/common/mime/mimeapps.list b/system-config/config/user/common/mime/mimeapps.list new file mode 100644 index 0000000..3ab5fb9 --- /dev/null +++ b/system-config/config/user/common/mime/mimeapps.list @@ -0,0 +1,15 @@ +[Default Applications] +x-scheme-handler/mailto=userapp-Thunderbird-JBPLA3.desktop +message/rfc822=userapp-Thunderbird-JBPLA3.desktop +x-scheme-handler/mid=userapp-Thunderbird-JBPLA3.desktop +x-scheme-handler/webcal=userapp-Thunderbird-0DWKA3.desktop +text/calendar=userapp-Thunderbird-0DWKA3.desktop +application/x-extension-ics=userapp-Thunderbird-0DWKA3.desktop +x-scheme-handler/webcals=userapp-Thunderbird-0DWKA3.desktop +image/png=nomacs.desktop + +[Added Associations] +x-scheme-handler/mailto=userapp-Thunderbird-JBPLA3.desktop; +x-scheme-handler/mid=userapp-Thunderbird-JBPLA3.desktop; +x-scheme-handler/webcal=userapp-Thunderbird-0DWKA3.desktop; +x-scheme-handler/webcals=userapp-Thunderbird-0DWKA3.desktop; diff --git a/system-config/config/user/common/noctalia/10-base.toml b/system-config/config/user/common/noctalia/10-base.toml index f80a6cd..0c367d0 100644 --- a/system-config/config/user/common/noctalia/10-base.toml +++ b/system-config/config/user/common/noctalia/10-base.toml @@ -6,8 +6,8 @@ external_ip_enabled = false telemetry_enabled = false # Noctalia owns idle handling so ScreenSaver/Wayland idle inhibitors (such as -# browser video playback) prevent these actions. Power displays down after five -# minutes, lock after ten minutes, then suspend-then-hibernate after thirty. +# browser video playback) prevent these actions. The desktop profile overrides +# the five-minute screen-off action with its Hypridle OLED overlay. [idle] behavior_order = ["lock", "screen-off", "suspend-then-hibernate"] pre_action_fade_seconds = 2.0 diff --git a/.local/share/noctalia/plugins/knowledge-lookup/.gitignore b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/.gitignore similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/.gitignore rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/.gitignore diff --git a/.local/share/noctalia/plugins/knowledge-lookup/create-entry.py b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/create-entry.py similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/create-entry.py rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/create-entry.py diff --git a/.local/share/noctalia/plugins/knowledge-lookup/focus-obsidian.py b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/focus-obsidian.py similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/focus-obsidian.py rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/focus-obsidian.py diff --git a/.local/share/noctalia/plugins/knowledge-lookup/index.py b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/index.py similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/index.py rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/index.py diff --git a/.local/share/noctalia/plugins/knowledge-lookup/manage-entry.py b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/manage-entry.py similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/manage-entry.py rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/manage-entry.py diff --git a/.local/share/noctalia/plugins/knowledge-lookup/panel.luau b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/panel.luau similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/panel.luau rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/panel.luau diff --git a/.local/share/noctalia/plugins/knowledge-lookup/plugin.toml b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/plugin.toml similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/plugin.toml rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/plugin.toml diff --git a/.local/share/noctalia/plugins/knowledge-lookup/vault-info.py b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/vault-info.py similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/vault-info.py rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/vault-info.py diff --git a/.local/share/noctalia/plugins/knowledge-lookup/widget.luau b/system-config/config/user/common/noctalia/plugins/knowledge-lookup/widget.luau similarity index 100% rename from .local/share/noctalia/plugins/knowledge-lookup/widget.luau rename to system-config/config/user/common/noctalia/plugins/knowledge-lookup/widget.luau diff --git a/system-config/config/user/common/noctalia/plugins/pi-status-bridge/bridge.luau b/system-config/config/user/common/noctalia/plugins/pi-status-bridge/bridge.luau new file mode 100644 index 0000000..da8fa2d --- /dev/null +++ b/system-config/config/user/common/noctalia/plugins/pi-status-bridge/bridge.luau @@ -0,0 +1,102 @@ +local request_in_flight = false + +local function shell_quote(value) + return "'" .. string.gsub(value, "'", "'\\\"'\\\"'") .. "'" +end + +local function ui_binary() + local configured = noctalia.getenv("PI_STATUS_UI_BINARY") + if configured ~= nil and configured ~= "" then return configured end + return (noctalia.getenv("HOME") or "") .. "/projects/pi-status-bridge/ui/src-tauri/target/release/pi-status-ui" +end + +local function bridge_client_binary() + local configured = noctalia.getenv("PI_STATUS_BRIDGE_CLIENT") + if configured ~= nil and configured ~= "" then return shell_quote(configured) end + return "pi-status-bridge-client" +end + +local function socket_path() + local runtime = noctalia.getenv("XDG_RUNTIME_DIR") + if runtime == nil or runtime == "" then return nil end + return runtime .. "/pi-status-bridge/bridge.sock" +end + +local bridge_start_in_flight = false +local pending_ui_open = false + +local function open_ui() + local binary = shell_quote(ui_binary()) + local command = "if test -x " .. binary .. "; then setsid -f env TMPDIR=/tmp " + .. binary .. " --toggle >/tmp/pi-status-ui.log 2>&1; else exit 1; fi" + noctalia.runAsync(command, function(result) + if result.exitCode ~= 0 then + barWidget.setGlyph("alert-triangle") + barWidget.setText("Pi UI unavailable") + barWidget.setTooltip("Build Pi Status UI or set PI_STATUS_UI_BINARY") + end + end) +end + +local function start_bridge(open_after_start) + if open_after_start then pending_ui_open = true end + if bridge_start_in_flight then return end + bridge_start_in_flight = true + barWidget.setGlyph("terminal-2") + barWidget.setText("Pi starting") + barWidget.setTooltip("Bridge is starting") + noctalia.runAsync("systemctl --user start pi-status-bridge.service", function(result) + bridge_start_in_flight = false + if result.exitCode ~= 0 then + pending_ui_open = false + barWidget.setGlyph("alert-triangle") + barWidget.setText("Pi offline") + barWidget.setTooltip("Could not start pi-status-bridge.service") + return + end + if pending_ui_open then pending_ui_open = false; open_ui() end + end) +end + +local function json_count(payload, key) + local value = string.match(payload, '"' .. key .. '":(%d+)') + return tonumber(value) or 0 +end + +local function update_summary(payload) + local open = json_count(payload, "openCount") + local working = json_count(payload, "workingCount") + local attention = json_count(payload, "attentionCount") + local recovering = json_count(payload, "recoveringCount") + local errors = json_count(payload, "errorCount") + local glyph = errors > 0 and "alert-triangle" or attention > 0 and "circle-alert" or working > 0 and "terminal-2" or recovering > 0 and "refresh-cw" or "terminal" + local text = errors > 0 and "Pi needs attention" or working > 0 and "Pi working" or recovering > 0 and "Pi recovering" or "Pi ready" + local detail = open .. " open · " .. working .. " working · " .. attention .. " attention · " .. recovering .. " recovering · " .. errors .. " errors" + barWidget.setGlyph(glyph) + barWidget.setText(text) + barWidget.setTooltip(detail .. "; click to open Pi Status UI") +end + +function update() + noctalia.setUpdateInterval(2000) + local socket = socket_path() + if socket == nil then start_bridge(false); return end + if request_in_flight then return end + request_in_flight = true + local command = bridge_client_binary() .. " --socket \"" .. socket .. "\" request '{\"op\":\"get_workspace_summary\"}'" + noctalia.runAsync(command, function(result) + request_in_flight = false + if result.exitCode ~= 0 then + start_bridge(false) + barWidget.setGlyph("terminal-2") + barWidget.setText("Pi reconnecting") + barWidget.setTooltip("Refreshing Pi workspace summary") + return + end + update_summary(result.stdout) + end) +end + +function onClick() + start_bridge(true) +end diff --git a/system-config/config/user/common/noctalia/plugins/pi-status-bridge/plugin.toml b/system-config/config/user/common/noctalia/plugins/pi-status-bridge/plugin.toml new file mode 100644 index 0000000..a7b6646 --- /dev/null +++ b/system-config/config/user/common/noctalia/plugins/pi-status-bridge/plugin.toml @@ -0,0 +1,10 @@ +id = "alex/pi-status-bridge" +name = "Pi Status Bridge" +version = "0.2.0" +plugin_api = 3 +author = "alex" +description = "Compact Pi status and launcher for the standalone Pi Status UI." + +[[widget]] +id = "bridge" +entry = "bridge.luau" diff --git a/.local/share/noctalia/plugins/system-status/battery-rate.luau b/system-config/config/user/common/noctalia/plugins/system-status/battery-rate.luau similarity index 100% rename from .local/share/noctalia/plugins/system-status/battery-rate.luau rename to system-config/config/user/common/noctalia/plugins/system-status/battery-rate.luau diff --git a/.local/share/noctalia/plugins/system-status/cpu.luau b/system-config/config/user/common/noctalia/plugins/system-status/cpu.luau similarity index 100% rename from .local/share/noctalia/plugins/system-status/cpu.luau rename to system-config/config/user/common/noctalia/plugins/system-status/cpu.luau diff --git a/.local/share/noctalia/plugins/system-status/gpu-mode.luau b/system-config/config/user/common/noctalia/plugins/system-status/gpu-mode.luau similarity index 100% rename from .local/share/noctalia/plugins/system-status/gpu-mode.luau rename to system-config/config/user/common/noctalia/plugins/system-status/gpu-mode.luau diff --git a/.local/share/noctalia/plugins/system-status/inhibitors-panel.luau b/system-config/config/user/common/noctalia/plugins/system-status/inhibitors-panel.luau similarity index 100% rename from .local/share/noctalia/plugins/system-status/inhibitors-panel.luau rename to system-config/config/user/common/noctalia/plugins/system-status/inhibitors-panel.luau diff --git a/.local/share/noctalia/plugins/system-status/inhibitors.luau b/system-config/config/user/common/noctalia/plugins/system-status/inhibitors.luau similarity index 100% rename from .local/share/noctalia/plugins/system-status/inhibitors.luau rename to system-config/config/user/common/noctalia/plugins/system-status/inhibitors.luau diff --git a/.local/share/noctalia/plugins/system-status/memory.luau b/system-config/config/user/common/noctalia/plugins/system-status/memory.luau similarity index 100% rename from .local/share/noctalia/plugins/system-status/memory.luau rename to system-config/config/user/common/noctalia/plugins/system-status/memory.luau diff --git a/.local/share/noctalia/plugins/system-status/network-rate.luau b/system-config/config/user/common/noctalia/plugins/system-status/network-rate.luau similarity index 100% rename from .local/share/noctalia/plugins/system-status/network-rate.luau rename to system-config/config/user/common/noctalia/plugins/system-status/network-rate.luau diff --git a/.local/share/noctalia/plugins/system-status/plugin.toml b/system-config/config/user/common/noctalia/plugins/system-status/plugin.toml similarity index 100% rename from .local/share/noctalia/plugins/system-status/plugin.toml rename to system-config/config/user/common/noctalia/plugins/system-status/plugin.toml diff --git a/system-config/config/user/common/systemd/user/pi-status-bridge.service b/system-config/config/user/common/systemd/user/pi-status-bridge.service index 948c490..bb43f44 100644 --- a/system-config/config/user/common/systemd/user/pi-status-bridge.service +++ b/system-config/config/user/common/systemd/user/pi-status-bridge.service @@ -4,7 +4,7 @@ After=graphical-session.target [Service] Type=simple -Environment=PATH=/home/alex/.npm-global/bin:/usr/local/bin:/usr/bin:/bin +Environment=PATH=/home/alex/.local/bin:/usr/local/bin:/usr/bin:/bin ExecStart=/usr/bin/env pi-status-bridge --session-root %h/.local/state/pi-status-bridge/sessions Restart=on-failure RestartSec=3 diff --git a/.config/user-dirs.dirs b/system-config/config/user/common/user-dirs/user-dirs.dirs similarity index 100% rename from .config/user-dirs.dirs rename to system-config/config/user/common/user-dirs/user-dirs.dirs diff --git a/system-config/config/user/desktop/noctalia/90-machine.toml b/system-config/config/user/desktop/noctalia/90-machine.toml index 4b01449..ebbce77 100644 --- a/system-config/config/user/desktop/noctalia/90-machine.toml +++ b/system-config/config/user/desktop/noctalia/90-machine.toml @@ -1,17 +1,21 @@ # Desktop-specific shell layout and hardware telemetry. -# Pi Status Bridge is installed locally from ~/projects/pi-status-bridge. +# Pi Status Bridge is installed from ~/projects/pi-gui on both hosts. [plugins] enabled = ["alex/system-status", "alex/pi-status-bridge", "alex/knowledge-lookup"] [widget.pi-status] type = "alex/pi-status-bridge:bridge" +[shell.screenshot] +confirm_region = true +directory = "/home/alex/downloads" + [bar.main] position = "bottom" layer = "top" scale = 0.95 capsule_radius = 5 -center = ["group:g3", "notifications"] +center = ["pi-status", "knowledge-lookup", "group:g3", "notifications", "screenshot"] end = ["group:g2", "group:g6", "group:g1", "session"] font_weight = 400 margin_ends = 0 @@ -19,11 +23,11 @@ padding = 0 panel_overlap = 3 radius = 0 shadow = false -# Keep the desktop status bar visible and reserve its screen edge. -auto_hide = false +# Auto-hide while reserving the screen edge; reveal the bar at its edge. +auto_hide = true smart_auto_hide = false reserve_space = true -start = ["tray", "group:g4", "privacy"] +start = ["tray", "group:g4"] thickness = 39 widget_spacing = 10 @@ -56,7 +60,7 @@ radius = 5.0 enabled = true fill = "surface_variant" id = "g4" -members = ["pi-status", "cpu", "temp", "ram", "gpu", "gpu_temp", "disk"] +members = ["cpu", "temp", "ram", "gpu", "gpu_temp", "disk"] opacity = 1.0 padding = 6.0 @@ -89,3 +93,8 @@ width = 880 [system.monitor] # GPU polling is disabled by Noctalia by default; enable it for the RTX 3090 widgets. gpu_poll_seconds = 2.0 + +# The desktop's Hypridle listener provides a five-minute input-dismissable black +# OLED overlay. Keep Noctalia from issuing a competing DPMS screen-off action. +[idle.behavior.screen-off] +enabled = false diff --git a/system-config/config/user/laptop/hypr/machine.lua b/system-config/config/user/laptop/hypr/machine.lua index 5493998..2a34f11 100644 --- a/system-config/config/user/laptop/hypr/machine.lua +++ b/system-config/config/user/laptop/hypr/machine.lua @@ -1,6 +1,7 @@ -- Laptop profile: leave monitor selection to Hyprland's hotplug support. -- Noctalia replaces the i3-era Redshift, Polybar, Blueman Applet, and Picom stack. return { + is_laptop = true, input = { touchpad = { -- Standard laptop behavior: one/two/three-finger taps map to diff --git a/system-config/hosts.py b/system-config/hosts.py index 84b8a30..7fdee4d 100644 --- a/system-config/hosts.py +++ b/system-config/hosts.py @@ -5,6 +5,7 @@ from modules.packages import PackageConcern COMMON = ( "common/core", + "common/hardware", "common/wayland", "common/fonts", "common/development", @@ -15,7 +16,7 @@ COMMON = ( "common/services", ) LAPTOP = ("laptop/hardware",) -DESKTOP = () +DESKTOP = ("desktop/local",) def _concerns(names: tuple[str, ...]) -> list[PackageConcern]: @@ -28,5 +29,5 @@ def laptop() -> list: def desktop() -> list: - """Future desktop: shared concerns plus desktop-only concerns when declared.""" + """Desktop: shared packages plus desktop-specific system configuration.""" return [*_concerns((*COMMON, *DESKTOP)), *desktop_system()] diff --git a/system-config/manifests/desktop/hardware-system.txt b/system-config/manifests/desktop/hardware-system.txt new file mode 100644 index 0000000..1250be4 --- /dev/null +++ b/system-config/manifests/desktop/hardware-system.txt @@ -0,0 +1,3 @@ +keyd.service +nvidia-powerd.service +sddm.service diff --git a/system-config/modules/host_system.py b/system-config/modules/host_system.py index 66b855d..daaae16 100644 --- a/system-config/modules/host_system.py +++ b/system-config/modules/host_system.py @@ -28,7 +28,7 @@ class UserConfigConcern(decman.Module): def __init__( self, name: str, - files: dict[str, str] | None = None, + files: dict[str, str | tuple[str, int]] | None = None, directories: dict[str, str] | None = None, user: str = "alex", ) -> None: @@ -40,7 +40,11 @@ class UserConfigConcern(decman.Module): def files(self) -> dict[str, decman.File]: return { target: decman.File( - source_file=str(ROOT / source), owner=self.user, permissions=0o644 + source_file=str( + ROOT / (source[0] if isinstance(source, tuple) else source) + ), + owner=self.user, + permissions=source[1] if isinstance(source, tuple) else 0o644, ) for target, source in self._files.items() } @@ -113,6 +117,7 @@ def common_user_config() -> list[UserConfigConcern]: "/home/alex/.config/hypr/hyprland.lua": "config/user/common/hypr/hyprland.lua", "/home/alex/.config/hypr/hyprlock.conf": "config/user/common/hypr/hyprlock.conf", "/home/alex/.config/kitty/kitty.conf": "config/user/common/kitty/kitty.conf", + "/home/alex/.config/mimeapps.list": "config/user/common/mime/mimeapps.list", "/home/alex/.config/noctalia/10-base.toml": "config/user/common/noctalia/10-base.toml", "/home/alex/.config/noctalia/palettes/Ember OLED.json": ( "config/user/common/noctalia/palettes/Ember OLED.json" @@ -126,8 +131,33 @@ def common_user_config() -> list[UserConfigConcern]: "/home/alex/.config/systemd/user/ssh-agent.service": ( "config/user/common/systemd/user/ssh-agent.service" ), + "/home/alex/.config/user-dirs.dirs": "config/user/common/user-dirs/user-dirs.dirs", + "/home/alex/.local/bin/idle-inhibitor-monitor": ( + "config/user/common/bin/idle-inhibitor-monitor", + 0o755, + ), + "/home/alex/.local/bin/pi-status-ui": ( + "config/user/common/bin/pi-status-ui", + 0o755, + ), + "/home/alex/.local/bin/wayshell-blanker": ( + "config/user/common/bin/wayshell-blanker", + 0o755, + ), + }, + { + "/home/alex/.config/alacritty": "config/user/common/alacritty", + "/home/alex/.config/yazi": "config/user/common/yazi", + "/home/alex/.local/share/noctalia/plugins/knowledge-lookup": ( + "config/user/common/noctalia/plugins/knowledge-lookup" + ), + "/home/alex/.local/share/noctalia/plugins/pi-status-bridge": ( + "config/user/common/noctalia/plugins/pi-status-bridge" + ), + "/home/alex/.local/share/noctalia/plugins/system-status": ( + "config/user/common/noctalia/plugins/system-status" + ), }, - {"/home/alex/.config/yazi": "config/user/common/yazi"}, ) ] @@ -234,5 +264,31 @@ def laptop_system() -> list[SystemConcern | UserConfigConcern]: def desktop_system() -> list[SystemConcern | UserConfigConcern]: - """Desktop: shared policy plus desktop-specific home configuration.""" - return [*common_system(), *desktop_user_config()] + """Desktop: shared policy plus this host's boot, GPU, input, and session state.""" + return [ + *common_system(), + SystemConcern( + "desktop-host", + { + "/etc/fstab": "config/system/desktop/storage/fstab", + "/etc/hostname": "config/system/desktop/identity/hostname", + "/etc/keyd/default.conf": "config/system/desktop/input/keyd.conf", + "/etc/modprobe.d/nvidia-pm.conf": "config/system/desktop/nvidia/nvidia-pm.conf", + "/etc/NetworkManager/NetworkManager.conf": ( + "config/system/desktop/network/NetworkManager.conf" + ), + "/etc/sddm.conf.d/10-theme.conf": "config/system/desktop/sddm/10-theme.conf", + "/etc/udev/rules.d/50-zsa.rules": "config/system/desktop/input/50-zsa.rules", + }, + system_manifests=("desktop/hardware-system.txt",), + ), + SystemConcern( + "boot", + { + "/boot/EFI/refind/refind.conf": "config/system/desktop/boot/refind.conf", + "/boot/refind_linux.conf": "config/system/desktop/boot/refind_linux.conf", + "/etc/mkinitcpio.conf": "config/system/desktop/boot/mkinitcpio.conf", + }, + ), + *desktop_user_config(), + ] diff --git a/system-config/packages/common/core-repo.txt b/system-config/packages/common/core-repo.txt index 5886f05..998cd88 100644 --- a/system-config/packages/common/core-repo.txt +++ b/system-config/packages/common/core-repo.txt @@ -32,5 +32,6 @@ rsync starship unzip yadm +zellij zoxide zsh diff --git a/system-config/packages/common/development-aur.txt b/system-config/packages/common/development-aur.txt index c97ff71..72e5fa7 100644 --- a/system-config/packages/common/development-aur.txt +++ b/system-config/packages/common/development-aur.txt @@ -4,6 +4,5 @@ gti mongodb-compass-bin pi postman-bin -pycharm vagrant yay diff --git a/system-config/packages/common/hardware-aur.txt b/system-config/packages/common/hardware-aur.txt new file mode 100644 index 0000000..e69de29 diff --git a/system-config/packages/common/hardware-repo.txt b/system-config/packages/common/hardware-repo.txt new file mode 100644 index 0000000..5a6edf7 --- /dev/null +++ b/system-config/packages/common/hardware-repo.txt @@ -0,0 +1,5 @@ +keyd +mesa-utils +nvidia-open +nvtop +vulkan-tools diff --git a/system-config/packages/common/network-repo.txt b/system-config/packages/common/network-repo.txt index 2d46b9d..c26a44d 100644 --- a/system-config/packages/common/network-repo.txt +++ b/system-config/packages/common/network-repo.txt @@ -1,7 +1,6 @@ avahi cups cups-pdf -dhcpcd gvfs-smb network-manager-applet networkmanager diff --git a/system-config/packages/common/productivity-aur.txt b/system-config/packages/common/productivity-aur.txt index ed5ce1b..8985a0a 100644 --- a/system-config/packages/common/productivity-aur.txt +++ b/system-config/packages/common/productivity-aur.txt @@ -1,4 +1,3 @@ brave-bin -nomacs spotify zotero-bin diff --git a/system-config/packages/common/productivity-repo.txt b/system-config/packages/common/productivity-repo.txt index 1f36cd4..a3303d8 100644 --- a/system-config/packages/common/productivity-repo.txt +++ b/system-config/packages/common/productivity-repo.txt @@ -7,6 +7,7 @@ nextcloud-client obsidian okular qalculate-gtk +qalculate-qt qbittorrent signal-desktop teamspeak3 diff --git a/system-config/packages/common/services-repo.txt b/system-config/packages/common/services-repo.txt index a2fa66b..7840279 100644 --- a/system-config/packages/common/services-repo.txt +++ b/system-config/packages/common/services-repo.txt @@ -1,4 +1,3 @@ libva-utils -ly pcmanfm sddm diff --git a/system-config/packages/common/wayland-aur.txt b/system-config/packages/common/wayland-aur.txt index 4a25dc2..b2d1965 100644 --- a/system-config/packages/common/wayland-aur.txt +++ b/system-config/packages/common/wayland-aur.txt @@ -1,2 +1 @@ noctalia-git -ranger-git diff --git a/system-config/packages/common/wayland-repo.txt b/system-config/packages/common/wayland-repo.txt index 3d07e7f..27aadb1 100644 --- a/system-config/packages/common/wayland-repo.txt +++ b/system-config/packages/common/wayland-repo.txt @@ -16,6 +16,7 @@ pavucontrol pipewire-alsa pipewire-pulse playerctl +rofi satty slurp tmux diff --git a/system-config/packages/desktop/local-aur.txt b/system-config/packages/desktop/local-aur.txt new file mode 100644 index 0000000..3ae44cd --- /dev/null +++ b/system-config/packages/desktop/local-aur.txt @@ -0,0 +1,5 @@ +beads +downgrade +nomacs-git +yay-debug +zsa-keymapp-bin diff --git a/system-config/packages/desktop/local-repo.txt b/system-config/packages/desktop/local-repo.txt new file mode 100644 index 0000000..0ab4ef2 --- /dev/null +++ b/system-config/packages/desktop/local-repo.txt @@ -0,0 +1,34 @@ +bun +fakeroot +geoclue +github-cli +gtk4-layer-shell +lsof +lvm2 +mpv +numlockx +nvidia-container-toolkit +nvidia-settings +ollama-cuda +opencode +perl-yaml-tiny +pipewire +powerline +qpwgraph +ranger +retry +rustup +screengrab +seahorse +sudo +sway +texlive-bin +texlive-meta +tree +ttf-meslo-nerd +unrar +vlc-plugins-all +vulkan-radeon +wdisplays +wget +xournalpp diff --git a/system-config/packages/laptop/hardware-repo.txt b/system-config/packages/laptop/hardware-repo.txt index 136e819..2b8239f 100644 --- a/system-config/packages/laptop/hardware-repo.txt +++ b/system-config/packages/laptop/hardware-repo.txt @@ -2,11 +2,7 @@ ddcutil intel-gpu-tools intel-media-driver intel-ucode -keyd -mesa-utils -nvidia-open nvidia-prime -nvtop nwg-displays powertop psensor @@ -15,5 +11,4 @@ tlp tlp-pd tlp-rdw vulkan-intel -vulkan-tools wireless_tools diff --git a/system-config/pyrightconfig.json b/system-config/pyrightconfig.json index b292365..b888057 100644 --- a/system-config/pyrightconfig.json +++ b/system-config/pyrightconfig.json @@ -1,4 +1,9 @@ { "include": ["source.py", "hosts.py", "modules", "scripts"], - "executionEnvironments": [{ "root": ".", "extraPaths": ["."] }] + "executionEnvironments": [ + { + "root": ".", + "extraPaths": [".", "/usr/lib/python3.14/site-packages"] + } + ] } diff --git a/system-config/scripts/split_packages.py b/system-config/scripts/split_packages.py index 590873e..61b5cea 100755 --- a/system-config/scripts/split_packages.py +++ b/system-config/scripts/split_packages.py @@ -15,12 +15,12 @@ PACKAGES = ROOT / "packages" CONCERNS: Final = { "common/core": """base base-devel linux linux-firmware linux-headers cryptsetup refind arch-install-scripts git yadm openssh man-db jq ripgrep fd fzf 7zip unzip rsync - ntfs-3g os-prober fwupd fish zsh zoxide htop glances starship cowsay ex-vi-compat + ntfs-3g os-prober fwupd fish zsh zellij zoxide htop glances starship cowsay ex-vi-compat mtools dmidecode libsmbios catdoc odt2txt hunspell-de""", "common/wayland": """hyprland hypridle hyprlock xdg-desktop-portal-hyprland pipewire-alsa pipewire-pulse wireplumber pavucontrol pamixer mako waybar wofi grim slurp satty wl-clipboard wlr-randr alacritty kitty tmux neovim vim yazi ueberzugpp - flameshot playerctl bluez bluez-utils blueman gnome-keyring xorg-xwayland + flameshot playerctl rofi bluez bluez-utils blueman gnome-keyring xorg-xwayland noctalia-git ranger-git""", "common/fonts": """noto-fonts noto-fonts-cjk noto-fonts-emoji ttf-jetbrains-mono-nerd ttf-icomoon-feather ttf-meslo-nerd-font-powerlevel10k""", @@ -30,7 +30,7 @@ CONCERNS: Final = { decman yay gti fcron""", "common/productivity": """brave-bin firefox chromium thunderbird obsidian bitwarden nextcloud-client signal-desktop telegram-desktop libreoffice-fresh evince okular - nomacs zotero-bin qalculate-gtk qbittorrent teams teamspeak3 cerebro-bin chatgtk + nomacs zotero-bin qalculate-gtk qalculate-qt qbittorrent teams teamspeak3 cerebro-bin chatgtk torbrowser-launcher spotify""", "common/media": """vlc mpv smplayer audacity imagemagick steam cudnn""", "common/research": """biber r texlive-basic texlive-bibtexextra texlive-binextra @@ -39,13 +39,20 @@ CONCERNS: Final = { texlive-latexrecommended texlive-luatex texlive-mathscience texlive-metapost texlive-music texlive-pictures texlive-plaingeneric texlive-pstricks texlive-publishers texlive-xetex resvg""", - "common/network": """networkmanager network-manager-applet avahi nss-mdns dhcpcd gvfs-smb + "common/network": """networkmanager network-manager-applet avahi nss-mdns gvfs-smb cups cups-pdf mullvad-vpn-beta-bin""", + "common/hardware": """keyd mesa-utils nvidia-open nvtop vulkan-tools""", + "desktop/local": """bun fakeroot geoclue github-cli gtk4-layer-shell lsof + lvm2 mpv numlockx nvidia-container-toolkit nvidia-settings ollama-cuda opencode + perl-yaml-tiny pipewire powerline qpwgraph ranger retry rustup screengrab seahorse + sudo sway texlive-bin texlive-meta tree ttf-meslo-nerd unrar vlc-plugins-all + vulkan-radeon wdisplays wget xournalpp beads downgrade nomacs-git yay-debug + zsa-keymapp-bin""", "laptop/hardware": """intel-ucode thermald tlp tlp-pd tlp-rdw powertop psensor lm_sensors - ddcutil intel-gpu-tools intel-media-driver mesa-utils vulkan-intel vulkan-tools - nvidia-open nvidia-prime nvtop envycontrol light keyd nwg-displays + ddcutil intel-gpu-tools intel-media-driver vulkan-intel + nvidia-prime envycontrol light nwg-displays wireless_tools caffeine woeusb""", - "common/services": """sddm ly pcmanfm libva-utils""", + "common/services": """sddm pcmanfm libva-utils""", } diff --git a/system-config/source.py b/system-config/source.py index 41e896d..749061f 100644 --- a/system-config/source.py +++ b/system-config/source.py @@ -1,14 +1,14 @@ """Decman entrypoint for this machine. -Select one profile only. The package lists describe the complete current laptop -state, so the first Decman run must not remove a package. +Select the profile that matches this host. This desktop uses the shared package +concerns and its desktop-specific Hyprland and Noctalia configuration. """ -import decman +import decman # pyright: ignore[reportMissingImports] # Provided by the Arch AUR package. from modules.packages import configure_no_removal_guard -from hosts import laptop +from hosts import desktop configure_no_removal_guard() -decman.modules += laptop() +decman.modules += desktop() decman.execution_order = ["files", "pacman", "aur", "systemd"]