Anzeige automatisch klonen

Hallo,

ich bräuchte etwas Hilfe beim Ermitteln der nativen Auflösung eines Anzeigegerätes damit das oben veröffentlichte Skript oder sein verbesserter Nachfolger (auf einem Anzeigegerät die native Auflösung; keine verzerrten Darstellungen bei den anderen Anzeigegerät, sondern maximale Einpassung mit schwarzen Rändern) in mehr Fällen korrekt funktioniert.

Das Problem ist, dass manche Anzeigegeräte mehr als eine native Auflösung in xrandr anbieten, zu erkenen an den Pluszeichen - hier bei VGA1:

linuxadmin@edv-l24oss ~ $ xrandr
Screen 0: minimum 320 x 200, current 1366 x 768, maximum 32767 x 32767
LVDS1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 310mm x 174mm
   1366x768       60.0*+
   1360x768       59.8     60.0  
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
VGA1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 518mm x 324mm
   1920x1200      60.0*+
   1920x1080      60.0 +
   1600x1200      60.0  
   1680x1050      60.0  
   1280x1024      60.0  
   1280x960       60.0  
   1024x768       60.0  
   800x600        60.3  
   640x480        60.0  
   720x400        70.1  
HDMI1 disconnected (normal left inverted right x axis y axis)
DP1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
HDMI3 disconnected (normal left inverted right x axis y axis)
DP2 disconnected (normal left inverted right x axis y axis)
DP3 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

Ich bräuchte einen bash-Code, der für jedes Anzeigegerät nur die erste der Auflösungen mit einem Pluszeichen ermittelt.

Die momentan verwendete Codezeile gibt alle Auflösungen mit einem Pluszeichen in der Zeile aus. dadurch kann die Zuordnung der nativen Auflösungen zu den Anzeigegeräten fehlerhaft werden.

linuxadmin@edv-l24oss ~ $ xrandr --query | grep -e [[:space:]]\+$ -e *\+$ -e \+[[:space:]] | awk '{print $1}'
1366x768
1920x1200
1920x1080

Wer kann helfen?

Stefan

Ich:
xrandr --query | grep -e [[:space:]]\+$ -e *\+$ -e \+[[:space:]] | awk '{print $1}'|sed -n 1p

L.G.
Christoph Gü

Hallo Christoph,

Danke für den Versuch, aber der sed-Befehl gibt einfach nur die erste aller Zeilen mit dem “+” aus.

Ich brauche aber JEWEILS die erste Zeile der Auflösung mit “+” für JEDES Anzeigegerät. Das ist knifflig, weil das Anzeigegerät (z.B. VGA1) nicht in der selben Zeile steht, wie die erste Zeile der Auflösung mit “+”.

Man kann es also nicht einfach mit einem Tool lösen, welches nur zeilenweise funktioniert.

Gruß
Stefan

Lieber Stefan,

uups, sorry…wer lesen kann, ist klar im Vorteil !
Ich hab eine ALternative, bitte etwas Geduld - Du brauchst zwei ineinander verschachtelte Schleifen…

Gruß Christoph Gü.

Lieber Stefan,

hier ist das Script:

    #!/bin/bash
    # by Christoph Guenschmann

    xrandr -q >xrandr_output
    za=`cat xrandr_output|wc -l`

    for ((z=1;z<=$za;z++));
     do
       cat xrandr_output|sed -n `echo $z`p >line1 
       vo=`awk '{ if ($1 ~ /[L,V,D,H]/) print $1 }' line1`
       vo_state=`awk '{ if ($1 ~ /[L,V,D,H]/) print $2 }' line1`
      
       if [ "$vo_state" =  "connected" ] 
        then
         echo "Ausgang:$vo"
         echo "Status:$vo_state"
         unset vo_res
    # Innere Schleife  
        while [ "$vo_res" = '' ]
        do
        ((z++))
        cat xrandr_output|sed -n `echo $z`p >line2 
        vo_res=`cat line2  | grep -e [[:space:]]\+$ -e *\+$ -e \+[[:space:]] \
                                                              | awk '{print $1}'`
    # Endlosschleife bei fehlerhafter Ausgabe von xrandr vermeiden
        if [ "$z" -gt 50 ] ; then
                break
        fi
      done  
    echo $vo_res
    echo "--------------"
    fi
    done




Liebe Grüße,
Christoph Gü
(P.S. Ich bin nicht der bash/awk/sed-Experte. Insbesondere bei der Variablenübergabe habe ich sehr grob gearbeitet - da ist sicher mehr Eleganz möglich)

Hallo Christoph,

Danke vielmals für den Code - er funktioniert prima!

Ich werde das ganze jetzt noch mit Array-Variablen in das ursprüngliche Skript einfügen und mich dann damit hier wieder melden.

Gruß
Stefan

Hallo zusammen,

hier nun das Skript, welche die Anzeigen mehrerer Anzeigegeräte automatisch klont

  • und zwar ohne irgendwelche Bildverzerrungen,
  • so dass die native Bildschirmauflösung für 1 Anzeigegerät eingestellt wird
  • und die anderen Anzeigegeräte unter maximaler möglicher Ausnutzung der Pixel skaliert werden.
  • Durch erneutes Starten des Skriptes wird das nächste Anzeigegerät als jenes mit der nativen Bildschirmauflösung ausgewählt. Um es den Benutzern einfach zu machen, kann man deshalb einen Starter mit passendem Icon auf dem Desktop erstellen. So müssen die Benutzer einfach nur so lange darauf klicken bis eine gefällige Anzeige erscheint.
  • Man kann das Skript zusätzlich auch in den Login-Autostart legen, so dass es nach der Anmeldung gleich ausgeführt wird.

Skript:
/opt/videosettings/xrandr-video-clone.sh

Eintrag wurde entfernt - Aktueller Beitrag siehe unten


Starter:
Desktop aller Benutzer: /home/linuxadmin/Desktop/xrandr-video-clone.desktop
Programmenü: /usr/share/applications/xrandr-video-clone.desktop
Autostart: /etc/xdg/autostart/xrandr-video-clone.desktop

[Desktop Entry]
Version=1.0
Type=Application
Name=Anzeige optimieren
Comment=Optimiert die Anzeige bei oder nach der Verwendung von mehreren Anzeigegeräten. Starten Sie diese Anwendung so oft bis die Auflösungen der Bildschirmanzeigen Ihnen zusagen. Tastaturkürzel: Strg+Alt+r
Exec=/opt/videosettings/xrandr-video-clone.sh
Icon=/usr/share/icons/resolution.png
Categories=Utility
Terminal=false
StartupNotify=false

Download (Endung .txt muss entfernt werden): xrandr-video-clone.desktop.txt (417 Bytes)


Icon:
/usr/share/icons/resolution.png

resolution

Download (Endung .txt muss entfernt werden): resolution.png.txt (9,5 KB)


Mit der Bitte um Rückmeldung
Stefan

3 „Gefällt mir“

Lieber Stefan,

das sieht ja schön aus ! Vielen Dank !
Sobald ich Zeit habe, teste ich das mal.

Gruß Christoph Gü

Hallo,

habe noch zwei BUGs entdeckt und entfernt:

Skript:
/opt/videosettings/xrandr-video-clone.sh

#!/bin/bash

# xrandr-video-clone
#
# Speicherort: /opt/videosettings/xrandr-video-clone.sh
# 
# Stellt die native Bildschirmauflösung für 1 Anzeigegerät ein und skaliert die anderen Anzeigegeräte ohne Bildverzerrung.
# Durch erneutes Starten wird das nächste Anzeigegerät als jenes mit der nativen Bildschirmauflösung ausgewählt
# 
# Linux Mint 17.0 Xfce 64bit
# Linux Mint 18.2 Xfce 64bit
#
# Sen 2017-12-10
# GPL v3


### Shortcut setzen, um Skript per Shortcut aufrufen zu können (NUR FÜR XFCE-Desktop)
# xfconf-query -c xfce4-keyboard-shortcuts -p "/commands/custom/<Primary><Alt>r" -n -t string -s "/opt/videosettings/xrandr-video-clone.sh"


### Ermitteln der angeschlossenen Anzeigeräte und der jewiligen ersten nativen Auflösung
xrandr --query --verbose > /tmp/xrandr-video-clone.xdr
za=`cat /tmp/xrandr-video-clone.xdr | wc -l`
nmbr=0
# Äußere Schleife
for ((z=1;z<=$za;z++)) ; do
  cat /tmp/xrandr-video-clone.xdr | sed -n `echo $z`p > /tmp/xrandr-video-clone.ln1 
  vo=`awk '{ if ($1 ~ /[L,V,D,H]/) print $1 }' /tmp/xrandr-video-clone.ln1`
  vo_state=`awk '{ if ($1 ~ /[L,V,D,H]/) print $2 }' /tmp/xrandr-video-clone.ln1`
  if [ "$vo_state" =  "connected" ] ; then
    unset vo_res
