Xdamage:获取有关 window 内容更改的事件
Xdamage: get event on window content changes
我是 xlib 的初学者,我想在 window 内容更改时捕获事件。例如,如果某些区域发生变化。我读到我需要为此使用 Xdamage,这是我的代码
Display* display = XOpenDisplay(NULL);
Window root = DefaultRootWindow(display);
XWindowAttributes attributes = {0};
XGetWindowAttributes(display, root, &attributes);
int width, height;
width = attributes.width;
height = attributes.height;
//XDAMAGE INIT
int damage_event, damage_error, test;
test = XDamageQueryExtension(display, &damage_event, &damage_error);
Damage damage = XDamageCreate(display, root, XDamageReportNonEmpty);
while (true){
XEvent event;
XNextEvent(display,&event);
//HERE I GET EVENT
XDamageSubtract(display,damage,None,None);
}
XCloseDisplay(display);
所以,我有一个工作示例,我可以在其中获取事件及其 type.The 类型,据我所知是 xlib 类型 - https://tronche.com/gui/x/xlib/events/types.html。但是我如何从事件中发现 window 已更改。
您实际收到的是正常事件循环中的 DamageNotify
个事件,如下所示:
typedef struct {
int type; /* event base */
unsigned long serial;
Bool send_event;
Display *display;
Drawable drawable;
Damage damage;
int level;
Bool more; /* more events will be delivered immediately */
Time timestamp;
XRectangle area;
XRectangle geometry;
} XDamageNotifyEvent;
根据 https://www.x.org/releases/current/doc/damageproto/damageproto.txt
的文档
area
成员将损坏的矩形区域报告为 XRectangle。
drawable
成员通常报告损坏的 window。
注意 XNextEvent
将始终 return 一个 XEvent
即由函数编辑的 static 类型 return。它还具有依赖于 ev->type
成员的 dynamic 类型。 - 检查其 type
字段以了解您是否可以将其转换为 XDamageEvent
:
XEvent ev;
/* We might need a pointer to an XDamageEvent... */
XDamageNotifyEvent *dev;
while (1) {
XNextEvent(display,&ev);
switch (ev.type){
...
case DamageNotify:
dev = (XDamageNotifyEvent*)&ev; /* if type matches, cast to XDamageNotify event */
printf ("Damage notification in window %d\n", dev->drawable);
printf ("Rectangle x=%d, y=%d, w=%d, h=%d\n",
dev->area.x, dev->area.y,
dev->area.width, dev->area.height);
break;
...
}
晚了,但对于寻找实际变化区域的任何人(ev->area 是 window 坐标和大小,至少对我而言):
auto ev = (XDamageNotifyEvent*)e;
auto region = XFixesCreateRegion(display, null, 0);
XDamageSubtract(display, ev->damage, None, region);
int count;
auto area = XFixesFetchRegion(display, region, &count);
if(area){
for(int i; i < count; i++){
auto rect = area[i];
// do something with rect
}
XFree(area);
}
XFixesDestroyRegion(display, region);
我是 xlib 的初学者,我想在 window 内容更改时捕获事件。例如,如果某些区域发生变化。我读到我需要为此使用 Xdamage,这是我的代码
Display* display = XOpenDisplay(NULL);
Window root = DefaultRootWindow(display);
XWindowAttributes attributes = {0};
XGetWindowAttributes(display, root, &attributes);
int width, height;
width = attributes.width;
height = attributes.height;
//XDAMAGE INIT
int damage_event, damage_error, test;
test = XDamageQueryExtension(display, &damage_event, &damage_error);
Damage damage = XDamageCreate(display, root, XDamageReportNonEmpty);
while (true){
XEvent event;
XNextEvent(display,&event);
//HERE I GET EVENT
XDamageSubtract(display,damage,None,None);
}
XCloseDisplay(display);
所以,我有一个工作示例,我可以在其中获取事件及其 type.The 类型,据我所知是 xlib 类型 - https://tronche.com/gui/x/xlib/events/types.html。但是我如何从事件中发现 window 已更改。
您实际收到的是正常事件循环中的 DamageNotify
个事件,如下所示:
typedef struct {
int type; /* event base */
unsigned long serial;
Bool send_event;
Display *display;
Drawable drawable;
Damage damage;
int level;
Bool more; /* more events will be delivered immediately */
Time timestamp;
XRectangle area;
XRectangle geometry;
} XDamageNotifyEvent;
根据 https://www.x.org/releases/current/doc/damageproto/damageproto.txt
的文档area
成员将损坏的矩形区域报告为 XRectangle。
drawable
成员通常报告损坏的 window。
注意 XNextEvent
将始终 return 一个 XEvent
即由函数编辑的 static 类型 return。它还具有依赖于 ev->type
成员的 dynamic 类型。 - 检查其 type
字段以了解您是否可以将其转换为 XDamageEvent
:
XEvent ev;
/* We might need a pointer to an XDamageEvent... */
XDamageNotifyEvent *dev;
while (1) {
XNextEvent(display,&ev);
switch (ev.type){
...
case DamageNotify:
dev = (XDamageNotifyEvent*)&ev; /* if type matches, cast to XDamageNotify event */
printf ("Damage notification in window %d\n", dev->drawable);
printf ("Rectangle x=%d, y=%d, w=%d, h=%d\n",
dev->area.x, dev->area.y,
dev->area.width, dev->area.height);
break;
...
}
晚了,但对于寻找实际变化区域的任何人(ev->area 是 window 坐标和大小,至少对我而言):
auto ev = (XDamageNotifyEvent*)e;
auto region = XFixesCreateRegion(display, null, 0);
XDamageSubtract(display, ev->damage, None, region);
int count;
auto area = XFixesFetchRegion(display, region, &count);
if(area){
for(int i; i < count; i++){
auto rect = area[i];
// do something with rect
}
XFree(area);
}
XFixesDestroyRegion(display, region);