]> git.sur5r.net Git - i3/i3/blobdiff - src/handlers.c
handle destroynotify events
[i3/i3] / src / handlers.c
index 11cbc37c8e6aeb19f587057d1d64f83604996d0c..535d963eaad82ce6af1b1f8d472b6170eecad378 100644 (file)
@@ -19,7 +19,7 @@
    changing workspaces */
 static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events;
 
-static void add_ignore_event(const int sequence) {
+void add_ignore_event(const int sequence) {
     struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
 
     event->sequence = sequence;
@@ -48,8 +48,11 @@ static bool event_is_ignored(const int sequence) {
         if (event->sequence != sequence)
             continue;
 
-        SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
-        free(event);
+        /* 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). */
+        //SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
+        //free(event);
         return true;
     }
 
@@ -267,6 +270,7 @@ int handle_map_request(void *prophs, xcb_connection_t *conn, xcb_map_request_eve
     add_ignore_event(event->sequence);
 
     manage_window(event->window, cookie, false);
+    x_push_changes(croot);
     return 1;
 }
 #if 0
@@ -447,9 +451,11 @@ int handle_screen_change(void *prophs, xcb_connection_t *conn,
  */
 int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_notify_event_t *event) {
 
-    //add_ignore_event(event->sequence);
+    /* we need to ignore EnterNotify events which will be generated because a
+     * different window is visible now */
+    add_ignore_event(event->sequence);
 
-    DLOG("UnmapNotify for 0x%08x (received from 0x%08x)\n", event->window, event->event);
+    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);
     if (con == NULL) {
         LOG("Not a managed window, ignoring\n");
@@ -501,7 +507,6 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti
         return 1;
 }
 
-#if 0
 /*
  * A destroy notify event is sent when the window is not unmapped, but
  * immediately destroyed (for example when starting a window and immediately
@@ -512,16 +517,16 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti
  *
  */
 int handle_destroy_notify_event(void *data, xcb_connection_t *conn, xcb_destroy_notify_event_t *event) {
-        DLOG("destroy notify for 0x%08x, 0x%08x\n", event->event, event->window);
+    DLOG("destroy notify for 0x%08x, 0x%08x\n", event->event, event->window);
 
-        xcb_unmap_notify_event_t unmap;
-        unmap.sequence = event->sequence;
-        unmap.event = event->event;
-        unmap.window = event->window;
+    xcb_unmap_notify_event_t unmap;
+    unmap.sequence = event->sequence;
+    unmap.event = event->event;
+    unmap.window = event->window;
 
-        return handle_unmap_notify_event(NULL, conn, &unmap);
+    return handle_unmap_notify_event(NULL, conn, &unmap);
 }
-#endif
+
 /*
  * Called when a window changes its title
  *
@@ -637,36 +642,40 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *
 #endif
 }
 
-#if 0
 /*
  * Handle client messages (EWMH)
  *
  */
 int handle_client_message(void *data, xcb_connection_t *conn, xcb_client_message_event_t *event) {
-        if (event->type == atoms[_NET_WM_STATE]) {
-                if (event->format != 32 || event->data.data32[1] != atoms[_NET_WM_STATE_FULLSCREEN])
-                        return 0;
-
-                Client *client = table_get(&by_child, event->window);
-                if (client == NULL)
-                        return 0;
-
-                /* Check if the fullscreen state should be toggled */
-                if ((client->fullscreen &&
-                     (event->data.data32[0] == _NET_WM_STATE_REMOVE ||
-                      event->data.data32[0] == _NET_WM_STATE_TOGGLE)) ||
-                    (!client->fullscreen &&
-                     (event->data.data32[0] == _NET_WM_STATE_ADD ||
-                      event->data.data32[0] == _NET_WM_STATE_TOGGLE)))
-                        client_toggle_fullscreen(conn, client);
-        } else {
-                ELOG("unhandled clientmessage\n");
-                return 0;
-        }
+    LOG("ClientMessage for window 0x%08x\n", event->window);
+    if (event->type == atoms[_NET_WM_STATE]) {
+        if (event->format != 32 || event->data.data32[1] != atoms[_NET_WM_STATE_FULLSCREEN])
+            return 0;
+
+        Con *con = con_by_window_id(event->window);
+        if (con == NULL)
+            return 0;
+
+        /* Check if the fullscreen state should be toggled */
+        if ((con->fullscreen_mode != CF_NONE &&
+             (event->data.data32[0] == _NET_WM_STATE_REMOVE ||
+              event->data.data32[0] == _NET_WM_STATE_TOGGLE)) ||
+            (con->fullscreen_mode == CF_NONE &&
+             (event->data.data32[0] == _NET_WM_STATE_ADD ||
+              event->data.data32[0] == _NET_WM_STATE_TOGGLE)))
+                con_toggle_fullscreen(con);
+
+        tree_render();
+        x_push_changes(croot);
+    } else {
+        ELOG("unhandled clientmessage\n");
+        return 0;
+    }
 
-        return 1;
+    return 1;
 }
 
+#if 0
 int handle_window_type(void *data, xcb_connection_t *conn, uint8_t state, xcb_window_t window,
                         xcb_atom_t atom, xcb_get_property_reply_t *property) {
         /* TODO: Implement this one. To do this, implement a little test program which sleep(1)s