# Innere Schleife  
    while [ "$vo_res" = '' ] ; do
      ((z++))
      cat /tmp/xrandr-video-clone.xdr | sed -n `echo $z`p > /tmp/xrandr-video-clone.ln2 
      vo_res=`cat /tmp/xrandr-video-clone.ln2  | grep -e \+preferred$ -e \+preferred[[:space:]] | awk '{print $1}'`
# Endlosschleife bei fehlerhafter Ausgabe von xrandr vermeiden
      if [ "$z" -gt 1000 ] ; then
        break
      fi
    done
    # Bezeichnungen des angeschlossenen Anzeigeräts speichern
    disp[nmbr]=$vo
    echo "Angeschlossenes Anzeigegerät Nr.$nmbr: ${disp[nmbr]}"
    # Native Auflösungen des angeschlossenen Anzeigeräts speichern
    natres[nmbr]=$vo_res
    echo ${natres[nmbr]}
    natresx[nmbr]=$(echo $vo_res | cut -dx -f1)
    natresy[nmbr]=$(echo $vo_res | cut -dx -f2)
    echo "xres: ${natresx[nmbr]}"
    echo "yres: ${natresy[nmbr]}"
    echo "--------------"
    disp[nmbr]=$vo
    # Höchste Nummer der angeschlossenen Anzeigeräte speichern (beginnend mit 0)
    dispmaxnumb=$nmbr
    # Zähler erhöhen
    nmbr=$((nmbr + 1))
    # Anzahl der angeschlossenen Anzeigeräte speichern (beginnend mit 1) 
    dispcon=$nmbr
  fi
done
echo "Höchste Nr. der angeschlossenen Anzeigegeräte: $dispmaxnumb"
echo "Anzahl der angeschlossenen Anzeigegeräte: $dispcon"

### Fallunterscheidung falls nur 1 Anzeigegerät angeschlossen ist
case $dispcon in 
 1*)
  ### Ein Anzeigegerät angeschlossen
  # Standardauflösung einstellen
  xrandr --output ${disp[0]} --mode ${natres[0]} --scale 1x1
 ;;
 *)
  ### Mehrere Anzeigegeräte angeschlossen
  # Zähler für natives Anzeigegerät
  numb=$(head -n 1 /tmp/xrandr-video-clone.log)
  # Zähler erhöhen
  numb=$((numb + 1))
  # Zähler überprüfen und gegebenenfalls zurücksetzen
  [[ ! $numb = [0-$dispmaxnumb] ]] && numb=0
  # Zähler in Datei schreiben
  echo $numb > /tmp/xrandr-video-clone.log
  # Zähler für anzupassende Anzeigegeräte
  for((i=0; i<$dispcon; i++)) ; do
    if [ ! $i = $numb ] ; then 
      # Anzupassenden Anzeigemodus berechnen
      quotx=$(echo "scale=8; ${natresx[$numb]} / ${natresx[$i]}" | bc -l)
      echo "xopt: ${natresx[$numb]}"
      echo "xtofit: ${natresx[$i]}"
      echo "xquot: $quotx"
      quoty=$(echo "scale=8; ${natresy[$numb]} / ${natresy[$i]}" | bc -l)
      echo "yopt: ${natresy[$numb]}"
      echo "ytofit: ${natresy[$i]}"
      echo "yquot: $quoty"
        if [ $(echo "scale=8; $quotx > $quoty" | bc -l) = 1 ] ; then
          echo "xquot>yquot"
          fitresx[$i]=${natresx[$i]}
          fitresy[$i]=$(echo "scale=0; ${natresx[$i]} * ${natresy[$numb]} / ${natresx[$numb]}" | bc -l)
          echo "xfit: ${fitresx[$i]}"
          echo "yfit: ${fitresy[$i]}"
        else
          echo "yquot>xquot"
          fitresy[$i]=${natresy[$i]}
          fitresx[$i]=$(echo "scale=0; ${natresy[$i]} * ${natresx[$numb]} / ${natresy[$numb]}" | bc -l)
          echo "xfit: ${fitresx[$i]}"
          echo "yfit: ${fitresy[$i]}"
        fi
      fitmodeline[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f3 | sed 's/\"//g')
      fitmode[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f2 | cut -d\_ -f1)
      echo "fitmodeline: ${fitmodeline[$i]}"
      echo "fitmode: ${fitmode[$i]}"
      # Berechneten Anzeigemodus registrieren
      echo "Befehlszeile: xrandr --newmode ${fitmode[$i]} ${fitmodeline[$i]}"
      xrandr --newmode ${fitmode[$i]} ${fitmodeline[$i]}
      echo "Befehlszeile: xrandr --addmode ${disp[$i]} ${fitmode[$i]}"
      xrandr --addmode ${disp[$i]} ${fitmode[$i]}
      # Anzeige klonen
      echo "Befehlszeile: xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from ${natres[$numb]}"
      xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from ${natres[$numb]}
    fi  
  done
 ;;
