我正在编写一个使用 wmctrl 移动窗口的平铺脚本。在 xfce4-terminal 实例上使用它时,第二次连续相同的运行会调整窗口大小。这是重要的代码:
#!/usr/bin/python3
import subprocess
import os
import sys
class Screen(object):
def __init__(self, rows, cols):
self.rows = rows
self.cols = cols
# All workspaces and their data
desk_output = subprocess.getoutput("wmctrl -d").split("\n")
# All workspace numbers
desk_list = [line.split()[0] for line in desk_output]
# Data about current desktop. Not sure how it works with multiple.
current = [line for line in desk_output if line.split()[1] == "*"][0].split()
self.desktop = current[0]
self.width, self.height = map(int, current[8].split('x'))
self.orig_x, self.orig_y = current[7].split(',')
row_division = self.height // self.rows
col_division = self.width // self.cols
self.grid = []
for rownum in range(rows):
row = []
for colnum in range(cols):
col = []
col.append((col_division*colnum, col_division*(colnum+1)))
col.append((row_division*rownum, row_division*(rownum+1)))
row.append(col)
self.grid.append(row)
# Grid format is something like this:
# [[(0, 640), (0, 522)], [(640, 1280), (0, 522)], [(1280, 1920), (0, 522)]],
# [[(0, 640), (522, 1044)], [(640, 1280), (522, 1044)], [(1280, 1920), (522, 1044)]]
# Debug purposes
for i in self.grid:
print(i)
def get_coords(self, cols, rows):
"""Precondition: two two-tuples of (start,end) for rows and columns.
postcondition: desired x, y, width, height of window in pixels.
"""
row_start, row_end = rows
col_start, col_end = cols
x_start_coord = self.grid[0][col_start-1][0][0]
x_end_coord = self.grid[0][col_end - 1][0][1]
x_coords = (x_start_coord, x_end_coord)
y_start_coord = self.grid[row_start-1][0][1][0]
y_end_coord = self.grid[row_end - 1][0][1][1]
y_coords = (y_start_coord, y_end_coord)
x = x_coords[0]
y = y_coords[0]
w = y_coords[1] - y_coords[0]
h = x_coords[1] - x_coords[0]
return (x, y, h, w)
def move_active(self,x,y,w,h):
command = ','.join(map(str, [" wmctrl -r :ACTIVE: -e 0", x, y, w, h]))
# Print command for debugging
print(command)
os.system(command)
if __name__ == "__main__":
screen_rows = int(sys.argv[1])
screen_cols = int(sys.argv[2])
first_row = int(sys.argv[3])
last_row = int(sys.argv[4])
first_col = int(sys.argv[5])
last_col = int(sys.argv[6])
cols_filled = (first_col, last_col)
rows_filled = (first_row, last_row)
s = Screen(screen_rows, screen_cols)
c = s.get_coords(cols_filled, rows_filled)
# Print the coords we are about to move to
print(c)
s.move_active(*c)
如果我使用相同的坐标连续两次调用此脚本:
python3 screen.py 2 2 1 2 1 1
(这意味着网格大小:2x2,第 1-2 行,第 1-1 列(又名屏幕的右半部分(它将运行的命令打印到终端))
窗口第二次再次调整大小,忽略边框并扩展超出 xfce 面板。下面是第一个和第二个脚本运行后的图像。有关差异,请参见窗口底部。注意 wmctrl 命令运行两次都是一样的。
第一次运行终端仿真器从中心向右移动
第二次运行,终端模拟器将几个像素扩展到面板中
当直接从命令行运行 wmctrl 时也会发生这种行为,因此问题不在 python 中。(对于我的屏幕大小,wmctrl -r :ACTIVE: -e 0,0,0,960,1024
我包含了 python 脚本,因为如果您想测试行为,它允许您专门为您的屏幕获取该信息/命令。)
这表明问题在于“wmctrl 正在返回装饰内窗口的几何形状”。但是,我无法获取父窗口,并且它似乎不存在,因此该解决方案似乎可能特定于 unity/gedit。它也没有解释为什么一个连续的重复移动命令会改变窗口的几何形状,当第一个命令将它放在正确的位置时。
我测试了一些终端模拟器,看看模拟器是否可能是问题的根源。
从 xterm、terminator(尽管有奇怪的行为)、qterminal、eterm、rxvt、stterm 和 kterm 运行命令或程序时不会出现此问题。它确实出现在 xfce4-terminal 和 lilyterm 中。在 gnome-terminal 和 roxterm 中有类似但不相同的奇怪行为。这让我相信它是终端模拟器特定的错误/怪癖。问题可能与第一次调整大小有关,而不是第二次调整大小,因为 xterm 和其他模拟器在第一次运行时会完全扩展。
我在 Ubuntu 16.04 (xenial) 衍生版本(内核:x86_64 Linux 4.8.17-galliumos)上运行 xfce 4.12。我的 wmctrl 版本是 1.07。我的 xfwm4 版本是 4.12.3(修订版 7fdcb53)。我的屏幕分辨率是 1920x1080。我正在调整大小的窗口是 xfce4-terminal 0.6.3。
我想知道我是否可以做些什么来防止这种情况发生。我一直在将窗口大小调整为 0,0,0,0,然后调整为所需的尺寸,但这需要另一个命令和丑陋的闪光灯。
wmctrl -r :ACTIVE: -e 0,960,0,960,1024
Tldr:从 xfce4-terminal 实例运行 SAME wmctrl 命令两次( )第二次移动窗口,将其向下扩展。我想知道为什么会发生这种情况以及如何阻止它发生。