我在XPeekIfEvent
执行libX11
时遇到问题,
它第二次被调用我得到了一个分段错误。
当我将send_event
添加到结构中时会发生这种情况。
如果您在代码中看到@NOTE
,则会向我发送一条说明。
相关文件:
来自Xlib.h
和X.h
的相关C / C ++定义:
// X.h
typedef unsigned long XID;
typedef XID Window;
typedef CARD32 XID;
typedef CARD32 Time;
typedef XID Window;
// Xlib.h
#define Bool int
typedef struct _XDisplay Display;
struct _XDisplay; /* Forward declare before use for C++ */
typedef struct {
int type; /* of event */
unsigned long serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display; /* Display the event was read from */
Window window; /* "event" window reported relative to */
Window root; /* root window that the event occurred on */
Window subwindow; /* child window */
Time time; /* milliseconds */
int x, y; /* pointer x, y coordinates in event window */
int x_root, y_root; /* coordinates relative to root */
unsigned int state; /* key or button mask */
char is_hint; /* detail */
Bool same_screen; /* same screen flag */
} XMotionEvent;
typedef XMotionEvent XPointerMovedEvent;
typedef struct {
int type;
unsigned long serial; /* # of last request processed by server */
Bool send_event; /* true if this came from a SendEvent request */
Display *display;/* Display the event was read from */
Window window; /* window on which event was requested in event mask */
} XAnyEvent;
/*
* this union is defined so Xlib can always use the same sized
* event structure internally, to avoid memory fragmentation.
*/
typedef union _XEvent {
int type; /* must not be changed; first element */
XAnyEvent xany;
XKeyEvent xkey;
XButtonEvent xbutton;
XMotionEvent xmotion;
XCrossingEvent xcrossing;
XFocusChangeEvent xfocus;
XExposeEvent xexpose;
XGraphicsExposeEvent xgraphicsexpose;
XNoExposeEvent xnoexpose;
XVisibilityEvent xvisibility;
XCreateWindowEvent xcreatewindow;
XDestroyWindowEvent xdestroywindow;
XUnmapEvent xunmap;
XMapEvent xmap;
XMapRequestEvent xmaprequest;
XReparentEvent xreparent;
XConfigureEvent xconfigure;
XGravityEvent xgravity;
XResizeRequestEvent xresizerequest;
XConfigureRequestEvent xconfigurerequest;
XCirculateEvent xcirculate;
XCirculateRequestEvent xcirculaterequest;
XPropertyEvent xproperty;
XSelectionClearEvent xselectionclear;
XSelectionRequestEvent xselectionrequest;
XSelectionEvent xselection;
XColormapEvent xcolormap;
XClientMessageEvent xclient;
XMappingEvent xmapping;
XErrorEvent xerror;
XKeymapEvent xkeymap;
XGenericEvent xgeneric;
XGenericEventCookie xcookie;
long pad[24];
} XEvent;
我的代码如下(删除了一些不相关的部分......):
# License: GPL2+
# Typedefs:
class Display( Structure ):
_fields_ = []
Bool = c_int
Time = c_ulong
Atom = c_ulong
#Display = c_int
DisplayPtr = POINTER( Display )
Window = c_ulong
WindowPtr = POINTER( Window )
XPointer = c_char_p
# Typedefs: Structs & Unions & FunPtr:s:
class XAnyEvent( Structure ):
_fields_ = [
('type', c_int),
('serial', c_ulong),
('send_event', Bool),
('display', DisplayPtr ),
('window', Window)
]
class XMotionEvent( Structure ):
_fields_ = [
('type', c_int),
('serial', c_ulong),
('send_event', Bool),
('display', DisplayPtr ),
('window', Window),
('root', Window),
('subwindow', Window),
('time', Time),
('x', c_int), ('y', c_int),
('x_root', c_int), ('y_root', c_int),
('state', c_uint),
('is_hint', c_char),
('same_screen', Bool)
]
class XEvent( Union ):
_fields_ = [
('type', c_int),
('xany', XAnyEvent),
('xmotion', XMotionEvent)
]
EventPredicate = CFUNCTYPE( Bool, DisplayPtr, POINTER( XEvent ), XPointer )
# Constants:
MotionNotify = 6
PointerMotionMask = (1 << 6)
# @NOTE: irrelevant parts removed.
# @NOTE: Assume sublimes is a list of X11 Window:s but wrapped.
for w in sublimes: w.select_input( PointerMotionMask )
# NOTE: All of the below really happens in another thread:
def motion_predicate( d, e, a ):
return e.contents.type == MotionNotify
pred = EventPredicate( motion_predicate )
# Event pump:
atexit.register( self.stop )
event = XEvent()
while self.alive:
print( "a" )
print( "#6")
# NOTE: Here we fail!
x.XPeekIfEvent( disp, byref( event ), pred, None )
print( event )
print( "type", event.type )
print( "b" )
如果删除type
和XAnyEvent
中XMotionEvent
以外的所有字段
它可以工作,否则它会因分段错误而失败:
window 81788931 pid 2990 title ~/programming/sublime-autohide-sidebar/x.py (sublime-autohide-sidebar) - Sublime Text
window 82632928 pid 2990 title untitled - Sublime Text
#1
#1
<__main__.XEvent object at 0x7f9a873b4bf8>
#2 type 6
#3
#1
Segmentation fault (core dumped)
或者:
window 81788931 pid 2990 title ~/programming/sublime-autohide-sidebar/x.py (sublime-autohide-sidebar) - Sublime Text
window 82632928 pid 2990 title untitled - Sublime Text
#1
*** Error in `python3': malloc(): memory corruption (fast): 0x00007fb904001060 ***
Aborted (core dumped)
当我实际在其中一个窗口内移动鼠标时会发生这种情况。
我错过了什么?
答案 0 :(得分:0)
在这篇SO帖子中回答: https://jsfiddle.net/tw79mvau/1/
......我将解决方案改编为:
class XMotionEvent( Structure ):
_fields_ = [
('type', c_int),
('serial', c_ulong),
('send_event', Bool),
('display', DisplayPtr ),
('window', Window),
('root', Window),
('subwindow', Window),
('time', Time),
('x', c_int), ('y', c_int),
('x_root', c_int), ('y_root', c_int),
('state', c_uint),
('is_hint', c_char),
('same_screen', Bool)
]
class XEvent( Union ):
_fields_ = [
('type', c_int),
('xmotion', XMotionEvent),
('pad', c_long * 24),
]