在特定显示器上启动应用程序

在特定显示器上启动应用程序

我有 Ubuntu 14.04 和两台显示器。当我打开应用程序时,我需要其中一些在主显示器上,而另一些在辅助显示器上。
目前,应用程序始终在主显示器上打开。

我只有一个(左侧)显示屏上有破折号图标,因此我无法使用 Compiz 中的光标或活动窗口设置启动应用程序。

答案1

下面的解决方案的工作原理如下:

  1. 按下组合键
  2. 15 秒内启动的第一个应用程序将在屏幕 1 上启动

或者:

  1. 按(另一个)组合键
  2. 15 秒内启动的第一个应用程序将在屏幕 2 上启动

换句话说:您需要两个组合键来确保新的应用程序窗口出现在第一个或第二个屏幕上。

如何设置

该脚本同时使用了xdotoolwmctrl

sudo apt-get install xdotool
sudo apt-get install wmctrl

然后:

  1. 将下面的脚本复制到一个空文件中,将其另存为preferred_screen(无扩展名)~/bin。如有必要,创建目录。
  2. 使脚本可执行
  3. 在头部部分,设置左屏的水平分辨率(我已经为你设置为1600)
  4. 如果您刚刚创建了目录~bin,请在终端中运行:

    source ~/.profile
    
  5. 通过在终端窗口中运行以下命令来测试运行脚本:

    preferred_screen 1
    

    现在打开一个(任意)应用程序,它应该在第一个屏幕上打开

    使用以下命令重复该步骤:

    preferred_screen 2
    

    现在该应用程序应该在第二个屏幕上打开。

  6. 如果一切正常,请将两个命令添加到两个不同的组合键中:选择:系统设置 > “键盘” > “快捷键” > “自定义快捷键”。单击“+”并添加命令:

    preferred_screen 1
    preferred_screen 2
    

剧本

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

#--- enter the horizontal resolution of the left screen below
left_width = 1600
#---

target_screen = int(sys.argv[1])
get = lambda cmd: subprocess.check_output(cmd).decode("utf-8")

def new_window(left_width):
    w_list1 = get(["wmctrl", "-lG"]).splitlines()
    while True:
        time.sleep(1)
        w_list2 = get(["wmctrl", "-lG"]).splitlines()
        new = [w.split() for w in w_list2 if not w in w_list1]
        if len(new) != 0:
            data = new[0]
            pos = 1 if int(data[2]) < left_width else 2
            coords = data[2:4]
            w_id = data[0]
            return [w_id, pos, coords]
            break

subject = new_window(left_width)
if not int(subject[1]) == target_screen:
    move = -left_width if target_screen == 1 else left_width - int(subject[2][0])
    subprocess.Popen(["xdotool", "windowmove", subject[0], str(int(subject[2][0])+move), subject[2][1]])

解释

在这种情况下,闯入启动过程本身对我来说似乎不是一个干净的解决方案,因此下面的解决方案在“偶然”的基础上起作用(仅当您从组合键调用它时)。

如果调用该脚本,它会等待 15 秒以等待新窗口出现,并将其移动到右侧或左侧屏幕(如果它尚未在目标屏幕上),然后终止。15 秒后,如果没有窗口出现,它会终止,以防止无限运行。

笔记

脚本假定屏幕是顶部对齐的。如果差异很大,则可能需要对脚本进行一些调整,以防止窗口“碰到”另一个屏幕的边框。

答案2

以下是一个启动脚本的想法,或者至少是一个可以绑定到快捷方式以首次启动窗口的脚本:

步骤1

找出根窗口的宽度和高度。可以使用

xwininfo -root | awk '/Width/,/Height/ {print}'

或者

xprop -root | awk '$1~/NET_DESKTOP_GEOMETRY/ {print }

示例输出如下

$ xwininfo -root | awk '/Width/,/Height/ {print}'                           
  Width: 1366
  Height: 768
$ xprop -root | awk '$1~/NET_DESKTOP_GEOMETRY/ {print}'                                                      
_NET_DESKTOP_GEOMETRY(CARDINAL) = 1366, 768

第2步

安装wmctrlsudo apt-get install wmctrl

此工具允许通过引用其十六进制 ID 或窗口标题来更改某些窗口属性。我已在另一个问题中解释了它的工作原理,稍后我会在此处链接

步骤3 在您的文件夹或路径的某个位置创建此脚本~/bin。您还可以将此脚本的完整路径绑定到快捷方式或创建.desktop快捷方式。请注意,由于我的屏幕是 1366 x 768,因此我使用 1300 作为我的最大右侧 x 偏移。根据您的规格在步骤 1 中调整脚本。请注意,如果您有重复的窗口,这可能会中断,因此这主要适用于首次启动两个程序窗口

#!/bin/sh
# Author: Serg Kolo
# Description: Send two different applications to different windows
set -x

LEFT=$(zenity --entry --text="What to put on the left?")
RIGHT=$(zenity --entry --text="What to put on the right?")

$LEFT &
$RIGHT &
sleep 1

if [ $? -eq 0 ]; then
    # Get title of the left window
    LEFT_TITLE="$(wmctrl -l | grep -i $LEFT | awk '{$1=$2=$3="";print}')"
    # Get title of the right window
    RIGHT_TITLE="$(wmctrl -l | grep -i $RIGHT | awk '{$1=$2=$3="";print }')"
printf "THIS IS A TEST %s",$LEFT_TITLE
printf "THIS IS A TEST 2 %s",$RIGHT_TITLE
    wmctrl -r $LEFT_TITLE -e 0,0,0,600,600

    sleep 0.5

    wmctrl -r $RIGHT_TITLE -e 0,1300,0,600,600

fi

现在,您可以调整此脚本,使其仅充当一个窗口的启动器,并指定您希望它位于右侧还是左侧。我将在今天晚些时候研究这个想法,但基本想法是再次使用两个弹出窗口和 if 语句。我的另一个想法是使用 awk 从单个弹出窗口中提取相关信息。完成脚本后,我将编辑我的答案

编辑

这是单个窗口的启动器;输入programname,L表示左侧放置,输入programname,R表示右侧放置

#!/bin/sh

# set -x
PROG=$(zenity --entry --text="Program,L or R ?")

NAME=$(echo $PROG | cut -d ',' -f1)
SIDE=$(echo $PROG | cut -d ',' -f2)
$NAME &
sleep 1

if [ $? -eq 0 ] 
then

    TITLE=$( wmctrl -l | grep -i $NAME| awk '{$1=$2=$3=""; print}' )

    sleep 0.5
if [ $SIDE = "L" ];then
    wmctrl -r $TITLE -e 0,0,0,600,600
else
    wmctrl -r $TITLE -e 0,1300,0,600,600
fi

fi

相关内容