esac

### Benachrichtigung anzeigen
notify-send -t 8700 "Anzeige ist nun optimiert für Anzeigerät ${disp[$numb]}"

exit 0

Download (Endung .txt muss entfernt werden): xrandr-video-clone.sh.txt (5,1 KB)

Gruß
Stefan

1 „Gefällt mir“

Hallo,

habe noch weitere BUGs entdeckt und entfernt:

Skript:
/opt/videosettings/xrandr-video-clone.sh

#!/bin/bash

# xrandr-video-clone
#
# Speicherort: /opt/videosettings/xrandr-video-clone.sh
# 
# Stellt die native Bildschirmauflösung für 1 Anzeigegerät ein und skaliert die anderen Anzeigegeräte ohne Bildverzerrung.
# Durch erneutes Starten wird das nächste Anzeigegerät als jenes mit der nativen Bildschirmauflösung ausgewählt
# 
# Linux Mint 17.0 Xfce 64bit
# Linux Mint 18.2 Xfce 64bit
#
# Sen 2017-12-12
# GPL v3


### Shortcut setzen, um Skript per Shortcut aufrufen zu können (NUR FÜR XFCE-Desktop)
# xfconf-query -c xfce4-keyboard-shortcuts -p "/commands/custom/<Primary><Alt>r" -n -t string -s "/opt/videosettings/xrandr-video-clone.sh"


### Ermitteln der angeschlossenen Anzeigeräte und der jewiligen ersten nativen Auflösung
xrandr --query --verbose > /tmp/xrandr-video-clone.xdr
za=`cat /tmp/xrandr-video-clone.xdr | wc -l`
nmbr=0
# Äußere Schleife
for ((z=1;z<=$za;z++)) ; do
  cat /tmp/xrandr-video-clone.xdr | sed -n `echo $z`p > /tmp/xrandr-video-clone.ln1 
  vo=`awk '{ if ($1 ~ /[L,V,D,H]/) print $1 }' /tmp/xrandr-video-clone.ln1`
  vo_state=`awk '{ if ($1 ~ /[L,V,D,H]/) print $2 }' /tmp/xrandr-video-clone.ln1`
  if [ "$vo_state" = "connected" ] ; then
    unset vo_res
# Innere Schleife  
    while [ "$vo_res" = '' ] ; do
      ((z++))
      cat /tmp/xrandr-video-clone.xdr | sed -n `echo $z`p > /tmp/xrandr-video-clone.ln2 
      vo_res=`cat /tmp/xrandr-video-clone.ln2  | grep -e \+preferred$ -e \+preferred[[:space:]] | awk '{print $1}'`
# Endlosschleife bei fehlerhafter Ausgabe von xrandr vermeiden
      if [ "$z" -gt 1000 ] ; then
        break
      fi
    done
    # Bezeichnungen des angeschlossenen Anzeigeräts speichern
    disp[nmbr]=$vo
    echo "Angeschlossenes Anzeigegerät Nr.$nmbr: ${disp[nmbr]}"
    # Native Auflösungen des angeschlossenen Anzeigeräts speichern
    natres[nmbr]=$vo_res
    echo ${natres[nmbr]}
    natresx[nmbr]=$(echo $vo_res | cut -dx -f1)
    natresy[nmbr]=$(echo $vo_res | cut -dx -f2)
    echo "xres: ${natresx[nmbr]}"
    echo "yres: ${natresy[nmbr]}"
    echo "--------------"
    disp[nmbr]=$vo
    # Höchste Nummer der angeschlossenen Anzeigeräte speichern (beginnend mit 0)
    dispmaxnumb=$nmbr
    # Zähler erhöhen
    nmbr=$((nmbr + 1))
    # Anzahl der angeschlossenen Anzeigeräte speichern (beginnend mit 1) 
    dispcon=$nmbr
  fi
done
echo "Höchste Nr. der angeschlossenen Anzeigegeräte: $dispmaxnumb"
echo "Anzahl der angeschlossenen Anzeigegeräte: $dispcon"

