]> git.sur5r.net Git - i3/i3/blobdiff - src/x.c
Use 32-bit visuals for i3bar when possible and allow RGBA colors.
[i3/i3] / src / x.c
diff --git a/src/x.c b/src/x.c
index 2dcffe6b15929ae8d25d6a656ae1017d8d122a20..d312666bda116dd6b956885215af9607fb3a897e 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -12,6 +12,8 @@
  */
 #include "all.h"
 
+xcb_window_t ewmh_window;
+
 /* Stores the X11 window ID of the currently focused window */
 xcb_window_t focused_id = XCB_NONE;
 
@@ -143,11 +145,19 @@ void x_con_init(Con *con, uint16_t depth) {
 
     Rect dims = {-15, -15, 10, 10};
     con->frame = create_window(conn, dims, depth, visual, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCURSOR_CURSOR_POINTER, false, mask, values);
+    xcb_change_property(conn,
+                        XCB_PROP_MODE_REPLACE,
+                        con->frame,
+                        XCB_ATOM_WM_CLASS,
+                        XCB_ATOM_STRING,
+                        8,
+                        (strlen("i3-frame") + 1) * 2,
+                        "i3-frame\0i3-frame\0");
 
     if (win_colormap != XCB_NONE)
         xcb_free_colormap(conn, win_colormap);
 
-    struct con_state *state = scalloc(sizeof(struct con_state));
+    struct con_state *state = scalloc(1, sizeof(struct con_state));
     state->id = con->frame;
     state->mapped = false;
     state->initial = true;
@@ -286,7 +296,7 @@ void x_window_kill(xcb_window_t window, kill_window_t kill_window) {
     /* Every X11 event is 32 bytes long. Therefore, XCB will copy 32 bytes.
      * In order to properly initialize these bytes, we allocate 32 bytes even
      * though we only need less for an xcb_configure_notify_event_t */
-    void *event = scalloc(32);
+    void *event = scalloc(32, 1);
     xcb_client_message_event_t *ev = event;
 
     ev->response_type = XCB_CLIENT_MESSAGE;
@@ -337,7 +347,7 @@ void x_draw_decoration(Con *con) {
         return;
 
     /* 1: build deco_params and compare with cache */
-    struct deco_render_params *p = scalloc(sizeof(struct deco_render_params));
+    struct deco_render_params *p = scalloc(1, sizeof(struct deco_render_params));
 
     /* find out which colors to use */
     if (con->urgent)
@@ -542,17 +552,20 @@ void x_draw_decoration(Con *con) {
         FREE(formatted_mark);
         mark_width = predict_text_width(mark);
 
-        draw_text(mark, parent->pixmap, parent->pm_gc,
+        draw_text(mark, parent->pixmap, parent->pm_gc, NULL,
                   con->deco_rect.x + con->deco_rect.width - mark_width - logical_px(2),
                   con->deco_rect.y + text_offset_y, mark_width);
 
         I3STRING_FREE(mark);
     }
 
-    draw_text(win->name,
-              parent->pixmap, parent->pm_gc,
+    i3String *title = win->title_format == NULL ? win->name : window_parse_title_format(win);
+    draw_text(title,
+              parent->pixmap, parent->pm_gc, NULL,
               con->deco_rect.x + logical_px(2) + indent_px, con->deco_rect.y + text_offset_y,
               con->deco_rect.width - logical_px(2) - indent_px - mark_width - logical_px(2));
+    if (win->title_format != NULL)
+        I3STRING_FREE(title);
 
 after_title:
     /* Since we don’t clip the text at all, it might in some cases be painted
@@ -626,16 +639,14 @@ static void set_hidden_state(Con *con) {
     if (should_be_hidden == state->is_hidden)
         return;
 
-    unsigned int num = 0;
-    uint32_t values[1];
     if (should_be_hidden) {
         DLOG("setting _NET_WM_STATE_HIDDEN for con = %p\n", con);
-        values[num++] = A__NET_WM_STATE_HIDDEN;
+        xcb_add_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_HIDDEN);
     } else {
         DLOG("removing _NET_WM_STATE_HIDDEN for con = %p\n", con);
+        xcb_remove_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_HIDDEN);
     }
 
-    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id, A__NET_WM_STATE, XCB_ATOM_ATOM, 32, num, values);
     state->is_hidden = should_be_hidden;
 }
 
@@ -1087,10 +1098,12 @@ void x_push_changes(Con *con) {
     }
 
     if (focused_id == XCB_NONE) {
-        DLOG("Still no window focused, better set focus to the root window\n");
-        xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, root, XCB_CURRENT_TIME);
+        /* If we still have no window to focus, we focus the EWMH window instead. We use this rather than the
+         * root window in order to avoid an X11 fallback mechanism causing a ghosting effect (see #1378). */
+        DLOG("Still no window focused, better set focus to the EWMH support window (%d)\n", ewmh_window);
+        xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, ewmh_window, XCB_CURRENT_TIME);
         ewmh_update_active_window(XCB_WINDOW_NONE);
-        focused_id = root;
+        focused_id = ewmh_window;
     }
 
     xcb_flush(conn);