Last active
          April 17, 2025 16:12 
        
      - 
      
- 
        Save nicolas-oliveira/709e93d87e7fb2bd56cb054392c3767b to your computer and use it in GitHub Desktop. 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | #!/bin/bash | |
| # Absolute path to xrandr | |
| TARGET_WIDTH=${TARGET_WIDTH:-2560} | |
| TARGET_HEIGHT=${TARGET_HEIGHT:-1440} | |
| POSITION="right" | |
| XRANDR="/usr/bin/xrandr" | |
| # NVIDIA="$(nvidia-settings -q CurrentMetaMode -t)" | |
| LAPTOP=$($XRANDR | awk '/ connected/ && /eDP/{print $1}') | |
| EXT=$(xrandr | awk '/ connected/ && !/eDP/{print $1}') | |
| if [[ -z "$LAPTOP" ]]; then | |
| echo "Error: Could not detect laptop (eDP) output." >&2 | |
| exit 1 | |
| fi | |
| if [[ -z "$EXT" ]]; then | |
| echo "Apenas um monitor foi detectado. Redefinindo: $LAPTOP." | |
| $XRANDR --output "$LAPTOP" --auto | |
| exit 0 | |
| fi | |
| # FUNÇÃO QUE PREPARA O SCRIPT PARA SER EXECUTADO EM CASOS | |
| # EM QUE O USUÁRIO ATUAL NÃO É USUÁRIO QUE ESTÁ USANDO O MONITOR | |
| # ESSA FUNÇÃO FOI CRIADA JUNTAMENTE COM A TENTATIVA DE EXECUTAR ESSE | |
| # SCRIPT COMO DAEMON PORÉM NÃO FUNCIONOU | |
| # function run-in-user-session() { | |
| # _display_id=":$(find /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)" | |
| # _username=$(who | grep "\(${_display_id}\)" | awk '{print $1}') | |
| # _user_id=$(id -u "$_username") | |
| # _environment=("DISPLAY=$_display_id" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$_user_id/bus") | |
| # sudo -Hu "$_username" env "${_environment[@]}" "$@" | |
| # } | |
| second_monitor_commands() { | |
| gsettings set org.gnome.shell.extensions.dash-to-dock dash-max-icon-size 50 | |
| gsettings set org.gnome.desktop.interface text-scaling-factor 1.05 | |
| gsettings set org.gnome.desktop.interface monospace-font-name 'SF Mono Powerline 11' | |
| gsettings set org.gnome.desktop.interface font-name 'SF Pro Display 11' | |
| gsettings set org.gnome.desktop.interface document-font-name 'SF Pro Display 11' | |
| gsettings set org.gnome.desktop.wm.preferences titlebar-font 'SF Pro Text Regular 11' | |
| # LER AS VARIÁVEIS ORIUNDAS DO XRANDR | |
| read LAP_W LAP_H < <(xrandr | awk -v MON="$LAPTOP" '$1==MON && /connected/{getline; print $1}' | awk -Fx '{print $1, $2}') | |
| read EXT_W EXT_H < <(xrandr | awk -v MON="$EXT" '$1==MON && /connected/{getline; print $1}' | awk -Fx '{print $1, $2}') | |
| # CALCULAR A RESOLUÇÃO FINAL | |
| scaleX=$(awk "BEGIN {printf \"%.10f\", $TARGET_WIDTH/$EXT_W}") | |
| scaleY=$(awk "BEGIN {printf \"%.10f\", $TARGET_HEIGHT/$EXT_H}") | |
| # Calcular as dimensões gerais do framebuffer | |
| FB_W=$(awk "BEGIN {printf \"%d\", $LAP_W + $EXT_W * $scaleX}") | |
| FB_H=$(awk "BEGIN {printf \"%d\", ( $LAP_H > $EXT_H * $scaleY ? $LAP_H : $EXT_H * $scaleY ) }") | |
| echo $FB_W | |
| echo $FB_H | |
| # APLICAR O NOVO FRAMEBUFFER | |
| $XRANDR --fb ${FB_W}x${FB_H} | |
| # Determine positions based on --position | |
| if [[ "$POSITION" == "right" ]]; then | |
| # External on left, laptop on right | |
| EXT_POS="0x0" | |
| LAP_POS=$(awk "BEGIN {printf \"%d\", $EXT_W * $scaleX}")"x0" | |
| PRIMARY="$EXT" | |
| else | |
| # Laptop on left, external on right | |
| LAP_POS="0x0" | |
| EXT_POS=$(awk "BEGIN {printf \"%d\", $LAP_W}")"x0" | |
| PRIMARY="$LAPTOP" | |
| fi | |
| # Apply scaling and positioning | |
| $XRANDR --output "$EXT" --mode ${EXT_W}x${EXT_H} \ | |
| --scale ${scaleX}x${scaleY} --pos $EXT_POS --primary | |
| $XRANDR --output "$LAPTOP" --mode ${LAP_W}x${LAP_H} \ | |
| --scale 1x1 --pos $LAP_POS | |
| # DESABILITADO POR INSTABILIDADE DO DRIVER | |
| # if [[ "${NVIDIA}" != "" ]]; then | |
| # NVIDIA="${NVIDIA#*" :: "}" | |
| # nvidia-settings -a CurrentMetaMode="${NVIDIA//\}/, ForceFullCompositionPipeline=On\}}" | |
| # fi | |
| } | |
| only_one_monitor_commands() { | |
| gsettings set org.gnome.desktop.interface text-scaling-factor 0.97 | |
| gsettings set org.gnome.desktop.interface monospace-font-name 'SF Mono Powerline 10' | |
| gsettings set org.gnome.desktop.interface font-name 'SF Pro Display 10' | |
| gsettings set org.gnome.desktop.interface document-font-name 'SF Pro Display 10' | |
| gsettings set org.gnome.desktop.wm.preferences titlebar-font 'SF Pro Text Regular 10' | |
| gsettings set org.gnome.shell.extensions.dash-to-dock dash-max-icon-size 44 | |
| } | |
| check_hdmi() { | |
| if [ "$XDG_SESSION_TYPE" = "x11" ]; then | |
| if $XRANDR | awk '/ connected/ && !/eDP/{print $1}'; then | |
| second_monitor_commands && | |
| notify-send "Segundo monitor identificado!" "Configurações aplicadas automaticamente" | |
| else | |
| only_one_monitor_commands && | |
| notify-send "Único monitor identificado!" "Configurações aplicadas automaticamente" | |
| fi | |
| fi | |
| } | |
| # DESABILITADO POIS NÃO TEM UMA FORMA DE FAZER O MÉTODO NO WAYLAND | |
| # if [ $XDG_SESSION_TYPE == "wayland" ]; then | |
| # if $XRANDR | grep -q "XWAYLAND1 connected"; then | |
| # second_monitor_commands | |
| # else | |
| # only_one_monitor_commands | |
| # fi | |
| # fi | |
| check_hdmi | |
| # CASO FOSSE POSSÍVEL COLOCAR EM UM DAEMON ESSA FUNÇÃO VIGIARIA A MUDANÇA DE HDMI | |
| # udevadm monitor --udev --subsystem-match=drm | while read -r line; do | |
| # if echo "$line" | grep -q "change"; then | |
| # check_hdmi | |
| # fi | |
| # done | 
Correção ChatGPT
#!/usr/bin/env
# Improved HDMI/Laptop multi-monitor scaling script
# Dynamically detects eDP (laptop) and external HDMI outputs
# Computes scale factors to achieve a target virtual resolution
# Supports positioning external monitor to the left or right
XRANDR="/usr/bin/xrandr"
# Set your desired virtual resolution for the external monitor
TARGET_WIDTH=${TARGET_WIDTH:-2560}
TARGET_HEIGHT=${TARGET_HEIGHT:-1440}
# Default position: "right" (external monitor on the left, laptop on the right)
POSITION="right"
# Parse optional arguments
function usage() {
    echo "Usage: $0 [--position left|right]"
    exit 1
}
while [[ "$1" =~ ^- ]]; do
  case "$1" in
    --position)
      POSITION="$2"; shift 2;;
    -h|--help)
      usage;;
    *)
      echo "Unknown option: $1"; usage;;
  esac
