在启动应用程序的同一屏幕上打开应用程序窗口

在启动应用程序的同一屏幕上打开应用程序窗口

我使用的是双屏设置。Ubuntu 14.10/Unity。每个屏幕都有自己的启动器/Dash。我使用启动器的屏幕上会显示 Firefox、nautilus、terminal 和 thunderbird 等默认应用程序。因此...当我在右侧屏幕上使用 Firefox 启动器时,浏览器会在右侧屏幕上打开。正如应该的那样。

我希望其他应用程序(例如 Google Chrome)也能有这种行为。我似乎找不到合适的解决方案。

答案1

Unity 使用 Compiz 作为合成管理器,它有各种插件用于此类内容。为了简化操作,长话短说,无需在命令行中乱七八糟,请安装 Compiz 配置设置管理器(使用sudo apt-get install compizconfig-settings-manager或通过软件中心),然后查找Place Windows,确保已选中

在此处输入图片描述

在该插件下,将有几个选项Multi Output Mode。你想要的是Use output device of focused window。因此,它将打开文件窗口放置在文件管理器所在的位置 在此处输入图片描述

答案2

重定向命令以运行应用程序

大多数应用程序都会在启动它们的屏幕上打开窗口(无论是通过 Dash 还是启动器)。然而,有些应用程序却不会这样做,但可以通过重定向命令以通过以下脚本运行应用程序来强制它们这样做。为此,您需要编辑相应的.desktop文件(启动器)。

设置似乎有点复杂,但如果遵循程序(“如何使用”),它就不会太困难。

怎么运行的

  • 该脚本会在您单击启动器或从 Dash 中选择应用程序时读取鼠标位置,并确定在哪个屏幕上(左/右)。
  • 随后,它等待新窗口出现,该窗口由您启动的应用程序 (pid) 拥有。
  • 一旦窗口出现,它会检查窗口(屏幕)位置是否与鼠标(屏幕)初始位置匹配。
  • 如果不是,它会将窗口移动到您启动应用程序的屏幕。在大多数情况下,该操作将发生在窗口存在的(非常)早期阶段,因此您甚至不会注意到它。

问题/解决方案

有一个缺点:如果你替换.desktop文件的主要的通过命令来调用此脚本,右键单击“打开用 ”无法正常工作。对于像 Google Chrome 这样的网络浏览器来说,这不是什么大问题。对于其他应用程序,一个简单的解决方案是添加打开新窗口的选项在当前屏幕上作为快捷方式(请参阅下文)。

<图片>

如何使用:

  • 该脚本同时使用了wmctrlxautomation

    sudo apt-get install xautomation
    sudo apt-get install wmctrl
    
  • ~/bin如果目录尚不存在,则创建一个目录。

  • 将脚本复制到一个空文件中,保存为open_oncurrent(无扩展名)~/bin

  • 使其可执行(!)
  • 将相应.desktop文件从/usr/share/applications复制到~/.local/share/applications

    cp /usr/share/applications/google-chrome.desktop ~/.local/share/applications/google-chrome.desktop
    
  • 在以下位置打开本地副本~/.local/share/applications

    gedit ~/.local/share/applications/google-chrome.desktop
    
  • 编辑文件(两个选项):

    1. 要更改主要的启动器的命令:

      • 找到以下行:

        Exec=/usr/bin/google-chrome-stable %U
        
      • 将其更改为

        Exec=/bin/bash -c "open_oncurrent /usr/bin/google-chrome-stable"
        
    2. 要将该选项添加为快捷方式(如上图所示):

      • 找到以下行:

        X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;
        
      • 替换为:

        X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;New window on this screen;
        
      • 然后将以下部分添加到文件的最末尾:

        [New window on this screen Shortcut Group]
        Name=New window on this screen
        Exec=/bin/bash -c "open_oncurrent /usr/bin/google-chrome-stable"
        TargetEnvironment=Unity
        

如何与其他应用程序一起使用:

类似地,您可以将该解决方案应用于其他应用程序。文件中使用的命令的语法.desktop如下例所示:

Exec=/bin/bash -c "open_oncurrent <command>"

脚本中对如何处理异常做了一些补充说明。

剧本

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

t = 0; user = getpass.getuser(); application = sys.argv[1]
"""
In most cases, the command to run an application is the same as the process
name. There are however exceptions, to be listed below, if you use these appli-
cations i.c.w. this script. Just add an item to the list in the format:
["<command>", "<process_name>"],
"""
exceptions = [
    ["/usr/bin/google-chrome-stable", "chrome"],
    ]
try:
    procname = [app[1] for app in exceptions if app[0] == application][0]
except IndexError:
    procname = application

get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
# initial position of the mouse (click position)
start_pos = int(get("xmousepos").strip().split()[0])
# x- position of right side of the screen  
x_res = [int(s.split("x")[0]) for s in get("xrandr").split() if s.endswith("+0+0")][0]
# current windows
start_windows = get("wmctrl -l")
# open application
subprocess.call(["/bin/bash", "-c", application+"&"])
while t < 30:
    procs = get("ps -u "+user).splitlines()
    new = [w for w in get("wmctrl -lpG").splitlines() if not w.split()[0] in start_windows]
    match = sum([[line for line in procs if w.split()[2] in line and procname[:15] in line] for w in new], [])
    if len(match) == 1:
        data = new[0].split(); curr_pos = int(data[3]); compare = (start_pos > x_res, curr_pos > x_res)
        if compare[0] == compare[1]:
            pass
        else:
            if compare[0] == True:
                data[3] = str(int(data[3])+x_res)
            else:
                data[3] = str(int(data[3])-x_res)
            cmd1 = "wmctrl -r "+data[0]+" -b remove,maximized_vert,maximized_horz"
            cmd2 = "wmctrl -ir "+data[0]+" -e 0,"+(",").join(data[3:7])
            for cmd in [cmd1, cmd2]:
                subprocess.Popen(["/bin/bash", "-c", cmd])
        break
    t = t + 1
    time.sleep(0.5)

相关内容