diff --git a/local-bin/.local/bin/dev-launcher b/local-bin/.local/bin/dev-launcher index ff4d54c..bcc6c57 100755 --- a/local-bin/.local/bin/dev-launcher +++ b/local-bin/.local/bin/dev-launcher @@ -5,7 +5,7 @@ set -euo pipefail CACHE_MAX_AGE=300 MRU_SIZE=20 -# Debug logging (set DEBUG=1 to enable) +# Debug logging (set DEBUG=1 to enable via environment variable) DEBUG="${DEBUG:-0}" debug() { @@ -87,7 +87,7 @@ find_git_repos() { find "$DEV_DIR" -maxdepth 3 -type d -name ".git" -print0 | xargs -0 -n1 dirname | sort -u >"$CACHE_FILE" fi - local repo_count=$(wc -l < "$CACHE_FILE") + local repo_count=$(wc -l <"$CACHE_FILE") debug "Found $repo_count repositories" cat "$CACHE_FILE" } @@ -200,9 +200,9 @@ debug "Class name: $CLASS_NAME" debug "Launching ghostty with launch-or-focus..." launch-or-focus ghostty \ + --class "$CLASS_NAME" \ + --title "$PROJECT_NAME" \ --working-directory="$SELECTED" \ - --title="$PROJECT_NAME" \ - --class="$CLASS_NAME" \ -e bash -c "if tmux has-session -t '$SESSION_NAME' 2>/dev/null; then \ tmux attach -t '$SESSION_NAME'; \ else \ diff --git a/local-bin/.local/bin/launch-or-focus b/local-bin/.local/bin/launch-or-focus index 720abf3..17e94cd 100755 --- a/local-bin/.local/bin/launch-or-focus +++ b/local-bin/.local/bin/launch-or-focus @@ -1,167 +1,96 @@ #!/usr/bin/env bash set -euo pipefail -# Script to launch an application or focus it if already running in sway -# Usage: launch-or-focus [args...] -# Set DEBUG=1 to enable debug logging +# Simple script to launch an application or focus it if already running in sway +# Usage: launch-or-focus [--class CLASS] [--title TITLE] [args...] +# +# Examples: +# launch-or-focus firefox +# launch-or-focus code --class Code --title "My Project" +# launch-or-focus kitty --class kitty -DEBUG="${DEBUG:-0}" +CLASS="" +TITLE="" +ARGS=() -debug() { - [ "$DEBUG" = "1" ] && echo "[DEBUG] $*" >&2 || true -} +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --class) + CLASS="$2" + shift 2 + ;; + --title) + TITLE="$2" + shift 2 + ;; + *) + ARGS+=("$1") + shift + ;; + esac +done -if [ $# -eq 0 ]; then - echo "Usage: $0 [args...]" >&2 +if [ ${#ARGS[@]} -eq 0 ]; then + echo "Usage: $0 [--class CLASS] [--title TITLE] [args...]" >&2 exit 1 fi -COMMAND="$1" -shift -ARGS=("$@") - +COMMAND="${ARGS[0]}" APP_NAME=$(basename "$COMMAND") -debug "Command: $COMMAND" -debug "App name: $APP_NAME" -debug "Args: ${ARGS[*]}" +unset 'ARGS[0]' +ARGS=("${ARGS[@]}") -# Extract --class and --title values from args if present -# Handle both --class VALUE and --class=VALUE formats -CLASS_NAME="" -TITLE_NAME="" -for i in "${!ARGS[@]}"; do - if [[ "${ARGS[$i]}" =~ ^--class=(.+)$ ]]; then - CLASS_NAME="${BASH_REMATCH[1]}" - debug "Found class (format --class=VALUE): $CLASS_NAME" - elif [ "${ARGS[$i]}" = "--class" ] && [ $((i+1)) -lt ${#ARGS[@]} ]; then - CLASS_NAME="${ARGS[$((i+1))]}" - debug "Found class (format --class VALUE): $CLASS_NAME" - elif [[ "${ARGS[$i]}" =~ ^--title=(.+)$ ]]; then - TITLE_NAME="${BASH_REMATCH[1]}" - debug "Found title (format --title=VALUE): $TITLE_NAME" - elif [ "${ARGS[$i]}" = "--title" ] && [ $((i+1)) -lt ${#ARGS[@]} ]; then - TITLE_NAME="${ARGS[$((i+1))]}" - debug "Found title (format --title VALUE): $TITLE_NAME" - fi -done -debug "Extracted CLASS_NAME: '$CLASS_NAME'" -debug "Extracted TITLE_NAME: '$TITLE_NAME'" - -find_window_by_class() { - local class="$1" - debug "Searching for window by class: $class" - local result - result=$(swaymsg -t get_tree | jq -r --arg class "$class" ' - recurse(.nodes[]?, .floating_nodes[]?) | - select( - ((.window_properties.class | type) == "string" and .window_properties.class == $class) or - ((.app_id | type) == "string" and .app_id == $class) - ) | - .id - ' | head -n 1) - debug "find_window_by_class result: '$result'" - echo "$result" -} - -find_window_by_title() { - local title="$1" - local app="$2" - local result - - debug "Searching for window by title: '$title' and app: '$app'" - - # Search for windows matching both app and title (most specific) - result=$(swaymsg -t get_tree | jq -r --arg title "$title" --arg app "$app" ' - recurse(.nodes[]?, .floating_nodes[]?) | - select( - ( - ((.app_id | type) == "string" and (.app_id == $app or (.app_id | test($app; "i")))) or - ((.window_properties.class | type) == "string" and (.window_properties.class == $app or (.window_properties.class | test($app; "i")))) - ) and - ((.name | type) == "string" and .name == $title) - ) | - .id - ' | head -n 1) - - debug "find_window_by_title (app+title) result: '$result'" - [ -n "$result" ] && [ "$result" != "null" ] && echo "$result" && return - - # Fall back to title-only exact match - debug "Falling back to title-only exact match" - result=$(swaymsg -t get_tree | jq -r --arg title "$title" ' - recurse(.nodes[]?, .floating_nodes[]?) | - select((.name | type) == "string" and .name == $title) | - .id - ' | head -n 1) - - debug "find_window_by_title (title only) result: '$result'" - [ -n "$result" ] && [ "$result" != "null" ] && echo "$result" && return - - # Final fallback: title-only case-insensitive match - debug "Falling back to title-only case-insensitive match" - result=$(swaymsg -t get_tree | jq -r --arg title "$title" ' - recurse(.nodes[]?, .floating_nodes[]?) | - select((.name | type) == "string" and (.name | test($title; "i"))) | - .id - ' | head -n 1) - debug "find_window_by_title (case-insensitive) result: '$result'" - echo "$result" -} +# If class/title were provided as flags, add them to command args (for apps that support them) +if [ -n "$CLASS" ]; then + ARGS=("--class=$CLASS" "${ARGS[@]}") +fi +if [ -n "$TITLE" ]; then + ARGS=("--title=$TITLE" "${ARGS[@]}") +fi +# Find window by app_id (sway uses app_id), title, or app name find_window() { - local app_name="$1" - debug "Searching for window by app name: $app_name" - local result - result=$(swaymsg -t get_tree | jq -r --arg app "$app_name" ' - recurse(.nodes[]?, .floating_nodes[]?) | - select( - ((.app_id | type) == "string" and (.app_id == $app or (.app_id | test($app; "i")))) or - ((.window_properties.class | type) == "string" and (.window_properties.class == $app or (.window_properties.class | test($app; "i")))) or - ((.name | type) == "string" and (.name | test($app; "i"))) - ) | - .id - ' | head -n 1) - debug "find_window result: '$result'" - echo "$result" -} - -focus_window() { - local window_id="$1" - debug "Focusing window ID: $window_id" - swaymsg "[con_id=$window_id]" focus -} - -WINDOW_ID="" - -debug "Starting window search..." -# Only search by class/title if provided - don't fall back to generic app search -# This prevents matching the wrong window -if [ -n "$CLASS_NAME" ]; then - WINDOW_ID=$(find_window_by_class "$CLASS_NAME") - debug "After class search: WINDOW_ID='$WINDOW_ID'" -fi - -if ([ -z "$WINDOW_ID" ] || [ "$WINDOW_ID" = "null" ]) && [ -n "$TITLE_NAME" ]; then - WINDOW_ID=$(find_window_by_title "$TITLE_NAME" "$APP_NAME") - debug "After title search: WINDOW_ID='$WINDOW_ID'" -fi - -# Only fall back to generic app search if we don't have class or title -# This means the user wants to focus any instance of the app -if ([ -z "$WINDOW_ID" ] || [ "$WINDOW_ID" = "null" ]) && [ -z "$CLASS_NAME" ] && [ -z "$TITLE_NAME" ]; then - WINDOW_ID=$(find_window "$APP_NAME") - debug "After app name search (no class/title): WINDOW_ID='$WINDOW_ID'" + local class="$1" + local title="$2" + local app="$3" - ([ -z "$WINDOW_ID" ] || [ "$WINDOW_ID" = "null" ]) && WINDOW_ID=$(find_window "${APP_NAME,,}") - debug "After lowercase app name search: WINDOW_ID='$WINDOW_ID'" + # If class provided, search by app_id first (sway uses app_id) + if [ -n "$class" ]; then + swaymsg -t get_tree | jq -r --arg class "$class" ' + recurse(.nodes[]?, .floating_nodes[]?) | + select((.app_id | type) == "string" and .app_id == $class) | + .id + ' | head -n 1 + return + fi + + # If only title provided, search by title + if [ -n "$title" ]; then + swaymsg -t get_tree | jq -r --arg title "$title" ' + recurse(.nodes[]?, .floating_nodes[]?) | + select((.name | type) == "string" and .name == $title) | + .id + ' | head -n 1 + return + fi + + # Fallback to app name (search by app_id) + swaymsg -t get_tree | jq -r --arg app "$app" ' + recurse(.nodes[]?, .floating_nodes[]?) | + select((.app_id | type) == "string" and .app_id == $app) | + .id + ' | head -n 1 +} + +# Try to find existing window +WINDOW_ID=$(find_window "$CLASS" "$TITLE" "$APP_NAME") + +# Focus if found, otherwise launch +if [ -n "$WINDOW_ID" ] && [ "$WINDOW_ID" != "null" ]; then + swaymsg "[con_id=$WINDOW_ID]" focus +else + "$COMMAND" "${ARGS[@]}" >/dev/null 2>&1 & + disown fi -if [ -n "$WINDOW_ID" ] && [ "$WINDOW_ID" != "null" ] && [ "$WINDOW_ID" -eq "$WINDOW_ID" ] 2>/dev/null; then - debug "Window found! Focusing window ID: $WINDOW_ID" - focus_window "$WINDOW_ID" - exit 0 -fi - -debug "No matching window found, launching new instance" -"$COMMAND" "${ARGS[@]}" >/dev/null 2>&1 & -disown diff --git a/ssh/.ssh/config b/ssh/.ssh/config index 2189234..809250a 100644 Binary files a/ssh/.ssh/config and b/ssh/.ssh/config differ diff --git a/sway/.config/sway/config.d/autostart b/sway/.config/sway/config.d/autostart index 5f1127b..813f457 100644 --- a/sway/.config/sway/config.d/autostart +++ b/sway/.config/sway/config.d/autostart @@ -5,29 +5,28 @@ exec { $(nix-locate -w polkit-gnome-authentication-agent-1 | awk '{print $NF}') blueman-applet nm-applet - # swaync - wlsunset -l -34.9 -L -56.2 -t 4500 -g 0.9 + # wlsunset -l -34.9 -L -56.2 -t 4500 -g 0.9 easyeffects --gapplication-service clapboard --record } -# + # # User Interface exec { noctalia-shell - # ~/.local/bin/randwall - # ~/.local/bin/waybar.sh } -# + # Applications exec { $term --class="uy.com.mzunino" - slack - davmail + zen-twilight thunderbird - zen obsidian - localsend_app vesktop +} + +# Work Shit +exec { + slack gtk-launch com.microsoft.Edge.flextop.msedge-cifhbcnohmdccbgoicgdjpfamggdegmo-Default gtk-launch com.microsoft.Edge.flextop.msedge-faolnafnngnfdaknnbpnkhgohbobgegn-Default } diff --git a/sway/.config/sway/config.d/keybindings b/sway/.config/sway/config.d/keybindings index 7c77eff..717b626 100644 --- a/sway/.config/sway/config.d/keybindings +++ b/sway/.config/sway/config.d/keybindings @@ -2,7 +2,7 @@ # System Controls bindsym { $mod+Shift+r exec swaymsg reload && notify-send "Reloaded sway config" - $mod+Shift+e exec --no-startup-id wlogout + $mod+Shift+e exec --no-startup-id noctalia-shell ipc call sessionMenu toggle $mod+Escape exec ~/.local/bin/lock.sh } @@ -21,7 +21,7 @@ bindsym { $mod+n exec ~/.local/bin/sdm-ui.sh dmenu $mod+o exec ~/.local/bin/launch-or-focus obsidian "cd /home/forbi/Documents/Vault && $term --class obsidian nvim" $mod+e exec ~/.local/bin/launch-or-focus thunar - $mod+y exec clapboard + $mod+y exec noctalia-shell ipc call launcher clipboard $mod+b exec rofi-rbw --action copy } @@ -91,29 +91,25 @@ bindsym { bindsym { $mod+Shift+minus move scratchpad $mod+minus scratchpad show - $mod+u [instance="claude.ai"] move scratchpad; [app_id="uy.com.mzunino"] scratchpad show, move position center, fullscreen disable, resize set 1366 768 - $mod+g [app_id="uy.com.mzunino"] move scratchpad; [instance="claude.ai"] scratchpad show, move position center, fullscreen disable, resize set 1366 768 + $mod+u [app_id="uy.com.mzunino"] scratchpad show, move position center, fullscreen disable, resize set 1366 768 $mod+Shift+u exec --no-startup-id $term --class="uy.com.mzunino" - $mod+shift+g exec chromium --new-window --app="https://claude.ai" } # Special Functions bindsym { - F4 exec switch-windows - $mod+r exec --no-startup-id ~/.local/bin/record.sh + $mod+r exec --no-startup-id noctalia-shell ipc call screenRecorder toggle $mod+p exec --no-startup-id grim -g "$(slurp -d)" - | swappy -f - $mod+shift+p exec --no-startup-id ~/.local/bin/screenshot-upload $mod+F5 exec --no-startup-id ~/.local/bin/pause-notifications $mod+shift+d exec ~/.local/bin/satty-window } -# Multimedia Keys bindsym { - XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 0 +2% - XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 0 -2% - XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle - XF86MonBrightnessUp exec --no-startup-id brightnessctl set +5% - XF86MonBrightnessDown exec --no-startup-id brightnessctl set 5%- + XF86AudioRaiseVolume exec --no-startup-id noctalia-shell ipc call volume increase + XF86AudioLowerVolume exec --no-startup-id noctalia-shell ipc call volume decrease + XF86AudioMute exec --no-startup-id noctalia-shell ipc call volume mute + XF86MonBrightnessUp exec --no-startup-id noctalia-shell ipc call brightness increase + XF86MonBrightnessDown exec --no-startup-id noctalia-shell ipc call brightness decrease } # Mouse Bindings