Apakah ada cara untuk mencegah windows Anda bergerak ketika monitor eksternal terhubung?

9

Jadi, saya menggunakan Ubuntu 14.10 di laptop saya dan kadang-kadang hubungkan ke TV saya untuk layar kedua. TV saya ada di sebelah kiri meja saya. Ketika saya mengaktifkannya sebagai monitor eksternal di sebelah kiri layar laptop saya, semua jendela yang ada di layar laptop saya pindah ke layar TV. Saya dapat memindahkannya kembali, tetapi sangat menjengkelkan harus melakukannya setiap waktu, terutama ketika ada beberapa jendela yang terbuka.

TV di Kiri

Jendela tidak bergerak, bagaimanapun, jika saya mengatur layar TV saya di sebelah kanan layar laptop saya (secara virtual). Tapi ini bisa dimengerti membingungkan untuk digunakan karena itu kebalikan dari pengaturan fisik. Juga, saya tidak ingin memindahkan meja saya.

TV di Kanan

Sepertinya Ubuntu atau server tampilan hanya berasumsi bahwa monitor paling kiri adalah yang utama dan di mana semua jendela seharusnya. Apakah ada cara untuk menonaktifkan perilaku ini?

Saya telah memeriksa forum-forum ini tetapi belum pernah melihat orang memposting tentang ini. Utas terdekat yang saya temukan adalah yang ini, meskipun itu bukan masalah yang sama.

Dapatkan Ubuntu untuk TIDAK memindahkan windows ketika mematikan salah satu dari beberapa monitor

Adakah yang punya ide? Tolong beri tahu saya jika Anda melakukannya. Terima kasih!

K0j0
sumber

Jawaban:

2

Saya tidak menemukan pengaturan "rahasia" untuk mengubah perilaku, yang tampaknya, perilaku yang dirancang. Tampaknya memang seolah-olah layar kiri diasumsikan sebagai layar "dasar".

Namun sangat mungkin untuk membuat solusi, dengan hasil yang pada dasarnya sama. Anda dapat membuat skrip yang, pada kesempatan menghubungkan layar kedua, mencantumkan semua jendela. Selanjutnya, semua jendela yang pada awalnya dipindahkan ke layar kiri, digeser kembali ke layar di sebelah kanan, dalam satu atau dua detik. Ukuran semua jendela akan dipertahankan.
Itulah yang dilakukan skrip di bawah ini.

Dua versi

Anda dapat memulihkan jendela yang diatur dengan dua cara:

  • Kadang-kadang, dengan tombol pintas untuk dijalankan setelah layar kedua terhubung.
  • Secara otomatis, menjalankan skrip di latar belakang, menunggu layar Anda terhubung.

Cara Penggunaan

persiapan

  • Install wmctrl

    sudo apt-get install wmctrl

  • Cari nama dua layar Anda dengan bantuan xrandr, nama-nama layar akan tepat sebelum kata "terhubung".

  • Salin salah satu skrip di bawah ini, di bagian kepala, ganti di dua baris ini nama layar dengan yang benar:

    screen_1 = "LVDS1"     # your main screen (laptop)
    screen_2 = "VGA1"      # secundary screen (on the left)
    

    simpan skrip sebagai move_windows.py

  • Pastikan dalam pengaturan tampilan, layar sekunder Anda ada di sebelah kiri. Baris teratas dari kedua layar harus sejalan (seperti pada gambar pertama dari pertanyaan Anda).

Jalankan skrip
- Jika Anda menggunakan yang berjalan sesekali, jalankan setelah layar kedua terhubung.

    python3 /path/to/move_windows.py

Anda mungkin ingin menambahkannya ke pintasan keyboard jika Anda berpikir itu melakukan apa yang harus dilakukan, Pilih: Pengaturan Sistem> "Keyboard"> "Pintasan"> "Pintasan Khusus". Klik "+" dan tambahkan perintah:

  • Jika Anda menggunakan yang dijalankan di latar belakang, jalankan juga dengan perintah:

    python3 /path/to/move_windows.py
    

    Jika berfungsi sesuai keinginan Anda, tambahkan ke aplikasi start-up Anda: Dash> Aplikasi Startup> Tambah

Saya menguji skrip dengan laptop saya (di sebelah kanan) dan dua layar berbeda (di sebelah kiri). Hasilnya sama.

