diff options
author | Timo Sirainen <cras@irssi.org> | 2001-08-07 12:41:10 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2001-08-07 12:41:10 +0000 |
commit | 45bb5c3ceed83ef937a373413ac7921b6b050682 (patch) | |
tree | 9d45cf174d1cb47ca88db1ed5c73d9b973e3a052 /src/fe-text | |
parent | 58f52343fdda263e54afeafea6aaf11945b5deca (diff) | |
download | irssi-45bb5c3ceed83ef937a373413ac7921b6b050682.zip |
Restoring layout for split windows works betters now. Some sticky window
changes/fixes. Renamed /WINDOW MOVE LEFT|RIGHT -> PREV|NEXT, added commands
/WINDOW MOVE UP|DOWN|LEFT|RIGHT. The new LEFT|RIGHT now moves the window
only inside split windows. mainwindows-save.c -> mainwindows-layout.c
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1710 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/fe-text')
-rw-r--r-- | src/fe-text/Makefile.am | 2 | ||||
-rw-r--r-- | src/fe-text/gui-windows.c | 61 | ||||
-rw-r--r-- | src/fe-text/gui-windows.h | 5 | ||||
-rw-r--r-- | src/fe-text/irssi.c | 8 | ||||
-rw-r--r-- | src/fe-text/mainwindows-layout.c | 140 | ||||
-rw-r--r-- | src/fe-text/mainwindows-save.c | 195 | ||||
-rw-r--r-- | src/fe-text/mainwindows.c | 285 | ||||
-rw-r--r-- | src/fe-text/mainwindows.h | 3 | ||||
-rw-r--r-- | src/fe-text/statusbar-items.c | 3 |
9 files changed, 364 insertions, 338 deletions
diff --git a/src/fe-text/Makefile.am b/src/fe-text/Makefile.am index b3c43d48..ed261a3e 100644 --- a/src/fe-text/Makefile.am +++ b/src/fe-text/Makefile.am @@ -32,7 +32,7 @@ irssi_SOURCES = \ lastlog.c \ mainwindows.c \ mainwindow-activity.c \ - mainwindows-save.c \ + mainwindows-layout.c \ screen.c \ statusbar.c \ statusbar-items.c \ diff --git a/src/fe-text/gui-windows.c b/src/fe-text/gui-windows.c index 31fcc646..e8f5dae3 100644 --- a/src/fe-text/gui-windows.c +++ b/src/fe-text/gui-windows.c @@ -61,33 +61,33 @@ static void sig_window_create_override(gpointer tab) window_create_override = GPOINTER_TO_INT(tab); } -static void gui_window_created(WINDOW_REC *window) +static void gui_window_created(WINDOW_REC *window, void *automatic) { MAIN_WINDOW_REC *parent; + int empty_window; g_return_if_fail(window != NULL); parent = window_create_override != 0 && active_win != NULL && WINDOW_GUI(active_win) != NULL ? - WINDOW_GUI(active_win)->parent : mainwindow_create(); + WINDOW_MAIN(active_win) : mainwindow_create(); if (parent == NULL) { /* not enough space for new window, but we really can't abort creation of the window anymore, so create hidden window instead. */ - parent = WINDOW_GUI(active_win)->parent; + parent = WINDOW_MAIN(active_win); } window_create_override = -1; - if (settings_get_bool("autostick_split_windows") && - (parent->sticky_windows != NULL || - (mainwindows->next != NULL && parent->active == NULL))) { - /* set the window sticky */ - parent->sticky_windows = - g_slist_append(parent->sticky_windows, window); - } + empty_window = parent->active == NULL; if (parent->active == NULL) parent->active = window; window->gui_data = gui_window_init(window, parent); + + if (settings_get_bool("autostick_split_windows") && + automatic == NULL && (parent->sticky_windows || empty_window)) + gui_window_set_sticky(window); + signal_emit("gui window created", 1, window); } @@ -101,10 +101,9 @@ static void gui_window_destroyed(WINDOW_REC *window) gui = WINDOW_GUI(window); parent = gui->parent; - signal_emit("gui window destroyed", 1, window); + gui_window_set_unsticky(window); - parent->sticky_windows = - g_slist_remove(parent->sticky_windows, window); + signal_emit("gui window destroyed", 1, window); gui_window_deinit(gui); window->gui_data = NULL; @@ -141,6 +140,26 @@ void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line) signal_emit("gui page scrolled", 1, window); } +void gui_window_set_sticky(WINDOW_REC *window) +{ + GUI_WINDOW_REC *gui = WINDOW_GUI(window); + + if (!gui->sticky) { + gui->sticky = TRUE; + gui->parent->sticky_windows++; + } +} + +void gui_window_set_unsticky(WINDOW_REC *window) +{ + GUI_WINDOW_REC *gui = WINDOW_GUI(window); + + if (gui->sticky) { + gui->sticky = FALSE; + gui->parent->sticky_windows--; + } +} + void window_update_prompt(void) { const char *special; @@ -193,13 +212,17 @@ void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent) { MAIN_WINDOW_REC *oldparent; - oldparent = WINDOW_GUI(window)->parent; + oldparent = WINDOW_MAIN(window); if (oldparent == parent) return; + gui_window_set_unsticky(window); textbuffer_view_set_window(WINDOW_GUI(window)->view, NULL); - WINDOW_GUI(window)->parent = parent; + WINDOW_MAIN(window) = parent; + if (parent->sticky_windows) + gui_window_set_sticky(window); + if (parent->height != oldparent->height || parent->width != oldparent->width) gui_window_resize(window, parent->width, parent->height); @@ -212,7 +235,7 @@ static MAIN_WINDOW_REC *mainwindow_find_unsticky(void) for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) { MAIN_WINDOW_REC *rec = tmp->data; - if (rec->sticky_windows == NULL) + if (!rec->sticky_windows) return rec; } @@ -229,20 +252,20 @@ static void signal_window_changed(WINDOW_REC *window) if (quitting) return; - parent = WINDOW_GUI(window)->parent; + parent = WINDOW_MAIN(window); if (is_window_visible(window)) { /* already visible */ active_mainwin = parent; } else if (active_mainwin == NULL) { /* no main window set yet */ active_mainwin = parent; - } else if (g_slist_find(parent->sticky_windows, window) != NULL) { + } else if (WINDOW_GUI(window)->sticky) { /* window is sticky, switch to correct main window */ if (parent != active_mainwin) active_mainwin = parent; } else { /* move window to active main window */ - if (active_mainwin->sticky_windows != NULL) { + if (active_mainwin->sticky_windows) { /* active mainwindow is sticky, we'll need to set the window active somewhere else */ active_mainwin = mainwindow_find_unsticky(); diff --git a/src/fe-text/gui-windows.h b/src/fe-text/gui-windows.h index fb94b46f..4b9792ce 100644 --- a/src/fe-text/gui-windows.h +++ b/src/fe-text/gui-windows.h @@ -5,6 +5,7 @@ #include "textbuffer-view.h" #define WINDOW_GUI(a) ((GUI_WINDOW_REC *) ((a)->gui_data)) +#define WINDOW_MAIN(a) (WINDOW_GUI(a)->parent) #define is_window_visible(win) \ (WINDOW_GUI(win)->parent->active == (win)) @@ -13,6 +14,7 @@ typedef struct { MAIN_WINDOW_REC *parent; TEXT_BUFFER_VIEW_REC *view; + unsigned int sticky:1; unsigned int use_insert_after:1; LINE_REC *insert_after; } GUI_WINDOW_REC; @@ -31,6 +33,9 @@ void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent); void gui_window_scroll(WINDOW_REC *window, int lines); void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line); +void gui_window_set_sticky(WINDOW_REC *window); +void gui_window_set_unsticky(WINDOW_REC *window); + void window_update_prompt(void); #endif diff --git a/src/fe-text/irssi.c b/src/fe-text/irssi.c index 94fc18c2..cf6f974b 100644 --- a/src/fe-text/irssi.c +++ b/src/fe-text/irssi.c @@ -65,8 +65,8 @@ void lastlog_deinit(void); void mainwindow_activity_init(void); void mainwindow_activity_deinit(void); -void mainwindows_save_init(void); -void mainwindows_save_deinit(void); +void mainwindows_layout_init(void); +void mainwindows_layout_deinit(void); static GMainLoop *main_loop; int quitting; @@ -129,7 +129,7 @@ static void textui_finish_init(void) lastlog_init(); mainwindows_init(); mainwindow_activity_init(); - mainwindows_save_init(); + mainwindows_layout_init(); gui_windows_init(); statusbar_init(); screen_refresh_thaw(); @@ -167,7 +167,7 @@ static void textui_deinit(void) gui_printtext_deinit(); gui_readline_deinit(); gui_windows_deinit(); - mainwindows_save_deinit(); + mainwindows_layout_deinit(); mainwindow_activity_deinit(); mainwindows_deinit(); gui_expandos_deinit(); diff --git a/src/fe-text/mainwindows-layout.c b/src/fe-text/mainwindows-layout.c new file mode 100644 index 00000000..1657c9e6 --- /dev/null +++ b/src/fe-text/mainwindows-layout.c @@ -0,0 +1,140 @@ +/* + mainwindows-layout.c : irssi + + Copyright (C) 2001 Timo Sirainen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "module.h" +#include "signals.h" +#include "misc.h" +#include "lib-config/iconfig.h" +#include "settings.h" + +#include "mainwindows.h" +#include "gui-windows.h" + +static void sig_window_save(WINDOW_REC *window, CONFIG_NODE *node) +{ + if (WINDOW_GUI(window)->sticky) + iconfig_node_set_bool(node, "sticky", TRUE); +} + +static void sig_window_restore(WINDOW_REC *window, CONFIG_NODE *node) +{ + WINDOW_REC *parent; + + parent = window_find_refnum(config_node_get_int(node, "parent", -1)); + if (parent != NULL) + gui_window_reparent(window, WINDOW_MAIN(parent)); + + if (config_node_get_bool(node, "sticky", FALSE)) + gui_window_set_sticky(window); +} + +static void main_window_save(MAIN_WINDOW_REC *window, CONFIG_NODE *node) +{ + char num[MAX_INT_STRLEN]; + + ltoa(num, window->active->refnum); + node = config_node_section(node, num, NODE_TYPE_BLOCK); + + iconfig_node_set_int(node, "first_line", window->first_line); + iconfig_node_set_int(node, "lines", window->height); +} + +static void sig_windows_saved(void) +{ + CONFIG_NODE *node; + + iconfig_set_str(NULL, "mainwindows", NULL); + node = iconfig_node_traverse("mainwindows", TRUE); + + g_slist_foreach(mainwindows, (GFunc) main_window_save, node); +} + +static int window_node_cmp(CONFIG_NODE *n1, CONFIG_NODE *n2) +{ + return config_node_get_int(n1, "first_line", 0) > + config_node_get_int(n2, "first_line", 0) ? -1 : 1; +} + +/* Returns list of mainwindow nodes sorted by first_line + (lowest in screen first) */ +static GSList *get_sorted_windows_config(CONFIG_NODE *node) +{ + GSList *tmp, *output; + + output = NULL; + for (tmp = node->value; tmp != NULL; tmp = tmp->next) { + output = g_slist_insert_sorted(output, tmp->data, + (GCompareFunc) window_node_cmp); + } + + return output; +} + +static void sig_windows_restored(void) +{ + MAIN_WINDOW_REC *lower_window; + WINDOW_REC *window; + CONFIG_NODE *node; + GSList *tmp, *sorted_config; + int lower_size; + + node = iconfig_node_traverse("mainwindows", FALSE); + if (node == NULL) return; + + /* create all the visible windows with correct size */ + lower_window = NULL; lower_size = 0; + + sorted_config = get_sorted_windows_config(node); + for (tmp = sorted_config; tmp != NULL; tmp = tmp->next) { + CONFIG_NODE *node = tmp->data; + + /* create a new window + mainwindow */ + signal_emit("gui window create override", 1, + GINT_TO_POINTER(0)); + window = window_create(NULL, TRUE); + window_set_refnum(window, atoi(node->key)); + + if (lower_size > 0) + mainwindow_set_size(lower_window, lower_size); + + lower_window = WINDOW_MAIN(window); + lower_size = config_node_get_int(node, "lines", 0); + } + g_slist_free(sorted_config); + + if (lower_size > 0) + mainwindow_set_size(lower_window, lower_size); +} + +void mainwindows_layout_init(void) +{ + signal_add("window save", (SIGNAL_FUNC) sig_window_save); + signal_add("window restore", (SIGNAL_FUNC) sig_window_restore); + signal_add("windows saved", (SIGNAL_FUNC) sig_windows_saved); + signal_add_first("windows restored", (SIGNAL_FUNC) sig_windows_restored); +} + +void mainwindows_layout_deinit(void) +{ + signal_remove("window save", (SIGNAL_FUNC) sig_window_save); + signal_remove("window restore", (SIGNAL_FUNC) sig_window_restore); + signal_remove("windows saved", (SIGNAL_FUNC) sig_windows_saved); + signal_remove("windows restored", (SIGNAL_FUNC) sig_windows_restored); +} diff --git a/src/fe-text/mainwindows-save.c b/src/fe-text/mainwindows-save.c deleted file mode 100644 index 113037b1..00000000 --- a/src/fe-text/mainwindows-save.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - mainwindows-save.c : irssi - - Copyright (C) 2001 Timo Sirainen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "module.h" -#include "signals.h" -#include "misc.h" -#include "lib-config/iconfig.h" -#include "settings.h" - -#include "mainwindows.h" -#include "gui-windows.h" - -static void main_window_save(MAIN_WINDOW_REC *window, CONFIG_NODE *node) -{ - GSList *tmp; - GString *str; - char num[MAX_INT_STRLEN]; - - ltoa(num, window->active->refnum); - node = config_node_section(node, num, NODE_TYPE_BLOCK); - - iconfig_node_set_int(node, "first_line", window->first_line); - iconfig_node_set_int(node, "lines", window->height); - - str = g_string_new(NULL); - for (tmp = window->sticky_windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; - g_string_sprintfa(str, "%d ", rec->refnum); - } - if (str->len > 1) { - g_string_truncate(str, str->len-1); - iconfig_node_set_str(node, "sticky", str->str); - } - g_string_free(str, TRUE); -} - -static void sig_windows_saved(void) -{ - CONFIG_NODE *node; - - iconfig_set_str(NULL, "mainwindows", NULL); - node = iconfig_node_traverse("mainwindows", TRUE); - - g_slist_foreach(mainwindows, (GFunc) main_window_save, node); -} - -static int window_node_cmp(CONFIG_NODE *n1, CONFIG_NODE *n2) -{ - return config_node_get_int(n1, "first_line", 0) < - config_node_get_int(n2, "first_line", 0) ? -1 : 1; -} - -static GSList *read_sorted_windows(CONFIG_NODE *node) -{ - GSList *tmp, *output; - - output = NULL; - for (tmp = node->value; tmp != NULL; tmp = tmp->next) { - output = g_slist_insert_sorted(output, tmp->data, - (GCompareFunc) window_node_cmp); - } - - return output; -} - -static void restore_sticky_windows(CONFIG_NODE *node, - MAIN_WINDOW_REC *mainwindow) -{ - WINDOW_REC *window; - char **sticky_list, **sticky; - - sticky_list = g_strsplit(config_node_get_str(node, "sticky", ""), " ", -1); - for (sticky = sticky_list; *sticky != NULL; sticky++) { - window = window_find_refnum(atoi(*sticky)); - if (window != NULL) { - mainwindow->sticky_windows = - g_slist_append(mainwindow->sticky_windows, - window); - } - } - g_strfreev(sticky_list); -} - -static WINDOW_REC *window_find_hidden(void) -{ - GSList *tmp; - - for (tmp = windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; - - if (!is_window_visible(rec)) - return rec; - } - - return NULL; -} - -static void sig_windows_restored(void) -{ - MAIN_WINDOW_REC *mainwindow, *lowerwin; - WINDOW_REC *window; - CONFIG_NODE *node; - GSList *tmp, *tmp2, *sorted_windows, *sorted_config; - int count, newsize; - - node = iconfig_node_traverse("mainwindows", FALSE); - if (node == NULL) return; - - /* create all windows, shrink the lower windows to minimum size */ - lowerwin = mainwindows->data; - count = g_slist_length(node->value); - while (count > 1) { - window = window_find_hidden(); - if (window == NULL) - break; - - mainwindow = mainwindow_create(); - if (mainwindow == NULL) - break; - - mainwindow->active = window; - WINDOW_GUI(window)->parent = mainwindow; - - active_mainwin = NULL; - window_set_active(window); - - if (lowerwin->height > WINDOW_MIN_SIZE) - mainwindow_set_size(lowerwin, WINDOW_MIN_SIZE); - count--; - - lowerwin = mainwindow; - } - - sorted_config = read_sorted_windows(node); - sorted_windows = mainwindows_get_sorted(FALSE); - for (tmp = sorted_windows, tmp2 = sorted_config; - tmp != NULL && tmp2 != NULL; - tmp = tmp->next, tmp2 = tmp2->next) { - MAIN_WINDOW_REC *mainwindow = tmp->data; - CONFIG_NODE *node = tmp2->data; - - window = window_find_refnum(atoi(node->key)); - if (window == NULL) { - mainwindow_destroy(mainwindow); - continue; - } - - if (is_window_visible(window)) { - active_mainwin = WINDOW_GUI(window)->parent; - window_set_active(window_find_hidden()); - } - - active_mainwin = mainwindow; - window_set_active(window); - - restore_sticky_windows(node, mainwindow); - - newsize = config_node_get_int(node, "lines", 0); - if (newsize > 0) - mainwindow_set_size(mainwindow, newsize); - } - g_slist_free(sorted_windows); - g_slist_free(sorted_config); - - irssi_redraw(); -} - -void mainwindows_save_init(void) -{ - signal_add("windows saved", (SIGNAL_FUNC) sig_windows_saved); - signal_add("windows restored", (SIGNAL_FUNC) sig_windows_restored); -} - -void mainwindows_save_deinit(void) -{ - signal_remove("windows saved", (SIGNAL_FUNC) sig_windows_saved); - signal_remove("windows restored", (SIGNAL_FUNC) sig_windows_restored); -} diff --git a/src/fe-text/mainwindows.c b/src/fe-text/mainwindows.c index 2f87307d..26a6a6dd 100644 --- a/src/fe-text/mainwindows.c +++ b/src/fe-text/mainwindows.c @@ -88,25 +88,41 @@ static void mainwindow_resize(MAIN_WINDOW_REC *window, int xdiff, int ydiff) signal_emit("mainwindow resized", 1, window); } +static GSList *get_sticky_windows_sorted(MAIN_WINDOW_REC *mainwin) +{ + GSList *tmp, *list; + + list = NULL; + for (tmp = windows; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; + + if (WINDOW_GUI(rec)->sticky && WINDOW_MAIN(rec) == mainwin) { + list = g_slist_insert_sorted(list, rec, (GCompareFunc) + window_refnum_cmp); + } + } + + return list; +} + void mainwindow_change_active(MAIN_WINDOW_REC *mainwin, WINDOW_REC *skip_window) { - MAIN_WINDOW_REC *parent; GSList *tmp; mainwin->active = NULL; - if (mainwin->sticky_windows != NULL) { + if (mainwin->sticky_windows) { /* sticky window */ - window_set_active(mainwin->sticky_windows->data); + tmp = get_sticky_windows_sorted(mainwin); + window_set_active(tmp->data); + g_slist_free(tmp); return; } for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *rec = tmp->data; - parent = WINDOW_GUI(rec)->parent; - if (rec != skip_window && - g_slist_find(parent->sticky_windows, rec) == NULL) { + if (rec != skip_window && WINDOW_MAIN(rec) == mainwin) { window_set_active(rec); return; } @@ -146,7 +162,7 @@ MAIN_WINDOW_REC *mainwindow_create(void) reserved_down-rec->statusbar_lines; rec->height = rec->last_line-rec->first_line+1; } else { - parent = WINDOW_GUI(active_win)->parent; + parent = WINDOW_MAIN(active_win); if (parent->height < WINDOW_MIN_SIZE+NEW_WINDOW_SIZE) parent = find_window_with_room(); if (parent == NULL) @@ -237,7 +253,7 @@ static void gui_windows_remove_parent(MAIN_WINDOW_REC *window) for (tmp = windows; tmp != NULL; tmp = tmp->next) { WINDOW_REC *rec = tmp->data; - if (rec->gui_data != NULL && WINDOW_GUI(rec)->parent == window) + if (rec->gui_data != NULL && WINDOW_MAIN(rec) == window) gui_window_reparent(rec, new_parent); } } @@ -546,7 +562,7 @@ static void cmd_window_grow(const char *data) int count; count = *data == '\0' ? 1 : atoi(data); - window = WINDOW_GUI(active_win)->parent; + window = WINDOW_MAIN(active_win); if (!mainwindow_grow(window, count)) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, @@ -557,13 +573,10 @@ static void cmd_window_grow(const char *data) /* SYNTAX: WINDOW SHRINK [<lines>] */ static void cmd_window_shrink(const char *data) { - MAIN_WINDOW_REC *window; int count; count = *data == '\0' ? 1 : atoi(data); - window = WINDOW_GUI(active_win)->parent; - - if (!mainwindow_shrink(window, count)) { + if (!mainwindow_shrink(WINDOW_MAIN(active_win), count)) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_TOO_SMALL); } @@ -578,7 +591,7 @@ static void cmd_window_size(const char *data) if (!is_numeric(data, 0)) return; size = atoi(data); - size -= WINDOW_GUI(active_win)->parent->height; + size -= WINDOW_MAIN(active_win)->height; if (size == 0) return; ltoa(sizestr, size < 0 ? -size : size); @@ -653,16 +666,16 @@ static void cmd_window_hide(const char *data) if (window == NULL || !is_window_visible(window)) return; - if (WINDOW_GUI(window)->parent->sticky_windows != NULL) { + if (WINDOW_MAIN(window)->sticky_windows) { printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_CANT_HIDE_STICKY_WINDOWS); return; } - mainwindow_destroy(WINDOW_GUI(window)->parent); + mainwindow_destroy(WINDOW_MAIN(window)); if (active_mainwin == NULL) { - active_mainwin = WINDOW_GUI(active_win)->parent; + active_mainwin = WINDOW_MAIN(active_win); window_set_active(active_mainwin->active); } } @@ -688,20 +701,19 @@ static void cmd_window_show(const char *data) if (window == NULL || is_window_visible(window)) return; - if (WINDOW_GUI(window)->parent->sticky_windows != NULL) { + if (WINDOW_MAIN(window)->sticky_windows) { printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_CANT_SHOW_STICKY_WINDOWS); return; } parent = mainwindow_create(); - if (settings_get_bool("autostick_split_windows")) { - parent->sticky_windows = - g_slist_append(parent->sticky_windows, window); - } - parent->active = window; + parent->active = window; gui_window_reparent(window, parent); + if (settings_get_bool("autostick_split_windows")) + gui_window_set_sticky(window); + active_mainwin = NULL; window_set_active(window); } @@ -726,73 +738,88 @@ static void cmd_window_down(void) window_set_active(rec->active); } +#define WINDOW_STICKY_MATCH(window, sticky_parent) \ + ((!WINDOW_GUI(window)->sticky && (sticky_parent) == NULL) || \ + (WINDOW_GUI(window)->sticky && \ + WINDOW_MAIN(window) == (sticky_parent))) + +static int window_refnum_left(int refnum, int wrap) +{ + MAIN_WINDOW_REC *find_sticky; + WINDOW_REC *window; + + window = window_find_refnum(refnum); + g_return_val_if_fail(window != NULL, -1); + + find_sticky = WINDOW_MAIN(window)->sticky_windows ? + WINDOW_MAIN(window) : NULL; + + do { + refnum = window_refnum_prev(refnum, wrap); + if (refnum < 0) + break; + + window = window_find_refnum(refnum); + } while (!WINDOW_STICKY_MATCH(window, find_sticky)); + + return refnum; +} + +static int window_refnum_right(int refnum, int wrap) +{ + MAIN_WINDOW_REC *find_sticky; + WINDOW_REC *window; + + window = window_find_refnum(refnum); + g_return_val_if_fail(window != NULL, -1); + + find_sticky = WINDOW_MAIN(window)->sticky_windows ? + WINDOW_MAIN(window) : NULL; + + do { + refnum = window_refnum_next(refnum, wrap); + if (refnum < 0) + break; + + window = window_find_refnum(refnum); + } while (!WINDOW_STICKY_MATCH(window, find_sticky)); + + return refnum; +} + /* SYNTAX: WINDOW LEFT */ static void cmd_window_left(const char *data, SERVER_REC *server, void *item) { - MAIN_WINDOW_REC *parent; - WINDOW_REC *window; - int pos, num; - - window = NULL; - if (active_mainwin->sticky_windows == NULL) { - /* no sticky windows, go to previous non-sticky window */ - num = active_win->refnum; - do { - num = window_refnum_prev(num, TRUE); - if (num < 0) { - window = NULL; - break; - } - window = window_find_refnum(num); - parent = WINDOW_GUI(window)->parent; - } while (g_slist_find(parent->sticky_windows, window) != NULL); - } else { - pos = g_slist_index(active_mainwin->sticky_windows, - active_win); - if (pos > 0) { - window = g_slist_nth_data( - active_mainwin->sticky_windows, pos-1); - } else { - window = g_slist_last( - active_mainwin->sticky_windows)->data; - } - } + int refnum; - if (window != NULL) - window_set_active(window); + refnum = window_refnum_left(active_win->refnum, TRUE); + if (refnum != -1) + window_set_active(window_find_refnum(refnum)); } /* SYNTAX: WINDOW RIGHT */ static void cmd_window_right(void) { - MAIN_WINDOW_REC *parent; - WINDOW_REC *window; - GSList *tmp; - int num; - - window = NULL; - if (active_mainwin->sticky_windows == NULL) { - /* no sticky windows, go to next non-sticky window */ - num = active_win->refnum; - do { - num = window_refnum_next(num, TRUE); - if (num < 0) { - window = NULL; - break; - } - window = window_find_refnum(num); - parent = WINDOW_GUI(window)->parent; - } while (g_slist_find(parent->sticky_windows, window) != NULL); - } else { - tmp = g_slist_find(active_mainwin->sticky_windows, active_win); - if (tmp != NULL) { - window = tmp->next != NULL ? tmp->next->data : - active_mainwin->sticky_windows->data; - } - } + int refnum; + + refnum = window_refnum_right(active_win->refnum, TRUE); + if (refnum != -1) + window_set_active(window_find_refnum(refnum)); +} - if (window != NULL) - window_set_active(window); +static void window_reparent(WINDOW_REC *win, MAIN_WINDOW_REC *mainwin) +{ + MAIN_WINDOW_REC *old_mainwin; + + old_mainwin = WINDOW_MAIN(win); + + if (old_mainwin != mainwin) { + gui_window_reparent(win, mainwin); + window_set_active(win); + + if (old_mainwin->active == win) + mainwindow_change_active(old_mainwin, win); + } } /* SYNTAX: WINDOW STICK [<ref#>] [ON|OFF] */ @@ -819,62 +846,79 @@ static void cmd_window_stick(const char *data) if (g_strncasecmp(data, "OF", 2) == 0 || toupper(*data) == 'N') { /* unset sticky */ - if (g_slist_find(mainwin->sticky_windows, win) == NULL) { + if (!WINDOW_GUI(win)->sticky) { printformat_window(win, MSGLEVEL_CLIENTERROR, TXT_WINDOW_NOT_STICKY); } else { - mainwin->sticky_windows = - g_slist_remove(mainwin->sticky_windows, win); + gui_window_set_unsticky(win); printformat_window(win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_UNSET_STICKY); } } else { /* set sticky */ - MAIN_WINDOW_REC *old_mainwin; - - old_mainwin = WINDOW_GUI(win)->parent; - old_mainwin->sticky_windows = - g_slist_remove(old_mainwin->sticky_windows, win); - - if (g_slist_find(mainwin->sticky_windows, win) == NULL) { - mainwin->sticky_windows = - g_slist_append(mainwin->sticky_windows, win); - } - if (old_mainwin != mainwin) { - if (old_mainwin->active == win) - mainwindow_change_active(old_mainwin, win); - gui_window_reparent(win, mainwin); - window_set_active(win); - } + window_reparent(win, mainwin); + gui_window_set_sticky(win); printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_SET_STICKY); } } -static void windows_print_sticky(MAIN_WINDOW_REC *win) +/* SYNTAX: WINDOW MOVE LEFT */ +static void cmd_window_move_left(void) { - GSList *tmp, *sorted; - GString *str; + int refnum; - /* sort the sticky windows */ - sorted = NULL; - for (tmp = win->sticky_windows; tmp != NULL; tmp = tmp->next) { - WINDOW_REC *rec = tmp->data; + refnum = window_refnum_left(active_win->refnum, TRUE); + if (refnum != -1) + window_set_refnum(active_win, refnum); +} - sorted = g_slist_insert_sorted(sorted, rec, (GCompareFunc) - window_refnum_cmp); - } +/* SYNTAX: WINDOW MOVE RIGHT */ +static void cmd_window_move_right(void) +{ + int refnum; + + refnum = window_refnum_right(active_win->refnum, TRUE); + if (refnum != -1) + window_set_refnum(active_win, refnum); +} + +/* SYNTAX: WINDOW MOVE UP */ +static void cmd_window_move_up(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_upper(active_mainwin->first_line); + if (rec != NULL) + window_reparent(active_win, rec); +} + +/* SYNTAX: WINDOW MOVE DOWN */ +static void cmd_window_move_down(void) +{ + MAIN_WINDOW_REC *rec; + + rec = mainwindows_find_lower(active_mainwin->last_line); + if (rec != NULL) + window_reparent(active_win, rec); +} + +static void windows_print_sticky(MAIN_WINDOW_REC *win) +{ + GSList *tmp, *list; + GString *str; /* convert to string */ - str = g_string_new(NULL); - while (sorted != NULL) { - WINDOW_REC *rec = sorted->data; + str = g_string_new(NULL); + list = get_sticky_windows_sorted(win); + for (tmp = list; tmp != NULL; tmp = tmp->next) { + WINDOW_REC *rec = tmp->data; g_string_sprintfa(str, "#%d, ", rec->refnum); - sorted = g_slist_remove(sorted, rec); } g_string_truncate(str, str->len-2); + g_slist_free(list); printformat_window(win->active, MSGLEVEL_CLIENTCRAP, TXT_WINDOW_INFO_STICKY, str->str); @@ -883,11 +927,8 @@ static void windows_print_sticky(MAIN_WINDOW_REC *win) static void sig_window_print_info(WINDOW_REC *win) { - MAIN_WINDOW_REC *mainwin; - - mainwin = WINDOW_GUI(win)->parent; - if (mainwin->sticky_windows != NULL) - windows_print_sticky(mainwin); + if (WINDOW_MAIN(win)->sticky_windows) + windows_print_sticky(WINDOW_MAIN(win)); } void mainwindows_init(void) @@ -913,6 +954,10 @@ void mainwindows_init(void) command_bind("window left", NULL, (SIGNAL_FUNC) cmd_window_left); command_bind("window right", NULL, (SIGNAL_FUNC) cmd_window_right); command_bind("window stick", NULL, (SIGNAL_FUNC) cmd_window_stick); + command_bind("window move left", NULL, (SIGNAL_FUNC) cmd_window_move_left); + command_bind("window move right", NULL, (SIGNAL_FUNC) cmd_window_move_right); + command_bind("window move up", NULL, (SIGNAL_FUNC) cmd_window_move_up); + command_bind("window move down", NULL, (SIGNAL_FUNC) cmd_window_move_down); signal_add("window print info", (SIGNAL_FUNC) sig_window_print_info); } @@ -932,5 +977,9 @@ void mainwindows_deinit(void) command_unbind("window left", (SIGNAL_FUNC) cmd_window_left); command_unbind("window right", (SIGNAL_FUNC) cmd_window_right); command_unbind("window stick", (SIGNAL_FUNC) cmd_window_stick); + command_unbind("window move left", (SIGNAL_FUNC) cmd_window_move_left); + command_unbind("window move right", (SIGNAL_FUNC) cmd_window_move_right); + command_unbind("window move up", (SIGNAL_FUNC) cmd_window_move_up); + command_unbind("window move down", (SIGNAL_FUNC) cmd_window_move_down); signal_remove("window print info", (SIGNAL_FUNC) sig_window_print_info); } diff --git a/src/fe-text/mainwindows.h b/src/fe-text/mainwindows.h index 91a5a326..2c45eb54 100644 --- a/src/fe-text/mainwindows.h +++ b/src/fe-text/mainwindows.h @@ -8,11 +8,12 @@ typedef struct { WINDOW_REC *active; - GSList *sticky_windows; /* list of windows allowed to show only in this mainwindow */ SCREEN_WINDOW *screen_win; + int sticky_windows; /* number of sticky windows */ int first_line, last_line, width, height; + int statusbar_lines; void *statusbar; void *statusbar_window_item; diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index ff10434e..7031a071 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -604,6 +604,9 @@ static void sig_mainwindow_created(MAIN_WINDOW_REC *window) static void sig_mainwindow_destroyed(MAIN_WINDOW_REC *window) { if (window == mainbar_window) { + statusbar_destroy(mainbar); + window->statusbar = NULL; + mainbar = NULL; mainbar_window = NULL; } |