#include <libsn/sn-monitor.h>
int randr_base = -1;
+int xkb_base = -1;
+int xkb_current_group;
/* After mapping/unmapping windows, a notify event is generated. However, we don’t want it,
since it’d trigger an infinite loop of switching between the different windows when
add_ignore_event(event->sequence, -1);
manage_window(event->window, cookie, false);
- x_push_changes(croot);
return;
}
tree_close(con, DONT_KILL_WINDOW, false, false);
tree_render();
- x_push_changes(croot);
ignore_end:
/* If the client (as opposed to i3) destroyed or unmapped a window, an
XCB_ATOM_CARDINAL, 32, 4,
&r);
xcb_flush(conn);
+ } else if (event->type == A_WM_CHANGE_STATE) {
+ /* http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4 */
+ Con *con = con_by_window_id(event->window);
+
+ if (con && event->data.data32[0] == 3) {
+ /* this request is so we can play some animiation showing the
+ * window physically moving to the tray before we close it (I
+ * think) */
+ DLOG("Client has requested iconic state. Closing this con. (con = %p)\n", con);
+ tree_close(con, DONT_KILL_WINDOW, false, false);
+ tree_render();
+ } else {
+ DLOG("Not handling WM_CHANGE_STATE request. (window = %d, state = %d)\n", event->window, event->data.data32[0]);
+ }
+
} else {
DLOG("unhandled clientmessage\n");
return;
*
*/
void handle_event(int type, xcb_generic_event_t *event) {
+ DLOG("event type %d, xkb_base %d\n", type, xkb_base);
if (randr_base > -1 &&
type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
handle_screen_change(event);
return;
}
+ if (xkb_base > -1 && type == xkb_base) {
+ DLOG("xkb event, need to handle it.\n");
+
+ xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
+ if (state->xkbType == XCB_XKB_MAP_NOTIFY) {
+ if (event_is_ignored(event->sequence, type)) {
+ DLOG("Ignoring map notify event for sequence %d.\n", state->sequence);
+ } else {
+ DLOG("xkb map notify, sequence %d, time %d\n", state->sequence, state->time);
+ add_ignore_event(event->sequence, type);
+ ungrab_all_keys(conn);
+ translate_keysyms();
+ grab_all_keys(conn, false);
+ }
+ } else if (state->xkbType == XCB_XKB_STATE_NOTIFY) {
+ DLOG("xkb state group = %d\n", state->group);
+
+ /* See The XKB Extension: Library Specification, section 14.1 */
+ /* We check if the current group (each group contains
+ * two levels) has been changed. Mode_switch activates
+ * group XkbGroup2Index */
+ if (xkb_current_group == state->group)
+ return;
+ xkb_current_group = state->group;
+ if (state->group == XCB_XKB_GROUP_1) {
+ DLOG("Mode_switch disabled\n");
+ ungrab_all_keys(conn);
+ grab_all_keys(conn, false);
+ } else {
+ DLOG("Mode_switch enabled\n");
+ grab_all_keys(conn, false);
+ }
+ }
+
+ return;
+ }
+
switch (type) {
case XCB_KEY_PRESS:
case XCB_KEY_RELEASE: