Вычисление видимой области частично скрытого окна

Вычисление видимой области частично скрытого окна

Мне приходится (скриптово) делать скриншоты окон, некоторые из которых могут быть частично или полностью скрыты другими окнами. Конечно, в таком случае скриншот бесполезен, и я бы лучше напечатал предупреждение.

К сожалению, я не в той ситуации, когда я могу использоватьоконный менеджер, который печатает даже скрытые или свернутые окна— Я застрял на старом KDE.

Я могу использовать, например, xwininfo -id <windowid> | grep "Map State"для определения того, перекрывает ли окно IsViewable(что по сути означает, что стандартные инструменты создания снимков экрана не будут жаловаться), но я не могу понять, как определить, перекрывается ли окно другими окнами и насколько это происходит (тогда я мог бы вывести предупреждение, если, скажем, видно менее 50% окна).

(Поскольку я на самом деле пытаюсь обойти это, потому что не верю, что это существует, конечно, я не буду жаловаться, если кто-нибудь укажет мне простой способ, например, «виртуально перерисовать» окна так, чтобы снимок экрана того стоил…)

решение1

Насколько мне известно (но я не эксперт по X), видимость отслеживается только через VisibilityNotifyсобытия, это не состояние, которое можно запросить как IsViewable. Вам нужно заставить KDE выдать это, я не знаю, может ли он это сделать.

Вы можете решить свою проблему, отправив окну VisibilityNotify(state=VisibilityUnobscured)событие. Я не знаю, достаточно ли этого, вам также может понадобиться отправить событие MapNotify. Вот непроверенный код Python для отправки VisibilityNotifyсобытия.

#! /usr/bin/env python
import re, sys, time
import Xlib.X, Xlib.XK, Xlib.display, Xlib.protocol

def parse_action(string):
    state = {
              '0': 0,
              '1': 1,
              '2': 2,
              'unobscured': 0,
              'partiallyobscured': 1,
              'fullyobscured': 2,
              'visibilityunobscured': 0,
              'visibilitypartiallyobscured': 1,
              'visibilityfullyobscured': 2,
             }[string.lower()]
    return state

def parse_window(display, arg):
    wid = int(arg, 0)
    return display.create_resource_object('window', wid)

def send_event(display, window, state):
    window.send_event(Xlib.protocol.event.VisibilityNotify(window=window,
                                                           state=state))
    display.sync()

if __name__ == "__main__":
    display = Xlib.display.Display()
    send_event(display, parse_window(display, sys.argv[1]), parse_action(sys.argv[2]))

Связанный контент