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:
Daniel Eklöf 2019-02-17 20:05:44 +01:00
parent f959d96c17
commit 546a4b5009

View file

@ -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;
} }