From: <sa...@us...> - 2006-11-30 05:52:21
|
Revision: 17851 http://svn.sourceforge.net/gaim/?rev=17851&view=rev Author: sadrul Date: 2006-11-29 21:52:21 -0800 (Wed, 29 Nov 2006) Log Message: ----------- 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 Modified Paths: -------------- trunk/console/libgnt/gntstyle.c trunk/console/libgnt/gntstyle.h trunk/console/libgnt/gntwm.c trunk/console/libgnt/gntwm.h trunk/console/libgnt/wms/s.c Modified: trunk/console/libgnt/gntstyle.c =================================================================== --- trunk/console/libgnt/gntstyle.c 2006-11-30 02:01:49 UTC (rev 17850) +++ trunk/console/libgnt/gntstyle.c 2006-11-30 05:52:21 UTC (rev 17851) @@ -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) Modified: trunk/console/libgnt/gntstyle.h =================================================================== --- trunk/console/libgnt/gntstyle.h 2006-11-30 02:01:49 UTC (rev 17850) +++ trunk/console/libgnt/gntstyle.h 2006-11-30 05:52:21 UTC (rev 17851) @@ -6,6 +6,7 @@ GNT_STYLE_COLOR = 1, GNT_STYLE_MOUSE = 2, GNT_STYLE_WM = 3, + GNT_STYLE_REMPOS = 4, GNT_STYLES } GntStyle; Modified: trunk/console/libgnt/gntwm.c =================================================================== --- trunk/console/libgnt/gntwm.c 2006-11-30 02:01:49 UTC (rev 17850) +++ trunk/console/libgnt/gntwm.c 2006-11-30 05:52:21 UTC (rev 17851) @@ -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,32 +127,106 @@ 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) { GntWM *wm = GNT_WM(instance); @@ -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); } Modified: trunk/console/libgnt/gntwm.h =================================================================== --- trunk/console/libgnt/gntwm.h 2006-11-30 02:01:49 UTC (rev 17850) +++ trunk/console/libgnt/gntwm.h 2006-11-30 05:52:21 UTC (rev 17851) @@ -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; Modified: trunk/console/libgnt/wms/s.c =================================================================== --- trunk/console/libgnt/wms/s.c 2006-11-30 02:01:49 UTC (rev 17850) +++ trunk/console/libgnt/wms/s.c 2006-11-30 05:52:21 UTC (rev 17851) @@ -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); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |