|
#!/usr/bin/env bash |
|
|
|
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH" |
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
|
|
|
source "$SCRIPT_DIR/ui-utils.sh" |
|
|
|
POSITION="${1:-top}" |
|
|
|
# Validate position |
|
case "$POSITION" in |
|
top | right | bottom | left) ;; |
|
*) |
|
shalert "Invalid position" "Allowed: top, right, bottom, left. Default: top" |
|
exit 1 |
|
;; |
|
esac |
|
|
|
# Parse displayplacer list output |
|
DISPLAY_LIST=$(displayplacer list) |
|
|
|
# Extract displays: map contextual_id -> (persistent_id, resolution, scaling, current_origin) |
|
declare -A DISPLAYS |
|
|
|
while IFS= read -r line; do |
|
# Contextual ID |
|
if echo "$line" | grep -q "Contextual screen id:"; then |
|
CTX_ID=$(echo "$line" | awk '{print $NF}') |
|
fi |
|
|
|
# Persistent ID |
|
if echo "$line" | grep -q "Persistent screen id:"; then |
|
PERSIST_ID=$(echo "$line" | awk '{print $NF}') |
|
fi |
|
|
|
# Resolution |
|
if echo "$line" | grep -q "^Resolution:"; then |
|
WIDTH=$(echo "$line" | awk -F'[x:]' '{print $2}' | tr -d ' ') |
|
HEIGHT=$(echo "$line" | awk -F'[x:]' '{print $3}' | tr -d ' ') |
|
fi |
|
|
|
# Scaling |
|
if echo "$line" | grep -q "^Scaling:"; then |
|
SCALING=$(echo "$line" | awk '{print $NF}') |
|
fi |
|
|
|
# Origin: parse "(x,y)" |
|
if echo "$line" | grep -q "^Origin:"; then |
|
ORIGIN_X=$(echo "$line" | sed -E 's/.*\(([^,]+),.*/\1/') |
|
ORIGIN_Y=$(echo "$line" | sed -E 's/.*,([^)]+)\).*/\1/') |
|
# Store this display's info |
|
DISPLAYS[$CTX_ID]="$PERSIST_ID|$WIDTH|$HEIGHT|$SCALING|$ORIGIN_X|$ORIGIN_Y" |
|
fi |
|
done <<<"$DISPLAY_LIST" |
|
|
|
# Validate we have at least 2 displays |
|
if [ ${#DISPLAYS[@]} -lt 2 ]; then |
|
shalert "Display Detection Failed" "Found ${#DISPLAYS[@]} display(s), need at least 2" |
|
exit 1 |
|
fi |
|
|
|
# Extract MacBook (contextual 1) and external (contextual 2) specs |
|
IFS='|' read -r MB_ID MB_W MB_H MB_SCALE MB_OX MB_OY <<<"${DISPLAYS[1]}" |
|
IFS='|' read -r EXT_ID EXT_W EXT_H EXT_SCALE _ _ <<<"${DISPLAYS[2]}" |
|
|
|
if [ -z "$MB_ID" ] || [ -z "$EXT_ID" ]; then |
|
shalert "Display Parsing Failed" "Could not extract primary displays" |
|
exit 1 |
|
fi |
|
|
|
# Calculate new external display origin based on position |
|
# MacBook always at (0, 0) |
|
case "$POSITION" in |
|
top) |
|
NEW_EXT_X=0 |
|
NEW_EXT_Y=$((-EXT_H)) |
|
;; |
|
right) |
|
NEW_EXT_X=$MB_W |
|
NEW_EXT_Y=0 |
|
;; |
|
bottom) |
|
NEW_EXT_X=0 |
|
NEW_EXT_Y=$MB_H |
|
;; |
|
left) |
|
NEW_EXT_X=$((-EXT_W)) |
|
NEW_EXT_Y=0 |
|
;; |
|
esac |
|
|
|
# Build displayplacer arguments |
|
MB_ARG="id:$MB_ID res:${MB_W}x${MB_H} scaling:$MB_SCALE origin:(0,0)" |
|
EXT_ARG="id:$EXT_ID res:${EXT_W}x${EXT_H} scaling:$EXT_SCALE origin:($NEW_EXT_X,$NEW_EXT_Y)" |
|
|
|
printf "place-external-display: %s\nMacBook: %s\nExternal: %s\n" "$POSITION" "$MB_ARG" "$EXT_ARG" |
|
|
|
displayplacer "$MB_ARG" "$EXT_ARG" |
|
shnotif "External Display" "Placed to the $POSITION" |