done
# Detect connected outputs
LAPTOP=$(xrandr | awk '/ connected/ && /eDP/{print $1}')
EXT=$(xrandr | awk '/ connected/ && !/eDP/{print $1}')
if [[ -z "$LAPTOP" ]]; then
    echo "Error: Could not detect laptop (eDP) output." >&2
    exit 1
fi
if [[ -z "$EXT" ]]; then
    echo "Only one monitor detected. Resetting to auto on $LAPTOP."
    $XRANDR --output "$LAPTOP" --auto
    exit 0
fi
# Query native resolutions
read LAP_W LAP_H < <(xrandr | awk -v MON="$LAPTOP" '$1==MON && /connected/{getline; print $1}' | awk -Fx '{print $1, $2}')
read EXT_W EXT_H < <(xrandr | awk -v MON="$EXT" '$1==MON && /connected/{getline; print $1}' | awk -Fx '{print $1, $2}')
# Compute floating-point scale factors
scaleX=$(awk "BEGIN {printf \"%.10f\", $TARGET_WIDTH/$EXT_W}")
scaleY=$(awk "BEGIN {printf \"%.10f\", $TARGET_HEIGHT/$EXT_H}")
# Compute overall framebuffer dimensions
FB_W=$(awk "BEGIN {printf \"%d\", $LAP_W + $EXT_W * $scaleX}")
FB_H=$(awk "BEGIN {printf \"%d\", ( $LAP_H > $EXT_H * $scaleY ? $LAP_H : $EXT_H * $scaleY ) }")
# Apply new framebuffer
$XRANDR --fb ${FB_W}x${FB_H}
# Determine positions based on --position
if [[ "$POSITION" == "right" ]]; then
    # External on left, laptop on right
    EXT_POS="0x0"
    LAP_POS=$(awk "BEGIN {printf \"%d\", $EXT_W * $scaleX}")"x0"
    PRIMARY="$EXT"
else
    # Laptop on left, external on right
    LAP_POS="0x0"
    EXT_POS=$(awk "BEGIN {printf \"%d\", $LAP_W}")"x0"
    PRIMARY="$LAPTOP"
fi
# Apply scaling and positioning
$XRANDR --output "$EXT" --mode ${EXT_W}x${EXT_H} \
        --scale ${scaleX}x${scaleY} --pos $EXT_POS --primary
$XRANDR --output "$LAPTOP" --mode ${LAP_W}x${LAP_H} \
        --scale 1x1 --pos $LAP_POS
# Optional: adjust GNOME scaling for consistency (run in user session)
# Uncomment and customize if you use GNOME:
# function run-in-user-session() {
#   _display_id=":$(find /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n1)"
#   _user=$(who | grep "(${_display_id})" | awk '{print $1}')
#   _uid=$(id -u "$_user")
#   env DISPLAY=$_display_id DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$_uid/bus \
#       sudo -Hu "$_user" gsettings set org.gnome.desktop.interface text-scaling-factor $(awk "BEGIN {printf \"%.2f\", $scaleX}")
#}
#run-in-user-session
echo "Applied scaling for $EXT: ${scaleX}x${scaleY} (target ${TARGET_WIDTH}x${TARGET_HEIGHT}), framebuffer ${FB_W}x${FB_H}."Não funcionou
Segunda correção
#!/usr/bin/env bash
# Improved HDMI/Laptop multi-monitor scaling script
# Dynamically detects internal (eDP) and external outputs via xrandr --listmonitors
# Computes scale factors to achieve a target virtual resolution on the external display
# Correctly assigns scaling to the intended monitor regardless of UI primary settings
set -euo pipefail
XRANDR="/usr/bin/xrandr"
# Default target virtual resolution for external monitor (override via env vars)
TARGET_WIDTH=${TARGET_WIDTH:-2560}
TARGET_HEIGHT=${TARGET_HEIGHT:-1440}
# Position of external relative to laptop: "right" or "left"
POSITION="right"
# Whether to explicitly set --primary on external (yes|no)
MAKE_PRIMARY="no"
function usage() {
    cat << EOF
Usage: $0 [--position left|right] [--primary yes|no]
  --position    Place external monitor to the left or right of laptop (default: right)
  --primary     Mark external as primary display (yes or no, default: no)
You can also override TARGET_WIDTH and TARGET_HEIGHT via environment variables.
EOF
    exit 1
}
# Parse arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        --position)
            POSITION="$2"; shift 2;;
        --primary)
            MAKE_PRIMARY="$2"; shift 2;;
        -h|--help)
            usage;;
        *)
            echo "Unknown option: $1" >&2; usage;;
    esac