### Fallunterscheidung falls nur 1 Anzeigegerät angeschlossen ist
case $dispcon in 
 1*)
  ### Ein Anzeigegerät angeschlossen
  # Standardauflösung einstellen
  xrandr --output ${disp[0]} --mode ${natres[0]} --scale 1x1
 ;;
 *)
  ### Mehrere Anzeigegeräte angeschlossen
  # Zähler für natives Anzeigegerät
  numb=$(head -n 1 /tmp/xrandr-video-clone.log)
  # Zähler erhöhen
  numb=$((numb + 1))
  # Zähler überprüfen und gegebenenfalls zurücksetzen
  [[ ! $numb = [0-$dispmaxnumb] ]] && numb=0
  # Zähler in Datei schreiben
  echo $numb > /tmp/xrandr-video-clone.log
  # Zähler für anzupassende Anzeigegeräte
  for((i=0; i<$dispcon; i++)) ; do
    if [ ! $i = $numb ] ; then 
      # Anzupassenden Anzeigemodus berechnen
      quotx=$(echo "scale=8; ${natresx[$numb]} / ${natresx[$i]}" | bc -l)
      echo "xopt: ${natresx[$numb]}"
      echo "xtofit: ${natresx[$i]}"
      echo "xquot: $quotx"
      quoty=$(echo "scale=8; ${natresy[$numb]} / ${natresy[$i]}" | bc -l)
      echo "yopt: ${natresy[$numb]}"
      echo "ytofit: ${natresy[$i]}"
      echo "yquot: $quoty"
        if ( expr $quotx \> $quoty >/dev/null ) ; then
          echo "xquot>yquot"
          fitresx[$i]=${natresx[$i]}
          fitresy[$i]=$(echo "scale=0; ${natresx[$i]} * ${natresy[$numb]} / ${natresx[$numb]}" | bc -l)
          echo "xfit: ${fitresx[$i]}"
          echo "yfit: ${fitresy[$i]}"
        else
          echo "yquot>xquot"
          fitresy[$i]=${natresy[$i]}
          fitresx[$i]=$(echo "scale=0; ${natresy[$i]} * ${natresx[$numb]} / ${natresy[$numb]}" | bc -l)
          echo "xfit: ${fitresx[$i]}"
          echo "yfit: ${fitresy[$i]}"
        fi
      fitmodeline[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f2,3 | sed 's/\"//g')
      fitmode[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f2)
      echo "fitmodeline: ${fitmodeline[$i]}"
      echo "fitmode: ${fitmode[$i]}"
      # Berechneten Anzeigemodus registrieren
      echo "Befehlszeile: xrandr --newmode ${fitmodeline[$i]}"
      xrandr --newmode ${fitmodeline[$i]}
      echo "Befehlszeile: xrandr --addmode ${disp[$i]} ${fitmode[$i]}"
      xrandr --addmode ${disp[$i]} ${fitmode[$i]}
      # Anzeige klonen
      echo "Befehlszeile: xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from ${natres[$numb]}"
      xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from ${natres[$numb]}
    fi  
  done
 ;;
esac

### Benachrichtigung anzeigen
notify-send -t 8700 "Anzeige ist nun optimiert für Anzeigerät ${disp[$numb]}"

exit 0

Download (Endung .txt muss entfernt werden): xrandr-video-clone.sh.txt (5,1 KB)

Gruß
Stefan

2 „Gefällt mir“

Übrigens…

Wer das Skript einmal vom Terminal aus aufruft, bekommt viele Ausgaben angezeigt mit denen man überprüfen kann, was berechnet wird und welche xrandr-Befehle abgesetzt werden.

Das Skripte sollte auch für mehr als 2 Anzeigegeräte funktionieren. Das konnte ich aber bei mir nicht testen.

Über Rückmeldungen würde ich mich freuen.

Gruß
Stefan

Hallo STefan, habe hier: Bionic-Client: Bildschirme steuern in v7 im Thread für v7 mal dasselbe versucht und bin nach reichlich probieren mit deinem Skript zufrieden. Vielen Dank! Ich habe die SChleifen etwas angepasst, aber den rescale-mechanismus nicht angefasst und poste es mal hier:

#!/bin/bash                                                                                                                                                                             

# xrandr-video-clone                                                                                                                                                                    
#                                                                                                                                                                                       
# Speicherort: /opt/videosettings/xrandr-video-clone.sh                                                                                                                                 
#                                                                                                                                                                                       
# Stellt die maximale Bildschirmauflösung für 1 Anzeigegerät ein und skaliert die anderen Anzeigegeräte ohne Bildverzerrung.                                                            
# Durch erneutes Starten wird das nächste Anzeigegerät als jenes mit der nativen Bildschirmauflösung ausgewählt                                                                         
#                                                                                                                                                                                       
# Linux Mint 17.0 Xfce 64bit                                                                                                                                                            
# Linux Mint 18.2 Xfce 64bit                                                                                                                                                            
# Ubuntu Bionic 18.04 64bit                                                                                                                                                             
#                                                                                                                                                                                       
# Sen 2017-12-12                                                                                                                                                                        
# T.Küchel 2019-09-30                                                                                                                                                                   
# GPL v3                                                                                                                                                                                

