]> git.sur5r.net Git - i3/i3/blobdiff - src/main.c
Merge branch 'master' into next
[i3/i3] / src / main.c
index 7738dacc12e1e6725e975cce0446dd97fa5f6fde..76ea838d71ce9143f4cbfe552fefdff0901d8714 100644 (file)
@@ -53,7 +53,13 @@ xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME;
 
 xcb_screen_t *root_screen;
 xcb_window_t root;
+
+/* Color depth, visual id and colormap to use when creating windows and
+ * pixmaps. Will use 32 bit depth and an appropriate visual, if available,
+ * otherwise the root window’s default (usually 24 bit TrueColor). */
 uint8_t root_depth;
+xcb_visualid_t visual_id;
+xcb_colormap_t colormap;
 
 struct ev_loop *main_loop;
 
@@ -244,6 +250,7 @@ int main(int argc, char *argv[]) {
     bool delete_layout_path = false;
     bool force_xinerama = false;
     bool disable_signalhandler = false;
+    bool enable_32bit_visual = false;
     static struct option long_options[] = {
         {"no-autostart", no_argument, 0, 'a'},
         {"config", required_argument, 0, 'c'},
@@ -258,9 +265,12 @@ int main(int argc, char *argv[]) {
         {"shmlog_size", required_argument, 0, 0},
         {"get-socketpath", no_argument, 0, 0},
         {"get_socketpath", no_argument, 0, 0},
+        {"enable-32bit-visual", no_argument, 0, 0},
+        {"enable_32bit_visual", no_argument, 0, 0},
         {0, 0, 0, 0}
     };
     int option_index = 0, opt;
+    xcb_void_cookie_t colormap_cookie;
 
     setlocale(LC_ALL, "");
 
@@ -358,6 +368,11 @@ int main(int argc, char *argv[]) {
                     layout_path = sstrdup(optarg);
                     delete_layout_path = true;
                     break;
+                } else if (strcmp(long_options[option_index].name, "enable_32bit_visual") == 0 ||
+                           strcmp(long_options[option_index].name, "enable-32bit-visual") == 0) {
+                    LOG("Enabling 32 bit visual (if available)\n");
+                    enable_32bit_visual = true;
+                    break;
                 }
                 /* fall-through */
             default:
@@ -384,6 +399,10 @@ int main(int argc, char *argv[]) {
                                 "\tto 0 disables SHM logging entirely.\n"
                                 "\tThe default is %d bytes.\n", shmlog_size);
                 fprintf(stderr, "\n");
+                fprintf(stderr, "\t--enable-32bit-visual\n"
+                                "\tMakes i3 use a 32 bit visual, if available. Necessary for\n"
+                                "\tpseudo-transparency with xcompmgr.\n");
+                fprintf(stderr, "\n");
                 fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
                                 "to send to a currently running i3 (like i3-msg). This allows you to\n"
                                 "use nice and logical commands, such as:\n"
@@ -494,7 +513,38 @@ int main(int argc, char *argv[]) {
 
     root_screen = xcb_aux_get_screen(conn, conn_screen);
     root = root_screen->root;
+
+    /* By default, we use the same depth and visual as the root window, which
+     * usually is TrueColor (24 bit depth) and the corresponding visual.
+     * However, we also check if a 32 bit depth and visual are available (for
+     * transparency) and use it if so. */
     root_depth = root_screen->root_depth;
+    visual_id = root_screen->root_visual;
+    colormap = root_screen->default_colormap;
+
+    if (enable_32bit_visual) {
+        xcb_depth_iterator_t depth_iter;
+        xcb_visualtype_iterator_t visual_iter;
+        for (depth_iter = xcb_screen_allowed_depths_iterator(root_screen);
+             depth_iter.rem;
+             xcb_depth_next(&depth_iter)) {
+            if (depth_iter.data->depth != 32)
+                continue;
+            visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
+            if (!visual_iter.rem)
+                continue;
+
+            visual_id = visual_iter.data->visual_id;
+            root_depth = depth_iter.data->depth;
+            colormap = xcb_generate_id(conn);
+            colormap_cookie = xcb_create_colormap_checked(conn, XCB_COLORMAP_ALLOC_NONE, colormap, root, visual_id);
+            DLOG("Found a visual with 32 bit depth.\n");
+            break;
+        }
+    }
+
+    DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id);
+
     xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root);
     xcb_query_pointer_cookie_t pointercookie = xcb_query_pointer(conn, root);
 
@@ -524,6 +574,20 @@ int main(int argc, char *argv[]) {
     cookie = xcb_change_window_attributes_checked(conn, root, mask, values);
     check_error(conn, cookie, "Another window manager seems to be running");
 
+    /* By now we already checked for replies once, so let’s see if colormap
+     * creation worked (if requested). */
+    if (colormap != root_screen->default_colormap) {
+        xcb_generic_error_t *error = xcb_request_check(conn, colormap_cookie);
+        if (error != NULL) {
+            ELOG("Could not create ColorMap for 32 bit visual, falling back to X11 default.\n");
+            root_depth = root_screen->root_depth;
+            visual_id = root_screen->root_visual;
+            colormap = root_screen->default_colormap;
+            DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id);
+            free(error);
+        }
+    }
+
     xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(conn, gcookie, NULL);
     if (greply == NULL) {
         ELOG("Could not get geometry of the root window, exiting\n");