Bugfix: Use both parts of WM_CLASS (it contains instance and class) (Thanks fallen)
Actually, WM_CLASS contains two null-terminated strings, so we cannot use asprintf() to get its value but rather use strdup() to get both of them. Both values are compared when a client is matched against a wm_class/title combination (for assignments for example).
This commit is contained in:
parent
f399c3ef9d
commit
3d13d53ae7
|
@ -378,8 +378,10 @@ struct Client {
|
||||||
* in. If set to true, legacy window names are ignored. */
|
* in. If set to true, legacy window names are ignored. */
|
||||||
bool uses_net_wm_name;
|
bool uses_net_wm_name;
|
||||||
|
|
||||||
/** Holds the WM_CLASS, useful for matching the client in commands */
|
/** Holds the WM_CLASS (which consists of two strings, the instance
|
||||||
char *window_class;
|
* and the class), useful for matching the client in commands */
|
||||||
|
char *window_class_instance;
|
||||||
|
char *window_class_class;
|
||||||
|
|
||||||
/** Holds the client’s mark, for vim-like jumping */
|
/** Holds the client’s mark, for vim-like jumping */
|
||||||
char *mark;
|
char *mark;
|
||||||
|
|
|
@ -122,7 +122,10 @@ void client_kill(xcb_connection_t *conn, Client *window) {
|
||||||
bool client_matches_class_name(Client *client, char *to_class, char *to_title,
|
bool client_matches_class_name(Client *client, char *to_class, char *to_title,
|
||||||
char *to_title_ucs, int to_title_ucs_len) {
|
char *to_title_ucs, int to_title_ucs_len) {
|
||||||
/* Check if the given class is part of the window class */
|
/* Check if the given class is part of the window class */
|
||||||
if (client->window_class == NULL || strcasestr(client->window_class, to_class) == NULL)
|
if ((client->window_class_instance == NULL ||
|
||||||
|
strcasestr(client->window_class_instance, to_class) == NULL) &&
|
||||||
|
(client->window_class_class == NULL ||
|
||||||
|
strcasestr(client->window_class_class, to_class) == NULL))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* If no title was given, we’re done */
|
/* If no title was given, we’re done */
|
||||||
|
|
|
@ -534,7 +534,8 @@ int handle_unmap_notify_event(void *data, xcb_connection_t *conn, xcb_unmap_noti
|
||||||
client->urgent = false;
|
client->urgent = false;
|
||||||
workspace_update_urgent_flag(client->workspace);
|
workspace_update_urgent_flag(client->workspace);
|
||||||
|
|
||||||
FREE(client->window_class);
|
FREE(client->window_class_instance);
|
||||||
|
FREE(client->window_class_class);
|
||||||
FREE(client->name);
|
FREE(client->name);
|
||||||
free(client);
|
free(client);
|
||||||
|
|
||||||
|
@ -692,28 +693,23 @@ int handle_windowclass_change(void *data, xcb_connection_t *conn, uint8_t state,
|
||||||
Client *client = table_get(&by_child, window);
|
Client *client = table_get(&by_child, window);
|
||||||
if (client == NULL)
|
if (client == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
char *new_class;
|
|
||||||
if (asprintf(&new_class, "%.*s", xcb_get_property_value_length(prop), (char*)xcb_get_property_value(prop)) == -1) {
|
|
||||||
perror("Could not get window class");
|
|
||||||
LOG("Could not get window class\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG("WM_CLASS changed to %s\n", new_class);
|
/* We cannot use asprintf here since this property contains two
|
||||||
char *old_class = client->window_class;
|
* null-terminated strings (for compatibility reasons). Instead, we
|
||||||
client->window_class = new_class;
|
* use strdup() on both strings */
|
||||||
FREE(old_class);
|
char *new_class = xcb_get_property_value(prop);
|
||||||
|
|
||||||
if (!client->initialized)
|
FREE(client->window_class_instance);
|
||||||
return 1;
|
FREE(client->window_class_class);
|
||||||
|
|
||||||
if (strcmp(new_class, "tools") == 0 || strcmp(new_class, "Dialog") == 0) {
|
client->window_class_instance = strdup(new_class);
|
||||||
LOG("tool/dialog window, should we put it floating?\n");
|
if ((strlen(new_class) + 1) < xcb_get_property_value_length(prop))
|
||||||
if (client->floating == FLOATING_AUTO_OFF)
|
client->window_class_class = strdup(new_class + strlen(new_class) + 1);
|
||||||
toggle_floating_mode(conn, client, true);
|
else client->window_class_class = NULL;
|
||||||
}
|
LOG("WM_CLASS changed to %s (instance), %s (class)\n",
|
||||||
|
client->window_class_instance, client->window_class_class);
|
||||||
|
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -465,7 +465,8 @@ Client *get_matching_client(xcb_connection_t *conn, const char *window_classtitl
|
||||||
|
|
||||||
Client *client;
|
Client *client;
|
||||||
SLIST_FOREACH(client, &(ws->focus_stack), focus_clients) {
|
SLIST_FOREACH(client, &(ws->focus_stack), focus_clients) {
|
||||||
LOG("Checking client with class=%s, name=%s\n", client->window_class, client->name);
|
LOG("Checking client with class=%s / %s, name=%s\n", client->window_class_instance,
|
||||||
|
client->window_class_class, client->name);
|
||||||
if (!client_matches_class_name(client, to_class, to_title, to_title_ucs, to_title_ucs_len))
|
if (!client_matches_class_name(client, to_class, to_title, to_title_ucs, to_title_ucs_len))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue