i3 - improved tiling WM


libi3/root_atom_contents: handle data of arbitrary length

Patch status: merged

Patch by Lancelot SIX

Long description:

Handle data fetched from xcb_get_property_unchecked with arbitrary
length. This avoids having to rely on PATH_MAX macro where it is not
necessary.

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

b/i3-config-wizard/i3-config-wizard.mk

21
@@ -5,7 +5,7 @@ CLEAN_TARGETS += clean-i3-config-wizard
22
 i3_config_wizard_SOURCES           := $(wildcard i3-config-wizard/*.c)
23
 i3_config_wizard_HEADERS           := $(wildcard i3-config-wizard/*.h)
24
 i3_config_wizard_CFLAGS             = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(X11_CFLAGS) $(PANGO_CFLAGS)
25
-i3_config_wizard_LIBS               = $(XCB_LIBS) $(XCB_KBD_LIBS) $(X11_LIBS) $(PANGO_LIBS)
26
+i3_config_wizard_LIBS               = $(XCB_LIBS) $(XCB_KBD_LIBS) $(X11_LIBS) $(PANGO_LIBS) -lm
27
 
28
 i3_config_wizard_OBJECTS := $(i3_config_wizard_SOURCES:.c=.o)
29
 

b/i3-dump-log/i3-dump-log.mk

34
@@ -5,7 +5,7 @@ CLEAN_TARGETS += clean-i3-dump-log
35
 i3_dump_log_SOURCES := $(wildcard i3-dump-log/*.c)
36
 i3_dump_log_HEADERS := $(wildcard i3-dump-log/*.h)
37
 i3_dump_log_CFLAGS   = $(XCB_CFLAGS) $(PANGO_CFLAGS)
38
-i3_dump_log_LIBS     = $(XCB_LIBS)
39
+i3_dump_log_LIBS     = $(XCB_LIBS) -lm
40
 
41
 i3_dump_log_OBJECTS := $(i3_dump_log_SOURCES:.c=.o)
42
 

b/i3-input/i3-input.mk

47
@@ -5,7 +5,7 @@ CLEAN_TARGETS += clean-i3-input
48
 i3_input_SOURCES := $(wildcard i3-input/*.c)
49
 i3_input_HEADERS := $(wildcard i3-input/*.h)
50
 i3_input_CFLAGS   = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS)
51
-i3_input_LIBS     = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS)
52
+i3_input_LIBS     = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) -lm
53
 
54
 i3_input_OBJECTS := $(i3_input_SOURCES:.c=.o)
55
 

b/i3-msg/i3-msg.mk

60
@@ -5,7 +5,7 @@ CLEAN_TARGETS += clean-i3-msg
61
 i3_msg_SOURCES := $(wildcard i3-msg/*.c)
62
 i3_msg_HEADERS := $(wildcard i3-msg/*.h)
63
 i3_msg_CFLAGS   = $(XCB_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS)
64
-i3_msg_LIBS     = $(XCB_LIBS) $(YAJL_LIBS)
65
+i3_msg_LIBS     = $(XCB_LIBS) $(YAJL_LIBS) -lm
66
 
67
 i3_msg_OBJECTS := $(i3_msg_SOURCES:.c=.o)
68
 

b/i3bar/i3bar.mk

73
@@ -5,7 +5,7 @@ CLEAN_TARGETS += clean-i3bar
74
 i3bar_SOURCES := $(wildcard i3bar/src/*.c)
75
 i3bar_HEADERS := $(wildcard i3bar/include/*.h)
76
 i3bar_CFLAGS   = $(XCB_CFLAGS) $(X11_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS)
77
-i3bar_LIBS     = $(XCB_LIBS) $(X11_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS)
78
+i3bar_LIBS     = $(XCB_LIBS) $(X11_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) -lm
79
 
80
 i3bar_OBJECTS := $(i3bar_SOURCES:.c=.o)
81
 

b/libi3/root_atom_contents.c

86
@@ -10,6 +10,7 @@
87
 #include <stdbool.h>
88
 #include <limits.h>
89
 #include <stdlib.h>
90
+#include <math.h>
91
 
92
 #include <xcb/xcb.h>
93
 #include <xcb/xcb_aux.h>
94
@@ -31,6 +32,7 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn,
95
     xcb_intern_atom_cookie_t atom_cookie;
96
     xcb_intern_atom_reply_t *atom_reply;
97
     char *content;
98
+    size_t content_max_words = 256;
99
     xcb_connection_t *conn = provided_conn;
100
 
101
     if (provided_conn == NULL &&
102
@@ -50,12 +52,26 @@ char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn,
103
     xcb_get_property_cookie_t prop_cookie;
104
     xcb_get_property_reply_t *prop_reply;
105
     prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
106
-                                             XCB_GET_PROPERTY_TYPE_ANY, 0, PATH_MAX);
107
+                                             XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
108
     prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
109
     if (prop_reply == NULL) {
110
         free(atom_reply);
111
         return NULL;
112
     }
113
+    if (xcb_get_property_value_length(prop_reply) > 0 && prop_reply->bytes_after > 0) {
114
+        /* We received an incomplete value. Ask again but with a properly
115
+         * adjusted size. */
116
+        content_max_words += ceil(prop_reply->bytes_after / 4.0);
117
+        /* Repeat the request, with adjusted size */
118
+        free(prop_reply);
119
+        prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
120
+                                                 XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
121
+        prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
122
+        if (prop_reply == NULL) {
123
+            free(atom_reply);
124
+            return NULL;
125
+        }
126
+    }
127
     if (xcb_get_property_value_length(prop_reply) == 0) {
128
         free(atom_reply);
129
         free(prop_reply);