Wie kann das Offscreen-Fenster nach dem Trennen des zweiten Monitors wiederhergestellt werden?

8

Ich verwende Ubuntu 14.04 auf meinem Laptop an meinem Schreibtisch mit einem zweiten Monitor. Wenn ich mich vom zweiten Monitor trenne - ohne Fehler -, verschiebt sich mein Fenster für Emacs vom Bildschirm.

Ich kann Alt-TAB verwenden, um Emacs zum aktiven Fenster zu machen, und Emacs blind stoppen, damit ich es neu starten kann, wodurch es wieder auf dem Bildschirm angezeigt wird. Aber es scheint mir, dass es in Ubuntu eine Möglichkeit geben sollte, ein Off-Screen-Fenster wieder auf den Bildschirm zu bringen. Gibt es?

Eine bessere Lösung wäre natürlich, zu verhindern, dass die Fenster als Reaktion auf die Unterbrechung des Monitors vom Bildschirm verschwinden, und ich würde eine Lösung für dieses Problem akzeptieren .

AKTUALISIEREN:

Die Ausgabe von, xrandrwährend an einen zweiten Monitor angeschlossen:

Screen 0: minimum 320 x 200, current 3200 x 1080, maximum 32767 x 32767
eDP1 connected primary 1920x1080+1280+0 (normal left inverted right x axis y axis) 382mm x 215mm
   1920x1080      60.0*+   59.9  
   1680x1050      60.0     59.9  
   1600x1024      60.2  
   1400x1050      60.0  
   1280x1024      60.0  
   1440x900       59.9  
   1280x960       60.0  
   1360x768       59.8     60.0  
   1152x864       60.0  
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
VGA1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 376mm x 301mm
   1280x1024      60.0*+   75.0  
   1280x960       60.0  
   1152x864       75.0  
   1024x768       75.1     70.1     60.0  
   832x624        74.6  
   800x600        72.2     75.0     60.3     56.2  
   640x480        75.0     72.8     66.7     60.0  
   720x400        70.1  
HDMI1 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

Der Ausgang xrandrnach dem Trennen vom zweiten Monitor:

Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 32767 x 32767
eDP1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 382mm x 215mm
   1920x1080      60.0*+   59.9  
   1680x1050      60.0     59.9  
   1600x1024      60.2  
   1400x1050      60.0  
   1280x1024      60.0  
   1440x900       59.9  
   1280x960       60.0  
   1360x768       59.8     60.0  
   1152x864       60.0  
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

Außerdem habe ich versucht, die Links-Rechts-Positionen meines Terminalfensters und meines Emacs-Fensters zu vertauschen und dann die Verbindung zu trennen. Dadurch bleibt das Emacs-Fenster nach dem Trennen vom zweiten Monitor auf dem Bildschirm. Und das Terminalfenster bleibt in der Position erhalten, in der Emacs eliminiert wurde. Es scheint also, als ob die Anwendung etwas damit zu tun hat.

davidrmcharles
quelle
Die Sache ist, es sollte sich automatisch bewegen, und das tut es auf meinem System. Was ist deine Ubunto-Version? passiert es bei allen Anwendungen oder nur bei einigen? Was ist die Ausgabe von xrandr nach dem Trennen des zweiten Monitors?
Jacob Vlijm
Die von Ihnen angeforderten Informationen wurden hinzugefügt. Ubuntu-Version vom 14.04.
Davidrmcharles
Danke für die Information. Sie sind sich nicht sicher, woran es liegt, aber als Problemumgehung wäre ein Skript (Verknüpfung) zum Verschieben aller Fenster in den visuellen Bereich vorerst eine akzeptable Lösung?
Jacob Vlijm
Das ist sicherlich besser als nichts, und ich bin sehr gespannt, wie man das machen würde!
Davidrmcharles
Ich werde morgen eine posten :)
Jacob Vlijm

Antworten:

7

Bewegen Sie alle Fenster in den sichtbaren Bereich

Wie in einem Kommentar vorgeschlagen / angefordert, verschiebt das folgende Skript alle "normalen" Fenster in den sichtbaren Bereich des aktuellen Arbeitsbereichs.

Die Lösung ist eine Problemumgehung. Die Bildschirminformationen werden korrekt aktualisiert, da sich die Ausgabe xrandrvor, nach und nach dem Trennen unterscheidet. Der Grund, warum sich die Fenster nicht von selbst bewegen, ist (derzeit) unbekannt, es sei denn, eine andere Antwort löst das Problem.

Das Skript

#!/usr/bin/env python3
import subprocess

# get the resolution of the screen (+0+0)
res = [
    int(n) for n in [
        s.split("+")[0].split("x")\
        for s in subprocess.check_output(["xrandr"]).decode("utf-8").split()\
        if "+0+0" in s][0]
    ]
# create list of windows
w_list = [w.split() for w in subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines()]
# filter only "normal" ones
valid = [
    w for w in w_list if "_NET_WM_WINDOW_TYPE_NORMAL" in\
    subprocess.check_output(["xprop", "-id", w[0]]).decode("utf-8")
    ]
