]> Dogcows Code - chaz/openbox/commitdiff
history placement works. loads. saves. woot.
authorDana Jansens <danakj@orodu.net>
Sat, 22 Mar 2003 05:56:32 +0000 (05:56 +0000)
committerDana Jansens <danakj@orodu.net>
Sat, 22 Mar 2003 05:56:32 +0000 (05:56 +0000)
plugins/placement/history.c
plugins/placement/placement.c

index d979bb1f4de77202be2972e181e08c00be2c1ed4..fbfbf2529cdd43714c76f72c8a241113fda6bef4 100644 (file)
+#include "../../kernel/openbox.h"
+#include "../../kernel/dispatch.h"
 #include "../../kernel/frame.h"
 #include "../../kernel/client.h"
 #include <glib.h>
+#include <string.h>
+#ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+#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);
+}
index 8a5d995a620735ad2ee33ef992cd76d792ad0e95..2627eb84358fd27fea6a808ddf22184cb970b168 100644 (file)
@@ -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;
 
This page took 0.029773 seconds and 4 git commands to generate.