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.
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.
#!/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)
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
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.
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
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.
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.
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
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
Viele Grüße,
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)
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.