Get proper event window from xcb event

Find the event window and try to get a Client or Unmanaged from it
to pass it through the filter.
This commit is contained in:
Martin Gräßlin 2013-07-26 16:19:05 +02:00
parent 36984d69be
commit 075b0602e9
2 changed files with 78 additions and 52 deletions

View file

@ -72,6 +72,73 @@ extern int currentRefreshRate();
// Workspace // Workspace
// **************************************** // ****************************************
static xcb_window_t findEventWindow(xcb_generic_event_t *event)
{
const uint8_t eventType = event->response_type & ~0x80;
switch(eventType) {
case XCB_KEY_PRESS:
case XCB_KEY_RELEASE:
return reinterpret_cast<xcb_key_press_event_t*>(event)->event;
case XCB_BUTTON_PRESS:
case XCB_BUTTON_RELEASE:
return reinterpret_cast<xcb_button_press_event_t*>(event)->event;
case XCB_MOTION_NOTIFY:
return reinterpret_cast<xcb_motion_notify_event_t*>(event)->event;
case XCB_ENTER_NOTIFY:
case XCB_LEAVE_NOTIFY:
return reinterpret_cast<xcb_enter_notify_event_t*>(event)->event;
case XCB_FOCUS_IN:
case XCB_FOCUS_OUT:
return reinterpret_cast<xcb_focus_in_event_t*>(event)->event;
case XCB_EXPOSE:
return reinterpret_cast<xcb_expose_event_t*>(event)->window;
case XCB_GRAPHICS_EXPOSURE:
return reinterpret_cast<xcb_graphics_exposure_event_t*>(event)->drawable;
case XCB_NO_EXPOSURE:
return reinterpret_cast<xcb_no_exposure_event_t*>(event)->drawable;
case XCB_VISIBILITY_NOTIFY:
return reinterpret_cast<xcb_visibility_notify_event_t*>(event)->window;
case XCB_CREATE_NOTIFY:
return reinterpret_cast<xcb_create_notify_event_t*>(event)->window;
case XCB_DESTROY_NOTIFY:
return reinterpret_cast<xcb_destroy_notify_event_t*>(event)->window;
case XCB_UNMAP_NOTIFY:
return reinterpret_cast<xcb_unmap_notify_event_t*>(event)->window;
case XCB_MAP_NOTIFY:
return reinterpret_cast<xcb_map_notify_event_t*>(event)->window;
case XCB_MAP_REQUEST:
return reinterpret_cast<xcb_map_request_event_t*>(event)->window;
case XCB_REPARENT_NOTIFY:
return reinterpret_cast<xcb_reparent_notify_event_t*>(event)->window;
case XCB_CONFIGURE_NOTIFY:
return reinterpret_cast<xcb_configure_notify_event_t*>(event)->window;
case XCB_CONFIGURE_REQUEST:
return reinterpret_cast<xcb_configure_request_event_t*>(event)->window;
case XCB_GRAVITY_NOTIFY:
return reinterpret_cast<xcb_gravity_notify_event_t*>(event)->window;
case XCB_RESIZE_REQUEST:
return reinterpret_cast<xcb_resize_request_event_t*>(event)->window;
case XCB_CIRCULATE_NOTIFY:
case XCB_CIRCULATE_REQUEST:
return reinterpret_cast<xcb_circulate_notify_event_t*>(event)->window;
case XCB_PROPERTY_NOTIFY:
return reinterpret_cast<xcb_property_notify_event_t*>(event)->window;
case XCB_COLORMAP_NOTIFY:
return reinterpret_cast<xcb_colormap_notify_event_t*>(event)->window;
case XCB_CLIENT_MESSAGE:
return reinterpret_cast<xcb_client_message_event_t*>(event)->window;
default:
// extension handling
if (eventType == Xcb::Extensions::self()->shapeNotifyEvent()) {
return reinterpret_cast<xcb_shape_notify_event_t*>(event)->affected_window;
}
if (eventType == Xcb::Extensions::self()->damageNotifyEvent()) {
return reinterpret_cast<xcb_damage_notify_event_t*>(event)->drawable;
}
return XCB_WINDOW_NONE;
}
}
/*! /*!
Handles workspace specific XCB event Handles workspace specific XCB event
*/ */
@ -169,37 +236,31 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
break; break;
}; };
#if KWIN_QT5_PORTING const xcb_window_t eventWindow = findEventWindow(e);
if (Client* c = findClient(WindowMatchPredicate(e->xany.window))) { if (Client* c = findClient(WindowMatchPredicate(eventWindow))) {
if (c->windowEvent(e)) if (c->windowEvent(e))
return true; return true;
} else if (Client* c = findClient(WrapperIdMatchPredicate(e->xany.window))) { } else if (Client* c = findClient(WrapperIdMatchPredicate(eventWindow))) {
if (c->windowEvent(e)) if (c->windowEvent(e))
return true; return true;
} else if (Client* c = findClient(FrameIdMatchPredicate(e->xany.window))) { } else if (Client* c = findClient(FrameIdMatchPredicate(eventWindow))) {
if (c->windowEvent(e)) if (c->windowEvent(e))
return true; return true;
} else if (Client *c = findClient(InputIdMatchPredicate(e->xany.window))) { } else if (Client *c = findClient(InputIdMatchPredicate(eventWindow))) {
if (c->windowEvent(e)) if (c->windowEvent(e))
return true; return true;
} else if (Unmanaged* c = findUnmanaged(WindowMatchPredicate(e->xany.window))) { } else if (Unmanaged* c = findUnmanaged(WindowMatchPredicate(eventWindow))) {
if (c->windowEvent(e)) if (c->windowEvent(e))
return true; return true;
} else { } else {
Window special = findSpecialEventWindow(e);
if (special != None)
if (Client* c = findClient(WindowMatchPredicate(special))) {
if (c->windowEvent(e))
return true;
}
// We want to pass root window property events to effects // We want to pass root window property events to effects
if (e->type == PropertyNotify && e->xany.window == rootWindow()) { if (eventType == XCB_PROPERTY_NOTIFY) {
XPropertyEvent* re = &e->xproperty; auto event = reinterpret_cast<xcb_property_notify_event_t*>(e);
emit propertyNotify(re->atom); if (event->window == rootWindow()) {
emit propertyNotify(event->atom);
}
} }
} }
#endif
if (movingClient) { if (movingClient) {
if (eventType == XCB_BUTTON_PRESS || eventType == XCB_BUTTON_RELEASE) { if (eventType == XCB_BUTTON_PRESS || eventType == XCB_BUTTON_RELEASE) {
if (movingClient->moveResizeGrabWindow() == reinterpret_cast<xcb_button_press_event_t*>(e)->event && movingClient->windowEvent(e)) { if (movingClient->moveResizeGrabWindow() == reinterpret_cast<xcb_button_press_event_t*>(e)->event && movingClient->windowEvent(e)) {
@ -409,39 +470,6 @@ bool Workspace::workspaceEvent(QEvent* e)
return false; return false;
} }
// Some events don't have the actual window which caused the event
// as e->xany.window (e.g. ConfigureRequest), but as some other
// field in the XEvent structure.
xcb_window_t Workspace::findSpecialEventWindow(XEvent *e)
{
switch(e->type) {
case CreateNotify:
return e->xcreatewindow.window;
case DestroyNotify:
return e->xdestroywindow.window;
case UnmapNotify:
return e->xunmap.window;
case MapNotify:
return e->xmap.window;
case MapRequest:
return e->xmaprequest.window;
case ReparentNotify:
return e->xreparent.window;
case ConfigureNotify:
return e->xconfigure.window;
case GravityNotify:
return e->xgravity.window;
case ConfigureRequest:
return e->xconfigurerequest.window;
case CirculateNotify:
return e->xcirculate.window;
case CirculateRequest:
return e->xcirculaterequest.window;
default:
return None;
};
}
// **************************************** // ****************************************
// Client // Client
// **************************************** // ****************************************

View file

@ -442,8 +442,6 @@ private:
Unmanaged* createUnmanaged(xcb_window_t w); Unmanaged* createUnmanaged(xcb_window_t w);
void addUnmanaged(Unmanaged* c); void addUnmanaged(Unmanaged* c);
xcb_window_t findSpecialEventWindow(XEvent* e);
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void closeActivePopup(); void closeActivePopup();