### Shortcut setzen, um Skript per Shortcut aufrufen zu können (NUR FÜR XFCE-Desktop)                                                                                                   
# xfconf-query -c xfce4-keyboard-shortcuts -p "/commands/custom/<Primary><Alt>r" -n -t string -s "/opt/videosettings/xrandr-video-clone.sh"                                             

outputfile=`mktemp`
logger -t "$0[$USER]" "Output in $outputfile"

### Ermitteln der angeschlossenen Anzeigeräte und der jewiligen ersten nativen Auflösung                                                                                                
xrandr --query --verbose > $outputfile
## Fehlerhaftes xrandr (z.B. kein DISPLAY) abfangen                                                                                                                                     
[ $? -ne 0 ] && { echo usage: $0 ;  exit 1;  }
## Zeilenanzahl                                                                                                                                                                         
za=`cat $outputfile | wc -l`
nmbr=0
z=0

# Äußere Schleife über alle Zeilen von $outputfile                                                                                                                                      
while read line1; do
    ((z++))
    ## need the lines with either "connected" or "disconnected"                                                                                                                         
    if echo $line1 | grep -i "connected"  >/dev/null ; then
        vo=$(echo -n $line1 | cut -d " " -f 1)
        vo_state=$(echo -n $line1 | cut -d " " -f 2)
        if [ "$vo_state" = "connected" ] ; then

            ## maximale gemeinsame Auflösung, wenn es mehr als ein Display gibt (Danke, @Sven)                                                                                          
            MAXAUFLOESUNG=$(xrandr --query | awk '/^ *[0-9]*x[0-9]*/{ print $1 }' | sort -n | uniq -d | tail -1)
            if [ -z "$MAXAUFLOESUNG" ]; then
                MAXAUFLOESUNG=$(xrandr --query | awk '/^ *[0-9]*x[0-9]*/{ print $1 }' | sort -n | tail -1)
            fi

            ## Standardauflösung finden                                                                                                                                                 
            preferredfile=`mktemp`
            unset vo_res
            # Innere Schleife, um die nachfolgenden Zeilen nach der bevorzugten Auflösung zu durchsuchen                                                                                
            while [ "$vo_res" = '' ] ; do
                ((z++))
                cat $outputfile | sed -n `echo $z`p > $preferredfile
                line2=$(cat $preferredfile)
                if echo $line2 | grep -i "preferred" >/dev/null; then
                    vo_res=$(echo -n $line2 | cut -d " " -f 1)
                fi
                #vo_res=`cat /tmp/xrandr-video-clone.ln2  | grep -e \+preferred$ -e \+preferred[[:space:]] | awk '{print $1}'`                                                          
                # Endlosschleife bei fehlerhafter Ausgabe von xrandr vermeiden                                                                                                          
                if [ "$z" -gt 1000 ] ; then
                    echo "no preferred resolution found"
                    break
                fi
            done
            rm -f $preferredfile

            ## Bezeichnungen des angeschlossenen Anzeigeräts speichern                                                                                                                  
            disp[nmbr]=$vo
            echo "Angeschlossenes Anzeigegerät Nr.$nmbr: ${disp[nmbr]}"
            logger -t "$0[$USER]" "Angeschlossenes Anzeigegerät Nr.$nmbr: ${disp[nmbr]}"
            # Native Auflösungen des angeschlossenen Anzeigeräts speichern                                                                                                              
            natres[nmbr]=$vo_res
            natresx[nmbr]=$(echo $vo_res | cut -dx -f1)
            natresy[nmbr]=$(echo $vo_res | cut -dx -f2)
            echo "Bevorzugte Auflösung: xres: ${natresx[nmbr]}, yres: ${natresy[nmbr]}"
            echo "Maximale (gemeinsame) Auflösung: $MAXAUFLOESUNG"
            echo "--------------"
            maxres[nmbr]=$MAXAUFLOESUNG
            maxresx[nmbr]=$(echo $MAXAUFLOESUNG | cut -dx -f1)
            maxresy[nmbr]=$(echo $MAXAUFLOESUNG | cut -dx -f2)
            # Höchste Nummer der angeschlossenen Anzeigeräte speichern (beginnend mit 0)                                                                                                
            dispmaxnumb=$nmbr
            # Zähler erhöhen                                                                                                                                                            
            nmbr=$((nmbr + 1))
            # Anzahl der angeschlossenen Anzeigeräte speichern (beginnend mit 1)                                                                                                        
            dispcon=$nmbr
        fi
    fi