layar laptop

masukkan deskripsi gambar di sini

menghubungkan tanpa skrip

masukkan deskripsi gambar di sini

menghubungkan dengan skrip berjalan

masukkan deskripsi gambar di sini

Setelah script melakukan tugasnya, windows akan "dibiarkan sendiri" (tentu saja), dan Anda dapat mengatur windows Anda dengan cara Anda.

Skrip

1. versi "Manual", untuk dijalankan setelah layar terhubung

#!/usr/bin/env python3
import subprocess
import time

#--
screen_2 = "LVDS1"       # replace with your internal screen (right)
screen_2 = "VGA1"        # replace with your external screen (left)
#--

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c",  cmd]).decode("utf-8")

def get_shift(xr_output):
    lines = [l for l in xr_output.splitlines() if " connected" in l][0].split()
    return int([it for it in lines if "x" in it][0].split("x")[0])

def shift_windows(shift):
    w_data = [l.split() for l in get("wmctrl -lG").splitlines()]
    relevant = []
    for w in w_data:
        props = get("xprop -id "+w[0])
        if (int(w[2]) < shift, "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True) == 2:
            command = "wmctrl -ir "+w[0]+" -e 0,"+(",").join([str(int(w[2])+shift), w[3], w[4], w[5]])
            subprocess.Popen(["/bin/bash", "-c", command])

shift_windows(get_shift(get("xrandr")))

2. Versi otomatis, untuk berjalan di latar belakang

#!/usr/bin/env python3
import subprocess
import time

#--
screen_2 = "LVDS1"       # replace with your internal screen (right)
screen_2 = "VGA1"        # replace with your external screen (left)
#--

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c",  cmd]).decode("utf-8")

def get_shift(xr_output):
    lines = [l for l in xr_output.splitlines() if " connected" in l][0].split()
    return int([it for it in lines if "x" in it][0].split("x")[0])

def shift_windows(shift):
    w_data = [l.split() for l in get("wmctrl -lG").splitlines()]
    relevant = []
    for w in w_data:
        props = get("xprop -id "+w[0])
        if (int(w[2]) < shift, "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True) == 2:
            command = "wmctrl -ir "+w[0]+" -e 0,"+(",").join([str(int(w[2])+shift), w[3], w[4], w[5]])
            subprocess.Popen(["/bin/bash", "-c", command])

while True:
    try:
        screen_info1 = get("xrandr")
        time.sleep(5)
        screen_info2 = get("xrandr")
        check = screen_2+" connected"
        if (check in screen_info1, check in screen_info2) == (False, True):
            time.sleep(5)
            shift_windows(get_shift(screen_info2))
    except:
        pass
Yakub Vlijm
sumber
Keterampilan yang benar-benar sakit, Yakub!
don.joey
@ K0j0 Apakah Anda berhasil?
Jacob Vlijm
@ JacobVlijm Tidak yakin apakah polling setiap 5 detik adalah solusi terbaik (apakah tidak ada kemungkinan event-driven?). Lagi pula, jika Anda tertarik untuk mengubah skrip ini menjadi indikator Unity ( seperti ini di sini ), silakan hubungi kami.
Peterino
@ Peterino Jika ada sinyal yang digerakkan oleh peristiwa, itu akan menjadi pilihan pertama saya. Pada saat yang sama: Jika naskah latar belakang ditulis dengan baik, beban tambahannya seharusnya (dan tidak bisa) tidak ada, dan saya selalu menguji skrip saya secara khusus mengenai hal itu. Saya menjalankan sendiri sejumlah skrip latar belakang. Bahkan semua bersama-sama tidak memiliki efek nyata. Ingat banyak loop berjalan dengan definisi pada sistem Anda. Tentang saran indikator Unity: Saya benar - benar tertarik mempelajari cara membuat indikator, baik untuk situasi ini atau yang lain :).
Jacob Vlijm
@JacobVlijm Sepertinya penempatan otomatis windows akan terjadi secara otomatis dimulai dengan salah satu rilis Ubuntu berikutnya ("work in progress"), menurut sumber di Canonical . Mungkin tidak layak berinvestasi dalam beberapa bulan tersisa pada rilis saat ini. Saya akan mengecek dengan pengembang Mir di IRC # ubuntu-mir @ freenode.
Peterino