module/i3: use a tllist for workspaces instead of a dynamic array

This commit is contained in:
Daniel Eklöf 2020-12-03 18:31:42 +01:00
parent b9fda4482d
commit 678d82e4d4
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F

View file

@ -7,6 +7,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
#include <tllist.h>
#define LOG_MODULE "i3" #define LOG_MODULE "i3"
#define LOG_ENABLE_DBG 0 #define LOG_ENABLE_DBG 0
#include "../log.h" #include "../log.h"
@ -50,10 +52,7 @@ struct private {
size_t count; size_t count;
} ws_content; } ws_content;
struct { tll(struct workspace) workspaces;
struct workspace *v;
size_t count;
} workspaces;
}; };
static bool static bool
@ -87,54 +86,50 @@ workspace_from_json(const struct json_object *json, struct workspace *ws)
} }
static void static void
workspace_free(struct workspace ws) workspace_free(struct workspace *ws)
{ {
free(ws.name); free(ws->name);
free(ws.output); free(ws->output);
free(ws.window.title); free(ws->window.title);
free(ws.window.application); free(ws->window.application);
} }
static void static void
workspaces_free(struct private *m) workspaces_free(struct private *m)
{ {
for (size_t i = 0; i < m->workspaces.count; i++) tll_foreach(m->workspaces, it)
workspace_free(m->workspaces.v[i]); workspace_free(&it->item);
tll_free(m->workspaces);
free(m->workspaces.v);
m->workspaces.v = NULL;
m->workspaces.count = 0;
} }
static void static void
workspace_add(struct private *m, struct workspace ws) workspace_add(struct private *m, struct workspace ws)
{ {
size_t new_count = m->workspaces.count + 1; #if 0
struct workspace *new_v = realloc(m->workspaces.v, new_count * sizeof(new_v[0])); tll_push_back(m->workspaces, ws);
#else
tll_rforeach(m->workspaces, it) {
if (strcasecmp(it->item.name, ws.name) < 0) {
tll_insert_after(m->workspaces, it, ws);
return;
}
}
m->workspaces.count = new_count; tll_push_front(m->workspaces, ws);
m->workspaces.v = new_v; #endif
m->workspaces.v[new_count - 1] = ws;
} }
static void static void
workspace_del(struct private *m, const char *name) workspace_del(struct private *m, const char *name)
{ {
struct workspace *workspaces = m->workspaces.v; tll_foreach(m->workspaces, it) {
struct workspace *ws = &it->item;
for (size_t i = 0; i < m->workspaces.count; i++) {
const struct workspace *ws = &workspaces[i];
if (strcmp(ws->name, name) != 0) if (strcmp(ws->name, name) != 0)
continue; continue;
workspace_free(*ws); workspace_free(ws);
tll_remove(m->workspaces, it);
memmove(
&workspaces[i],
&workspaces[i + 1],
(m->workspaces.count - i - 1) * sizeof(workspaces[0]));
m->workspaces.count--;
break; break;
} }
} }
@ -142,13 +137,14 @@ workspace_del(struct private *m, const char *name)
static struct workspace * static struct workspace *
workspace_lookup(struct private *m, const char *name) workspace_lookup(struct private *m, const char *name)
{ {
for (size_t i = 0; i < m->workspaces.count; i++) tll_foreach(m->workspaces, it) {
if (strcmp(m->workspaces.v[i].name, name) == 0) struct workspace *ws = &it->item;
return &m->workspaces.v[i]; if (strcmp(ws->name, name) == 0)
return ws;
}
return NULL; return NULL;
} }
static bool static bool
handle_get_version_reply(int type, const struct json_object *json, void *_m) handle_get_version_reply(int type, const struct json_object *json, void *_m)
{ {
@ -191,18 +187,17 @@ handle_get_workspaces_reply(int type, const struct json_object *json, void *_mod
m->dirty = true; m->dirty = true;
size_t count = json_object_array_length(json); size_t count = json_object_array_length(json);
m->workspaces.count = count;
m->workspaces.v = calloc(count, sizeof(m->workspaces.v[0]));
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
if (!workspace_from_json( struct workspace ws = {};
json_object_array_get_idx(json, i), &m->workspaces.v[i])) { if (!workspace_from_json(json_object_array_get_idx(json, i), &ws)) {
workspaces_free(m); workspaces_free(m);
mtx_unlock(&mod->lock); mtx_unlock(&mod->lock);
return false; return false;
} }
LOG_DBG("#%zu: %s", i, m->workspaces.v[i].name); LOG_DBG("#%zu: %s", i, m->workspaces.v[i].name);
workspace_add(m, ws);
} }
mtx_unlock(&mod->lock); mtx_unlock(&mod->lock);
@ -250,7 +245,7 @@ handle_workspace_event(int type, const struct json_object *json, void *_mod)
struct workspace *already_exists = workspace_lookup(m, current_name); struct workspace *already_exists = workspace_lookup(m, current_name);
if (already_exists != NULL) { if (already_exists != NULL) {
LOG_WARN("workspace 'init' event for already existing workspace: %s", current_name); LOG_WARN("workspace 'init' event for already existing workspace: %s", current_name);
workspace_free(*already_exists); workspace_free(already_exists);
if (!workspace_from_json(current, already_exists)) if (!workspace_from_json(current, already_exists))
goto err; goto err;
} else { } else {
@ -284,8 +279,8 @@ handle_workspace_event(int type, const struct json_object *json, void *_mod)
LOG_DBG("w: %s", w->name); LOG_DBG("w: %s", w->name);
/* Mark all workspaces on current's output invisible */ /* Mark all workspaces on current's output invisible */
for (size_t i = 0; i < m->workspaces.count; i++) { tll_foreach(m->workspaces, it) {
struct workspace *ws = &m->workspaces.v[i]; struct workspace *ws = &it->item;
if (strcmp(ws->output, w->output) == 0) if (strcmp(ws->output, w->output) == 0)
ws->visible = false; ws->visible = false;
} }
@ -346,9 +341,9 @@ handle_window_event(int type, const struct json_object *json, void *_mod)
struct workspace *ws = NULL; struct workspace *ws = NULL;
size_t focused = 0; size_t focused = 0;
for (size_t i = 0; i < m->workspaces.count; i++) { tll_foreach(m->workspaces, it) {
if (m->workspaces.v[i].focused) { if (it->item.focused) {
ws = &m->workspaces.v[i]; ws = &it->item;
focused++; focused++;
} }
} }
@ -536,11 +531,11 @@ content(struct module *mod)
mtx_lock(&mod->lock); mtx_lock(&mod->lock);
size_t particle_count = 0; size_t particle_count = 0;
struct exposable *particles[m->workspaces.count + 1]; struct exposable *particles[tll_length(m->workspaces) + 1];
struct exposable *current = NULL; struct exposable *current = NULL;
for (size_t i = 0; i < m->workspaces.count; i++) { tll_foreach(m->workspaces, it) {
const struct workspace *ws = &m->workspaces.v[i]; struct workspace *ws = &it->item;
const struct ws_content *template = NULL; const struct ws_content *template = NULL;
/* Lookup content template for workspace. Fall back to default /* Lookup content template for workspace. Fall back to default