Anzeige automatisch klonen

Hallo,

ich habe ein Skript gesucht, dass die Anzeige von Laptop mit Beamer sinnvoll klont, egal welche native Auflösungen die Anzeigegeräte haben. Nach kurzer weltweiter Recherche hab’ ich doch tatsächlich was gefunden und zwar hier bei uns:
http://www.linuxmuster.net/forum/post/6845

Ein großes Danke an Sven Röhrauer!

Ich habe das Skript so erweitert, dass es erst einmal abfragt, wie viele Anzeigegeräte angeschlossen sind und danach bei 2 Anzeigegeräten die Anzeige sinnvoll klont (größte gemeinsame Auflösung), bei nur 1 Anzeigegerät dessen Standardauflösung wieder herstellt und bei mehr als 2 Anzeigegeräten eine Warnmeldung für den Benutzer ausgibt.

Das schien mir sinnvoll für den Fall, dass Anzeigegeräte erst nach der Anmeldung am Computer angeschlossen oder ausgeschaltet werden. Wenn man das Skript dann nochmal startet, optimiert es die Anzeige entsprechend der gerade vorliegenden Situation. Dafür ist ein Starter für die Benutzer sinnvoll:
/usr/share/applications/BeamerModus.desktop

[Desktop Entry]
Version=1.0
Type=Application
Name=Anzeige optimieren
Comment=Optimiert die Anzeige bei der Verwendung von ein oder zwei Anzeigegeräten, z.B. wenn ein Beamer nach der Anmeldung am Computer angeschaltet oder abgeschaltet wird. Tastaturkürzel: Strg+Alt+r 
Exec=/opt/xrandr-beamer/xrandr-beamer-clone.sh
Icon=/usr/share/icons/beamer.png
Path=
Categories=Utility
Terminal=false
StartupNotify=false

Ich habe diesen übrigens unter /usr/share/applications abgelegt so dass er im App-Menü erscheint.

Ich habe für den XFCE-Desktop noch einen Tastatur-Shortcut hinzugefügt (ist im Skript durch # noch deaktiviert, da die meisten wohl kein XFCE einsetzen). Dadurch kann man das Skript per Strg+Alt+r aufrufen.
Ich hoffe, dass es mir dann dient, wenn die Anzeige mal wieder komplett abgeschaltet wird, sobald ich den PC an einer KVM-Station angeschlossen habe und auf einen anderen PC umschalte und dann wieder zurück. (Per ssh kann man dann mit xrandr ersehen, dass kein Anzeigemodus gesetzt ist, da das Sternchen-Symbol nirgends erscheint.)

Außerdem habe ich die groß geschriebenen Variablen von Sven gegen klein geschriebene ersetzt, damit man nicht mit Systemvariablen (z.B. DISPLAY) in Konflikt gerät, die wohl immer groß geschriebenen werden.
http://rowa.giso.de/german/shell-variablen.html


Bei den Clients, die an Beamern angeschlossen sind (lässt sich bei mir aus der 10.Stelle des Clientnamen ermitteln) kopiere ich den Starter auf den Desktop per Postsync:

### Auflösung automatisch anpassen
# Desktop-Icon kopieren in Abhängigkeit vom Clientnamen
displaytype="${HOSTNAME:9:1}"
case $displaytype in 
 b*)
  cp /mnt/usr/share/applications/BeamerModus.desktop /mnt/home/linuxadmin/Desktop/BeamerModus.desktop
  chmod +x /mnt/home/linuxadmin/Desktop/BeamerModus.desktop
esac

Hier das eigentliche Skript:
/opt/xrandr-beamer/xrandr-beamer-clone.sh

#!/bin/bash
# Anzeige automatisch klonen
# Sen 2017-07-02
# Linux Mint 17.0 Xfce 64bit
# GPL v3
# Dank an Sven Röhrauer für seinen Code für 2 Anzeigegeräte
# NUR FÜR XFCE-Desktop geeignet: Shortcut setzen, um Skript per Shortcut aufrufen zu können
# xfconf-query -c xfce4-keyboard-shortcuts -p "/commands/custom/<Primary><Alt>r" -n -t string -s "/opt/xrandr-beamer/xrandr-beamer-clone.sh"
# Alle angeschlossenen Anzeigeräte ermitteln
disp=($(xrandr --query | grep " connected" | awk '{print $1}'))
# Anzahl der angeschlossenen Anzeigeräte ermitteln 
dispnum=($(xrandr --query | grep -c " connected"))
case $dispnum in 
 1*)
  ### Ein Anzeigegerät angeschlossen
  # Standardauflösung ermitteln
  orires=($(xrandr | grep "+  "| awk '{print $1}'))
  # Standardauflösung einstellen
  xrandr --output ${disp[0]} --mode $orires
 ;;
 2*)
  ### Zwei Anzeigegeräte angeschlossen
  # Finde die höchste gemeinsame Auflösung
  maxres=$(xrandr --query | awk '/^ *[0-9]*x[0-9]*/{ print $1 }' | \
  sort -n | uniq -d | tail -1)
  # Auflösung einstellen
  xrandr --output ${disp[0]} --mode $maxres --output ${disp[1]} \
  --mode $maxres --same-as ${disp[0]}
 ;;
 *)
  ### Andere Fälle: Skript funtkioniert nur für 1 und 2 Anzeigegeräte
  LANG=de_DE.utf8 /usr/bin/zenity --warning --text="\nDieses Skript funktioniert nur für 1 und 2 Anzeigegeräte. \n\nMehr Anzeigegeräte können nur manuell konfiguriert werden. \n\nVerwenden Sie dazu die Anzeigeeinstellungen." --title="Anzeige automatisch klonen"
 ;; 
esac

Gruß
Stefan

Das Skript läuft soweit gut, bis auf eine Ungenauigkeit, die ich in dieser Zeile behoben habe:

orires=($(xrandr | grep "+"$ | awk '{print $1}'))

Eine Sache stört mich noch: Wenn von 2 Anzeigegeräten die gemeinsame höchste Auflösung ermittelt wird, so wird bei einem Laptop mit 16:9 (nativ 1366x768) und einem Beamer mit 4:3 (nativ 1024x768) die 16:9-Darstellung ermittelt, weil der Beamer eben auch 1366x768 als Anzeigemodus anbietet.

Wenn man jetzt eine 4:3-Präsentation zeigt, führt das dazu, dass das Publikum über den Beamer nur eine sehr kleine Anzeige hat: Oben schwarze Ränder wegen 16:9-Modus an 4:3-Beamer, rechts und links schwarze Ränder wegen 4:3-Format der Präsentation über die 16:9-Darstellung.

Mir wäre es lieber, wenn die native Auflösung des Beamers verwendet würde.

Wie seht ihr das?

Gruß
Stefan

P.S:
Hier nochmal das ganze Skript:
/opt/xrandr-beamer/xrandr-beamer-clone.sh

#!/bin/bash

# Anzeige automatisch klonen
# Sen 2017-07-02
# Linux Mint 17.0 Xfce 64bit
# GPL v3
# Dank an Sven Röhrauer für seinen Code für 2 Anzeigegeräte


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

# Alle angeschlossenen Anzeigeräte ermitteln
disp=($(xrandr --query | grep " connected" | awk '{print $1}'))
# Anzahl der angeschlossenen Anzeigeräte ermitteln 
dispnum=($(xrandr --query | grep -c " connected"))

case $dispnum in 
 1*)
  ### Ein Anzeigegerät angeschlossen
  # Standardauflösung ermitteln
  orires=($(xrandr | grep "+"$ | awk '{print $1}'))
  # Standardauflösung einstellen
  xrandr --output ${disp[0]} --mode $orires
 ;;
 2*)
  ### Zwei Anzeigegeräte angeschlossen
  # Finde die höchste gemeinsame Auflösung
  maxres=$(xrandr --query | awk '/^ *[0-9]*x[0-9]*/{ print $1 }' | \
  sort -n | uniq -d | tail -1)
  # Auflösung einstellen
  xrandr --output ${disp[0]} --mode $maxres --output ${disp[1]} \
  --mode $maxres --same-as ${disp[0]}
 ;;
 *)
  ### Andere Fälle: Skript funtkioniert nur für 1 und 2 Anzeigegeräte
  LANG=de_DE.utf8 /usr/bin/zenity --warning --text="\nDieses Skript funktioniert nur für 1 und 2 Anzeigegeräte. \n\nMehr Anzeigegeräte können nur manuell konfiguriert werden. \n\nVerwenden Sie dazu die Anzeigeeinstellungen." --title="Anzeige automatisch klonen"
 ;; 
esac

Hallo,

Die Zeile für das Herausfinden der nativen Auflösung eines Anzeigegeräts (bei der xrander-Ausgabe durch ein + gekennzeichnet) hatte nicht bei allen Test-Clients funktioniert. Hier die optimierte Zeile:

orires=($(xrandr --query | grep -e \+$ -e \+[[:space:]] | awk '{print $1}'))

Gruß
Stefan

Hallo,

ich möchte unbedingt auch eine Möglichkeit finden um die native Auflösung des Beamers zu verwenden, damit bei Präsentationen die beste Anzeigequalität für das Publikum garantiert ist.

Wie man die native Auflösung herausfindet, habe ich nun ja gelöst.

Ich rätsele aber noch daran, wie man dann die beste Auflösung des zweiten Anzeigegeräts bestimmen könnte. Da bräuchte ich Hilfe.

Ich meine, dass man mehrere Überprüfungen machen müsste:

Bester Fall: Wird die native Beamerauflösung auch vom zweiten Anzeigegerät unterstützt?

  • Bingo!

Nächter Fall: Passt das Bild ganz auf das zweite Anzeigegerät (mit möglichst wenig schwarzen Rändern)?

  • Gibt es Auflösungen vom zweiten Anzeigegerät, bei der x- und y-Auflösung größergleich sind als bei der Beamerauflösung? Dann davon die kleinste nehmen.

Nächster Fall: Es wird ein Teil des Bildes auf jeden Fall abgeschnitten. Es soll aber möglichst wenig Verlust geben.

  • Wie könnte man dann die versch. Verlustmöglichkeiten priorisieren?
    x-Auflösung ohne Verlust
    vor
    y-Auflösung ohne Verlust
    vor
    geringsten Verlust ermitteln aus Summe von Verlust bei x-Auflösung + Verlust bei y-Auflösung

Wer denkt mit?

Gruß
Stefan

Hallo,

nach längerem Ausprobieren, habe ich nun eine Lösung gefunden, die sich im privaten Bereich mit 2 Anzeigegeräten schon bewährt:

Ein Skript stellt beim Aufrufen die native Bildschirmauflösung für 1 Anzeigegerät ein und klont die Anzeige skaliert auf das andere Anzeigegerät.
So ist auf einem Anzeigegerät immer die optimale Darstellung gegeben und auf dem anderen Anzeigegerät wird die Darstellung zwar verzerrt aber vollständig angezeigt unter Ausnutzung der gesamten Bildschirmfläche. Durch erneutes Starten wird das andere Anzeigegerät als jenes mit der native Bildschirmauflösung gesetzt.

Das Skript habe ich nun so erweitert, dass alle Einstellungen vom Skript selbst ermittelt werden. Man muss also das Skript nicht konfigurieren.

Getestet habe ich es nur mit 2 Anzeigegeräten - aber ich habe die Hoffnung, dass es auch mit mehr als 2 Anzeigegeräten funktionieren könnte. Ich habe jedenfalls versucht die for-Schleife so zu bauen, dass es möglich sein sollte. Ob der xrandr-Befehl das aber packt, weiß ich nicht.

Wer Lust hat zu testen, möge bitte Rückmeldung geben.

#!/bin/bash

# Anzeige skaliert klonen
#
# Stellt die native Bildschirmauflösung für 1 Anzeigegerät ein und skaliert die anderen Anzeigegeräte.
# So ist auf einem Anzeigegerät immer die optimale Darstellung gegeben
# und auf den restlichen Anzeigegeräten wird die Darstellung zwar verzerrt aber vollständig angezeigt
# unter Ausnutzung der gesamten Bildschirmfläche.
# Durch erneutes Starten wird das nächste Anzeigegerät als jenes mit der native Bildschirmauflösung ausgewählt
# 
# Sen 2017-10-14
# Linux Mint 18.2 Xfce 64bit
#
# GPL v3


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

# Anzahl der angeschlossenen Anzeigeräte ermitteln 
dispcon=($(xrandr --query | grep -c " connected"))
# Höchste Nummer der Anzeigegeräte
dispmaxnumb=$((dispcon - 1))
# Bezeichnungen aller angeschlossenen Anzeigeräte ermitteln
disp=($(xrandr --query | grep " connected" | awk '{print $1}'))
# Native Auflösungen der angeschlossenen Anzeigeräte ermitteln
natres=($(xrandr --query | grep -e \+$ -e \+[[:space:]] | awk '{print $1}'))

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 auslesen - Nummer des zuletzt nativ angezeigten Anzeigegeräts
  numb=$(head -n 1 /tmp/xrandr-beamer-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-beamer-clone.log
  # Auflösungen einstellen
  for((i=0; i<$dispcon; i++)); do
  if [ ! $i = $numb ]; then 
    xrandr --output ${disp[$numb]} --mode ${natres[$numb]} --scale 1x1 --output ${disp[$i]} --same-as ${disp[$numb]} --mode ${natres[$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

Hier die Datei zum Download: xrandr-beamer-clone.sh.txt (2,1 KB)

Gruß
Stefan

P.S: Ich bevorzuge nun diese Methode, weil die andere Methode, welche die größte gemeinsame Auflösung verwendet, sich mit den neueren Beamern leider bei mir nicht bewährt hat, da Beamer mit nativ 1024x768 mittlerweile auch Auflösungen anbieten wie 1366x768. Dann kommt es zu unschönen Anzeigen.

Hier noch ein verbessertes Desktop-Icon, dass ich selbst erstellt habe und frei für jedermann gerne zur Verfügung stelle:

resolution

Gruß
Stefan

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