Handle FocusIn events generated by clients and update decoration accordingly (Thanks mseed)
This commit is contained in:
parent
144deaaaf6
commit
c130cefa93
|
@ -215,4 +215,5 @@ int handle_clientleader_change(void *data, xcb_connection_t *conn,
|
||||||
uint8_t state, xcb_window_t window,
|
uint8_t state, xcb_window_t window,
|
||||||
xcb_atom_t name, xcb_get_property_reply_t *prop);
|
xcb_atom_t name, xcb_get_property_reply_t *prop);
|
||||||
|
|
||||||
|
int handle_focus_in(void *data, xcb_connection_t *conn, xcb_focus_in_event_t *event);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#ifndef _X_H
|
#ifndef _X_H
|
||||||
#define _X_H
|
#define _X_H
|
||||||
|
|
||||||
|
/** Stores the X11 window ID of the currently focused window */
|
||||||
|
extern xcb_window_t focused_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the X11 part for the given container. Called exactly once for
|
* Initializes the X11 part for the given container. Called exactly once for
|
||||||
* every container from con_new().
|
* every container from con_new().
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* i3 - an improved dynamic tiling window manager
|
* i3 - an improved dynamic tiling window manager
|
||||||
*
|
*
|
||||||
* (c) 2009 Michael Stapelberg and contributors
|
* © 2009-2011 Michael Stapelberg and contributors
|
||||||
*
|
*
|
||||||
* See file LICENSE for license information.
|
* See file LICENSE for license information.
|
||||||
*
|
*
|
||||||
|
@ -32,7 +32,8 @@
|
||||||
while rendering the layout) */
|
while rendering the layout) */
|
||||||
/** The XCB_CW_EVENT_MASK for the child (= real window) */
|
/** The XCB_CW_EVENT_MASK for the child (= real window) */
|
||||||
#define CHILD_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE | \
|
#define CHILD_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE | \
|
||||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY)
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY | \
|
||||||
|
XCB_EVENT_MASK_FOCUS_CHANGE)
|
||||||
|
|
||||||
/** The XCB_CW_EVENT_MASK for its frame */
|
/** The XCB_CW_EVENT_MASK for its frame */
|
||||||
#define FRAME_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | /* …mouse is pressed/released */ \
|
#define FRAME_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | /* …mouse is pressed/released */ \
|
||||||
|
|
|
@ -129,6 +129,10 @@ void handle_event(int type, xcb_generic_event_t *event) {
|
||||||
handle_mapping_notify(NULL, conn, (xcb_mapping_notify_event_t*)event);
|
handle_mapping_notify(NULL, conn, (xcb_mapping_notify_event_t*)event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case XCB_FOCUS_IN:
|
||||||
|
handle_focus_in(NULL, conn, (xcb_focus_in_event_t*)event);
|
||||||
|
break;
|
||||||
|
|
||||||
case XCB_PROPERTY_NOTIFY:
|
case XCB_PROPERTY_NOTIFY:
|
||||||
DLOG("Property notify\n");
|
DLOG("Property notify\n");
|
||||||
xcb_property_notify_event_t *e = (xcb_property_notify_event_t*)event;
|
xcb_property_notify_event_t *e = (xcb_property_notify_event_t*)event;
|
||||||
|
@ -1023,3 +1027,34 @@ int handle_clientleader_change(void *data, xcb_connection_t *conn, uint8_t state
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles FocusIn events which are generated by clients (i3’s focus changes
|
||||||
|
* don’t generate FocusIn events due to a different EventMask) and updates the
|
||||||
|
* decorations accordingly.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int handle_focus_in(void *data, xcb_connection_t *conn, xcb_focus_in_event_t *event) {
|
||||||
|
DLOG("focus change in, for window 0x%08x\n", event->event);
|
||||||
|
Con *con;
|
||||||
|
if ((con = con_by_window_id(event->event)) == NULL || con->window == NULL)
|
||||||
|
return 1;
|
||||||
|
DLOG("That is con %p / %s\n", con, con->name);
|
||||||
|
|
||||||
|
if (event->detail == XCB_NOTIFY_DETAIL_POINTER) {
|
||||||
|
DLOG("notify detail is pointer, ignoring this event\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (focused_id == event->event) {
|
||||||
|
DLOG("focus matches the currently focused window, not doing anything\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLOG("focus is different, updating decorations\n");
|
||||||
|
con_focus(con);
|
||||||
|
/* We update focused_id because we don’t need to set focus again */
|
||||||
|
focused_id = event->event;
|
||||||
|
x_push_changes(croot);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
15
src/x.c
15
src/x.c
|
@ -5,7 +5,7 @@
|
||||||
#include "all.h"
|
#include "all.h"
|
||||||
|
|
||||||
/* Stores the X11 window ID of the currently focused window */
|
/* Stores the X11 window ID of the currently focused window */
|
||||||
static xcb_window_t focused_id = XCB_NONE;
|
xcb_window_t focused_id = XCB_NONE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Describes the X11 state we may modify (map state, position, window stack).
|
* Describes the X11 state we may modify (map state, position, window stack).
|
||||||
|
@ -693,7 +693,18 @@ void x_push_changes(Con *con) {
|
||||||
focused_id = XCB_NONE;
|
focused_id = XCB_NONE;
|
||||||
} else {
|
} else {
|
||||||
DLOG("Updating focus (focused: %p / %s)\n", focused, focused->name);
|
DLOG("Updating focus (focused: %p / %s)\n", focused, focused->name);
|
||||||
|
/* We remove XCB_EVENT_MASK_FOCUS_CHANGE from the event mask to get
|
||||||
|
* no focus change events for our own focus changes. We only want
|
||||||
|
* these generated by the clients. */
|
||||||
|
if (focused->window != NULL) {
|
||||||
|
values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
|
||||||
|
xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
|
||||||
|
}
|
||||||
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
|
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
|
||||||
|
if (focused->window != NULL) {
|
||||||
|
values[0] = CHILD_EVENT_MASK;
|
||||||
|
xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
|
||||||
|
}
|
||||||
|
|
||||||
if (focused->window != NULL &&
|
if (focused->window != NULL &&
|
||||||
focused->window->needs_take_focus) {
|
focused->window->needs_take_focus) {
|
||||||
|
@ -724,6 +735,8 @@ void x_push_changes(Con *con) {
|
||||||
CIRCLEQ_FOREACH(state, &old_state_head, old_state) {
|
CIRCLEQ_FOREACH(state, &old_state_head, old_state) {
|
||||||
DLOG("old stack: 0x%08x\n", state->id);
|
DLOG("old stack: 0x%08x\n", state->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xcb_flush(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue