]> git.sur5r.net Git - i3/i3/blobdiff - src/manage.c
Merge branch 'master' into next
[i3/i3] / src / manage.c
index 22c2814fa4fcdcfb10f697e388b82a9640988d4b..653de156c24d7b2703bc5d126a8d7c01c228187b 100644 (file)
@@ -2,13 +2,11 @@
  * vim:ts=4:sw=4:expandtab
  *
  * i3 - an improved dynamic tiling window manager
- * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
+ * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
  *
- * manage.c: Contains all functions for initially managing new windows
- *           (or existing ones on restart).
+ * manage.c: Initially managing new windows (or existing ones on restart).
  *
  */
-
 #include "all.h"
 
 /*
@@ -79,12 +77,10 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     xcb_get_geometry_reply_t *geom;
     xcb_get_window_attributes_reply_t *attr = NULL;
 
-    DLOG("---> looking at window 0x%08x\n", window);
-
     xcb_get_property_cookie_t wm_type_cookie, strut_cookie, state_cookie,
                               utf8_title_cookie, title_cookie,
                               class_cookie, leader_cookie, transient_cookie,
-                              role_cookie, startup_id_cookie;
+                              role_cookie, startup_id_cookie, wm_hints_cookie;
 
 
     geomc = xcb_get_geometry(conn, d);
@@ -102,13 +98,11 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     }
 
     if (needs_to_be_mapped && attr->map_state != XCB_MAP_STATE_VIEWABLE) {
-        DLOG("map_state unviewable\n");
         FREE_GEOMETRY();
         goto out;
     }
 
     /* Don’t manage clients with the override_redirect flag */
-    DLOG("override_redirect is %d\n", attr->override_redirect);
     if (attr->override_redirect) {
         FREE_GEOMETRY();
         goto out;
@@ -148,9 +142,10 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     class_cookie = GET_PROPERTY(XCB_ATOM_WM_CLASS, 128);
     role_cookie = GET_PROPERTY(A_WM_WINDOW_ROLE, 128);
     startup_id_cookie = GET_PROPERTY(A__NET_STARTUP_ID, 512);
+    wm_hints_cookie = xcb_icccm_get_wm_hints(conn, window);
     /* TODO: also get wm_normal_hints here. implement after we got rid of xcb-event */
 
-    DLOG("reparenting!\n");
+    DLOG("Managing window 0x%08x\n", window);
 
     i3Window *cwindow = scalloc(sizeof(i3Window));
     cwindow->id = window;
@@ -175,6 +170,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     window_update_transient_for(cwindow, xcb_get_property_reply(conn, transient_cookie, NULL));
     window_update_strut_partial(cwindow, xcb_get_property_reply(conn, strut_cookie, NULL));
     window_update_role(cwindow, xcb_get_property_reply(conn, role_cookie, NULL), true);
+    window_update_hints(cwindow, xcb_get_property_reply(conn, wm_hints_cookie, NULL));
 
     xcb_get_property_reply_t *startup_id_reply;
     startup_id_reply = xcb_get_property_reply(conn, startup_id_cookie, NULL);
@@ -220,7 +216,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     DLOG("Initial geometry: (%d, %d, %d, %d)\n", geom->x, geom->y, geom->width, geom->height);
 
     Con *nc = NULL;
-    Match *match;
+    Match *match = NULL;
     Assignment *assignment;
 
     /* TODO: two matches for one container */
@@ -271,7 +267,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     nc->border_width = geom->border_width;
 
     char *name;
-    asprintf(&name, "[i3 con] container around %p", cwindow);
+    sasprintf(&name, "[i3 con] container around %p", cwindow);
     x_set_name(nc, name);
     free(name);
 
@@ -283,10 +279,16 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     if (fs == NULL) {
         DLOG("Not in fullscreen mode, focusing\n");
         if (!cwindow->dock) {
-            /* Check that the workspace is visible. If the window was assigned
-             * to an invisible workspace, we should not steal focus. */
-            if (workspace_is_visible(ws)) {
-                con_focus(nc);
+            /* Check that the workspace is visible and on the same output as
+             * the current focused container. If the window was assigned to an
+             * invisible workspace, we should not steal focus. */
+            Con *current_output = con_get_output(focused);
+            Con *target_output = con_get_output(ws);
+
+            if (workspace_is_visible(ws) && current_output == target_output) {
+                if (!match || !match->restart_mode) {
+                    con_focus(nc);
+                } else DLOG("not focusing, matched with restart_mode == true\n");
             } else DLOG("workspace not visible, not focusing\n");
         } else DLOG("dock, not focusing\n");
     } else {