Ubuntu 14.10 Aero snap在两个屏幕水平设置?

我设法让Aero snap左右工作在metacity Ubuntu 14.10中 ,现在我想提出正确的winctrl命令,这样我就能在两个屏幕设置上模仿相同的效果,其中两个屏幕水平放置在旁边彼此如下图所示。 我希望这能用于Metacity(GNOME经典),我不愿意转移到其他窗口管理器,因为我知道其中一些已经内置了这些function。 所以这是一个试图找到Metacity GNOME经典环境答案的问题:

在此处输入图像描述

我想要的是扩展我当前的winctrl命令。 它们目前通过使用屏幕总宽度的一半来工作,在屏幕总长度的左侧或右侧。 Super_L+left键入Super_L+left将使活动窗口使用左半部分,并且键入Super_L+right将使活动窗口使用总水平像素的右半部分。

 [hpenvy15 ~] $ cat > ~/bin/left.sh #!/bin/bash sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,0,0,`xwininfo -root | grep Width | awk '{ print (($2/2))}'`,`xwininfo -root | grep Height | awk '{ print $2 }'` ^C [hpenvy15 ~] $ cat > ~/bin/right.sh #!/bin/bash sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,`xwininfo -root | grep Width | awk '{ print (($2/2)+5) ",0," (($2/2)) }'`,`xwininfo -root | grep Height | awk '{ print $2 }'` ^C 

在具有两个屏幕的新设置中,我有1920 + 1920像素宽。 窗口的理想宽度是1920的一半,这是1920/2 = 960。 我想要新的right命令来计算当前找到的窗口的位置,然后如果键入left ,则转到最近的960宽像素块,在两个屏幕中出现的4个块中的任何一个,1920 + 1920配置,但也在一个屏幕1920配置中工作到最近的960宽块。 图表如下所示:

这是我在1和2中使用外部屏幕,在3和4中使用笔记本电脑屏幕时的配置。目前,单击Super_L+left会将窗口移动到屏幕左半部分的TotalWidth / 2,这太大了,去1 + 2。

我希望第一个left命令将其移动到窗格3,然后下一个left命令将其移动到2,然后下一个命令将其移动到1。

  +-------------------++-------------------++-------------------++-------------------+ | || || || +------------+ | | || || || | | | | || || <-------++-+ | | | || || || | | | | 1 || 2 || 3 || | 4 | | | || || || | | | | || || || +------------+ | | || || || | | || || || | +-------------------++-------------------++-------------------++-------------------+ 

这是我只有笔记本电脑屏幕的两半960像素宽的配置。

目前,单击Super_L+right将窗口移动到屏幕右半部分的TotalWidth / 2,这对应于数字4。

  +-------------------++-------------------+ | +------------+ || | | | | || | | | | || | | | |----++---> | | | 3 | || 4 | | | | || | | | | || | | +------------+ || | | || | +-------------------++-------------------+ 

当两个屏幕wmctrl时,这是wmctrl的输出:

 wmctrl -d 0 * DG: 3840x1080 VP: 0,0 WA: 0,0 3840x1080 Workspace 1 1 - DG: 3840x1080 VP: N/A WA: 0,0 3840x1080 Workspace 2 2 - DG: 3840x1080 VP: N/A WA: 0,0 3840x1080 Workspace 3 3 - DG: 3840x1080 VP: N/A WA: 0,0 3840x1080 Workspace 4 

当两个屏幕打开时,这也是xrandr的输出:

 [hpenvy15 ~] $ xrandr Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767 eDP1 connected primary 1920x1080+1920+0 (normal left inverted right x axis y axis) 344mm x 193mm 1920x1080 60.1*+ 59.9 40.0 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 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 521mm x 293mm 1920x1080 60.0*+ 50.0 59.9 30.0 25.0 24.0 30.0 24.0 1920x1080i 60.1 50.0 60.0 1680x1050 59.9 1600x900 60.0 1280x1024 75.0 60.0 1440x900 59.9 1366x768 59.8 1280x800 59.9 1152x864 75.0 1280x720 60.0 50.0 59.9 1440x576i 50.1 1024x768 75.1 70.1 60.0 1440x480i 60.1 60.1 832x624 74.6 800x600 72.2 75.0 60.3 720x576 50.0 720x480 60.0 59.9 640x480 75.0 72.8 66.7 60.0 59.9 720x400 70.1 VIRTUAL1 disconnected (normal left inverted right x axis y axis) 

