如何仅在需要时自动添加工作区?

ker*_*nic 16 unity automation workspaces workspace-switcher 14.04

假设我正在使用 4 个工作区并且我偶然需要更多,是否有自动化过程,或者如果不可能,有一种简单的方法来顺便添加更多工作区(而不是安装Ubuntu tweak等)。

Jac*_*ijm 14

自动设置工作区数量;根据您的需要添加和删除列和行

如果您输入工作区矩阵的最后一列或最后一行,将自动添加工作区的(该)后台脚本版本下方。

这是它的工作原理:

  1. 如果您到达最后一列或最后一行,则会添加其他视口:

    在此处输入图片说明

  2. 如果您的工作区有 5-10 秒未使用并且上面没有窗口,则额外的工作区将再次被删除。但是,您将始终在下方多保留一行,并在当前视口右侧多保留一列:

    在此处输入图片说明

剧本:

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

# --- set default workspaces below (horizontally, vertically)
hsize = 2
vsize = 2
# --- set the maximum number of workspaces below
max_ws = 10

def set_workspaces(size, axis):
    subprocess.Popen([
        "dconf", "write", "/org/compiz/profiles/unity/plugins/core/"+axis,
                str(size)
                ])

def get_res():
    resdata = subprocess.check_output(["xrandr"]).decode("utf-8").split()
    curr = resdata.index("current")
    return (int(resdata[curr+1]), int(resdata[curr+3].replace(",", "")))

def wspace():
    try:
        sp = subprocess.check_output(["wmctrl", "-d"]).decode("utf-8").split()
        return ([int(n) for n in sp[3].split("x")],
                [int(n) for n in sp[5].split(",")])

    except subprocess.CalledProcessError:
        pass


def clean_up(curr_col, curr_row):
    try:
        w_list = [l.split() for l in subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8").splitlines()]
        xpos = max([math.ceil((int(w[2])+span[1][0])/res[0]) for w in w_list])
        min_x = max(xpos, curr_col+1, hsize)
        if xpos >= hsize:
            set_workspaces(min_x, "hsize")
        else:
            set_workspaces(min_x, "hsize")
        ypos = max([math.ceil((int(w[3])+span[1][1])/res[1]) for w in w_list])
        min_y = max(ypos, curr_row+1, vsize)
        if ypos >= vsize:
            set_workspaces(min_y, "vsize")
        else:
            set_workspaces(min_y, "vsize")
    except subprocess.CalledProcessError:
        pass

res = get_res()
t = 0

while True:
    span = wspace()
    if span != None:
        cols = int(span[0][0]/res[0]); rows = int(span[0][1]/res[1])
        currcol = int((span[1][0]+res[0])/res[0])
        if all([currcol == cols, cols*rows < max_ws]):
            set_workspaces(cols+1, "hsize")
        currrow = int((span[1][1]+res[1])/res[1])
        if all([currrow == rows, cols*rows < max_ws]):
            set_workspaces(rows+1, "vsize")
        if t == 10:
            clean_up(currcol, currrow)
            t = 0
        else:
            t = t+1
        time.sleep(1)
Run Code Online (Sandbox Code Playgroud)

如何使用

  1. 将下面的脚本复制到一个空文件中,另存为 add_space.py
  2. 在脚本的头部部分,如果您喜欢其他设置(工作区的最大数量,默认矩阵,例如 2x2),请编辑这些行:

    # --- set default workspaces below (horizontally, vertically)
    hsize = 2
    vsize = 2
    # --- set the maximum number of workspaces below
    max_ws = 10
    
    Run Code Online (Sandbox Code Playgroud)
  3. 通过以下命令测试运行它:

    python3 /path/to/add_space.py
    
    Run Code Online (Sandbox Code Playgroud)
  4. 如果一切正常,请将其添加到您的启动应用程序中:Dash > Startup Applications > 添加命令:

    /bin/bash -c "sleep 15 &&  python3 /path/to/add_space.py`
    
    Run Code Online (Sandbox Code Playgroud)

笔记

与往常一样,该脚本非常“低效”,并且不会给您的处理器增加任何明显的负载。

解释

下面的故事有点复杂,主要是对概念过程的解释,而不是编码。只在你感兴趣的时候阅读。

如何计算所需的工作空间(示例列)

的输出wmctrl -d看起来像:

0  * DG: 3360x2100  VP: 1680,1050  WA: 65,24 1615x1026  N/A
Run Code Online (Sandbox Code Playgroud)

在输出中,VP: 1680,1050为我们提供了有关我们在跨越工作区(所有视口的矩阵)上的位置的信息。这个信息只有在我们也有屏幕分辨率时才有用,因为例如1680可能是屏幕的两倍(不太可能,但仍然)或屏幕的一倍。
幸运的是,我们可以从命令中解析出屏幕的分辨率xrandr

然后,如果我们知道屏幕的 x 大小是1680并且我们当前在 上VP: 1680,1050,我们就知道我们在工作区矩阵的第二列上。由于我们也知道总矩阵的大小(DG: 3360x2100,也来自 的输出wmctrl -d),我们知道当前矩阵包括两列(3360/1680),我们在“最后”一列。

在此处输入图片说明

然后脚本将发送一条指令,通过以下命令向矩阵添加一列:

dconf write /org/compiz/profiles/unity/plugins/core/hsize <current_viewport_column+1>
Run Code Online (Sandbox Code Playgroud)

这是原则。

如何计算要移除的工作空间(示例列)

脚本每 10 秒运行一次命令以列出所有当前打开的窗口,命令如下:

wmctrl -lG
Run Code Online (Sandbox Code Playgroud)

这也为我们提供了有关窗口位置的信息,如下所示:

0x04604837  0 3425 24   1615 1026 jacob-System-Product-Name Niet-opgeslagen document 2 - gedit
Run Code Online (Sandbox Code Playgroud)

在输出中,3425是窗口的 x 位置。然而,这个数字是相对于当前工作空间(左侧)的。要知道窗口在工作区矩阵中的绝对位置(x 方向),我们必须添加当前视口信息的第一个数字(例如VP: 1680,1050,来自 的输出wmctrl -d)。
然而,为了简单起见,假设我们在视口1,1(左上视口)上,因此窗口的相对位置等于其绝对位置。

由于屏幕的分辨率是1680,我们知道窗口在列上3425/1680,四舍五入,因为两者之间的所有内容都在3360 and 5040矩阵中的同一列上(分辨率的 3 到 4 倍)。为了正确计算,我们使用math.ceil()( python)

由于该脚本遵循始终在右侧/下方有一个额外工作区的规则,因此我们需要将列数设置为最高值:

  • 当前工作空间柱+ 1
  • 带有窗口的最后一
  • 默认的列数,在脚本的头部设置

所以脚本是:)

这些行以完全相同的过程进行管理。

  • @kernel_panic 哇,谢谢:) 我实际上正在考虑使它成为一个 ppa,就像这个:askubuntu.com/a/608295/72216,还有这个:askubuntu.com/a/560734/72216,最后(将来)将所有三个合并到一个“workspace_tools”应用程序中,可以将它们设置为选项或类似的东西:)。 (2认同)

Ser*_*nyy 6

从技术上讲,没有调整工作区大小的快捷方式,但您可以使用下面的简单脚本并将其绑定到快捷方式。

  1. 获取下面的脚本,将其保存在.local/share/applications文件夹中,或者您喜欢的任何位置。
  2. 确保脚本是可执行的 chmod 755 /path/to/script
  3. 将其绑定到系统设置 -> 键盘 -> 快捷方式 -> 自定义快捷方式中的快捷方式

例如,我有这样的设置:

在此处输入图片说明

该脚本绑定到ShiftCtrlAltI. 但CtrlAltI也可以工作。我给出了脚本的完整路径,即

/home/xieerqi/resize-workspaces.sh
Run Code Online (Sandbox Code Playgroud)

它应该是这样的:

在此处输入图片说明

脚本

#!/bin/bash
# Author : Serg Kolo
# Date: Sept 19, 2015
# Purpose: simple script to resize 
# unity workspaces
# Written for: http://askubuntu.com/q/676046/295286

HEIGHT=$(gsettings get org.compiz.core:/org/compiz/profiles/unity/plugins/core/ hsize)
WIDTH=$(gsettings get org.compiz.core:/org/compiz/profiles/unity/plugins/core/ vsize)
NEWSIZE=$(zenity --entry --text="Current desktop set-up $HEIGHT x $WIDTH. Enter new setup in HEIGHTxWIDTH format"  --width=250 | tr 'x' ' ' )

ARRAY=( $NEWSIZE )
[ -z ${ARRAY[1]}  ] && exit
    gsettings set org.compiz.core:/org/compiz/profiles/unity/plugins/core/ hsize ${ARRAY[0]}
    gsettings set org.compiz.core:/org/compiz/profiles/unity/plugins/core/ vsize ${ARRAY[1]}
Run Code Online (Sandbox Code Playgroud)

使用非常简单,设置非常简单