i3 - improved tiling WM


Fix wrong placement of i3bar when connecting/disconnecting outputs

Patch status: merged

Patch by jj

Long description:

When connecting or disconnecting an output, i3bar reconfigures its
windows. This also included an unmapping of the bars, and a remapping of
all docked bars. Thus, the bars were misplaced when a monitor was
disconnected.

This commit assures that the remapping of the bars only takes place,
when the mode has actually changed. This patch also takes care of an
inconsistency when pressing the bar_modifier while switching the mode.
Also, the xkbDisplay is now closed correctly, when deregestering the xkb
keyevents.

To apply this patch, use:
curl http://cr.i3wm.org/patch/169/raw.patch | git am

b/i3bar/include/xcb.h

26
@@ -114,7 +114,7 @@ void realloc_sl_buffer(void);
27
  * Reconfigure all bars and create new for newly activated outputs
28
  *
29
  */
30
-void reconfig_windows(void);
31
+void reconfig_windows(bool redraw_bars);
32
 
33
 /*
34
  * Render the bars, with buttons and statusline

b/i3bar/src/ipc.c

39
@@ -64,7 +64,7 @@ void got_output_reply(char *reply) {
40
     parse_outputs_json(reply);
41
     DLOG("Reconfiguring Windows...\n");
42
     realloc_sl_buffer();
43
-    reconfig_windows();
44
+    reconfig_windows(false);
45
 
46
     i3_output *o_walk;
47
     SLIST_FOREACH(o_walk, outputs, slist) {
48
@@ -167,7 +167,7 @@ void got_bar_config_update(char *event) {
49
     int old_mode = config.hide_on_modifier;
50
     parse_config_json(event);
51
     if (old_mode != config.hide_on_modifier) {
52
-        reconfig_windows();
53
+        reconfig_windows(true);
54
     }
55
 
56
     draw_bars(false);

b/i3bar/src/xcb.c

61
@@ -198,7 +198,7 @@ void refresh_statusline(void) {
62
  *
63
  */
64
 void hide_bars(void) {
65
-    if ((config.hide_on_modifier == M_DOCK) || (config.hidden_state == S_SHOW)) {
66
+    if ((config.hide_on_modifier == M_DOCK) || (config.hidden_state == S_SHOW && config.hide_on_modifier == M_HIDE)) {
67
         return;
68
     }
69
 
70
@@ -1041,9 +1041,10 @@ void register_xkb_keyevents() {
71
 void deregister_xkb_keyevents() {
72
     if (xkb_dpy != NULL) {
73
         ev_io_stop (main_loop, xkb_io);
74
+        XCloseDisplay(xkb_dpy);
75
         close(xkb_io->fd);
76
         FREE(xkb_io);
77
-        FREE(xkb_dpy);
78
+        xkb_dpy = NULL;
79
     }
80
 }
81
 
82
@@ -1367,7 +1368,7 @@ void realloc_sl_buffer(void) {
83
  * Reconfigure all bars and create new bars for recently activated outputs
84
  *
85
  */
86
-void reconfig_windows(void) {
87
+void reconfig_windows(bool redraw_bars) {
88
     uint32_t mask;
89
     uint32_t values[5];
90
     static bool tray_configured = false;
91
@@ -1570,27 +1571,31 @@ void reconfig_windows(void) {
92
                                                                     walk->rect.w,
93
                                                                     walk->rect.h);
94
 
95
-            /* Unmap the window, and draw it again when in dock mode */
96
-            xcb_void_cookie_t umap_cookie = xcb_unmap_window_checked(xcb_connection, walk->bar);
97
-            xcb_void_cookie_t map_cookie;
98
-            if (config.hide_on_modifier == M_DOCK) {
99
-                cont_child();
100
-                map_cookie = xcb_map_window_checked(xcb_connection, walk->bar);
101
-            }
102
+            xcb_void_cookie_t map_cookie, umap_cookie;
103
+            if (redraw_bars) {
104
+                /* Unmap the window, and draw it again when in dock mode */
105
+                umap_cookie = xcb_unmap_window_checked(xcb_connection, walk->bar);
106
+                if (config.hide_on_modifier == M_DOCK) {
107
+                    cont_child();
108
+                    map_cookie = xcb_map_window_checked(xcb_connection, walk->bar);
109
+                } else {
110
+                    stop_child();
111
+                }
112
 
113
-            if (config.hide_on_modifier == M_HIDE) {
114
-                /* Switching to hide mode, register for keyevents */
115
-                register_xkb_keyevents();
116
-            } else {
117
-                /* Switching to dock/invisible mode, deregister from keyevents */
118
-                deregister_xkb_keyevents();
119
+                if (config.hide_on_modifier == M_HIDE) {
120
+                    /* Switching to hide mode, register for keyevents */
121
+                    register_xkb_keyevents();
122
+                } else {
123
+                    /* Switching to dock/invisible mode, deregister from keyevents */
124
+                    deregister_xkb_keyevents();
125
+                }
126
             }
127
 
128
             if (xcb_request_failed(cfg_cookie, "Could not reconfigure window") ||
129
                 xcb_request_failed(chg_cookie, "Could not change window") ||
130
                 xcb_request_failed(pm_cookie,  "Could not create pixmap") ||
131
-                xcb_request_failed(umap_cookie,  "Could not unmap window") ||
132
-                ((config.hide_on_modifier == M_DOCK) && xcb_request_failed(map_cookie, "Could not map window"))) {
133
+                (redraw_bars && (xcb_request_failed(umap_cookie,  "Could not unmap window") ||
134
+                (config.hide_on_modifier == M_DOCK && xcb_request_failed(map_cookie, "Could not map window"))))) {
135
                 exit(EXIT_FAILURE);
136
             }
137
         }
138
@@ -1618,7 +1623,7 @@ void draw_bars(bool unhide) {
139
         }
140
         if (outputs_walk->bar == XCB_NONE) {
141
             /* Oh shit, an active output without an own bar. Create it now! */
142
-            reconfig_windows();
143
+            reconfig_windows(false);
144
         }
145
         /* First things first: clear the backbuffer */
146
         uint32_t color = colors.bar_bg;
147
@@ -1768,13 +1773,11 @@ void draw_bars(bool unhide) {
148
     bool should_unhide = (config.hidden_state == S_SHOW || (unhide && config.hidden_state == S_HIDE));
149
     bool should_hide = (config.hide_on_modifier == M_INVISIBLE);
150
 
151
-    if (!mod_pressed) {
152
-        if ((unhide || should_unhide) && !should_hide) {
153
-            unhide_bars();
154
-        } else if (walks_away || should_hide) {
155
-            FREE(last_urgent_ws);
156
-            hide_bars();
157
-        }
158
+    if (mod_pressed || (should_unhide && !should_hide)) {
159
+        unhide_bars();
160
+    } else if (!mod_pressed && (walks_away || should_hide)) {
161
+        FREE(last_urgent_ws);
162
+        hide_bars();
163
     }
164
 
165
     redraw_bars();