# HG changeset patch # User Sadrul Habib Chowdhury # Date 1164865941 0 # Node ID d08d7b7375c7a15bfd5f2c03b5b05772f2b8a558 # Parent 0f950428ef41b4587a07fcb13c2f54ef9c023933 [gaim-migrate @ 17851] Remember the positions of the windows depending on the titles. Moving all the chat windows to places was getting really really annoying. If you don't want it, turn it off by setting "remember_position" to 0 in .gntrc committer: Tailor Script diff -r 0f950428ef41 -r d08d7b7375c7 console/libgnt/gntstyle.c --- a/console/libgnt/gntstyle.c Thu Nov 30 02:01:49 2006 +0000 +++ b/console/libgnt/gntstyle.c Thu Nov 30 05:52:21 2006 +0000 @@ -282,6 +282,7 @@ {"customcolor", GNT_STYLE_COLOR}, {"mouse", GNT_STYLE_MOUSE}, {"wm", GNT_STYLE_WM}, + {"remember_position", GNT_STYLE_REMPOS}, {NULL, 0}}; if (error) diff -r 0f950428ef41 -r d08d7b7375c7 console/libgnt/gntstyle.h --- a/console/libgnt/gntstyle.h Thu Nov 30 02:01:49 2006 +0000 +++ b/console/libgnt/gntstyle.h Thu Nov 30 05:52:21 2006 +0000 @@ -6,6 +6,7 @@ GNT_STYLE_COLOR = 1, GNT_STYLE_MOUSE = 2, GNT_STYLE_WM = 3, + GNT_STYLE_REMPOS = 4, GNT_STYLES } GntStyle; diff -r 0f950428ef41 -r d08d7b7375c7 console/libgnt/gntwm.c --- a/console/libgnt/gntwm.c Thu Nov 30 02:01:49 2006 +0000 +++ b/console/libgnt/gntwm.c Thu Nov 30 05:52:21 2006 +0000 @@ -42,6 +42,9 @@ static void gnt_wm_give_focus(GntWM *wm, GntWidget *widget); static void update_window_in_list(GntWM *wm, GntWidget *wid); +static gboolean write_already(gpointer data); +static int write_timeout; + static GList * g_list_bring_to_front(GList *list, gpointer data) { @@ -124,31 +127,105 @@ doupdate(); return TRUE; } + +static gboolean +sanitize_position(GntWidget *widget, int *x, int *y) +{ + int X_MAX = getmaxx(stdscr); + int Y_MAX = getmaxy(stdscr) - 1; + int w, h; + int nx, ny; + gboolean changed = FALSE; + + gnt_widget_get_size(widget, &w, &h); + if (x) { + if (*x + w > X_MAX) { + nx = MAX(0, X_MAX - w); + if (nx != *x) { + *x = nx; + changed = TRUE; + } + } + } + if (y) { + if (*y + h > Y_MAX) { + ny = MAX(0, Y_MAX - h); + if (ny != *y) { + *y = ny; + changed = TRUE; + } + } + } + return changed; +} + static void refresh_node(GntWidget *widget, GntNode *node, gpointer null) { int x, y, w, h; - int nw, nh, nx, ny; + int nw, nh; int X_MAX = getmaxx(stdscr); int Y_MAX = getmaxy(stdscr) - 1; gnt_widget_get_position(widget, &x, &y); gnt_widget_get_size(widget, &w, &h); - nx = x; ny = y; - if (x + w >= X_MAX) - nx = MAX(0, X_MAX - w); - if (y + h >= Y_MAX) - ny = MAX(0, Y_MAX - h); - if (x != nx || y != ny) - gnt_screen_move_widget(widget, nx, ny); + if (sanitize_position(widget, &x, &y)) + gnt_screen_move_widget(widget, x, y); nw = MIN(w, X_MAX); nh = MIN(h, Y_MAX); if (nw != w || nh != h) gnt_screen_resize_widget(widget, nw, nh); } + +static void +read_window_positions(GntWM *wm) +{ +#if GLIB_CHECK_VERSION(2,6,0) + GKeyFile *gfile = g_key_file_new(); + char *filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL); + GError *error = NULL; + char **keys; + int nk; + + if (!g_key_file_load_from_file(gfile, filename, G_KEY_FILE_NONE, &error)) { + g_printerr("GntWM: %s\n", error->message); + g_error_free(error); + g_free(filename); + return; + } + + keys = g_key_file_get_keys(gfile, "positions", &nk, &error); + if (error) { + g_printerr("GntWM: %s\n", error->message); + g_error_free(error); + error = NULL; + } else { + while (nk--) { + char *title = keys[nk]; + int l; + char **coords = g_key_file_get_string_list(gfile, "positions", title, &l, NULL); + if (l == 2) { + int x = atoi(coords[0]); + int y = atoi(coords[1]); + GntPosition *p = g_new0(GntPosition, 1); + p->x = x; + p->y = y; + g_hash_table_replace(wm->positions, g_strdup(title + 1), p); + } else { + g_printerr("GntWM: Invalid number of arguments for positioing a window.\n"); + } + g_strfreev(coords); + } + g_strfreev(keys); + } + + g_free(filename); +#endif +} + static void gnt_wm_init(GTypeInstance *instance, gpointer class) { @@ -159,6 +236,9 @@ wm->windows = NULL; wm->actions = NULL; wm->nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); + wm->positions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + if (gnt_style_get_bool(GNT_STYLE_REMPOS, TRUE)) + read_window_positions(wm); } static void @@ -645,6 +725,8 @@ wm_quit(GntBindable *bindable, GList *list) { GntWM *wm = GNT_WM(bindable); + if (write_timeout) + write_already(wm); g_main_loop_quit(wm->loop); return TRUE; } @@ -905,6 +987,16 @@ return; } + if (GNT_IS_BOX(widget)) { + const char *title = GNT_BOX(widget)->title; + GntPosition *p = NULL; + if (title && (p = g_hash_table_lookup(wm->positions, title)) != NULL) { + sanitize_position(widget, &p->x, &p->y); + gnt_widget_set_position(widget, p->x, p->y); + mvwin(widget->window, p->y, p->x); + } + } + g_signal_emit(wm, signals[SIG_NEW_WIN], 0, widget); g_signal_emit(wm, signals[SIG_DECORATE_WIN], 0, widget); @@ -1088,6 +1180,46 @@ update_screen(wm); } +static void +write_gdi(gpointer key, gpointer value, gpointer data) +{ + GntPosition *p = value; + fprintf(data, ".%s = %d;%d\n", key, p->x, p->y); +} + +static gboolean +write_already(gpointer data) +{ + GntWM *wm = data; + FILE *file; + char *filename; + + filename = g_build_filename(g_get_home_dir(), ".gntpositions", NULL); + + file = fopen(filename, "wb"); + if (file == NULL) { + g_printerr("GntWM: error opening file to save positions\n"); + } else { + fprintf(file, "[positions]\n"); + g_hash_table_foreach(wm->positions, write_gdi, file); + fclose(file); + } + + g_free(filename); + g_source_remove(write_timeout); + write_timeout = 0; + return FALSE; +} + +static void +write_positions_to_file(GntWM *wm) +{ + if (write_timeout) { + g_source_remove(write_timeout); + } + write_timeout = g_timeout_add(10000, write_already, wm); +} + void gnt_wm_move_window(GntWM *wm, GntWidget *widget, int x, int y) { gboolean ret = TRUE; @@ -1107,6 +1239,17 @@ move_panel(node->panel, y, x); g_signal_emit(wm, signals[SIG_MOVED], 0, node); + if (gnt_style_get_bool(GNT_STYLE_REMPOS, TRUE) && GNT_IS_BOX(widget)) { + const char *title = GNT_BOX(widget)->title; + if (title) { + GntPosition *p = g_new0(GntPosition, 1); + GntWidget *wid = node->me; + p->x = wid->priv.x; + p->y = wid->priv.y; + g_hash_table_replace(wm->positions, g_strdup(title), p); + write_positions_to_file(wm); + } + } update_screen(wm); } diff -r 0f950428ef41 -r d08d7b7375c7 console/libgnt/gntwm.h --- a/console/libgnt/gntwm.h Thu Nov 30 02:01:49 2006 +0000 +++ b/console/libgnt/gntwm.h Thu Nov 30 05:52:21 2006 +0000 @@ -27,6 +27,12 @@ typedef struct _GntWM GntWM; +typedef struct _GnPosition +{ + int x; + int y; +} GntPosition; + /** * An application can register actions which will show up in a 'start-menu' like popup */ @@ -73,6 +79,8 @@ GntKeyPressMode mode; + GHashTable *positions; + void *res1; void *res2; void *res3; diff -r 0f950428ef41 -r d08d7b7375c7 console/libgnt/wms/s.c --- a/console/libgnt/wms/s.c Thu Nov 30 02:01:49 2006 +0000 +++ b/console/libgnt/wms/s.c Thu Nov 30 05:52:21 2006 +0000 @@ -97,19 +97,16 @@ mvwin(win->window, y, x); gnt_widget_set_size(win, -1, h + 2); /* XXX: Why is the +2 needed here? -- sadrul */ - } else if (name && strcmp(name, "conversation-window") == 0) { - /* Put the conversation windows to the far-right */ - x = maxx - w; - y = 0; - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); } else if (!GNT_WIDGET_IS_FLAG_SET(win, GNT_WIDGET_TRANSIENT)) { - /* In the middle of the screen */ - x = (maxx - w) / 2; - y = (maxy - h) / 2; + const char *title = GNT_BOX(win)->title; + if (title == NULL || !g_hash_table_lookup(wm->positions, title)) { + /* In the middle of the screen */ + x = (maxx - w) / 2; + y = (maxy - h) / 2; - gnt_widget_set_position(win, x, y); - mvwin(win->window, y, x); + gnt_widget_set_position(win, x, y); + mvwin(win->window, y, x); + } } } org_new_window(wm, win);