done < $outputfile
rm -f $outputfile
echo "Höchste Nr. der angeschlossenen Anzeigegeräte: $dispmaxnumb"
logger -t "$0[$USER]" "Höchste Nr. der angeschlossenen Anzeigegeräte: $dispmaxnumb"
echo "Anzahl der angeschlossenen Anzeigegeräte: $dispcon"
logger -t "$0[$USER]" "Anzahl der angeschlossenen Anzeigegeräte: $dispcon"

### Fallunterscheidung falls nur 1 Anzeigegerät angeschlossen ist                                                                                                                       
case $dispcon in
    1)
        ### Ein Anzeigegerät angeschlossen                                                                                                                                              
        # Standardauflösung einstellen                                                                                                                                                  
        #xrandr --output ${disp[0]} --mode ${natres[0]} --scale 1x1                                                                                                                     
        # Maximalauflösung einstellen                                                                                                                                                   
        xrandr --output ${disp[0]} --mode ${maxres[0]} --scale 1x1
        ;;
    2-9)
        ### Mehrere Anzeigegeräte angeschlossen                                                                                                                                         
        # Zähler für natives Anzeigegerät                                                                                                                                               
        numb=$(head -n 1 /tmp/xrandr-video-clone.log)
        # Zähler erhöhen                        
        numb=$((numb + 1))
        # Zähler überprüfen und gegebenenfalls zurücksetzen                                                                                                                             
        [[ ! $numb = [0-$dispmaxnumb] ]] && numb=0
        # Zähler in Datei schreiben                                                                                                                                                     
        echo $numb > /tmp/xrandr-video-clone.log
        # Zähler für anzupassende Anzeigegeräte                                                                                                                                         
        for ((i=0; i<$dispcon; i++)) ; do
            if [ ! $i = $numb ] ; then
                # Anzupassenden Anzeigemodus berechnen                                                                                                                                  
                quotx=$(echo "scale=8; ${natresx[$numb]} / ${natresx[$i]}" | bc -l)
                echo "xopt: ${natresx[$numb]}"
                echo "xtofit: ${natresx[$i]}"
                echo "xquot: $quotx"
                quoty=$(echo "scale=8; ${natresy[$numb]} / ${natresy[$i]}" | bc -l)
                echo "yopt: ${natresy[$numb]}"
                echo "ytofit: ${natresy[$i]}"
                echo "yquot: $quoty"
                if ( expr $quotx \> $quoty >/dev/null ) ; then
                    echo "xquot>yquot"
                    fitresx[$i]=${natresx[$i]}
                    fitresy[$i]=$(echo "scale=0; ${natresx[$i]} * ${natresy[$numb]} / ${natresx[$numb]}" | bc -l)
                    echo "xfit: ${fitresx[$i]}"
                    echo "yfit: ${fitresy[$i]}"
                else
                    echo "yquot>xquot"
                    fitresy[$i]=${natresy[$i]}
                    fitresx[$i]=$(echo "scale=0; ${natresy[$i]} * ${natresx[$numb]} / ${natresy[$numb]}" | bc -l)
                    echo "xfit: ${fitresx[$i]}"
                    echo "yfit: ${fitresy[$i]}"
                fi
                fitmodeline[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f2,3 | sed 's/\"//g')
                fitmode[$i]=$(cvt ${fitresx[$i]} ${fitresy[$i]} | grep Modeline | cut -d\" -f2)
                echo "fitmodeline: ${fitmodeline[$i]}"
                echo "fitmode: ${fitmode[$i]}"
                # Berechneten Anzeigemodus registrieren                                                                                                                                 
                echo "Befehlszeile: xrandr --newmode ${fitmodeline[$i]}"
                xrandr --newmode ${fitmodeline[$i]}
                echo "Befehlszeile: xrandr --addmode ${disp[$i]} ${fitmode[$i]}"
                xrandr --addmode ${disp[$i]} ${fitmode[$i]}
                # Anzeige klonen                                                                                                                                                        
                echo "Befehlszeile: xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from\
 ${natres[$numb]}"
                xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${fitmode[$i]} --scale-from ${natres[$numb]}
            fi
        done
        ;;
    *)
        echo "Mehr als 9 Anzeigegeräte vorsichtshalber nicht unterstützt. Kann man sicher machen..."
        ;;
esac

### Benachrichtigung anzeigen                                                                                                                                                           
notify-send -t 8700 "Optimiert für Anzeige ${disp[$numb]}"
logger -t "$0[$USER]" "Optimiert für Anzeige ${disp[$numb]}"

