如何移动或调整X11窗口的大小(即使它们被最大化)?

2024-09-24 22:27:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我想改变窗户的位置。我的问题是窗口可以最大化,这不允许改变它的大小和位置(窗口可以属于任何应用程序)。我用KDE4。在


我尝试使用ewmhPython模块。在我的例子中,当窗口最大化时,我只想把它从一个监视器移到另一个监视器,保持它最大化。我需要取消最大化来设置它的几何体,所以我尝试用ewmh.setWmState()来取消最大化,将_NET_WM_STATE_MAXIMIZED_VERT_NET_WM_STATE_MAXIMIZED_HORZ设置为{},然后ewmh.display.flush()。在

有时我可以配置先前最大化窗口的位置和大小,有时不能。由于某些原因,它不能可靠地工作,如果我只是用xrandr从一个监视器切换到三个监视器,它特别有可能在最大化窗口中失败。在

请注意,取消最大化总是有效的,但(通常)不起作用的是随后更改窗口位置(或大小)。在


我也试过在候机楼做这个。这是重现我的问题最简单的方法。首先,获取某个最大化窗口的窗口ID($WID)。然后:

wmctrl -i -r $WID -b remove,maximized_vert,maximized_horz
wmctrl -i -r $WID -e 0,1280,50,1250,1250

但是第二个命令什么也不做,除非我在运行它之前手动移动或调整窗口大小。与ewmh不同,如果窗口最大化,wmctrl永远不会按预期工作。wmctrl成功地取消了窗口的最大化,但之后无法更改其位置或大小。在

这在单监视器和三监视器X屏幕状态下都是可重复的。在

这个问题似乎并不是特定于任何特定的工具。例如,如果窗口只是取消最大化,但没有手动移动/调整大小,xdotool也无法更改窗口大小/位置。在


到目前为止,我找到的唯一可靠的解决方法是取消窗口的最大化,可以手动使用ewmh或使用wmctrl,然后手动更改窗口大小或手动移动一点。只有这样我才能用ewmhwmctrl移动或调整大小。但显然这是不可接受的解决办法。在

是否有可靠的方法来设置窗口的几何图形,即使窗口当前已最大化?最好是使用Python的方法,但是使用shell命令的解决方案也可以。在


Tags: 方法命令应用程序net手动监视器state窗户
1条回答
网友
1楼 · 发布于 2024-09-24 22:27:56

多亏了n.m.的评论,我找到了解决办法。以下是我的pythonscript中的相关部分(它保存和恢复所有窗口的状态和几何体,因此本示例取消对所有窗口的最大化、取消映射和映射):

from time import sleep
from ewmh import EWMH
from Xlib import display, protocol, X
from Xlib.protocol.request import *
...
ewmh = EWMH()
disp = display.Display()
poll_interval = 0.025 # s
poll_attempts_limit = 10
...
def unmaximize(window):
  ewmh.setWmState(window, 0, "_NET_WM_STATE_MAXIMIZED_VERT")
  ewmh.setWmState(window, 0, "_NET_WM_STATE_MAXIMIZED_HORZ")
...
  for client in all_win:
    unmaximize(client.window)
  ewmh.display.flush()
  for client in all_win:
    client.xwin.unmap() 
  poll_attempts = 0
  for client in all_win:
    while client.xwin.get_attributes().map_state == X.IsViewable \
      and poll_attempts < poll_attempts_limit:
      sleep(poll_interval)
      poll_attempts += 1
  for client in all_win:
    client.xwin.map()   
  poll_attempts = 0
  for client in all_win:
    while client.xwin.get_attributes().map_state != X.IsViewable \
      and poll_attempts < poll_attempts_limit:
      sleep(poll_interval)
      poll_attempts += 1

执行此代码后,可以为任何窗口设置窗口几何图形。all_win是所有窗口的列表,表示为使用ewmh.getClientList()中的数据填充的自定义类对象的列表。每个client.xwin = disp.create_resource_object("window", client.id)。等待映射/取消映射完成很重要,否则将不可靠。此外,有必要限制轮询尝试,以防某些窗口意外映射或取消映射时出现无限循环。在


如果您不想一次重新配置许多窗口,那么使用python xlib模块进行取消映射和映射并没有明显的性能改进,那么使用xdotool更容易:

^{pr2}$

如果要在shell脚本中设置窗口几何体,则即使窗口最大化,以下示例也应有效:

wmctrl -i -r $WID -b remove,maximized_vert,maximized_horz
xdotool windowunmap  sync $WID
xdotool windowmap    sync $WID
wmctrl -i -r $WID -e 0,$x,$y,$width,$height

相关问题 更多 >