From c3628a36eda55cb10545abd1e90365b23b6fbfa1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sat, 22 Mar 2003 05:56:32 +0000 Subject: [PATCH] history placement works. loads. saves. woot. --- plugins/placement/history.c | 220 +++++++++++++++++++++++++++++++++- plugins/placement/placement.c | 4 +- 2 files changed, 218 insertions(+), 6 deletions(-) diff --git a/plugins/placement/history.c b/plugins/placement/history.c index d979bb1f..fbfbf252 100644 --- a/plugins/placement/history.c +++ b/plugins/placement/history.c @@ -1,16 +1,228 @@ +#include "../../kernel/openbox.h" +#include "../../kernel/dispatch.h" #include "../../kernel/frame.h" #include "../../kernel/client.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); +} diff --git a/plugins/placement/placement.c b/plugins/placement/placement.c index 8a5d995a..2627eb84 100644 --- a/plugins/placement/placement.c +++ b/plugins/placement/placement.c @@ -14,6 +14,8 @@ static void place_random(Client *c) int x, y; Rect *area; + if (ob_state == State_Starting) return; + area = screen_area(c->desktop); l = area->x; @@ -35,8 +37,6 @@ static void event(ObEvent *e, void *foo) { g_assert(e->type == Event_Client_New); - if (ob_state == State_Starting) return; - /* requested a position */ if (e->data.c.client->positioned) return; -- 2.39.2