done
# Gather monitor list and primary from xrandr --listmonitors
readarray -t MONS < <($XRANDR --listmonitors | awk 'NR>1{print $4}')
PRIMARY_MON=$($XRANDR --listmonitors | awk '/\*/{print $4}')
# Assign laptop (internal) and external monitors
if [[ "$PRIMARY_MON" =~ eDP ]]; then
    LAPTOP="$PRIMARY_MON"
    for M in "${MONS[@]}"; do [[ "$M" != "$LAPTOP" ]] && EXT="$M"; done
else
    EXT="$PRIMARY_MON"
    for M in "${MONS[@]}"; do [[ "$M" != "$EXT" ]] && LAPTOP="$M"; done
fi
if [[ -z "${LAPTOP:-}" || -z "${EXT:-}" ]]; then
    echo "Error: Could not uniquely detect both laptop (eDP) and external monitor." >&2
    exit 1
fi
# Function to get native resolution of a monitor
function get_native() {
    local MON=$1
    $XRANDR --query | awk -v MON="$MON" '$1==MON { if (match($0, /([0-9]+)x([0-9]+)\+/, a)) print a[1], a[2] }'
}
read LAP_W LAP_H < <(get_native "$LAPTOP")
read EXT_W EXT_H < <(get_native "$EXT")
# Calculate precise scale factors
scaleX=$(awk "BEGIN {printf \"%.10f\", $TARGET_WIDTH/$EXT_W}")
scaleY=$(awk "BEGIN {printf \"%.10f\", $TARGET_HEIGHT/$EXT_H}")
# Compute framebuffer size (rounded up)
FB_W=$(awk "BEGIN {printf \"%d\", ($LAP_W + $EXT_W*$scaleX + 0.5)}")
FB_H=$(awk "BEGIN {tmp = ($LAP_H > $EXT_H*$scaleY ? $LAP_H : $EXT_H*$scaleY); printf \"%d\", (tmp + 0.5)}")
# Apply framebuffer
$XRANDR --fb ${FB_W}x${FB_H}
# Compute positions
if [[ "$POSITION" == "left" ]]; then
    EXT_POS="0x0"
    LAP_POS=$(awk "BEGIN {printf \"%d\", $TARGET_WIDTH}")"x0"
else
    LAP_POS="0x0"
    EXT_POS=$(awk "BEGIN {printf \"%d\", $LAP_W}")"x0"
fi
# Apply laptop (internal) monitor with no scaling
$XRANDR --output "$LAPTOP" --mode ${LAP_W}x${LAP_H} --scale 1x1 --pos $LAP_POS
# Apply external monitor scaling and optional primary
PRIMARY_FLAG=""
[[ "$MAKE_PRIMARY" == "yes" ]] && PRIMARY_FLAG="--primary"
$XRANDR --output "$EXT" --mode ${EXT_W}x${EXT_H} --scale ${scaleX}x${scaleY} --pos $EXT_POS $PRIMARY_FLAG
# Summary
echo "Applied scaling to $EXT: ${scaleX}x${scaleY} (target ${TARGET_WIDTH}x${TARGET_HEIGHT}); framebuffer ${FB_W}x${FB_H}."
echo "Laptop ($LAPTOP) reset to ${LAP_W}x${LAP_H} at pos $LAP_POS."
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment
  
            
Revisão do ClaudeAI
Não funcionou
Correção dele: