繁体   English   中英

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

[英]How to move or resize X11 windows (even if they are maximized)?

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


我试着使用ewmh Python模块。 在我的情况下,当窗口最大化时,我只想将它从一个监视器移动到另一个监视器,使其保持最大化。 我需要ewmh.setWmState()以设置其几何,所以我尝试使用ewmh.setWmState()将其ewmh.setWmState()以将_NET_WM_STATE_MAXIMIZED_VERT_NET_WM_STATE_MAXIMIZED_HORZ设置为0 ,然后设置为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命令的解决方案也可以。

感谢nm评论,我找到了解决方案。 以下是我的python 脚本中的相关部分(它保存并恢复所有窗口的状态和几何,因此这个示例取消最大化,取消映射并映射所有窗口):

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更容易:

from os import system
...
system("xdotool windowunmap --sync " + str(client.window.id))
system("xdotool windowmap   --sync " + str(client.window.id))

如果要在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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM