Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #4018 from orestisfl/reorder-docks
Browse files Browse the repository at this point in the history
Sort dock clients by class and instance
  • Loading branch information
Airblader committed Apr 15, 2020
2 parents 831a52d + 7df88f1 commit 0bce0d8
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 18 deletions.
19 changes: 4 additions & 15 deletions i3bar/src/xcb.c
Expand Up @@ -685,19 +685,6 @@ static void handle_visibility_notify(xcb_visibility_notify_event_t *event) {
}
}

static int strcasecmp_nullable(const char *a, const char *b) {
if (a == b) {
return 0;
}
if (a == NULL) {
return -1;
}
if (b == NULL) {
return 1;
}
return strcasecmp(a, b);
}

/*
* Comparison function to sort trayclients in ascending alphanumeric order
* according to their class.
Expand Down Expand Up @@ -1816,15 +1803,17 @@ void reconfig_windows(bool redraw_bars) {
bar_height);

/* Set the WM_CLASS and WM_NAME (we don't need UTF-8) atoms */
char *class;
int len = sasprintf(&class, "%s%ci3bar%c", config.bar_id, 0, 0);
xcb_void_cookie_t class_cookie;
class_cookie = xcb_change_property(xcb_connection,
XCB_PROP_MODE_REPLACE,
bar_id,
XCB_ATOM_WM_CLASS,
XCB_ATOM_STRING,
8,
(strlen("i3bar") + 1) * 2,
"i3bar\0i3bar\0");
len,
class);

char *name;
sasprintf(&name, "i3bar for output %s", walk->name);
Expand Down
6 changes: 6 additions & 0 deletions include/libi3.h
Expand Up @@ -181,6 +181,12 @@ ssize_t writeall_nonblock(int fd, const void *buf, size_t count);
*/
ssize_t swrite(int fd, const void *buf, size_t count);

/**
* Like strcasecmp but considers the case where either string is NULL.
*
*/
int strcasecmp_nullable(const char *a, const char *b);

/**
* Build an i3String from an UTF-8 encoded string.
* Returns the newly-allocated i3String.
Expand Down
17 changes: 17 additions & 0 deletions libi3/safewrappers.c
Expand Up @@ -110,3 +110,20 @@ ssize_t swrite(int fd, const void *buf, size_t count) {
else
return n;
}

/*
* Like strcasecmp but considers the case where either string is NULL.
*
*/
int strcasecmp_nullable(const char *a, const char *b) {
if (a == b) {
return 0;
}
if (a == NULL) {
return -1;
}
if (b == NULL) {
return 1;
}
return strcasecmp(a, b);
}
24 changes: 24 additions & 0 deletions src/con.c
Expand Up @@ -132,6 +132,30 @@ static void _con_attach(Con *con, Con *parent, Con *previous, bool ignore_focus)
goto add_to_focus_head;
}

if (parent->type == CT_DOCKAREA) {
/* Insert dock client, sorting alphanumerically by class and then
* instance name. This makes dock client order deterministic. As a side
* effect, bars without a custom bar id will be sorted according to
* their declaration order in the config file. See #3491. */
current = NULL;
TAILQ_FOREACH (loop, nodes_head, nodes) {
int result = strcasecmp_nullable(con->window->class_class, loop->window->class_class);
if (result == 0) {
result = strcasecmp_nullable(con->window->class_instance, loop->window->class_instance);
}
if (result < 0) {
current = loop;
break;
}
}
if (current) {
TAILQ_INSERT_BEFORE(loop, con, nodes);
} else {
TAILQ_INSERT_TAIL(nodes_head, con, nodes);
}
goto add_to_focus_head;
}

if (con->type == CT_FLOATING_CON) {
DLOG("Inserting into floating containers\n");
TAILQ_INSERT_TAIL(&(parent->floating_head), con, floating_windows);
Expand Down
4 changes: 1 addition & 3 deletions src/handlers.c
Expand Up @@ -1148,9 +1148,7 @@ static bool handle_strut_partial_change(Con *con, xcb_get_property_reply_t *prop

/* attach the dock to the dock area */
con_detach(con);
con->parent = dockarea;
TAILQ_INSERT_HEAD(&(dockarea->focus_head), con, focused);
TAILQ_INSERT_HEAD(&(dockarea->nodes_head), con, nodes);
con_attach(con, dockarea, true);

tree_render();

Expand Down

0 comments on commit 0bce0d8

Please sign in to comment.