Codebase list i3-gaps / 7df88f1
Sort dock clients by class and instance This is similar to #3820 but does not use qsort but an insertion sort in con_attach. Since each bar block automatically gets its own incremental bar id, bards end up being sorted according to their definition order in the config file. For i3bar, the WM_CLASS is modified to include an instance name which depends on the bar_id. This could be useful for other reason, e.g. users targeting a specific bar instance. Fixes #3491 Orestis Floros 4 years ago
5 changed file(s) with 48 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
682682 } else {
683683 cont_child();
684684 }
685 }
686
687 static int strcasecmp_nullable(const char *a, const char *b) {
688 if (a == b) {
689 return 0;
690 }
691 if (a == NULL) {
692 return -1;
693 }
694 if (b == NULL) {
695 return 1;
696 }
697 return strcasecmp(a, b);
698685 }
699686
700687 /*
181181 ssize_t swrite(int fd, const void *buf, size_t count);
182182
183183 /**
184 * Like strcasecmp but considers the case where either string is NULL.
185 *
186 */
187 int strcasecmp_nullable(const char *a, const char *b);
188
189 /**
184190 * Build an i3String from an UTF-8 encoded string.
185191 * Returns the newly-allocated i3String.
186192 *
109109 else
110110 return n;
111111 }
112
113 /*
114 * Like strcasecmp but considers the case where either string is NULL.
115 *
116 */
117 int strcasecmp_nullable(const char *a, const char *b) {
118 if (a == b) {
119 return 0;
120 }
121 if (a == NULL) {
122 return -1;
123 }
124 if (b == NULL) {
125 return 1;
126 }
127 return strcasecmp(a, b);
128 }
127127 else
128128 TAILQ_INSERT_TAIL(nodes_head, con, nodes);
129129 }
130 }
131 goto add_to_focus_head;
132 }
133
134 if (parent->type == CT_DOCKAREA) {
135 /* Insert dock client, sorting alphanumerically by class and then
136 * instance name. This makes dock client order deterministic. As a side
137 * effect, bars without a custom bar id will be sorted according to
138 * their declaration order in the config file. See #3491. */
139 current = NULL;
140 TAILQ_FOREACH (loop, nodes_head, nodes) {
141 int result = strcasecmp_nullable(con->window->class_class, loop->window->class_class);
142 if (result == 0) {
143 result = strcasecmp_nullable(con->window->class_instance, loop->window->class_instance);
144 }
145 if (result < 0) {
146 current = loop;
147 break;
148 }
149 }
150 if (current) {
151 TAILQ_INSERT_BEFORE(loop, con, nodes);
152 } else {
153 TAILQ_INSERT_TAIL(nodes_head, con, nodes);
130154 }
131155 goto add_to_focus_head;
132156 }
11461146
11471147 /* attach the dock to the dock area */
11481148 con_detach(con);
1149 con->parent = dockarea;
1150 TAILQ_INSERT_HEAD(&(dockarea->focus_head), con, focused);
1151 TAILQ_INSERT_HEAD(&(dockarea->nodes_head), con, nodes);
1149 con_attach(con, dockarea, true);
11521150
11531151 tree_render();
11541152