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 10c3d9d..0000000 Binary files a/.config/st/boxdraw.o and /dev/null differ diff --git a/.config/st/boxdraw_data.h b/.config/st/boxdraw_data.h deleted file mode 100644 index 7890500..0000000 --- a/.config/st/boxdraw_data.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2018 Avi Halachmi (:avih) avihpit@yahoo.com https://github.com/avih - * MIT/X Consortium License - */ - -/* - * U+25XX codepoints data - * - * References: - * http://www.unicode.org/charts/PDF/U2500.pdf - * http://www.unicode.org/charts/PDF/U2580.pdf - * - * Test page: - * https://github.com/GNOME/vte/blob/master/doc/boxes.txt - */ - -/* Each shape is encoded as 16-bits. Higher bits are category, lower are data */ -/* Categories (mutually exclusive except BDB): */ -/* For convenience, BDL/BDA/BBS/BDB are 1 bit each, the rest are enums */ -#define BDL (1<<8) /* Box Draw Lines (light/double/heavy) */ -#define BDA (1<<9) /* Box Draw Arc (light) */ - -#define BBD (1<<10) /* Box Block Down (lower) X/8 */ -#define BBL (2<<10) /* Box Block Left X/8 */ -#define BBU (3<<10) /* Box Block Upper X/8 */ -#define BBR (4<<10) /* Box Block Right X/8 */ -#define BBQ (5<<10) /* Box Block Quadrants */ -#define BRL (6<<10) /* Box Braille (data is lower byte of U28XX) */ - -#define BBS (1<<14) /* Box Block Shades */ -#define BDB (1<<15) /* Box Draw is Bold */ - -/* (BDL/BDA) Light/Double/Heavy x Left/Up/Right/Down/Horizontal/Vertical */ -/* Heavy is light+double (literally drawing light+double align to form heavy) */ -#define LL (1<<0) -#define LU (1<<1) -#define LR (1<<2) -#define LD (1<<3) -#define LH (LL+LR) -#define LV (LU+LD) - -#define DL (1<<4) -#define DU (1<<5) -#define DR (1<<6) -#define DD (1<<7) -#define DH (DL+DR) -#define DV (DU+DD) - -#define HL (LL+DL) -#define HU (LU+DU) -#define HR (LR+DR) -#define HD (LD+DD) -#define HH (HL+HR) -#define HV (HU+HD) - -/* (BBQ) Quadrants Top/Bottom x Left/Right */ -#define TL (1<<0) -#define TR (1<<1) -#define BL (1<<2) -#define BR (1<<3) - -/* Data for U+2500 - U+259F except dashes/diagonals */ -static const unsigned short boxdata[256] = { - /* light lines */ - [0x00] = BDL + LH, /* light horizontal */ - [0x02] = BDL + LV, /* light vertical */ - [0x0c] = BDL + LD + LR, /* light down and right */ - [0x10] = BDL + LD + LL, /* light down and left */ - [0x14] = BDL + LU + LR, /* light up and right */ - [0x18] = BDL + LU + LL, /* light up and left */ - [0x1c] = BDL + LV + LR, /* light vertical and right */ - [0x24] = BDL + LV + LL, /* light vertical and left */ - [0x2c] = BDL + LH + LD, /* light horizontal and down */ - [0x34] = BDL + LH + LU, /* light horizontal and up */ - [0x3c] = BDL + LV + LH, /* light vertical and horizontal */ - [0x74] = BDL + LL, /* light left */ - [0x75] = BDL + LU, /* light up */ - [0x76] = BDL + LR, /* light right */ - [0x77] = BDL + LD, /* light down */ - - /* heavy [+light] lines */ - [0x01] = BDL + HH, - [0x03] = BDL + HV, - [0x0d] = BDL + HR + LD, - [0x0e] = BDL + HD + LR, - [0x0f] = BDL + HD + HR, - [0x11] = BDL + HL + LD, - [0x12] = BDL + HD + LL, - [0x13] = BDL + HD + HL, - [0x15] = BDL + HR + LU, - [0x16] = BDL + HU + LR, - [0x17] = BDL + HU + HR, - [0x19] = BDL + HL + LU, - [0x1a] = BDL + HU + LL, - [0x1b] = BDL + HU + HL, - [0x1d] = BDL + HR + LV, - [0x1e] = BDL + HU + LD + LR, - [0x1f] = BDL + HD + LR + LU, - [0x20] = BDL + HV + LR, - [0x21] = BDL + HU + HR + LD, - [0x22] = BDL + HD + HR + LU, - [0x23] = BDL + HV + HR, - [0x25] = BDL + HL + LV, - [0x26] = BDL + HU + LD + LL, - [0x27] = BDL + HD + LU + LL, - [0x28] = BDL + HV + LL, - [0x29] = BDL + HU + HL + LD, - [0x2a] = BDL + HD + HL + LU, - [0x2b] = BDL + HV + HL, - [0x2d] = BDL + HL + LD + LR, - [0x2e] = BDL + HR + LL + LD, - [0x2f] = BDL + HH + LD, - [0x30] = BDL + HD + LH, - [0x31] = BDL + HD + HL + LR, - [0x32] = BDL + HR + HD + LL, - [0x33] = BDL + HH + HD, - [0x35] = BDL + HL + LU + LR, - [0x36] = BDL + HR + LU + LL, - [0x37] = BDL + HH + LU, - [0x38] = BDL + HU + LH, - [0x39] = BDL + HU + HL + LR, - [0x3a] = BDL + HU + HR + LL, - [0x3b] = BDL + HH + HU, - [0x3d] = BDL + HL + LV + LR, - [0x3e] = BDL + HR + LV + LL, - [0x3f] = BDL + HH + LV, - [0x40] = BDL + HU + LH + LD, - [0x41] = BDL + HD + LH + LU, - [0x42] = BDL + HV + LH, - [0x43] = BDL + HU + HL + LD + LR, - [0x44] = BDL + HU + HR + LD + LL, - [0x45] = BDL + HD + HL + LU + LR, - [0x46] = BDL + HD + HR + LU + LL, - [0x47] = BDL + HH + HU + LD, - [0x48] = BDL + HH + HD + LU, - [0x49] = BDL + HV + HL + LR, - [0x4a] = BDL + HV + HR + LL, - [0x4b] = BDL + HV + HH, - [0x78] = BDL + HL, - [0x79] = BDL + HU, - [0x7a] = BDL + HR, - [0x7b] = BDL + HD, - [0x7c] = BDL + HR + LL, - [0x7d] = BDL + HD + LU, - [0x7e] = BDL + HL + LR, - [0x7f] = BDL + HU + LD, - - /* double [+light] lines */ - [0x50] = BDL + DH, - [0x51] = BDL + DV, - [0x52] = BDL + DR + LD, - [0x53] = BDL + DD + LR, - [0x54] = BDL + DR + DD, - [0x55] = BDL + DL + LD, - [0x56] = BDL + DD + LL, - [0x57] = BDL + DL + DD, - [0x58] = BDL + DR + LU, - [0x59] = BDL + DU + LR, - [0x5a] = BDL + DU + DR, - [0x5b] = BDL + DL + LU, - [0x5c] = BDL + DU + LL, - [0x5d] = BDL + DL + DU, - [0x5e] = BDL + DR + LV, - [0x5f] = BDL + DV + LR, - [0x60] = BDL + DV + DR, - [0x61] = BDL + DL + LV, - [0x62] = BDL + DV + LL, - [0x63] = BDL + DV + DL, - [0x64] = BDL + DH + LD, - [0x65] = BDL + DD + LH, - [0x66] = BDL + DD + DH, - [0x67] = BDL + DH + LU, - [0x68] = BDL + DU + LH, - [0x69] = BDL + DH + DU, - [0x6a] = BDL + DH + LV, - [0x6b] = BDL + DV + LH, - [0x6c] = BDL + DH + DV, - - /* (light) arcs */ - [0x6d] = BDA + LD + LR, - [0x6e] = BDA + LD + LL, - [0x6f] = BDA + LU + LL, - [0x70] = BDA + LU + LR, - - /* Lower (Down) X/8 block (data is 8 - X) */ - [0x81] = BBD + 7, [0x82] = BBD + 6, [0x83] = BBD + 5, [0x84] = BBD + 4, - [0x85] = BBD + 3, [0x86] = BBD + 2, [0x87] = BBD + 1, [0x88] = BBD + 0, - - /* Left X/8 block (data is X) */ - [0x89] = BBL + 7, [0x8a] = BBL + 6, [0x8b] = BBL + 5, [0x8c] = BBL + 4, - [0x8d] = BBL + 3, [0x8e] = BBL + 2, [0x8f] = BBL + 1, - - /* upper 1/2 (4/8), 1/8 block (X), right 1/2, 1/8 block (8-X) */ - [0x80] = BBU + 4, [0x94] = BBU + 1, - [0x90] = BBR + 4, [0x95] = BBR + 7, - - /* Quadrants */ - [0x96] = BBQ + BL, - [0x97] = BBQ + BR, - [0x98] = BBQ + TL, - [0x99] = BBQ + TL + BL + BR, - [0x9a] = BBQ + TL + BR, - [0x9b] = BBQ + TL + TR + BL, - [0x9c] = BBQ + TL + TR + BR, - [0x9d] = BBQ + TR, - [0x9e] = BBQ + BL + TR, - [0x9f] = BBQ + BL + TR + BR, - - /* Shades, data is an alpha value in 25% units (1/4, 1/2, 3/4) */ - [0x91] = BBS + 1, [0x92] = BBS + 2, [0x93] = BBS + 3, - - /* U+2504 - U+250B, U+254C - U+254F: unsupported (dashes) */ - /* U+2571 - U+2573: unsupported (diagonals) */ -}; diff --git a/.config/st/config.h b/.config/st/config.h deleted file mode 100644 index de19b75..0000000 --- a/.config/st/config.h +++ /dev/null @@ -1,562 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "MesloLGS NF:pixelsize=30:antialias=true:autohint=true"; -static char *font2[] = { "JoyPixels:pixelsize=30:antialias=true:autohint=true" }; -static int borderpx = 2; - -/* - * What program is execed by st depends of these precedence rules: - * 1: program passed with -e - * 2: utmp option - * 3: SHELL environment variable - * 4: value of shell in /etc/passwd - * 5: value of shell in config.h - */ -static char *shell = "/bin/zsh"; -char *utmp = NULL; -char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; - -/* identification sequence returned in DA and DECID */ -char *vtiden = "\033[?6c"; - -/* Kerning / character bounding-box multipliers */ -static float cwscale = 1.0; -static float chscale = 1.0; - -/* - * word delimiter string - * - * More advanced example: L" `'\"()[]{}" - */ -wchar_t *worddelimiters = L" "; - -/* selection timeouts (in milliseconds) */ -static unsigned int doubleclicktimeout = 300; -static unsigned int tripleclicktimeout = 600; - -/* alt screens */ -int allowaltscreen = 1; - -/* - * draw latency range in ms - from new content/keypress/etc until drawing. - * within this range, st draws when content stops arriving (idle). mostly it's - * near minlatency, but it waits longer for slow updates to avoid partial draw. - * low minlatency will tear/flicker more, as it can "detect" idle too early. - */ -static double minlatency = 8; -static double maxlatency = 33; - -/* - * blinking timeout (set to 0 to disable blinking) for the terminal blinking - * attribute. - */ -static unsigned int blinktimeout = 800; - -/* - * interval (in milliseconds) between each successive call to ximspot. This - * improves terminal performance while not reducing functionality to those - * whom need XIM support. - */ -int ximspot_update_interval = 1000; - -/* - * thickness of underline and bar cursors - */ -static unsigned int cursorthickness = 2; - -/* - * 1: render most of the lines/blocks characters without using the font for - * perfect alignment between cells (U2500 - U259F except dashes/diagonals). - * Bold affects lines thickness if boxdraw_bold is not 0. Italic is ignored. - * 0: disable (render all U25XX glyphs normally from the font). - */ -const int boxdraw = 1; -const int boxdraw_bold = 1; - -/* braille (U28XX): 1: render as adjacent "pixels", 0: use font */ -const int boxdraw_braille = 1; - -/* - * bell volume. It must be a value between -100 and 100. Use 0 for disabling - * it - */ -static int bellvolume = 0; - -/* default TERM value */ -char *termname = "st-256color"; - -/* - * spaces per tab - * - * When you are changing this value, don't forget to adapt the »it« value in - * the st.info and appropriately install the st.info in the environment where - * you use this st version. - * - * it#$tabspaces, - * - * Secondly make sure your kernel is not expanding tabs. When running `stty - * -a` »tab0« should appear. You can tell the terminal to not expand tabs by - * running following command: - * - * stty tabs - */ -unsigned int tabspaces = 4; - -/* bg opacity */ -float alpha = 1.0; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ - "#cc241d", - "#98971a", - "#d79921", - "#458588", - "#b16286", - "#689d6a", - "#a89984", - "#928374", - "#fb4934", - "#b8bb26", - "#fabd2f", - "#83a598", - "#d3869b", - "#8ec07c", - "#ebdbb2", - [255] = 0, - /* more colors can be added after 255 to use with DefaultXX */ - "#add8e6", /* 256 -> 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 3556251..0000000 Binary files a/.config/st/st and /dev/null differ diff --git a/.config/st/st-copyout b/.config/st/st-copyout deleted file mode 100755 index 0d19e5a..0000000 --- a/.config/st/st-copyout +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Using external pipe with st, give a dmenu prompt of recent commands, -# allowing the user to copy the output of one. -# xclip required for this script. -# By Jaywalker and Luke -tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX) -trap 'rm "$tmpfile"' 0 1 15 -sed -n "w $tmpfile" -sed -i 's/\x0//g' "$tmpfile" -ps1="$(grep "\S" "$tmpfile" | tail -n 1 | sed 's/^\s*//' | cut -d' ' -f1)" -chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')" -eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')" -awk "/^$chosen$/{p=1;print;next} p&&/$eps1/{p=0};p" "$tmpfile" | xclip -selection clipboard diff --git a/.config/st/st-urlhandler b/.config/st/st-urlhandler deleted file mode 100755 index d44bb99..0000000 --- a/.config/st/st-urlhandler +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -urlregex="(((http|https)://|www\\.)[a-zA-Z0-9.]*[:]?[a-zA-Z0-9./@$&%?$#=_-]*)|((magnet:\\?xt=urn:btih:)[a-zA-Z0-9]*)" - -# First remove linebreaks and mutt sidebars: -urls="$(sed 's/.*│//g' | tr -d '\n' | - grep -aEo "$urlregex" | # grep only urls as defined above. - uniq | # Ignore neighboring duplicates. - sed 's/^www./http:\/\/www\./g')" - -[ -z "$urls" ] && exit - -chosen="$(echo "$urls" | dmenu -i -p 'Follow which url?' -l 10)" - -setsid xdg-open "$chosen" >/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 38b856f..0000000 Binary files a/.config/st/st.o and /dev/null differ 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 4574cb3..0000000 Binary files a/.config/st/x.o and /dev/null differ 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 0000000..4ba6c8d Binary files /dev/null and b/system-config/config/user/common/bin/wayshell-blanker differ 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"]