]> git.sur5r.net Git - i3/i3/blobdiff - src/handlers.c
Merge branch 'fix-active'
[i3/i3] / src / handlers.c
index fdc75abe604098816d16b8e36a77815d908e50f1..fce6627659487199dfe66f1286c4e3da406d6686 100644 (file)
@@ -13,6 +13,7 @@
 #include "all.h"
 
 #include <time.h>
+#include <float.h>
 #include <sys/time.h>
 #include <xcb/randr.h>
 #include <X11/XKBlib.h>
@@ -422,6 +423,19 @@ int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_n
 static void handle_screen_change(xcb_generic_event_t *e) {
     DLOG("RandR screen change\n");
 
+    /* The geometry of the root window is used for “fullscreen global” and
+     * changes when new outputs are added. */
+    xcb_get_geometry_cookie_t cookie = xcb_get_geometry(conn, root);
+    xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(conn, cookie, NULL);
+    if (reply == NULL) {
+        ELOG("Could not get geometry of the root window, exiting\n");
+        exit(1);
+    }
+    DLOG("root geometry reply: (%d, %d) %d x %d\n", reply->x, reply->y, reply->width, reply->height);
+
+    croot->rect.width = reply->width;
+    croot->rect.height = reply->height;
+
     randr_query_outputs();
 
     scratchpad_fix_resolution();
@@ -668,6 +682,11 @@ static void handle_client_message(xcb_client_message_event_t *event) {
             return;
         }
 
+        if (con_is_internal(ws)) {
+            DLOG("Workspace is internal, ignoring _NET_ACTIVE_WINDOW\n");
+            return;
+        }
+
         if (ws != con_get_workspace(focused))
             workspace_show(ws);
 
@@ -691,6 +710,36 @@ static void handle_client_message(xcb_client_message_event_t *event) {
         xcb_send_event(conn, false, window, XCB_EVENT_MASK_NO_EVENT, (char*)ev);
         xcb_flush(conn);
         free(reply);
+    } else if (event->type == A__NET_REQUEST_FRAME_EXTENTS) {
+        /*
+         * A client can request an estimate for the frame size which the window
+         * manager will put around it before actually mapping its window. Java
+         * does this (as of openjdk-7).
+         *
+         * Note that the calculation below is not entirely accurate — once you
+         * set a different border type, it’s off. We _could_ request all the
+         * window properties (which have to be set up at this point according
+         * to EWMH), but that seems rather elaborate. The standard explicitly
+         * says the application must cope with an estimate that is not entirely
+         * accurate.
+         */
+        DLOG("_NET_REQUEST_FRAME_EXTENTS for window 0x%08x\n", event->window);
+
+        /* The reply data: approximate frame size */
+        Rect r = {
+            config.default_border_width, /* left */
+            config.default_border_width, /* right */
+            config.font.height + 5, /* top */
+            config.default_border_width /* bottom */
+        };
+        xcb_change_property(
+                conn,
+                XCB_PROP_MODE_REPLACE,
+                event->window,
+                A__NET_FRAME_EXTENTS,
+                XCB_ATOM_CARDINAL, 32, 4,
+                &r);
+        xcb_flush(conn);
     } else {
         DLOG("unhandled clientmessage\n");
         return;
@@ -799,22 +848,18 @@ static bool handle_normal_hints(void *data, xcb_connection_t *conn, uint8_t stat
         goto render_and_return;
 
     /* Check if we need to set proportional_* variables using the correct ratio */
+    double aspect_ratio = 0.0;
     if ((width / height) < min_aspect) {
-        if (con->proportional_width != width ||
-            con->proportional_height != (width / min_aspect)) {
-            con->proportional_width = width;
-            con->proportional_height = width / min_aspect;
-            changed = true;
-        }
+        aspect_ratio = min_aspect;
     } else if ((width / height) > max_aspect) {
-        if (con->proportional_width != width ||
-            con->proportional_height != (width / max_aspect)) {
-            con->proportional_width = width;
-            con->proportional_height = width / max_aspect;
-            changed = true;
-        }
+        aspect_ratio = max_aspect;
     } else goto render_and_return;
 
+    if (fabs(con->aspect_ratio - aspect_ratio) > DBL_EPSILON) {
+        con->aspect_ratio = aspect_ratio;
+        changed = true;
+    }
+
 render_and_return:
     if (changed)
         tree_render();
@@ -834,24 +879,13 @@ static bool handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_
         return false;
     }
 
-    xcb_icccm_wm_hints_t hints;
-
+    bool urgency_hint;
     if (reply == NULL)
-        if (!(reply = xcb_get_property_reply(conn, xcb_icccm_get_wm_hints(conn, window), NULL)))
-            return false;
-
-    if (!xcb_icccm_get_wm_hints_from_reply(&hints, reply))
-        return false;
-
-    /* Update the flag on the client directly */
-    bool hint_urgent = (xcb_icccm_wm_hints_get_urgency(&hints) != 0);
-    con_set_urgency(con, hint_urgent);
-
+        reply = xcb_get_property_reply(conn, xcb_icccm_get_wm_hints(conn, window), NULL);
+    window_update_hints(con->window, reply, &urgency_hint);
+    con_set_urgency(con, urgency_hint);
     tree_render();
 
-    if (con->window)
-        window_update_hints(con->window, reply);
-    else free(reply);
     return true;
 }