使用 python xlib 进行选择性记录?
我正在尝试使用 python xlib 的 RECORD 扩展在根窗口上实现可点击区域。 这就是我到目前为止所得到的:
import sys
import os
from Xlib import X, XK, display
from Xlib.ext import record
from Xlib.protocol import rq
local_dpy = display.Display()
record_dpy = display.Display()
buttons={(0,200,0,200,"echo Hep")}
def record_callback(reply):
if reply.category != record.FromServer:
return
if reply.client_swapped:
print "* received swapped protocol data, cowardly ignored"
return
if not len(reply.data) or ord(reply.data[0]) < 2:
# not an event
return
data = reply.data
while len(data):
event, data = rq.EventField(None).parse_binary_value(data, record_dpy.display, None, None)
if event.type == X.ButtonRelease:
print "ButtonRelease", event
if(event.detail==1):
for btn in buttons:
if(event.root_x>=btn[0] and event.root_x<=btn[1]):
if(event.root_y>=btn[2] and event.root_y<=btn[3]):
os.system(btn[4])
# Check if the extension is present
if not record_dpy.has_extension("RECORD"):
print "RECORD extension not found"
sys.exit(1)
r = record_dpy.record_get_version(0, 0)
print "RECORD extension version %d.%d" % (r.major_version, r.minor_version)
ctx = record_dpy.record_create_context(
0,
[record.CurrentClients],
[{
'core_requests': (0, 0),
'core_replies': (0, 0),
'ext_requests': (0, 0, 0, 0),
'ext_replies': (0, 0, 0, 0),
'delivered_events': (0, 0),
'device_events': (X.KeyPress, X.MotionNotify),
'errors': (0, 0),
'client_started': False,
'client_died': False,
}])
record_dpy.record_enable_context(ctx, record_callback)
record_dpy.record_free_context(ctx)
问题是:我不知道是否(以及如何)可以让 RECORD 仅侦听根窗口事件,或者过滤接收到的事件。
示例: 单击根窗口:
Xlib.protocol.request.QueryExtension
Xlib.protocol.request.QueryExtension
RECORD extension version 1.13
ButtonRelease Xlib.protocol.event.ButtonRelease(event_y = 0, state = 256, type = 5, child = 0, detail = 1, window = <Xlib.display.Window 0x00000000>, same_screen = 0, time = 795133824, root_y = 76, root_x = 76, root = <Xlib.display.Window 0x00000000>, event_x = 0, sequence_number = 0)
Hep
单击 Firefox 的工具栏:
Xlib.protocol.request.QueryExtension
Xlib.protocol.request.QueryExtension
RECORD extension version 1.13
ButtonRelease Xlib.protocol.event.ButtonRelease(event_y = 0, state = 256, type = 5, child = 0, detail = 1, window = <Xlib.display.Window 0x00000000>, same_screen = 0, time = 795205475, root_y = 61, root_x = 92, root = <Xlib.display.Window 0x00000000>, event_x = 0, sequence_number = 0)
Hep
所以我必须通过以下方式过滤事件: 检查事件是否来自根窗口(事件都有 NULL 窗口,见上文...),或检查是否另一个窗口位于单击区域上方(所以我无法单击下面的根窗口)。
因为该事件不提供窗口信息,我想我会做第二个选项,但我不知道如何......
I'm trying to implement clickable areas on the root window, using python xlib's RECORD extension.
this is what i've got so far:
import sys
import os
from Xlib import X, XK, display
from Xlib.ext import record
from Xlib.protocol import rq
local_dpy = display.Display()
record_dpy = display.Display()
buttons={(0,200,0,200,"echo Hep")}
def record_callback(reply):
if reply.category != record.FromServer:
return
if reply.client_swapped:
print "* received swapped protocol data, cowardly ignored"
return
if not len(reply.data) or ord(reply.data[0]) < 2:
# not an event
return
data = reply.data
while len(data):
event, data = rq.EventField(None).parse_binary_value(data, record_dpy.display, None, None)
if event.type == X.ButtonRelease:
print "ButtonRelease", event
if(event.detail==1):
for btn in buttons:
if(event.root_x>=btn[0] and event.root_x<=btn[1]):
if(event.root_y>=btn[2] and event.root_y<=btn[3]):
os.system(btn[4])
# Check if the extension is present
if not record_dpy.has_extension("RECORD"):
print "RECORD extension not found"
sys.exit(1)
r = record_dpy.record_get_version(0, 0)
print "RECORD extension version %d.%d" % (r.major_version, r.minor_version)
ctx = record_dpy.record_create_context(
0,
[record.CurrentClients],
[{
'core_requests': (0, 0),
'core_replies': (0, 0),
'ext_requests': (0, 0, 0, 0),
'ext_replies': (0, 0, 0, 0),
'delivered_events': (0, 0),
'device_events': (X.KeyPress, X.MotionNotify),
'errors': (0, 0),
'client_started': False,
'client_died': False,
}])
record_dpy.record_enable_context(ctx, record_callback)
record_dpy.record_free_context(ctx)
the problem is: I don't know if (and how) it's possible to let RECORD listen for root window events only, or to filter the received events.
example: clicking the root window:
Xlib.protocol.request.QueryExtension
Xlib.protocol.request.QueryExtension
RECORD extension version 1.13
ButtonRelease Xlib.protocol.event.ButtonRelease(event_y = 0, state = 256, type = 5, child = 0, detail = 1, window = <Xlib.display.Window 0x00000000>, same_screen = 0, time = 795133824, root_y = 76, root_x = 76, root = <Xlib.display.Window 0x00000000>, event_x = 0, sequence_number = 0)
Hep
clicking firefox's toolbar:
Xlib.protocol.request.QueryExtension
Xlib.protocol.request.QueryExtension
RECORD extension version 1.13
ButtonRelease Xlib.protocol.event.ButtonRelease(event_y = 0, state = 256, type = 5, child = 0, detail = 1, window = <Xlib.display.Window 0x00000000>, same_screen = 0, time = 795205475, root_y = 61, root_x = 92, root = <Xlib.display.Window 0x00000000>, event_x = 0, sequence_number = 0)
Hep
so i somehow have to filter the events by: checking if the event came from the root window (the events all have NULL windows, see above...), or checking if another window is above the clicked area (so I can't have clicked the root window below).
because the event doesn't provide window information, I think Ill do the second option, but i don't know how to…
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我自己发现了这一点:
想法是检查指针下的窗口是否是根窗口的客户端之一。
found it out myself:
the idea is to check if the window under the pointer is one of the root window's clients.