Mercurial > pidgin.yaz
changeset 16691:3af867ef5a15
propagate from branch 'im.pidgin.pidgin' (head a35e9c6965a0723281ab3a62044581a55d2e59a2)
to branch 'im.pidgin.finch.workspaces' (head c2b0e8d280a1803b8344154667645fadb3a080db)
author | Richard Nelson <wabz@pidgin.im> |
---|---|
date | Sun, 29 Apr 2007 01:09:18 +0000 |
parents | ee8bb9b5acb8 (current diff) 5acee0788697 (diff) |
children | 8eed567eee39 |
files | PROGRAMMING_NOTES finch/libgnt/gntwm.c finch/libgnt/wms/s.c libpurple/version.h pidgin/plugins/perl/common/GtkUI.pm pidgin/plugins/perl/common/GtkUI.xs |
diffstat | 9 files changed, 711 insertions(+), 164 deletions(-) [+] |
line wrap: on
line diff
--- a/finch/libgnt/Makefile.am Sun Apr 29 00:15:08 2007 +0000 +++ b/finch/libgnt/Makefile.am Sun Apr 29 01:09:18 2007 +0000 @@ -1,6 +1,6 @@ EXTRA_DIST=genmarshal -SUBDIRS = . wms +SUBDIRS = . pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = gnt.pc @@ -32,6 +32,7 @@ gntutils.c \ gntwindow.c \ gntwm.c \ + gntws.c \ gntmain.c libgnt_la_headers = \ @@ -58,6 +59,7 @@ gntutils.h \ gntwindow.h \ gntwm.h \ + gntws.h \ gnt.h CLEANFILES = \
--- a/finch/libgnt/gntmain.c Sun Apr 29 00:15:08 2007 +0000 +++ b/finch/libgnt/gntmain.c Sun Apr 29 01:09:18 2007 +0000 @@ -91,7 +91,7 @@ GntWidget *widget = NULL; PANEL *p = NULL; - if (!wm->ordered || buffer[0] != 27) + if (!wm->cws->ordered || buffer[0] != 27) return FALSE; buffer++; @@ -147,7 +147,7 @@ if (event == GNT_LEFT_MOUSE_DOWN && widget && widget != wm->_list.window && !GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { - if (widget != wm->ordered->data) { + if (widget != wm->cws->ordered->data) { gnt_wm_raise_window(wm, widget); } if (y == widget->priv.y) { @@ -158,7 +158,7 @@ } else if (event == GNT_MOUSE_UP) { if (button == MOUSE_NONE && y == getmaxy(stdscr) - 1) { /* Clicked on the taskbar */ - int n = g_list_length(wm->list); + int n = g_list_length(wm->cws->list); if (n) { int width = getmaxx(stdscr) / n; gnt_bindable_perform_action_named(GNT_BINDABLE(wm), "switch-window-n", x/width, NULL); @@ -437,7 +437,7 @@ if (widget == wm->_list.window) return TRUE; - if (wm->ordered && wm->ordered->data == widget) { + if (wm->cws->ordered && wm->cws->ordered->data == widget) { if (GNT_IS_BOX(widget) && (GNT_BOX(widget)->active == w || widget == w)) return TRUE; @@ -450,7 +450,7 @@ while (widget->parent) widget = widget->parent; - if (wm->ordered && wm->ordered->data == widget) + if (wm->cws->ordered && wm->cws->ordered->data == widget) return; GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_URGENT);
--- a/finch/libgnt/gntstyle.c Sun Apr 29 00:15:08 2007 +0000 +++ b/finch/libgnt/gntstyle.c Sun Apr 29 01:09:18 2007 +0000 @@ -1,9 +1,13 @@ #include "gntstyle.h" #include "gntcolors.h" +#include "gntws.h" #include <ctype.h> +#include <glib/gprintf.h> #include <string.h> +#define MAX_WORKSPACES 99 + #if GLIB_CHECK_VERSION(2,6,0) static GKeyFile *gkfile; #endif @@ -87,6 +91,45 @@ return (char *)gnt_key_translate(key); } +void gnt_style_read_workspaces(GntWM *wm) +{ +#if GLIB_CHECK_VERSION(2,6,0) + int i; + gchar *name; + gsize c; + + for (i = 1; i < MAX_WORKSPACES; ++i) { + int j; + GntWS *ws; + gchar **titles; + char *group = calloc(12, 1); + g_sprintf(group, "Workspace-%d", i); + name = g_key_file_get_value(gkfile, group, "name", NULL); + if (!name) + return; + + ws = g_object_new(GNT_TYPE_WS, NULL); + gnt_ws_set_name(ws, name); + gnt_wm_add_workspace(wm, ws); + g_free(name); + + titles = g_key_file_get_string_list(gkfile, group, "window-names", &c, NULL); + if (titles) { + for (j = 0; j < c; ++j) + g_hash_table_replace(wm->name_places, g_strdup(titles[j]), ws); + g_strfreev(titles); + } + + titles = g_key_file_get_string_list(gkfile, group, "window-titles", &c, NULL); + if (titles) { + for (j = 0; j < c; ++j) + g_hash_table_replace(wm->title_places, g_strdup(titles[j]), ws); + g_strfreev(titles); + } + g_free(group); + } +#endif +} void gnt_style_read_actions(GType type, GntBindableClass *klass) { #if GLIB_CHECK_VERSION(2,6,0)
--- a/finch/libgnt/gntstyle.h Sun Apr 29 00:15:08 2007 +0000 +++ b/finch/libgnt/gntstyle.h Sun Apr 29 01:09:18 2007 +0000 @@ -1,4 +1,5 @@ #include "gnt.h" +#include "gntwm.h" typedef enum { @@ -21,6 +22,8 @@ void gnt_style_read_actions(GType type, GntBindableClass *klass); +void gnt_style_read_workspaces(GntWM *wm); + void gnt_init_styles(void); void gnt_uninit_styles(void);
--- a/finch/libgnt/gntwm.c Sun Apr 29 00:15:08 2007 +0000 +++ b/finch/libgnt/gntwm.c Sun Apr 29 01:09:18 2007 +0000 @@ -6,6 +6,8 @@ #include "config.h" #include <ctype.h> +#include <glib/gprintf.h> +#include <gmodule.h> #include <stdlib.h> #include <string.h> #include <time.h> @@ -47,11 +49,14 @@ static void gnt_wm_give_focus(GntWM *wm, GntWidget *widget); static void update_window_in_list(GntWM *wm, GntWidget *wid); static void shift_window(GntWM *wm, GntWidget *widget, int dir); +static gboolean workspace_next(GntBindable *wm, GList *n); +static gboolean workspace_prev(GntBindable *wm, GList *n); static gboolean write_already(gpointer data); static int write_timeout; static time_t last_active_time; static gboolean idle_update; +static GList *act = NULL; /* list of WS with unseen activitiy */ static GList * g_list_bring_to_front(GList *list, gpointer data) @@ -70,61 +75,8 @@ g_free(node); } -static void -draw_taskbar(GntWM *wm, gboolean reposition) -{ - static WINDOW *taskbar = NULL; - GList *iter; - int n, width = 0; - int i; - - if (taskbar == NULL) { - taskbar = newwin(1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0); - } else if (reposition) { - int Y_MAX = getmaxy(stdscr) - 1; - mvwin(taskbar, Y_MAX, 0); - } - - wbkgdset(taskbar, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); - werase(taskbar); - - n = g_list_length(wm->list); - if (n) - width = getmaxx(stdscr) / n; - - for (i = 0, iter = wm->list; iter; iter = iter->next, i++) - { - GntWidget *w = iter->data; - int color; - const char *title; - - if (w == wm->ordered->data) { - /* This is the current window in focus */ - color = GNT_COLOR_TITLE; - } else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_URGENT)) { - /* This is a window with the URGENT hint set */ - color = GNT_COLOR_URGENT; - } else { - color = GNT_COLOR_NORMAL; - } - wbkgdset(taskbar, '\0' | COLOR_PAIR(color)); - if (iter->next) - mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), width); - else - mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), getmaxx(stdscr) - width * i); - title = GNT_BOX(w)->title; - mvwprintw(taskbar, 0, width * i, "%s", title ? title : "<gnt>"); - if (i) - mvwaddch(taskbar, 0, width *i - 1, ACS_VLINE | A_STANDOUT | COLOR_PAIR(GNT_COLOR_NORMAL)); - - update_window_in_list(wm, w); - } - - wrefresh(taskbar); -} - -static void -copy_win(GntWidget *widget, GntNode *node) +void +gnt_wm_copy_win(GntWidget *widget, GntNode *node) { WINDOW *src, *dst; int shadow; @@ -136,6 +88,32 @@ copywin(src, dst, node->scroll, 0, 0, 0, getmaxy(dst) - 1, getmaxx(dst) - 1, 0); } +static void +update_act_msg() +{ + GntWidget *label; + GList *iter; + static GntWidget *message = NULL; + GString *text = g_string_new("act: "); + if (message) + gnt_widget_destroy(message); + if (g_list_length(act) == 0) + return; + for (iter = act; iter; iter = iter->next) { + GntWS *ws = iter->data; + g_string_sprintfa(text, "%s, ", gnt_ws_get_name(ws)); + } + g_string_erase(text, text->len - 2, 2); + message = gnt_vbox_new(FALSE); + label = gnt_label_new_with_format(text->str, GNT_TEXT_FLAG_BOLD | GNT_TEXT_FLAG_HIGHLIGHT); + GNT_WIDGET_UNSET_FLAGS(GNT_BOX(message), GNT_WIDGET_CAN_TAKE_FOCUS); + GNT_WIDGET_SET_FLAGS(GNT_BOX(message), GNT_WIDGET_TRANSIENT); + gnt_box_add_widget(GNT_BOX(message), label); + gnt_widget_set_name(message, "wm-message"); + gnt_widget_set_position(message, 0, 0); + gnt_widget_draw(message); + g_string_free(text, TRUE); +} static gboolean update_screen(GntWM *wm) { @@ -265,9 +243,19 @@ gnt_wm_init(GTypeInstance *instance, gpointer class) { GntWM *wm = GNT_WM(instance); - wm->list = NULL; - wm->ordered = NULL; + wm->workspaces = NULL; + wm->name_places = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + wm->title_places = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + gnt_style_read_workspaces(wm); + if (wm->workspaces == NULL) { + wm->cws = g_object_new(GNT_TYPE_WS, NULL); + gnt_ws_set_name(wm->cws, "default"); + gnt_wm_add_workspace(wm, wm->cws); + } else { + wm->cws = wm->workspaces->data; + } wm->event_stack = FALSE; + wm->tagged = NULL; wm->windows = NULL; wm->actions = NULL; wm->nodes = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_node); @@ -276,6 +264,7 @@ read_window_positions(wm); g_timeout_add(IDLE_CHECK_INTERVAL * 1000, check_idle, NULL); time(&last_active_time); + gnt_wm_switch_workspace(wm, 0); } static void @@ -287,23 +276,23 @@ if (wm->_list.window || wm->menu) return; - if (!wm->ordered || !wm->ordered->next) + if (!wm->cws->ordered || !wm->cws->ordered->next) return; - w = wm->ordered->data; - pos = g_list_index(wm->list, w); + w = wm->cws->ordered->data; + pos = g_list_index(wm->cws->list, w); pos += direction; if (pos < 0) - wid = g_list_last(wm->list)->data; - else if (pos >= g_list_length(wm->list)) - wid = wm->list->data; + wid = g_list_last(wm->cws->list)->data; + else if (pos >= g_list_length(wm->cws->list)) + wid = wm->cws->list->data; else if (pos >= 0) - wid = g_list_nth_data(wm->list, pos); + wid = g_list_nth_data(wm->cws->list, pos); - wm->ordered = g_list_bring_to_front(wm->ordered, wid); + wm->cws->ordered = g_list_bring_to_front(wm->cws->ordered, wid); - gnt_wm_raise_window(wm, wm->ordered->data); + gnt_wm_raise_window(wm, wm->cws->ordered->data); if (w != wid) { gnt_widget_set_focus(w, FALSE); @@ -334,7 +323,7 @@ GList *l; int n; - if (!wm->ordered) + if (!wm->cws->ordered) return TRUE; if (list) @@ -342,9 +331,9 @@ else n = 0; - w = wm->ordered->data; + w = wm->cws->ordered->data; - if ((l = g_list_nth(wm->list, n)) != NULL) + if ((l = g_list_nth(wm->cws->list, n)) != NULL) { gnt_wm_raise_window(wm, l->data); } @@ -363,17 +352,17 @@ GntWidget *window; GntNode *node; - if (!wm->ordered) + if (!wm->cws->ordered) return TRUE; - window = wm->ordered->data; + window = wm->cws->ordered->data; node = g_hash_table_lookup(wm->nodes, window); if (!node) return TRUE; if (node->scroll) { node->scroll--; - copy_win(window, node); + gnt_wm_copy_win(window, node); update_screen(wm); } return TRUE; @@ -387,10 +376,10 @@ GntNode *node; int w, h; - if (!wm->ordered) + if (!wm->cws->ordered) return TRUE; - window = wm->ordered->data; + window = wm->cws->ordered->data; node = g_hash_table_lookup(wm->nodes, window); if (!node) return TRUE; @@ -398,7 +387,7 @@ gnt_widget_get_size(window, &w, &h); if (h - node->scroll > getmaxy(node->window)) { node->scroll++; - copy_win(window, node); + gnt_wm_copy_win(window, node); update_screen(wm); } return TRUE; @@ -412,8 +401,8 @@ if (wm->_list.window) return TRUE; - if (wm->ordered) { - gnt_widget_destroy(wm->ordered->data); + if (wm->cws->ordered) { + gnt_widget_destroy(wm->cws->ordered->data); } return TRUE; @@ -426,10 +415,10 @@ GntWidget *widget, *tree, *win, *active; char *title; - if (!wm->ordered) + if (!wm->cws->ordered) return TRUE; - widget = wm->ordered->data; + widget = wm->cws->ordered->data; if (!GNT_IS_BOX(widget)) return TRUE; active = GNT_BOX(widget)->active; @@ -476,85 +465,126 @@ static void window_list_activate(GntTree *tree, GntWM *wm) { - GntWidget *widget = gnt_tree_get_selection_data(GNT_TREE(tree)); + GntBindable *sel = gnt_tree_get_selection_data(GNT_TREE(tree)); - if (!wm->ordered || !widget) + gnt_widget_destroy(wm->_list.window); + + if (!sel) return; - gnt_widget_destroy(wm->_list.window); - gnt_wm_raise_window(wm, widget); + if (GNT_IS_WS(sel)) { + gnt_wm_switch_workspace(wm, g_list_index(wm->workspaces, sel)); + } else { + GntNode *node = g_hash_table_lookup(wm->nodes, sel); + if (node && node->ws != wm->cws) + gnt_wm_switch_workspace(wm, g_list_index(wm->workspaces, node->ws)); + gnt_wm_raise_window(wm, GNT_WIDGET(sel)); + } } static void -populate_window_list(GntWM *wm) +populate_window_list(GntWM *wm, gboolean workspace) { GList *iter; GntTree *tree = GNT_TREE(wm->windows->tree); - for (iter = wm->list; iter; iter = iter->next) { - GntBox *box = GNT_BOX(iter->data); + if (!workspace) { + for (iter = wm->cws->list; iter; iter = iter->next) { + GntBox *box = GNT_BOX(iter->data); - gnt_tree_add_row_last(tree, box, - gnt_tree_create_row(tree, box->title), NULL); - update_window_in_list(wm, GNT_WIDGET(box)); + gnt_tree_add_row_last(tree, box, + gnt_tree_create_row(tree, box->title), NULL); + update_window_in_list(wm, GNT_WIDGET(box)); + } + } else { + GList *ws = wm->workspaces; + for (; ws; ws = ws->next) { + gnt_tree_add_row_last(tree, ws->data, + gnt_tree_create_row(tree, gnt_ws_get_name(GNT_WS(ws->data))), NULL); + for (iter = GNT_WS(ws->data)->list; iter; iter = iter->next) { + GntBox *box = GNT_BOX(iter->data); + + gnt_tree_add_row_last(tree, box, + gnt_tree_create_row(tree, box->title), ws->data); + update_window_in_list(wm, GNT_WIDGET(box)); + } + } } } static gboolean window_list_key_pressed(GntWidget *widget, const char *text, GntWM *wm) { - if (text[1] == 0 && wm->ordered) { - GntWidget *sel = gnt_tree_get_selection_data(GNT_TREE(widget)); + if (text[1] == 0 && wm->cws->ordered) { + GntBindable *sel = gnt_tree_get_selection_data(GNT_TREE(widget)); switch (text[0]) { case '-': case ',': - shift_window(wm, sel, -1); + if (GNT_IS_WS(sel)) { + /* reorder the workspace. */ + } else + shift_window(wm, GNT_WIDGET(sel), -1); break; case '=': case '.': - shift_window(wm, sel, 1); + if (GNT_IS_WS(sel)) { + /* reorder the workspace. */ + } else + shift_window(wm, GNT_WIDGET(sel), 1); break; default: return FALSE; } gnt_tree_remove_all(GNT_TREE(widget)); - populate_window_list(wm); + populate_window_list(wm, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "workspace"))); gnt_tree_set_selected(GNT_TREE(widget), sel); return TRUE; } return FALSE; } +static void +list_of_windows(GntWM *wm, gboolean workspace) +{ + GntWidget *tree, *win; + setup__list(wm); + wm->windows = &wm->_list; + + win = wm->windows->window; + tree = wm->windows->tree; + + gnt_box_set_title(GNT_BOX(win), workspace ? "Workspace List" : "Window List"); + + populate_window_list(wm, workspace); + + if (wm->cws->ordered) + gnt_tree_set_selected(GNT_TREE(tree), wm->cws->ordered->data); + else if (workspace) + gnt_tree_set_selected(GNT_TREE(tree), wm->cws); + + g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), wm); + g_signal_connect(G_OBJECT(tree), "key_pressed", G_CALLBACK(window_list_key_pressed), wm); + g_object_set_data(G_OBJECT(tree), "workspace", GINT_TO_POINTER(workspace)); + + gnt_tree_set_col_width(GNT_TREE(tree), 0, getmaxx(stdscr) / 3); + gnt_widget_set_size(tree, 0, getmaxy(stdscr) / 2); + gnt_widget_set_position(win, getmaxx(stdscr) / 3, getmaxy(stdscr) / 4); + + gnt_widget_show(win); +} + static gboolean window_list(GntBindable *bindable, GList *null) { GntWM *wm = GNT_WM(bindable); - GntWidget *tree, *win; if (wm->_list.window || wm->menu) return TRUE; - if (!wm->ordered) + if (!wm->cws->ordered) return TRUE; - setup__list(wm); - wm->windows = &wm->_list; - - win = wm->windows->window; - tree = wm->windows->tree; - - gnt_box_set_title(GNT_BOX(win), "Window List"); - - populate_window_list(wm); + list_of_windows(wm, FALSE); - gnt_tree_set_selected(GNT_TREE(tree), wm->ordered->data); - g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(window_list_activate), wm); - g_signal_connect(G_OBJECT(tree), "key_pressed", G_CALLBACK(window_list_key_pressed), wm); - - gnt_tree_set_col_width(GNT_TREE(tree), 0, getmaxx(stdscr) / 3); - gnt_widget_set_size(tree, 0, getmaxy(stdscr) / 2); - gnt_widget_set_position(win, getmaxx(stdscr) / 3, getmaxy(stdscr) / 4); - - gnt_widget_show(win); return TRUE; } @@ -673,7 +703,7 @@ static void shift_window(GntWM *wm, GntWidget *widget, int dir) { - GList *all = wm->list; + GList *all = wm->cws->list; GList *list = g_list_find(all, widget); int length, pos; if (!list) @@ -693,8 +723,8 @@ all = g_list_insert(all, widget, pos); all = g_list_delete_link(all, list); - wm->list = all; - draw_taskbar(wm, FALSE); + wm->cws->list = all; + gnt_ws_draw_taskbar(wm->cws, FALSE); } static gboolean @@ -704,7 +734,7 @@ if (wm->_list.window) return TRUE; - shift_window(wm, wm->ordered->data, -1); + shift_window(wm, wm->cws->ordered->data, -1); return TRUE; } @@ -715,7 +745,7 @@ if (wm->_list.window) return TRUE; - shift_window(wm, wm->ordered->data, 1); + shift_window(wm, wm->cws->ordered->data, 1); return TRUE; } @@ -839,7 +869,7 @@ for (i = 0; i < h; i += reverse_char(d, i, 0, set)); for (i = 0; i < h; i += reverse_char(d, i, w-1, set)); - copy_win(win, g_hash_table_lookup(wm->nodes, win)); + gnt_wm_copy_win(win, g_hash_table_lookup(wm->nodes, win)); update_screen(wm); } @@ -849,11 +879,11 @@ GntWM *wm = GNT_WM(bindable); if (wm->_list.window || wm->menu) return TRUE; - if (!wm->ordered) + if (!wm->cws->ordered) return TRUE; wm->mode = GNT_KP_MODE_MOVE; - window_reverse(GNT_WIDGET(wm->ordered->data), TRUE, wm); + window_reverse(GNT_WIDGET(wm->cws->ordered->data), TRUE, wm); return TRUE; } @@ -864,11 +894,11 @@ GntWM *wm = GNT_WM(bindable); if (wm->_list.window || wm->menu) return TRUE; - if (!wm->ordered) + if (!wm->cws->ordered) return TRUE; wm->mode = GNT_KP_MODE_RESIZE; - window_reverse(GNT_WIDGET(wm->ordered->data), TRUE, wm); + window_reverse(GNT_WIDGET(wm->cws->ordered->data), TRUE, wm); return TRUE; } @@ -900,7 +930,7 @@ g_hash_table_foreach(wm->nodes, (GHFunc)refresh_node, NULL); update_screen(wm); - draw_taskbar(wm, TRUE); + gnt_ws_draw_taskbar(wm->cws, TRUE); return FALSE; } @@ -931,6 +961,68 @@ return TRUE; } +static void remove_tag(gpointer wid, gpointer wim) +{ + GntWM *wm = GNT_WM(wim); + GntWidget *w = GNT_WIDGET(wid); + wm->tagged = g_list_remove(wm->tagged, w); + mvwhline(w->window, 0, 1, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), 3); + gnt_widget_draw(w); +} + +static gboolean +tag_widget(GntBindable *b, GList *params) +{ + GntWM *wm = GNT_WM(b); + GntWidget *widget; + + if (!wm->cws->ordered) + return FALSE; + widget = wm->cws->ordered->data; + + if (g_list_find(wm->tagged, widget)) { + remove_tag(widget, wm); + return TRUE; + } + + wm->tagged = g_list_prepend(wm->tagged, widget); + wbkgdset(widget->window, ' ' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT)); + mvwprintw(widget->window, 0, 1, "[T]"); + gnt_widget_draw(widget); + return TRUE; +} + +static void +widget_move_ws(gpointer wid, gpointer w) +{ + GntWM *wm = GNT_WM(w); + gnt_wm_widget_move_workspace(wm, wm->cws, GNT_WIDGET(wid)); +} + +static gboolean +place_tagged(GntBindable *b, GList *params) +{ + GntWM *wm = GNT_WM(b); + g_list_foreach(wm->tagged, widget_move_ws, wm); + g_list_foreach(wm->tagged, remove_tag, wm); + g_list_free(wm->tagged); + wm->tagged = NULL; + return TRUE; +} + +static gboolean +workspace_list(GntBindable *b, GList *params) +{ + GntWM *wm = GNT_WM(b); + + if (wm->_list.window || wm->menu) + return TRUE; + + list_of_windows(wm, TRUE); + + return TRUE; +} + static void gnt_wm_class_init(GntWMClass *klass) { @@ -1065,6 +1157,16 @@ "\033" GNT_KEY_CTRL_K, NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-widget", help_for_widget, "\033" "/", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-next", workspace_next, + "\033" ">", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-prev", workspace_prev, + "\033" "<", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-tag", tag_widget, + "\033" "t", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "place-tagged", place_tagged, + "\033" "T", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-list", workspace_list, + "\033" "s", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "toggle-clipboard", toggle_clipboard, "\033" "C", NULL); @@ -1109,6 +1211,118 @@ return type; } +void +gnt_wm_add_workspace(GntWM *wm, GntWS *ws) +{ + wm->workspaces = g_list_append(wm->workspaces, ws); +} + +gboolean +gnt_wm_switch_workspace(GntWM *wm, gint n) +{ + GntWS *s = g_list_nth_data(wm->workspaces, n); + if (!s) + return FALSE; + + if (wm->_list.window) { + gnt_widget_destroy(wm->_list.window); + } + gnt_ws_hide(wm->cws, wm->nodes); + wm->cws = s; + gnt_ws_show(wm->cws, wm->nodes); + + gnt_ws_draw_taskbar(wm->cws, TRUE); + update_screen(wm); + if (wm->cws->ordered) { + gnt_widget_set_focus(wm->cws->ordered->data, TRUE); + gnt_wm_raise_window(wm, wm->cws->ordered->data); + } + + if (act && g_list_find(act, wm->cws)) { + act = g_list_remove(act, wm->cws); + update_act_msg(); + } + return TRUE; +} + +gboolean +gnt_wm_switch_workspace_prev(GntWM *wm) +{ + int n = g_list_index(wm->workspaces, wm->cws); + return gnt_wm_switch_workspace(wm, --n); +} + +gboolean +gnt_wm_switch_workspace_next(GntWM *wm) +{ + int n = g_list_index(wm->workspaces, wm->cws); + return gnt_wm_switch_workspace(wm, ++n); +} + +static gboolean +workspace_next(GntBindable *wm, GList *n) +{ + return gnt_wm_switch_workspace_next(GNT_WM(wm)); +} + +static gboolean +workspace_prev(GntBindable *wm, GList *n) +{ + return gnt_wm_switch_workspace_prev(GNT_WM(wm)); +} + +void +gnt_wm_widget_move_workspace(GntWM *wm, GntWS *neww, GntWidget *widget) +{ + GntWS *oldw = gnt_wm_widget_find_workspace(wm, widget); + GntNode *node; + if (!oldw || oldw == neww) + return; + node = g_hash_table_lookup(wm->nodes, widget); + if (node && node->ws == neww) + return; + + if (node) + node->ws = neww; + + gnt_ws_remove_widget(oldw, widget); + gnt_ws_add_widget(neww, widget); + if (neww == wm->cws) { + gnt_ws_widget_show(widget, wm->nodes); + } else { + gnt_ws_widget_hide(widget, wm->nodes); + } +} + +static gint widget_in_workspace(gconstpointer workspace, gconstpointer wid) +{ + GntWS *s = (GntWS *)workspace; + if (s->list && g_list_find(s->list, wid)) + return 0; + return 1; +} + +GntWS *gnt_wm_widget_find_workspace(GntWM *wm, GntWidget *widget) +{ + GList *l = g_list_find_custom(wm->workspaces, widget, widget_in_workspace); + if (l) + return l->data; + return NULL; +} + +static void free_workspaces(gpointer data, gpointer n) +{ + GntWS *s = data; + g_free(s->name); +} + +void gnt_wm_set_workspaces(GntWM *wm, GList *workspaces) +{ + g_list_foreach(wm->workspaces, free_workspaces, NULL); + wm->workspaces = workspaces; + gnt_wm_switch_workspace(wm, 0); +} + static void update_window_in_list(GntWM *wm, GntWidget *wid) { @@ -1117,7 +1331,7 @@ if (wm->windows == NULL) return; - if (wid == wm->ordered->data) + if (wm->cws->ordered && wid == wm->cws->ordered->data) flag |= GNT_TEXT_FLAG_DIM; else if (GNT_WIDGET_IS_FLAG_SET(wid, GNT_WIDGET_URGENT)) flag |= GNT_TEXT_FLAG_BOLD; @@ -1125,6 +1339,29 @@ gnt_tree_set_row_flags(GNT_TREE(wm->windows->tree), wid, flag); } +static gboolean +match_title(gpointer title, gpointer n, gpointer wid_title) +{ + /* maybe check for regex.h? */ + if (g_strrstr((gchar *)wid_title, (gchar *)title)) + return TRUE; + return FALSE; +} + +static GntWS * +new_widget_find_workspace(GntWM *wm, GntWidget *widget, gchar *wid_title) +{ + GntWS *ret; + const gchar *name; + ret = g_hash_table_find(wm->title_places, match_title, wid_title); + if (ret) + return ret; + name = gnt_widget_get_name(widget); + if (name) + ret = g_hash_table_lookup(wm->name_places, name); + return ret ? ret : wm->cws; +} + static void gnt_wm_new_window_real(GntWM *wm, GntWidget *widget) { @@ -1171,7 +1408,7 @@ w = MIN(w, maxx); h = MIN(h, maxy); node->window = newwin(h + shadow, w + shadow, y, x); - copy_win(widget, node); + gnt_wm_copy_win(widget, node); } #endif @@ -1179,18 +1416,25 @@ set_panel_userptr(node->panel, node); if (!transient) { + GntWS *ws = wm->cws; if (node->me != wm->_list.window) { GntWidget *w = NULL; - if (wm->ordered) - w = wm->ordered->data; + if (GNT_IS_BOX(widget)) { + char *title = GNT_BOX(widget)->title; + ws = new_widget_find_workspace(wm, widget, title); + } - wm->list = g_list_append(wm->list, widget); + if (ws->ordered) + w = ws->ordered->data; + + node->ws = ws; + ws->list = g_list_append(ws->list, widget); if (wm->event_stack) - wm->ordered = g_list_prepend(wm->ordered, widget); + ws->ordered = g_list_prepend(ws->ordered, widget); else - wm->ordered = g_list_append(wm->ordered, widget); + ws->ordered = g_list_append(ws->ordered, widget); gnt_widget_set_focus(widget, TRUE); if (w) @@ -1198,10 +1442,14 @@ } if (wm->event_stack || node->me == wm->_list.window) { + if (wm->cws != ws) + gnt_wm_switch_workspace(wm, g_list_index(wm->workspaces, ws)); gnt_wm_raise_window(wm, node->me); } else { bottom_panel(node->panel); /* New windows should not grab focus */ gnt_widget_set_urgent(node->me); + if (wm->cws != ws) + gnt_ws_widget_hide(widget, wm->nodes); } } } @@ -1235,13 +1483,13 @@ && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_CAN_TAKE_FOCUS)) { gnt_tree_add_row_last(GNT_TREE(wm->windows->tree), widget, gnt_tree_create_row(GNT_TREE(wm->windows->tree), GNT_BOX(widget)->title), - NULL); + g_object_get_data(G_OBJECT(wm->windows->tree), "workspace") ? wm->cws : NULL); update_window_in_list(wm, widget); } } update_screen(wm); - draw_taskbar(wm, FALSE); + gnt_ws_draw_taskbar(wm->cws, FALSE); } void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget) @@ -1251,9 +1499,12 @@ void gnt_wm_window_close(GntWM *wm, GntWidget *widget) { + GntWS *s; GntNode *node; int pos; + s = gnt_wm_widget_find_workspace(wm, widget); + if ((node = g_hash_table_lookup(wm->nodes, widget)) == NULL) return; @@ -1264,18 +1515,20 @@ gnt_tree_remove(GNT_TREE(wm->windows->tree), widget); } - pos = g_list_index(wm->list, widget); + if (s) { + pos = g_list_index(s->list, widget); - if (pos != -1) { - wm->list = g_list_remove(wm->list, widget); - wm->ordered = g_list_remove(wm->ordered, widget); + if (pos != -1) { + s->list = g_list_remove(s->list, widget); + s->ordered = g_list_remove(s->ordered, widget); - if (wm->ordered) - gnt_wm_raise_window(wm, wm->ordered->data); + if (s->ordered && wm->cws == s) + gnt_wm_raise_window(wm, s->ordered->data); + } } update_screen(wm); - draw_taskbar(wm, FALSE); + gnt_ws_draw_taskbar(wm->cws, FALSE); } time_t gnt_wm_get_idle_time() @@ -1296,10 +1549,10 @@ } /* Do some manual checking */ - if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) { + if (wm->cws->ordered && wm->mode != GNT_KP_MODE_NORMAL) { int xmin = 0, ymin = 0, xmax = getmaxx(stdscr), ymax = getmaxy(stdscr) - 1; int x, y, w, h; - GntWidget *widget = GNT_WIDGET(wm->ordered->data); + GntWidget *widget = GNT_WIDGET(wm->cws->ordered->data); int ox, oy, ow, oh; gnt_widget_get_position(widget, &x, &y); @@ -1375,8 +1628,8 @@ ret = gnt_widget_key_pressed(GNT_WIDGET(wm->menu), keys); else if (wm->_list.window) ret = gnt_widget_key_pressed(wm->_list.window, keys); - else if (wm->ordered) - ret = gnt_widget_key_pressed(GNT_WIDGET(wm->ordered->data), keys); + else if (wm->cws->ordered) + ret = gnt_widget_key_pressed(GNT_WIDGET(wm->cws->ordered->data), keys); return ret; } @@ -1510,9 +1763,9 @@ return; if (widget != wm->_list.window && !GNT_IS_MENU(widget) && - wm->ordered->data != widget) { - GntWidget *w = wm->ordered->data; - wm->ordered = g_list_bring_to_front(wm->ordered, widget); + wm->cws->ordered->data != widget) { + GntWidget *w = wm->cws->ordered->data; + wm->cws->ordered = g_list_bring_to_front(wm->cws->ordered, widget); gnt_widget_set_focus(w, FALSE); } @@ -1526,27 +1779,35 @@ top_panel(nd->panel); } update_screen(wm); - draw_taskbar(wm, FALSE); + gnt_ws_draw_taskbar(wm->cws, FALSE); } void gnt_wm_update_window(GntWM *wm, GntWidget *widget) { - GntNode *node; + GntNode *node = NULL; + GntWS *ws; while (widget->parent) widget = widget->parent; if (!GNT_IS_MENU(widget)) gnt_box_sync_children(GNT_BOX(widget)); + ws = gnt_wm_widget_find_workspace(wm, widget); node = g_hash_table_lookup(wm->nodes, widget); if (node == NULL) { gnt_wm_new_window(wm, widget); } else g_signal_emit(wm, signals[SIG_UPDATE_WIN], 0, node); - copy_win(widget, node); - update_screen(wm); - draw_taskbar(wm, FALSE); + if (ws == wm->cws || GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_TRANSIENT)) { + gnt_wm_copy_win(widget, node); + update_screen(wm); + gnt_ws_draw_taskbar(wm->cws, FALSE); + } else if (ws != wm->cws && GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_URGENT)) { + if (!act || (act && !g_list_find(act, ws))) + act = g_list_prepend(act, ws); + update_act_msg(); + } } gboolean gnt_wm_process_click(GntWM *wm, GntMouseEvent event, int x, int y, GntWidget *widget)
--- a/finch/libgnt/gntwm.h Sun Apr 29 00:15:08 2007 +0000 +++ b/finch/libgnt/gntwm.h Sun Apr 29 01:09:18 2007 +0000 @@ -1,6 +1,9 @@ +#ifndef GNTWM_H +#define GNTWM_H #include "gntwidget.h" #include "gntmenu.h" +#include "gntws.h" #include <panel.h> #include <time.h> @@ -26,9 +29,11 @@ WINDOW *window; int scroll; PANEL *panel; + + GntWS *ws; } GntNode; -typedef struct _GnttWM GntWM; +typedef struct _GntWM GntWM; typedef struct _GntPosition { @@ -45,14 +50,15 @@ void (*callback)(); } GntAction; -struct _GnttWM +struct _GntWM { GntBindable inherit; GMainLoop *loop; - GList *list; /* List of windows ordered on their creation time */ - GList *ordered; /* List of windows ordered on their focus */ + GList *workspaces; + GList *tagged; /* tagged windows */ + GntWS *cws; struct { GntWidget *window; @@ -62,6 +68,8 @@ *actions; /* Action-list window */ GHashTable *nodes; /* GntWidget -> GntNode */ + GHashTable *name_places; /* window name -> ws*/ + GHashTable *title_places; /* window title -> ws */ GList *acts; /* List of actions */ @@ -146,6 +154,15 @@ GType gnt_wm_get_gtype(void); +void gnt_wm_add_workspace(GntWM *wm, GntWS *ws); + +gboolean gnt_wm_switch_workspace(GntWM *wm, gint n); +gboolean gnt_wm_switch_workspace_prev(GntWM *wm); +gboolean gnt_wm_switch_workspace_next(GntWM *wm); +void gnt_wm_widget_move_workspace(GntWM *wm, GntWS *neww, GntWidget *widget); +void gnt_wm_set_workspaces(GntWM *wm, GList *workspaces); +GntWS *gnt_wm_widget_find_workspace(GntWM *wm, GntWidget *widget); + void gnt_wm_new_window(GntWM *wm, GntWidget *widget); void gnt_wm_window_decorate(GntWM *wm, GntWidget *widget); @@ -166,6 +183,10 @@ void gnt_wm_set_event_stack(GntWM *wm, gboolean set); +void gnt_wm_copy_win(GntWidget *widget, GntNode *node); + time_t gnt_wm_get_idle_time(void); G_END_DECLS + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/finch/libgnt/gntws.c Sun Apr 29 01:09:18 2007 +0000 @@ -0,0 +1,158 @@ +#include <gmodule.h> + +#include "gntbox.h" +#include "gntws.h" +#include "gntwm.h" +#include "gntwidget.h" + +static void +widget_hide(gpointer data, gpointer nodes) +{ + GntWidget *widget = GNT_WIDGET(data); + GntNode *node = g_hash_table_lookup(nodes, widget); + hide_panel(node->panel); +} + +static void +widget_show(gpointer data, gpointer nodes) +{ + GntNode *node = g_hash_table_lookup(nodes, data); + GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(data), GNT_WIDGET_INVISIBLE); + if (node) { + show_panel(node->panel); + gnt_wm_copy_win(GNT_WIDGET(data), node); + } +} + +void +gnt_ws_draw_taskbar(GntWS *ws, gboolean reposition) +{ + static WINDOW *taskbar = NULL; + GList *iter; + int n, width = 0; + int i; + + if (taskbar == NULL) { + taskbar = newwin(1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0); + } else if (reposition) { + int Y_MAX = getmaxy(stdscr) - 1; + mvwin(taskbar, Y_MAX, 0); + } + + wbkgdset(taskbar, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + werase(taskbar); + + n = g_list_length(ws->list); + if (n) + width = getmaxx(stdscr) / n; + + for (i = 0, iter = ws->list; iter; iter = iter->next, i++) { + GntWidget *w = iter->data; + int color; + const char *title; + + if (w == ws->ordered->data) { + /* This is the current window in focus */ + color = GNT_COLOR_TITLE; + } else if (GNT_WIDGET_IS_FLAG_SET(w, GNT_WIDGET_URGENT)) { + /* This is a window with the URGENT hint set */ + color = GNT_COLOR_URGENT; + } else { + color = GNT_COLOR_NORMAL; + } + wbkgdset(taskbar, '\0' | COLOR_PAIR(color)); + if (iter->next) + mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), width); + else + mvwhline(taskbar, 0, width * i, ' ' | COLOR_PAIR(color), getmaxx(stdscr) - width * i); + title = GNT_BOX(w)->title; + mvwprintw(taskbar, 0, width * i, "%s", title ? title : "<gnt>"); + if (i) + mvwaddch(taskbar, 0, width *i - 1, ACS_VLINE | A_STANDOUT | COLOR_PAIR(GNT_COLOR_NORMAL)); + } + wrefresh(taskbar); +} + +static void +gnt_ws_init(GTypeInstance *instance, gpointer class) +{ + GntWS *ws = GNT_WS(instance); + ws->list = NULL; + ws->ordered = NULL; + ws->name = NULL; +} + +void gnt_ws_add_widget(GntWS *ws, GntWidget* wid) +{ + ws->list = g_list_append(ws->list, wid); + ws->ordered = g_list_prepend(ws->ordered, wid); +} + +void gnt_ws_remove_widget(GntWS *ws, GntWidget* wid) +{ + ws->list = g_list_remove(ws->list, wid); + ws->ordered = g_list_remove(ws->ordered, wid); +} + +void +gnt_ws_set_name(GntWS *ws, const gchar *name) +{ + g_free(ws->name); + ws->name = g_strdup(name); +} + +void +gnt_ws_hide(GntWS *ws, GHashTable *nodes) +{ + g_list_foreach(ws->ordered, widget_hide, nodes); +} + +void gnt_ws_widget_hide(GntWidget *widget, GHashTable *nodes) { + widget_hide(widget, nodes); +} + +void gnt_ws_widget_show(GntWidget *widget, GHashTable *nodes) { + widget_show(widget, nodes); +} + +void +gnt_ws_show(GntWS *ws, GHashTable *nodes) +{ + GList *l; + for (l = g_list_last(ws->ordered); l; l = g_list_previous(l)) + widget_show(l->data, nodes); +} + +GType +gnt_ws_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) { + static const GTypeInfo info = { + sizeof(GntWSClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, + /*(GClassInitFunc)gnt_ws_class_init,*/ + NULL, + NULL, /* class_data */ + sizeof(GntWS), + 0, /* n_preallocs */ + gnt_ws_init, /* instance_init */ + NULL /* value_table */ + }; + + type = g_type_register_static(GNT_TYPE_BINDABLE, + "GntWS", + &info, 0); + } + + return type; +} + +const char * gnt_ws_get_name(GntWS *ws) +{ + return ws->name; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/finch/libgnt/gntws.h Sun Apr 29 01:09:18 2007 +0000 @@ -0,0 +1,59 @@ +#ifndef GNTWS_H +#define GNTWS_H + +#include "gntwidget.h" + +#include <panel.h> + +#define GNT_TYPE_WS (gnt_ws_get_gtype()) +#define GNT_WS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_WS, GntWS)) +#define GNT_IS_WS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_WS)) +#define GNT_IS_WS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_WS)) +#define GNT_WS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_WS, GntWSClass)) + +typedef struct _GntWS GntWS; + +struct _GntWS +{ + GntBindable inherit; + gchar *name; + GList *list; + GList *ordered; + gpointer ui_data; + + void *res1; + void *res2; + void *res3; + void *res4; +}; + +typedef struct _GntWSClass GntWSClass; + +struct _GntWSClass +{ + GntBindableClass parent; + + void (*draw_taskbar)(GntWS *ws, gboolean ); + + void (*res1)(void); + void (*res2)(void); + void (*res3)(void); + void (*res4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_ws_get_gtype(void); + +void gnt_ws_set_name(GntWS *, const gchar *); +void gnt_ws_add_widget(GntWS *, GntWidget *); +void gnt_ws_remove_widget(GntWS *, GntWidget *); +void gnt_ws_widget_hide(GntWidget *, GHashTable *nodes); +void gnt_ws_widget_show(GntWidget *, GHashTable *nodes); +void gnt_ws_draw_taskbar(GntWS *, gboolean reposition); +void gnt_ws_hide(GntWS *, GHashTable *); +void gnt_ws_show(GntWS *, GHashTable *); + +const char * gnt_ws_get_name(GntWS *ws); + +#endif
--- a/finch/libgnt/wms/s.c Sun Apr 29 00:15:08 2007 +0000 +++ b/finch/libgnt/wms/s.c Sun Apr 29 01:09:18 2007 +0000 @@ -121,7 +121,7 @@ static GntWidget * find_widget(GntWM *wm, const char *wname) { - const GList *iter = wm->list; + const GList *iter = wm->cws->list; for (; iter; iter = iter->next) { GntWidget *widget = iter->data; const char *name = gnt_widget_get_name(widget);