# get the number of valid windows and calculate a targeted position
# the targeted position is a hunch, it will be exact if the window fits completely inside the resolution
# it will work anyway
parts = len(valid)+2
positions = [(int(n*res[0]/parts), int(n*res[1]/parts)) for n in list(range(parts))[1:-1]]
# unmaximaize, move the windows to the visible area (current workspace)
for i, w in enumerate(valid):
    subprocess.Popen(["wmctrl", "-ir", w[0], "-b", "remove,maximized_vert,remove,maximized_horz"])
    # weird, but sometimes wmctrl refuses to move a window if it is not resized first (?)
    subprocess.Popen(["wmctrl", "-ir", w[0], "-e", "0,200,200,200,200"])      
    subprocess.Popen(["wmctrl", "-ir", w[0], "-e", (",").join(["0", str(positions[i][0]), str(positions[i][1]),w[4],w[5]])])

Wie benutzt man

  1. Das Skript benötigt wmctrl:

    sudo apt-get install wmctrl
    
  2. Kopieren Sie das Skript in eine leere Datei und sichern Sie es als move_windows.py

  3. Testen Sie es: Öffnen Sie eine Reihe von Fenstern, platzieren Sie sie in verschiedenen Arbeitsbereichen usw. oder trennen Sie den zweiten Monitor. Führen Sie dann den folgenden Befehl aus:

    python3 /path/to/move_windows.py
    

    Alle "normalen" Fenster sollten in den sichtbaren Bereich des aktuellen Arbeitsbereichs verschoben werden.

  4. Wenn alles einwandfrei funktioniert, fügen Sie es einer Tastenkombination hinzu: Wählen Sie: Systemeinstellungen> "Tastatur"> "Tastenkombinationen"> "Benutzerdefinierte Tastenkombinationen". Klicken Sie auf das "+" und fügen Sie den Befehl hinzu:

    python3 /path/to/move_windows.py
    

Jetzt sollten Sie in der Lage sein, alle Fenster mit Ihrer Tastenkombination in den sichtbaren Bereich des aktuellen Arbeitsbereichs zu verschieben.

Jacob Vlijm
quelle
Tolles Skript, aber es wird die Fenster in meinem Dual-Screen-Setup nicht wieder an die richtige Stelle bringen. Ich fand heraus, dass die verlegten Fenster alle um x + 2 * screenwith verschoben werden - mit anderen Worten in einen virtuellen (und in meinem Fall nicht vorhandenen) Arbeitsbereich rechts. So etwas würde sie also wieder an den richtigen Ort bringen: while xpos > 3840*2: xpos -= 3840 subprocess.Popen(["wmctrl", "-ir", w[0], "-e", ",".join([w[1], str(xpos), w[3], w[4], w[5]])]) (sollte natürlich geändert werden, um die entsprechende Bildschirmbreite zu berücksichtigen)
Bachi
@Bachi Obwohl das Drehbuch vom August letzten Jahres stammt, fühlt es sich wie vor langer Zeit an :). Ein kurzer Blick zeigt, dass die "verlorenen" Fenster auf 200/200 verschoben werden, was das Ziel war, nicht so sehr die ursprüngliche Position wiederherzustellen (wenn Sie in einem Dual-Monitor-Setup davon sprechen können). Wenn dies in Ihrem Fall nicht der Fall ist und Fenster in einen nicht vorhandenen Arbeitsbereich verschoben werden, liegt möglicherweise ein weiterer außergewöhnlicher Fehler als OP vor. Dies ist zumindest der Eindruck auf einen kurzen Blick.
Jacob Vlijm
Ja, schade, dass dieser Fehler nach einem Jahr immer noch besteht. Mein Fall könnte etwas anders sein als der der OPs: Nach der Wiederaufnahme des Suspendierens, aber ohne die zweite Anzeige zu trennen, werden einige Fenster verschoben (aber immer auf die gleiche Weise), und ich möchte natürlich, dass die Fenster nicht vom Bildschirm verschwinden aber bleib wo sie zuletzt waren. Vielleicht hilft dies anderen bei diesem Problem. Danke für dein Skript!
Bachi
1
Dieses Skript gibt mir einen Fehler in Zeile 9 unter Ubuntu 17.04 - das if "+ 0 + 0" in s] [0] Zeile
RoundSparrow hilltx
@RoundSparrowhilltx Möglicherweise stammt Ihr Bildschirm-Setup nicht von 0, 0. Könnten Sie die Ausgabe von xrandrauf pastebin.com veröffentlichen , und was ist genau die Fehlermeldung?
Jacob Vlijm
0

Eine einfache Lösung, die für mich bei der Wiederherstellung von Fenstern funktioniert hat, die auf "Bildschirmen" von nicht verbundenen Monitoren verbleiben (nicht ganz das gleiche Problem wie beim OP, aber verwandt), ist die Verwendung der Tastenkombination, um das Fenster zu maximieren: Ctrl+ Super+ ↑.

[NB Superist der Schlüssel mit dem "Windows" -Symbol, normalerweise zwischen Fnund Alt. Auf einem Mac entspricht dies Command= ⌘. In älteren Versionen von Ubuntu als meiner (16.04) müssen Sie diese möglicherweise nicht einschließen Ctrl.]

Stromael
quelle