]> git.sur5r.net Git - i3/i3/blobdiff - i3bar/src/xcb.c
make i3bar use libi3’s root_atom_contents()
[i3/i3] / i3bar / src / xcb.c
index 15c68a0876dde8358ffa73f0a7b4461848b068ce..0c8de65ec5baeb5a8025deaee577f951ca3118b5 100644 (file)
@@ -59,6 +59,9 @@ xcb_connection_t *conn;
 /* The font we'll use */
 static i3Font font;
 
+/* Overall height of the bar (based on font size) */
+int bar_height;
+
 /* These are only relevant for XKB, which we only need for grabbing modifiers */
 Display          *xkb_dpy;
 int              xkb_event_base;
@@ -240,9 +243,9 @@ void unhide_bars(void) {
         values[0] = walk->rect.x;
         if (config.position == POS_TOP)
             values[1] = walk->rect.y;
-        else values[1] = walk->rect.y + walk->rect.h - font.height - 6;
+        else values[1] = walk->rect.y + walk->rect.h - bar_height;
         values[2] = walk->rect.w;
-        values[3] = font.height + 6;
+        values[3] = bar_height;
         values[4] = XCB_STACK_MODE_ABOVE;
         DLOG("Reconfiguring Window for output %s to %d,%d\n", walk->name, values[0], values[1]);
         cookie = xcb_configure_window_checked(xcb_connection,
@@ -957,26 +960,7 @@ char *init_xcb_early() {
     /* Now we get the atoms and save them in a nice data structure */
     get_atoms();
 
-    xcb_get_property_cookie_t path_cookie;
-    path_cookie = xcb_get_property_unchecked(xcb_connection,
-                                   0,
-                                   xcb_root,
-                                   atoms[I3_SOCKET_PATH],
-                                   XCB_GET_PROPERTY_TYPE_ANY,
-                                   0, PATH_MAX);
-
-    /* We check, if i3 set its socket-path */
-    xcb_get_property_reply_t *path_reply = xcb_get_property_reply(xcb_connection,
-                                                                  path_cookie,
-                                                                  NULL);
-    char *path = NULL;
-    if (path_reply) {
-        int len = xcb_get_property_value_length(path_reply);
-        if (len != 0) {
-            path = strndup(xcb_get_property_value(path_reply), len);
-        }
-    }
-
+    char *path = root_atom_contents("I3_SOCKET_PATH", xcb_connection, screen);
 
     if (xcb_request_failed(sl_pm_cookie, "Could not allocate statusline-buffer") ||
         xcb_request_failed(clear_ctx_cookie, "Could not allocate statusline-buffer-clearcontext") ||
@@ -1061,6 +1045,7 @@ void init_xcb_late(char *fontname) {
     font = load_font(fontname, true);
     set_font(&font);
     DLOG("Calculated Font-height: %d\n", font.height);
+    bar_height = font.height + 6;
 
     xcb_flush(xcb_connection);
 
@@ -1334,7 +1319,7 @@ void realloc_sl_buffer(void) {
                                                                statusline_pm,
                                                                xcb_root,
                                                                MAX(root_screen->width_in_pixels, statusline_width),
-                                                               root_screen->height_in_pixels);
+                                                               bar_height);
 
     uint32_t mask = XCB_GC_FOREGROUND;
     uint32_t vals[2] = { colors.bar_bg, colors.bar_bg };
@@ -1407,8 +1392,8 @@ void reconfig_windows(bool redraw_bars) {
                                                                      root_screen->root_depth,
                                                                      walk->bar,
                                                                      xcb_root,
-                                                                     walk->rect.x, walk->rect.y + walk->rect.h - font.height - 6,
-                                                                     walk->rect.w, font.height + 6,
+                                                                     walk->rect.x, walk->rect.y + walk->rect.h - bar_height,
+                                                                     walk->rect.w, bar_height,
                                                                      0,
                                                                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
                                                                      root_screen->root_visual,
@@ -1421,7 +1406,7 @@ void reconfig_windows(bool redraw_bars) {
                                                                     walk->buffer,
                                                                     walk->bar,
                                                                     walk->rect.w,
-                                                                    walk->rect.h);
+                                                                    bar_height);
 
             /* Set the WM_CLASS and WM_NAME (we don't need UTF-8) atoms */
             xcb_void_cookie_t class_cookie;
@@ -1482,12 +1467,12 @@ void reconfig_windows(bool redraw_bars) {
                 case POS_NONE:
                     break;
                 case POS_TOP:
-                    strut_partial.top = font.height + 6;
+                    strut_partial.top = bar_height;
                     strut_partial.top_start_x = walk->rect.x;
                     strut_partial.top_end_x = walk->rect.x + walk->rect.w;
                     break;
                 case POS_BOT:
-                    strut_partial.bottom = font.height + 6;
+                    strut_partial.bottom = bar_height;
                     strut_partial.bottom_start_x = walk->rect.x;
                     strut_partial.bottom_end_x = walk->rect.x + walk->rect.w;
                     break;
@@ -1527,10 +1512,20 @@ void reconfig_windows(bool redraw_bars) {
                 exit(EXIT_FAILURE);
             }
 
-            if (!tray_configured &&
-                (!config.tray_output ||
-                 strcasecmp("none", config.tray_output) != 0)) {
-                init_tray();
+            const char *tray_output = (config.tray_output ? config.tray_output : SLIST_FIRST(outputs)->name);
+            if (!tray_configured && strcasecmp(tray_output, "none") != 0) {
+                /* Configuration sanity check: ensure this i3bar instance handles the output on
+                 * which the tray should appear (e.g. don’t initialize a tray if tray_output ==
+                 * VGA-1 but output == [HDMI-1]).
+                 */
+                i3_output *output;
+                SLIST_FOREACH(output, outputs, slist) {
+                    if (strcasecmp(output->name, tray_output) == 0 ||
+                            (strcasecmp(tray_output, "primary") == 0 && output->primary)) {
+                        init_tray();
+                        break;
+                    }
+                }
                 tray_configured = true;
             }
         } else {
@@ -1541,9 +1536,9 @@ void reconfig_windows(bool redraw_bars) {
                    XCB_CONFIG_WINDOW_HEIGHT |
                    XCB_CONFIG_WINDOW_STACK_MODE;
             values[0] = walk->rect.x;
-            values[1] = walk->rect.y + walk->rect.h - font.height - 6;
+            values[1] = walk->rect.y + walk->rect.h - bar_height;
             values[2] = walk->rect.w;
-            values[3] = font.height + 6;
+            values[3] = bar_height;
             values[4] = XCB_STACK_MODE_ABOVE;
 
             DLOG("Destroying buffer for output %s\n", walk->name);
@@ -1569,7 +1564,7 @@ void reconfig_windows(bool redraw_bars) {
                                                                     walk->buffer,
                                                                     walk->bar,
                                                                     walk->rect.w,
-                                                                    walk->rect.h);
+                                                                    bar_height);
 
             xcb_void_cookie_t map_cookie, umap_cookie;
             if (redraw_bars) {
@@ -1612,9 +1607,6 @@ void draw_bars(bool unhide) {
 
     refresh_statusline();
 
-    static char *last_urgent_ws = NULL;
-    bool walks_away = true;
-
     i3_output *outputs_walk;
     SLIST_FOREACH(outputs_walk, outputs, slist) {
         if (!outputs_walk->active) {
@@ -1631,7 +1623,7 @@ void draw_bars(bool unhide) {
                       outputs_walk->bargc,
                       XCB_GC_FOREGROUND,
                       &color);
-        xcb_rectangle_t rect = { 0, 0, outputs_walk->rect.w, font.height + 6 };
+        xcb_rectangle_t rect = { 0, 0, outputs_walk->rect.w, bar_height };
         xcb_poly_fill_rectangle(xcb_connection,
                                 outputs_walk->buffer,
                                 outputs_walk->bargc,
@@ -1666,72 +1658,64 @@ void draw_bars(bool unhide) {
                           MIN(outputs_walk->rect.w - traypx - 4, statusline_width), font.height + 2);
         }
 
-        if (config.disable_ws) {
-            continue;
-        }
-
-        i3_ws *ws_walk;
-
-        TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
-            DLOG("Drawing Button for WS %s at x = %d, len = %d\n", i3string_as_utf8(ws_walk->name), i, ws_walk->name_width);
-            uint32_t fg_color = colors.inactive_ws_fg;
-            uint32_t bg_color = colors.inactive_ws_bg;
-            uint32_t border_color = colors.inactive_ws_border;
-            if (ws_walk->visible) {
-                if (!ws_walk->focused) {
-                    fg_color = colors.active_ws_fg;
-                    bg_color = colors.active_ws_bg;
-                    border_color = colors.active_ws_border;
-                } else {
-                    fg_color = colors.focus_ws_fg;
-                    bg_color = colors.focus_ws_bg;
-                    border_color = colors.focus_ws_border;
-                    if (last_urgent_ws && strcmp(i3string_as_utf8(ws_walk->name), last_urgent_ws) == 0)
-                        walks_away = false;
+        if (!config.disable_ws) {
+            i3_ws *ws_walk;
+            TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
+                DLOG("Drawing Button for WS %s at x = %d, len = %d\n",
+                     i3string_as_utf8(ws_walk->name), i, ws_walk->name_width);
+                uint32_t fg_color = colors.inactive_ws_fg;
+                uint32_t bg_color = colors.inactive_ws_bg;
+                uint32_t border_color = colors.inactive_ws_border;
+                if (ws_walk->visible) {
+                    if (!ws_walk->focused) {
+                        fg_color = colors.active_ws_fg;
+                        bg_color = colors.active_ws_bg;
+                        border_color = colors.active_ws_border;
+                    } else {
+                        fg_color = colors.focus_ws_fg;
+                        bg_color = colors.focus_ws_bg;
+                        border_color = colors.focus_ws_border;
+                    }
                 }
-            }
-            if (ws_walk->urgent) {
-                DLOG("WS %s is urgent!\n", i3string_as_utf8(ws_walk->name));
-                fg_color = colors.urgent_ws_fg;
-                bg_color = colors.urgent_ws_bg;
-                border_color = colors.urgent_ws_border;
-                unhide = true;
-                if (!ws_walk->focused) {
-                    FREE(last_urgent_ws);
-                    last_urgent_ws = sstrdup(i3string_as_utf8(ws_walk->name));
+                if (ws_walk->urgent) {
+                    DLOG("WS %s is urgent!\n", i3string_as_utf8(ws_walk->name));
+                    fg_color = colors.urgent_ws_fg;
+                    bg_color = colors.urgent_ws_bg;
+                    border_color = colors.urgent_ws_border;
+                    unhide = true;
                 }
-            }
-            uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
-            uint32_t vals_border[] = { border_color, border_color };
-            xcb_change_gc(xcb_connection,
-                          outputs_walk->bargc,
-                          mask,
-                          vals_border);
-            xcb_rectangle_t rect_border = { i, 1, ws_walk->name_width + 10, font.height + 4 };
-            xcb_poly_fill_rectangle(xcb_connection,
-                                    outputs_walk->buffer,
-                                    outputs_walk->bargc,
-                                    1,
-                                    &rect_border);
-            uint32_t vals[] = { bg_color, bg_color };
-            xcb_change_gc(xcb_connection,
-                          outputs_walk->bargc,
-                          mask,
-                          vals);
-            xcb_rectangle_t rect = { i + 1, 2, ws_walk->name_width + 8, font.height + 2 };
-            xcb_poly_fill_rectangle(xcb_connection,
-                                    outputs_walk->buffer,
-                                    outputs_walk->bargc,
-                                    1,
-                                    &rect);
-            set_font_colors(outputs_walk->bargc, fg_color, bg_color);
-            draw_text(ws_walk->name, outputs_walk->buffer, outputs_walk->bargc, i + 5, 3, ws_walk->name_width);
-            i += 10 + ws_walk->name_width + 1;
+                uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
+                uint32_t vals_border[] = { border_color, border_color };
+                xcb_change_gc(xcb_connection,
+                              outputs_walk->bargc,
+                              mask,
+                              vals_border);
+                xcb_rectangle_t rect_border = { i, 1, ws_walk->name_width + 10, font.height + 4 };
+                xcb_poly_fill_rectangle(xcb_connection,
+                                        outputs_walk->buffer,
+                                        outputs_walk->bargc,
+                                        1,
+                                        &rect_border);
+                uint32_t vals[] = { bg_color, bg_color };
+                xcb_change_gc(xcb_connection,
+                              outputs_walk->bargc,
+                              mask,
+                              vals);
+                xcb_rectangle_t rect = { i + 1, 2, ws_walk->name_width + 8, font.height + 2 };
+                xcb_poly_fill_rectangle(xcb_connection,
+                                        outputs_walk->buffer,
+                                        outputs_walk->bargc,
+                                        1,
+                                        &rect);
+                set_font_colors(outputs_walk->bargc, fg_color, bg_color);
+                draw_text(ws_walk->name, outputs_walk->buffer, outputs_walk->bargc,
+                          i + 5, 3, ws_walk->name_width);
+                i += 10 + ws_walk->name_width + 1;
 
+            }
         }
 
-        if (binding.name) {
-
+        if (binding.name && !config.disable_binding_mode_indicator) {
             uint32_t fg_color = colors.urgent_ws_fg;
             uint32_t bg_color = colors.urgent_ws_bg;
             uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
@@ -1770,13 +1754,11 @@ void draw_bars(bool unhide) {
     }
 
     /* Assure the bar is hidden/unhidden according to the specified hidden_state and mode */
-    bool should_unhide = (config.hidden_state == S_SHOW || (unhide && config.hidden_state == S_HIDE));
-    bool should_hide = (config.hide_on_modifier == M_INVISIBLE);
-
-    if (mod_pressed || (should_unhide && !should_hide)) {
+    if (mod_pressed ||
+            config.hidden_state == S_SHOW ||
+            unhide) {
         unhide_bars();
-    } else if (!mod_pressed && (walks_away || should_hide)) {
-        FREE(last_urgent_ws);
+    } else if (config.hide_on_modifier == M_HIDE) {
         hide_bars();
     }