我正在编写一个使用wmctrl移动窗口的平铺脚本。在xfce4终端实例上使用它时,第二次连续相同的运行会调整窗口的大小。这是重要的代码:
#!/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命令运行两次都是相同的。
终端模拟器从中心向右移动的second run终端模拟器向下扩展几个像素到面板
直接从命令行运行wmctrl时会发生此行为,因此问题不在python中。 (对于我的屏幕大小,wmctrl -r :ACTIVE: -e 0,0,0,960,1024
。我包含了python脚本,因为如果你想测试行为,它允许你专门为你的屏幕获取信息/命令。)
This表明问题是“wmctrl返回装饰内窗口的几何形状”。但是,我无法获得父窗口,并且它似乎不存在,因此解决方案似乎可能特定于unity / gedit。它也没有解释为什么连续的重复移动命令会改变窗口的几何形状,当第一个命令将它放在正确的位置时。
我测试了一些终端仿真器,看看仿真器是否可能是问题的根源。
当从xterm,终结器(虽然有奇怪的行为),qterminal,eterm,rxvt,stterm和kterm运行命令或程序时,会发生不这个问题。 确实出现在xfce4-terminal和lilyterm中。在gnome-terminal和roxterm中有类似但不完全相同的奇怪行为。这让我相信它是终端模拟器特定的bug /怪癖。问题可能与第一次调整有关,而不是第二次调整大小,因为xterm和其他模拟器在第一次运行时完全展开。
我在Ubuntu 16.04(xenial)派生版上运行xfce 4.12(内核:x86_64 Linux 4.8.17-galliumos)。我的wmctrl版本是1.07。我的xfwm4版本是4.12.3(修订版7fdcb53)。我的屏幕分辨率是1920x1080。我正在调整大小的窗口是xfce4-terminal 0.6.3。
我想知道我是否可以做些什么来防止这种情况发生。我一直在将窗口调整为0,0,0,0,然后调整到所需的尺寸,但这需要另一个命令和一个丑陋的闪光灯。
Tldr:从xfce4终端实例运行SAME wmctrl命令两次(wmctrl -r :ACTIVE: -e 0,960,0,960,1024
)会第二次移动窗口,将其展开。我想知道为什么会发生这种情况以及如何阻止它发生。