X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=plugins%2Fplacement%2Fhistory.c;h=ea3d60dfb5cf9a7b2d2d0b7d7b438390946dd543;hb=6c431d3a454eff91b21be0ad933c7e96a958816a;hp=d979bb1f4de77202be2972e181e08c00be2c1ed4;hpb=0edc14a4f92e34f5edcdb00898013206142ca71d;p=chaz%2Fopenbox diff --git a/plugins/placement/history.c b/plugins/placement/history.c index d979bb1f..ea3d60df 100644 --- a/plugins/placement/history.c +++ b/plugins/placement/history.c @@ -1,16 +1,229 @@ -#include "../../kernel/frame.h" -#include "../../kernel/client.h" +#include "kernel/openbox.h" +#include "kernel/dispatch.h" +#include "kernel/frame.h" +#include "kernel/client.h" +#include "kernel/screen.h" #include +#include +#ifdef HAVE_STDLIB_H +# include +#endif -void history_startup() -{ -} +struct HistoryItem { + char *name; + char *class; + char *role; + int x; + int y; + gboolean placed; +}; -void history_shutdown() +static GSList *history = NULL; +static char *history_path = NULL; + +static struct HistoryItem *find_history(Client *c) { + GSList *it; + struct HistoryItem *hi = NULL; + + /* find the client */ + for (it = history; it != NULL; it = it->next) { + hi = it->data; + g_assert(hi->name != NULL); + g_assert(hi->class != NULL); + g_assert(hi->role != NULL); + g_assert(c->name != NULL); + g_assert(c->class != NULL); + g_assert(c->role != NULL); + if (!strcmp(hi->name, c->name) && + !strcmp(hi->class, c->class) && + !strcmp(hi->role, c->role)) + return hi; + } + return NULL; } gboolean place_history(Client *c) { + struct HistoryItem *hi; + int x, y; + + hi = find_history(c); + + if (hi != NULL && !hi->placed) { + hi->placed = TRUE; + if (ob_state != State_Starting) { + x = hi->x; + y = hi->y; + + frame_frame_gravity(c->frame, &x, &y); /* get where the client + should be */ + client_configure(c, Corner_TopLeft, x, y, + c->area.width, c->area.height, + TRUE, TRUE); + } + return TRUE; + } + return FALSE; } + +static void strip_tabs(char *s) +{ + while (*s != '\0') { + if (*s == '\t') + *s = ' '; + ++s; + } +} + +static void set_history(Client *c) +{ + struct HistoryItem *hi; + + hi = find_history(c); + + if (hi == NULL) { + hi = g_new(struct HistoryItem, 1); + history = g_slist_append(history, hi); + hi->name = g_strdup(c->name); + strip_tabs(hi->name); + hi->class = g_strdup(c->class); + strip_tabs(hi->class); + hi->role = g_strdup(c->role); + strip_tabs(hi->role); + } + + hi->x = c->frame->area.x; + hi->y = c->frame->area.y; + hi->placed = FALSE; +} + +static void event(ObEvent *e, void *foo) +{ + g_assert(e->type == Event_Client_Destroy); + + set_history(e->data.c.client); +} + +static void save_history() +{ + GError *err = NULL; + GIOChannel *io; + GString *buf; + GSList *it; + struct HistoryItem *hi; + gsize ret; + + io = g_io_channel_new_file(history_path, "w", &err); + if (io != NULL) { + for (it = history; it != NULL; it = it->next) { + hi = it->data; + buf = g_string_sized_new(0); + buf=g_string_append(buf, hi->name); + g_string_append_c(buf, '\t'); + buf=g_string_append(buf, hi->class); + g_string_append_c(buf, '\t'); + buf=g_string_append(buf, hi->role); + g_string_append_c(buf, '\t'); + g_string_append_printf(buf, "%d", hi->x); + buf=g_string_append_c(buf, '\t'); + g_string_append_printf(buf, "%d", hi->y); + buf=g_string_append_c(buf, '\n'); + if (g_io_channel_write_chars(io, buf->str, buf->len, &ret, &err) != + G_IO_STATUS_NORMAL) + break; + g_string_free(buf, TRUE); + } + g_io_channel_unref(io); + } +} + +static void load_history() +{ + GError *err = NULL; + GIOChannel *io; + char *buf = NULL; + char *b, *c; + struct HistoryItem *hi = NULL; + + io = g_io_channel_new_file(history_path, "r", &err); + if (io != NULL) { + while (g_io_channel_read_line(io, &buf, NULL, NULL, &err) == + G_IO_STATUS_NORMAL) { + hi = g_new0(struct HistoryItem, 1); + + b = buf; + if ((c = strchr(b, '\t')) == NULL) break; + *c = '\0'; + hi->name = g_strdup(b); + + b = c + 1; + if ((c = strchr(b, '\t')) == NULL) break; + *c = '\0'; + hi->class = g_strdup(b); + + b = c + 1; + if ((c = strchr(b, '\t')) == NULL) break; + *c = '\0'; + hi->role = g_strdup(b); + + b = c + 1; + if ((c = strchr(b, '\t')) == NULL) break; + *c = '\0'; + hi->x = atoi(b); + + b = c + 1; + if ((c = strchr(b, '\n')) == NULL) break; + *c = '\0'; + hi->y = atoi(b); + + hi->placed = FALSE; + + g_free(buf); + buf = NULL; + + history = g_slist_append(history, hi); + hi = NULL; + } + g_io_channel_unref(io); + } + + g_free(buf); + + if (hi != NULL) { + g_free(hi->name); + g_free(hi->class); + g_free(hi->role); + } + g_free(hi); +} + +void history_startup() +{ + char *path; + + history = NULL; + + path = g_build_filename(g_get_home_dir(), ".openbox", "history", NULL); + history_path = g_strdup_printf("%s.%d", path, ob_screen); + g_free(path); + + load_history(); /* load from the historydb file */ + + dispatch_register(Event_Client_Destroy, (EventHandler)event, NULL); +} + +void history_shutdown() +{ + GSList *it; + + save_history(); /* save to the historydb file */ + for (it = history; it != NULL; it = it->next) + g_free(it->data); + g_slist_free(history); + + dispatch_register(0, (EventHandler)event, NULL); + + g_free(history_path); +}