]> git.lizzy.rs Git - bspwm.git/blobdiff - src/events.c
The insertion point might be NULL
[bspwm.git] / src / events.c
index 684ef34ecdb42b7b0e19e4e7b0568147ab63abf8..3b82c96fff235b763c163b76d1a0aa5337705937 100644 (file)
 #include "tree.h"
 #include "window.h"
 #include "pointer.h"
+#include "rule.h"
 #include "events.h"
 
+uint8_t randr_base;
+
 void handle_event(xcb_generic_event_t *evt)
 {
        uint8_t resp_type = XCB_EVENT_RESPONSE_TYPE(evt);
@@ -71,6 +74,9 @@ void handle_event(xcb_generic_event_t *evt)
                case XCB_FOCUS_IN:
                        focus_in(evt);
                        break;
+               case XCB_MAPPING_NOTIFY:
+                       mapping_notify(evt);
+                       break;
                case 0:
                        process_error(evt);
                        break;
@@ -171,7 +177,7 @@ void configure_request(xcb_generic_event_t *evt)
 
                monitor_t *m = monitor_from_client(c);
                if (m != loc.monitor) {
-                       transfer_node(loc.monitor, loc.desktop, loc.node, m, m->desk, m->desk->focus);
+                       transfer_node(loc.monitor, loc.desktop, loc.node, m, m->desk, m->desk->focus, false);
                }
        } else {
                if (c->state == STATE_PSEUDO_TILED) {
@@ -240,8 +246,15 @@ void unmap_notify(xcb_generic_event_t *evt)
                 * related unmap notify event. This is a technique used by i3-wm to
                 * filter enter notify events. */
                motion_recorder.sequence = e->sequence;
+               return;
+       }
+
+       /* Filter out destroyed windows */
+       if (!window_exists(e->window)) {
+               return;
        }
 
+       set_window_state(e->window, XCB_ICCCM_WM_STATE_WITHDRAWN);
        unmanage_window(e->window);
 }
 
@@ -249,7 +262,7 @@ void property_notify(xcb_generic_event_t *evt)
 {
        xcb_property_notify_event_t *e = (xcb_property_notify_event_t *) evt;
 
-       if (e->atom == ewmh->_NET_WM_STRUT_PARTIAL && ewmh_handle_struts(e->window)) {
+       if (!ignore_ewmh_struts && e->atom == ewmh->_NET_WM_STRUT_PARTIAL && ewmh_handle_struts(e->window)) {
                for (monitor_t *m = mon_head; m != NULL; m = m->next) {
                        for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
                                arrange(m, d);
@@ -263,7 +276,13 @@ void property_notify(xcb_generic_event_t *evt)
 
        coordinates_t loc;
        if (!locate_window(e->window, &loc)) {
-                       return;
+               for (pending_rule_t *pr = pending_rule_head; pr != NULL; pr = pr->next) {
+                       if (pr->win == e->window) {
+                               postpone_event(pr, evt);
+                               break;
+                       }
+               }
+               return;
        }
 
        if (e->atom == XCB_ATOM_WM_HINTS) {
@@ -293,6 +312,12 @@ void client_message(xcb_generic_event_t *evt)
 
        coordinates_t loc;
        if (!locate_window(e->window, &loc)) {
+               for (pending_rule_t *pr = pending_rule_head; pr != NULL; pr = pr->next) {
+                       if (pr->win == e->window) {
+                               postpone_event(pr, evt);
+                               break;
+                       }
+               }
                return;
        }
 
@@ -308,7 +333,7 @@ void client_message(xcb_generic_event_t *evt)
        } else if (e->type == ewmh->_NET_WM_DESKTOP) {
                coordinates_t dloc;
                if (ewmh_locate_desktop(e->data.data32[0], &dloc)) {
-                       transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus);
+                       transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus, false);
                }
        } else if (e->type == ewmh->_NET_CLOSE_WINDOW) {
                close_node(loc.node);
@@ -438,14 +463,18 @@ void motion_notify(xcb_generic_event_t *evt)
 void handle_state(monitor_t *m, desktop_t *d, node_t *n, xcb_atom_t state, unsigned int action)
 {
        if (state == ewmh->_NET_WM_STATE_FULLSCREEN) {
-               if (action == XCB_EWMH_WM_STATE_ADD) {
+               if (action == XCB_EWMH_WM_STATE_ADD && (ignore_ewmh_fullscreen & STATE_TRANSITION_ENTER) == 0) {
                        set_state(m, d, n, STATE_FULLSCREEN);
-               } else if (action == XCB_EWMH_WM_STATE_REMOVE) {
+               } else if (action == XCB_EWMH_WM_STATE_REMOVE && (ignore_ewmh_fullscreen & STATE_TRANSITION_EXIT) == 0) {
                        if (n->client->state == STATE_FULLSCREEN) {
                                set_state(m, d, n, n->client->last_state);
                        }
                } else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
-                       set_state(m, d, n, IS_FULLSCREEN(n->client) ? n->client->last_state : STATE_FULLSCREEN);
+                       client_state_t next_state = IS_FULLSCREEN(n->client) ? n->client->last_state : STATE_FULLSCREEN;
+                       if ((next_state == STATE_FULLSCREEN && (ignore_ewmh_fullscreen & STATE_TRANSITION_ENTER) == 0) ||
+                           (next_state != STATE_FULLSCREEN && (ignore_ewmh_fullscreen & STATE_TRANSITION_EXIT) == 0)) {
+                               set_state(m, d, n, next_state);
+                       }
                }
                arrange(m, d);
        } else if (state == ewmh->_NET_WM_STATE_BELOW) {
@@ -512,8 +541,32 @@ void handle_state(monitor_t *m, desktop_t *d, node_t *n, xcb_atom_t state, unsig
 #undef HANDLE_WM_STATE
 }
 
+void mapping_notify(xcb_generic_event_t *evt)
+{
+       if (mapping_events_count == 0) {
+               return;
+       }
+
+       xcb_mapping_notify_event_t *e = (xcb_mapping_notify_event_t *) evt;
+
+       if (e->request == XCB_MAPPING_POINTER) {
+               return;
+       }
+
+       if (mapping_events_count > 0) {
+               mapping_events_count--;
+       }
+
+       ungrab_buttons();
+       grab_buttons();
+}
+
 void process_error(xcb_generic_event_t *evt)
 {
        xcb_request_error_t *e = (xcb_request_error_t *) evt;
+       /* Ignore unavoidable failed requests */
+       if (e->error_code == ERROR_CODE_BAD_WINDOW) {
+               return;
+       }
        warn("Failed request: %s, %s: 0x%08X.\n", xcb_event_get_request_label(e->major_opcode), xcb_event_get_error_label(e->error_code), e->bad_value);
 }