X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fhandlers.c;h=c63f236c1c8510571d82dd824c257f578ac6fa1f;hb=b0e871e0cfdc35f2147c4497136c5b74c9ebafe7;hp=f1c6128b750aa42cffc2bb91978c5cd17403b479;hpb=e913e519f2d36300b8099fa9507461770319a365;p=i3%2Fi3 diff --git a/src/handlers.c b/src/handlers.c index f1c6128b..c63f236c 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -21,10 +21,11 @@ int randr_base = -1; changing workspaces */ static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events; -void add_ignore_event(const int sequence) { +void add_ignore_event(const int sequence, const int response_type) { struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event)); event->sequence = sequence; + event->response_type = response_type; event->added = time(NULL); SLIST_INSERT_HEAD(&ignore_events, event, ignore_events); @@ -34,7 +35,7 @@ void add_ignore_event(const int sequence) { * Checks if the given sequence is ignored and returns true if so. * */ -static bool event_is_ignored(const int sequence) { +static bool event_is_ignored(const int sequence, const int response_type) { struct Ignore_Event *event; time_t now = time(NULL); for (event = SLIST_FIRST(&ignore_events); event != SLIST_END(&ignore_events);) { @@ -50,6 +51,10 @@ static bool event_is_ignored(const int sequence) { if (event->sequence != sequence) continue; + if (event->response_type != 0 && + event->response_type != response_type) + continue; + /* instead of removing a sequence number we better wait until it gets * garbage collected. it may generate multiple events (there are multiple * enter_notifies for one configure_request, for example). */ @@ -153,8 +158,10 @@ static int handle_enter_notify(xcb_enter_notify_event_t *event) { } /* Some events are not interesting, because they were not generated * actively by the user, but by reconfiguration of windows */ - if (event_is_ignored(event->sequence)) + if (event_is_ignored(event->sequence, XCB_ENTER_NOTIFY)) { + DLOG("Event ignored\n"); return 1; + } bool enter_child = false; /* Get container by frame or by child window */ @@ -177,19 +184,14 @@ static int handle_enter_notify(xcb_enter_notify_event_t *event) { /* see if the user entered the window on a certain window decoration */ int layout = (enter_child ? con->parent->layout : con->layout); - Con *child; - TAILQ_FOREACH(child, &(con->nodes_head), nodes) - if (rect_contains(child->deco_rect, event->event_x, event->event_y)) { - LOG("using child %p / %s instead!\n", child, child->name); - con = child; - break; - } - - /* for stacked/tabbed layout we do not want to change focus when the user - * enters the window at the decoration of any child window. */ - if (layout == L_STACKED || layout == L_TABBED) { - con = TAILQ_FIRST(&(con->parent->focus_head)); - LOG("using focused %p / %s instead\n", con, con->name); + if (layout == L_DEFAULT) { + Con *child; + TAILQ_FOREACH(child, &(con->nodes_head), nodes) + if (rect_contains(child->deco_rect, event->event_x, event->event_y)) { + LOG("using child %p / %s instead!\n", child, child->name); + con = child; + break; + } } #if 0 @@ -285,7 +287,7 @@ static int handle_map_request(xcb_map_request_event_t *event) { cookie = xcb_get_window_attributes_unchecked(conn, event->window); DLOG("window = 0x%08x, serial is %d.\n", event->window, event->sequence); - add_ignore_event(event->sequence); + add_ignore_event(event->sequence, 0); manage_window(event->window, cookie, false); x_push_changes(croot); @@ -438,12 +440,9 @@ static int handle_screen_change(xcb_generic_event_t *e) { * */ static int handle_unmap_notify_event(xcb_unmap_notify_event_t *event) { - - /* FIXME: we cannot ignore this sequence because more UnmapNotifys with the same sequence - * numbers but different window IDs may follow */ /* we need to ignore EnterNotify events which will be generated because a * different window is visible now */ - //add_ignore_event(event->sequence); + add_ignore_event(event->sequence, XCB_ENTER_NOTIFY); DLOG("UnmapNotify for 0x%08x (received from 0x%08x), serial %d\n", event->window, event->event, event->sequence); Con *con = con_by_window_id(event->window); @@ -809,7 +808,13 @@ static int handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_w //CLIENT_LOG(con); LOG("Urgency flag changed to %d\n", con->urgent); - workspace_update_urgent_flag(con_get_workspace(con)); + Con *ws; + /* Set the urgency flag on the workspace, if a workspace could be found + * (for dock clients, that is not the case). */ + if ((ws = con_get_workspace(con)) != NULL) + workspace_update_urgent_flag(ws); + + tree_render(); #if 0 /* If the workspace this client is on is not visible, we need to redraw @@ -896,6 +901,12 @@ static int handle_focus_in(xcb_focus_in_event_t *event) { return 1; DLOG("That is con %p / %s\n", con, con->name); + if (event->mode == XCB_NOTIFY_MODE_GRAB || + event->mode == XCB_NOTIFY_MODE_UNGRAB) { + DLOG("FocusIn event for grab/ungrab, ignoring\n"); + return 1; + } + if (event->detail == XCB_NOTIFY_DETAIL_POINTER) { DLOG("notify detail is pointer, ignoring this event\n"); return 1;