我在Ubuntu(Gnome)Classic和Gnome Flashback(Metacity)14.04上测试了下面的脚本。 xdotoolwmctrl的“混合”应用程序是必要的,因为我遇到了编写Metacity脚本的一些特殊性。

解决方案

由于我希望脚本能够:

  • 确定哪个是左/右屏幕
  • 计算两个显示器的分辨率
  • 如果两个屏幕具有不同的分辨率(并计算窗口的位置和目标尺寸),也可以正常工作
  • 如果连接了第二个屏幕,则工作正常

– 我预见到的剧本有点广泛。

它能做什么:

如果连接了第二台显示器:
它的工作原理与您描述的完全相同:

  • 它将两个屏幕分成四个区域,每个区域的大小是它所在屏幕的一半(如上所述,也有不同的分辨率)
  • 使用选项“left”或“right”运行它:
    • 它将窗口移动到窗口左/右区域
    • 将其水平重新调整为目标屏幕大小的一半
    • 垂直最大化窗口

如果没有连接第二台显示器:
它以传统方式工作:

  • 使用选项“left”运行,它会在屏幕的左半部分垂直最大化最前面的窗口
  • 使用“右”选项运行,它会在屏幕的右半部分垂直最大化最前面的窗口

如何使用它

  • 安装xdotoolwmctrl

     sudo apt-get install wmctrl sudo apt-get install xdotool 
  • 将脚本复制到一个空文件中,将其保存为aero.py通过命令运行它

     python3 /path/to/aero.py left python3 /path/to/aero.py right 

剧本

 #!/usr/bin/env python3 import subprocess import sys move = sys.argv[1] def get(cmd): return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8") def execute(cmd): subprocess.call(["/bin/bash", "-c", cmd]) # screen resolutions ("raw") wds = [s for s in get("xrandr").split() if s.endswith("+0")] # x-res left/right) left = [scr.split("x")[0] for scr in wds if scr.endswith("+0+0")] right = [scr.split("x")[0] for scr in wds if not scr.endswith("+0+0")] # x-positions areas left_pos = [0, int(int(left[0])/2), int(left[0])] right_pos = [int(int(left[0])+int(right[0])/2)] if len(right) != 0 else [] x_positions = left_pos+right_pos # frontmost window pos frontmost =get("printf 0x%x "+get("xdotool getwindowfocus").strip()) frontmost = frontmost[:2]+"0"+frontmost[2:] f_data = [l.split() for l in get("wmctrl -lG").splitlines() if frontmost in l][0][:6] curr_pos = int(f_data[2]) area = len([x for x in x_positions if x <= curr_pos]) if move == "left": i = area-2; target_pos = x_positions[i] if i >= 0 else 0 elif move == "right": i = area; target_pos = x_positions[area] if area < len(x_positions) else x_positions[-1] if i >= 2: perc = int((100*(x_positions[-1]-x_positions[-2])/sum([int(it) for it in left+right]))) else: perc = int((100*(x_positions[1]-x_positions[0])/sum([int(it) for it in left+right]))) # execute actions cmd1 = "wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz" cmd2 = "wmctrl -ir "+f_data[0]+" -e 0,"+str(target_pos)+","+"30,300,300" cmd3 = "xdotool windowsize $(xdotool getactivewindow) "+str(perc)+"% 100%" for cmd in [cmd1, cmd2, cmd3]: execute(cmd) 

同时发布在gist.gisthub (最新版本)