当连接外接显示器时,有没有办法防止窗户移动?

所以,我在我的笔记本电脑上使用Ubuntu 14.10,偶尔将它插入我的电视机进行第二次屏幕。 我的电视在我办公桌的左边。 当我将其作为笔记本电脑屏幕左侧的外部显示器启用时,我笔记本电脑屏幕上的所有窗口都会移动到电视屏幕上。 我可以将它们移回去,但每次都必须这样做是非常烦人的,特别是当有几个窗户打开时。

左边的电视

但是,如果我将电视屏幕设置在笔记本电脑屏幕的右侧(虚拟),则窗口不会移动。 但这是可以理解的混淆使用,因为它与物理设置相反。 另外,我不想移动我的桌子。

右边的电视

似乎Ubuntu或显示服务器只是假设最左边的监视器是主监视器,所有窗口应该在哪里。 有没有办法禁用此行为?

我一直在检查这些论坛,但没有真正见过任何人发布此事。 我找到的最接近的线程是这个,虽然它不是完全相同的问题。

当关闭多个监视器中的一个时,让Ubuntu不移动窗口

有人有主意吗? 如果你这样做,请告诉我。 谢谢!

我没有找到一个“秘密”设置来改变设计行为的行为。 看起来确实假设左侧屏幕是“基本”屏幕。

但是,很有可能创建一个变通方法,结果基本相同。 您可以创建一个脚本,在连接第二个屏幕时,列出所有窗口。 随后,最初移动到左侧屏幕的所有窗口将在一秒或两秒内移回到右侧的屏幕。 将保留所有窗口的大小。
这就是下面的脚本所做的。

两个版本

您可以通过两种方式恢复排列的窗口:

  • 偶尔,使用快捷键在第二个屏幕连接后运行。
  • 自动在后台运行脚本,等待屏幕连接。

如何使用

准备

  • 安装wmctrl

    sudo apt-get install wmctrl

  • xrandr的帮助下查找两个屏幕的名称,屏幕名称将在“连接”字样之前。

  • 复制下面的任何一个脚本,在head部分中,用这两行代替正确的屏幕名称:

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

    将脚本保存为move_windows.py

  • 确保在显示设置中,辅助屏幕位于左侧。 两个屏幕的顶行需要排成一行(就像你问题的第一张图片一样)。

运行脚本
– 如果您使用偶尔运行的那个,请在连接第二个屏幕后运行它。

  python3 /path/to/move_windows.py 

如果您认为它应该执行的操作,您可能希望将其添加到键盘快捷键中,选择:系统设置>“键盘”>“快捷方式”>“自定义快捷方式”。 单击“+”并添加命令:

  • 如果您使用在后台运行的那个,也可以通过以下命令运行它:

     python3 /path/to/move_windows.py 

    如果它按预期运行,请将其添加到启动应用程序中:Dash> Startup Applications> Add

我用笔记本电脑(右侧)和两个不同的屏幕(左侧)测试了脚本。 结果是一样的。

笔记本屏幕

在此处输入图像描述

没有脚本连接

在此处输入图像描述

连接脚本运行

在此处输入图像描述

在脚本完成其工作后,Windows将“独自”(当然),您可以按照自己的方式安排窗口。

脚本

1.“手动”版本,在连接屏幕后运行

 #!/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.自动版,在后台运行

 #!/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