exit 0

VG, Tobias

2 „Gefällt mir“

Hallo Tobias,

Danke für Deine Rückmeldung.

Mit dem „rescale-mechanismus“ hatte ich bei einigen Rechnern Probleme.
An der Stelle

xrandr --newmode ${fitmodeline[$i]}

oder

xrandr --addmode ${disp[$i]} ${fitmode[$i]}

Es kam dort zu Fehlermeldungen, dass der mittels cvt ermittelte Modus fehlerhaft wäre. Um das zu beheben, reichte meine xrandr-Recherche leider nicht aus. Ich vermute und hoffe mich recht zu erinnern, dass es Probleme gibt, wenn der ermittelte neue Modus im Prinzip mit einem schon existierenden Modus überein stimmt. An der Stelle bin ich dann ausgestiegen.

Hoffe es hilft Dir etwas.

Gruß
Stefan

Hallo,

ich schalte vor solch „problematische“ Modi einen anderen Modus, von dem aus die Umschaltung klappt. Ihn finde ich durch Ausprobieren!

Gruß Christoph

Hallo Stefan,
erst mal vielen Dank für dein Script und die Mühe. Bei mir kommt in manchen Situationen die Anzeige „Außerhalb des Bereichs“. Ich glaube das passiert dann, wenn das Script fälschlicherweise den Beamer und nicht den Monitor als primäre Anzeige erkennt(?). Leider bin ich im Scripten schlecht, so dass ich das nicht ganz verstehe. Kannst du mir erklären, was das Problem ist?

Hallo Daniel,

leider kann ich Dir da nicht weiter helfen, außer auf das hin zu weisen, was ich oben schon geschrieben habe.

Gruß
Stefan

Hallo Stefan,

ich habe hier:

gefragt, ob das noch der aktuelle Stand ist. Kannst du dazu was sagen?

Grüße,
gerd

Hallo.
Ich pushe diesen Beitrag nochmal nach oben, weil uns heute auffiel, dass der Befehl „xrandr“ nicht mehr mit Ubuntu 22.04 (jammy) bzw Wayland zusammen funktioniert :scream:

Nach etwas Suche habe ich aber dieses Python-Script entdeckt, das die beiden Bildschirme dann doch wieder erfolgreich unter Jammy spiegelt und auf die gleiche Auflösung einstellen kann:

Wir nutzen seit heute:
python3 ./gnome-randr.py --output VGA-1 --mode 1280x800 --output HDMI-1 --mode 1280x800 --same-as VGA-1

Vielleicht kann’s ja jemand gebrauchen :thinking: :interrobang:
Viele Grüße,
Michael

P.S.: … oder gleich den Nachfolger: GitHub - maxwellainatchi/gnome-randr-rust: `xrandr` for Gnome/wayland, on distros that don't support `wlr-randr` (ungetestet)…

5 „Gefällt mir“

Hi Michael,

danke! Das können wir auf jeden Fall gebrauchen. (Darum kümmert sich mein Kollege, der ab morgen wieder da ist … ich muss ihn fragen wie hier unser Stand ist)

Grüße in den Norden,
gerd

Hallo,
habe deinen Beitrag nun erst gesehen - aber das Thema bleibt ja immer aktuell.

Ich hatte das gnome-randr.py erweitert, damit man die Auflösungen auch bei Erweitertem Modus (Zwei Bildschirme mit seperaten Inhalten) wählen kann. …falls es jemand braucht.

Um die Anzeige automatisch zu klonen, richten wir für jeden LehrerPC die monitors.xml für linuxadmin und gdm3 . Für das Erstellen der monitors.xml verwenden wir ein Srcipt
musterstick-create-monitorxml.zip (1,1 KB)

Dies wird als normaler Benutzer am PC ausgeführt. Dessen monitors.xml wird gelöscht und der Benutzer abgemeldet; danach wieder als dieser Benutzer anmelden und das Script nochmal aufrufen. Die gewünschten Monitoreinstellungen dann vornehmen. Die monitors.xml-Dateien werden dann in die passenden Postsync-Ordner des PCs auf den Server kopiert.
Danach den PC syncen, damit die Dateien auch auf den PC aufgespielt werden (Umständlich, spart aber die root-Passwort-Eingabe am PC. Das Script geht mit jedem normalen Benutzeraccount.)

Da die Beamer die meisten modelines nicht kennen, werden diese über den Umweg der base64-Kodierung angelegt. Durch den base64-Umweg ist alles in einem Script.

Viele Grüße, Helge