forked from external/yambar
module/i3: improve window event handling
* Only care about 'close', 'focus' and 'title' events * Remove application/title on 'close' * Ignore 'title' events if it's not for the currently active window (from the last 'focus' event) This fixes an issue where we rendered a 'title' event just like a focus event. Meaning that a non-focused window, perhaps even on a different workspace, that changed its title, would cause us to refresh with its title being used.
This commit is contained in:
parent
f959d96c17
commit
546a4b5009
1 changed files with 33 additions and 7 deletions
40
modules/i3.c
40
modules/i3.c
|
@ -33,6 +33,7 @@ struct workspace {
|
||||||
bool urgent;
|
bool urgent;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
unsigned id;
|
||||||
char *title;
|
char *title;
|
||||||
char *application;
|
char *application;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
@ -404,20 +405,29 @@ handle_window_event(int type, const struct json_object *json, void *_mod)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->dirty = true;
|
|
||||||
const char *change_str = json_object_get_string(change);
|
const char *change_str = json_object_get_string(change);
|
||||||
|
|
||||||
if (strcmp(change_str, "close") == 0 || strcmp(change_str, "new") == 0 ||
|
bool is_focus = strcmp(change_str, "focus") == 0;
|
||||||
strcmp(change_str, "floating") == 0)
|
bool is_close = !is_focus && strcmp(change_str, "close") == 0;
|
||||||
{
|
bool is_title = !is_focus && !is_close && strcmp(change_str, "title") == 0;
|
||||||
|
|
||||||
|
if (!is_focus && !is_close && !is_title) {
|
||||||
|
mtx_unlock(&mod->lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_close) {
|
||||||
free(ws->window.title);
|
free(ws->window.title);
|
||||||
free(ws->window.application);
|
free(ws->window.application);
|
||||||
|
|
||||||
|
ws->window.id = -1;
|
||||||
ws->window.title = ws->window.application = NULL;
|
ws->window.title = ws->window.application = NULL;
|
||||||
ws->window.pid = -1;
|
ws->window.pid = -1;
|
||||||
|
|
||||||
|
m->dirty = true;
|
||||||
mtx_unlock(&mod->lock);
|
mtx_unlock(&mod->lock);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct json_object *container = json_object_object_get(json, "container");
|
const struct json_object *container = json_object_object_get(json, "container");
|
||||||
|
@ -426,6 +436,13 @@ handle_window_event(int type, const struct json_object *json, void *_mod)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct json_object *id = json_object_object_get(container, "id");
|
||||||
|
if (id == NULL || !json_object_is_type(id, json_type_int)) {
|
||||||
|
LOG_ERR("'window' event (%s) did not contain a 'container.id' integer value",
|
||||||
|
change_str);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
struct json_object *name = json_object_object_get(container, "name");
|
struct json_object *name = json_object_object_get(container, "name");
|
||||||
if (name == NULL || !json_object_is_type(name, json_type_string)) {
|
if (name == NULL || !json_object_is_type(name, json_type_string)) {
|
||||||
LOG_ERR(
|
LOG_ERR(
|
||||||
|
@ -434,9 +451,6 @@ handle_window_event(int type, const struct json_object *json, void *_mod)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(ws->window.title);
|
|
||||||
ws->window.title = strdup(json_object_get_string(name));
|
|
||||||
|
|
||||||
const struct json_object *pid_node = json_object_object_get(container, "pid");
|
const struct json_object *pid_node = json_object_object_get(container, "pid");
|
||||||
if (pid_node == NULL || !json_object_is_type(pid_node, json_type_int)) {
|
if (pid_node == NULL || !json_object_is_type(pid_node, json_type_int)) {
|
||||||
LOG_ERR(
|
LOG_ERR(
|
||||||
|
@ -445,6 +459,16 @@ handle_window_event(int type, const struct json_object *json, void *_mod)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_title && ws->window.id != json_object_get_int(id)) {
|
||||||
|
/* Ignore title changed event if it's not current window */
|
||||||
|
mtx_unlock(&mod->lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ws->window.title);
|
||||||
|
ws->window.title = strdup(json_object_get_string(name));
|
||||||
|
ws->window.id = json_object_get_int(id);
|
||||||
|
|
||||||
/* If PID has changed, update application name from /proc/<pid>/comm */
|
/* If PID has changed, update application name from /proc/<pid>/comm */
|
||||||
pid_t pid = json_object_get_int(pid_node);
|
pid_t pid = json_object_get_int(pid_node);
|
||||||
if (ws->window.pid != pid) {
|
if (ws->window.pid != pid) {
|
||||||
|
@ -472,10 +496,12 @@ handle_window_event(int type, const struct json_object *json, void *_mod)
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m->dirty = true;
|
||||||
mtx_unlock(&mod->lock);
|
mtx_unlock(&mod->lock);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
m->dirty = false;
|
||||||
mtx_unlock(&mod->lock);
|
mtx_unlock(&mod->lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue