Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / fe-common / core / window-commands.c
index 17cf65e5aa8170ca8246dfb689bd0cf8d2402a81..05332cad4bef1b0f82acc3db7285e9bb712c1a17 100644 (file)
 #include "windows-layout.h"
 #include "printtext.h"
 
-static void cmd_window(const char *data, void *server, WI_ITEM_REC *item)
+static void window_print_binds(WINDOW_REC *win)
 {
-       if (is_numeric(data, 0)) {
-                signal_emit("command window refnum", 3, data, server, item);
-               return;
+       GSList *tmp;
+
+       printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                          TXT_WINDOW_INFO_BOUND_ITEMS_HEADER);
+       for (tmp = win->bound_items; tmp != NULL; tmp = tmp->next) {
+               WINDOW_BIND_REC *bind = tmp->data;
+
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_BOUND_ITEM,
+                                  bind->name, bind->servertag,
+                                  bind->sticky ? "sticky" : "");
        }
+       printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                          TXT_WINDOW_INFO_BOUND_ITEMS_FOOTER);
+}
 
-       command_runsub("window", data, server, item);
+static void window_print_items(WINDOW_REC *win)
+{
+       GSList *tmp;
+        const char *type;
+
+       printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                          TXT_WINDOW_INFO_ITEMS_HEADER);
+       for (tmp = win->items; tmp != NULL; tmp = tmp->next) {
+               WI_ITEM_REC *item = tmp->data;
+
+               type = module_find_id_str("WINDOW ITEM TYPE", item->type);
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_ITEM,
+                                  type == NULL ? "??" : type,
+                                  item->visible_name,
+                                  item->server == NULL ? "" :
+                                  item->server->tag);
+       }
+       printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                          TXT_WINDOW_INFO_ITEMS_FOOTER);
+}
+
+static void cmd_window_info(WINDOW_REC *win)
+{
+        char *levelstr;
+
+       printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                          TXT_WINDOW_INFO_HEADER);
+
+        /* Window reference number + sticky status */
+       if (!win->sticky_refnum) {
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_REFNUM, win->refnum);
+       } else {
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_REFNUM_STICKY, win->refnum);
+       }
+
+        /* Window name */
+       if (win->name != NULL) {
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_NAME, win->name);
+       }
+
+        /* Window width / height */
+       printformat_window(win, MSGLEVEL_CLIENTCRAP, TXT_WINDOW_INFO_SIZE,
+                          win->width, win->height);
+
+       /* Window immortality */
+       if (win->immortal) {
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_IMMORTAL);
+       }
+
+       /* Window history name */
+       if (win->history_name != NULL) {
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_HISTORY, win->history_name);
+       }
+
+        /* Window level */
+       levelstr = win->level == 0 ?
+               g_strdup("NONE") : bits2level(win->level);
+       printformat_window(win, MSGLEVEL_CLIENTCRAP, TXT_WINDOW_INFO_LEVEL,
+                          levelstr);
+       g_free(levelstr);
+
+        /* Active window server + sticky status */
+       if (win->servertag == NULL) {
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_SERVER,
+                                  win->active_server != NULL ?
+                                  win->active_server->tag : "NONE");
+       } else {
+               if (win->active_server != NULL &&
+                   strcmp(win->active_server->tag, win->servertag) != 0)
+                        g_warning("Active server isn't the sticky server!");
+
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_SERVER_STICKY,
+                                  win->servertag);
+       }
+
+        /* Window theme + error status */
+       if (win->theme_name != NULL) {
+               printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                                  TXT_WINDOW_INFO_THEME, win->theme_name,
+                                  win->theme != NULL ? "" : "(not loaded)");
+       }
+
+        /* Bound items in window */
+       if (win->bound_items != NULL)
+                window_print_binds(win);
+
+        /* Item */
+       if (win->items != NULL)
+                window_print_items(win);
+
+        signal_emit("window print info", 1, win);
+
+       printformat_window(win, MSGLEVEL_CLIENTCRAP,
+                          TXT_WINDOW_INFO_FOOTER);
+}
+
+static void cmd_window(const char *data, void *server, WI_ITEM_REC *item)
+{
+        while (*data == ' ') data++;
+
+       if (*data == '\0')
+                cmd_window_info(active_win);
+       else if (is_numeric(data, 0))
+                signal_emit("command window refnum", 3, data, server, item);
+        else
+               command_runsub("window", data, server, item);
 }
 
 /* SYNTAX: WINDOW NEW [hide] */
@@ -59,7 +183,7 @@ static void cmd_window_new(const char *data, void *server, WI_ITEM_REC *item)
        window_change_server(window, server);
 }
 
-/* SYNTAX: WINDOW CLOSE [<first> [<last>] */
+/* SYNTAX: WINDOW CLOSE [<first> [<last>]] */
 static void cmd_window_close(const char *data)
 {
         GSList *tmp, *destroys;
@@ -77,7 +201,7 @@ static void cmd_window_close(const char *data)
        }
 
        first_num = *first == '\0' ? active_win->refnum : atoi(first);
-       last_num = *last == '\0' ? active_win->refnum : atoi(last);
+       last_num = *last == '\0' ? first_num : atoi(last);
 
         /* get list of windows to destroy */
         destroys = NULL;
@@ -92,8 +216,14 @@ static void cmd_window_close(const char *data)
        while (destroys != NULL) {
                WINDOW_REC *rec = destroys->data;
 
-               if (windows->next != NULL)
-                       window_destroy(rec);
+               if (windows->next != NULL) {
+                       if (!rec->immortal)
+                               window_destroy(rec);
+                       else {
+                               printformat_window(rec, MSGLEVEL_CLIENTERROR,
+                                                  TXT_WINDOW_IMMORTAL_ERROR);
+                       }
+               }
 
                 destroys = g_slist_remove(destroys, rec);
        }
@@ -150,6 +280,8 @@ static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
 static void cmd_window_goto(const char *data)
 {
        WINDOW_REC *window;
+       char *target;
+       void *free_arg;
 
        g_return_if_fail(data != NULL);
 
@@ -158,13 +290,18 @@ static void cmd_window_goto(const char *data)
                return;
        }
 
-       if (g_strcasecmp(data, "active") == 0)
+       if (!cmd_get_params(data, &free_arg, 1, &target))
+               return;
+
+       if (g_strcasecmp(target, "active") == 0)
                 window = window_highest_activity(active_win);
        else
-                window = window_find_item(active_win->active_server, data);
+                window = window_find_item(active_win->active_server, target);
 
        if (window != NULL)
                window_set_active(window);
+
+       cmd_params_free(free_arg);
 }
 
 /* SYNTAX: WINDOW NEXT */
@@ -212,6 +349,36 @@ static void cmd_window_level(const char *data)
        g_free(level);
 }
 
+/* SYNTAX: WINDOW IMMORTAL on|off|toggle */
+static void cmd_window_immortal(const char *data)
+{
+       int set;
+
+       if (*data == '\0')
+               set = active_win->immortal;
+       else if (g_strcasecmp(data, "ON") == 0)
+                set = TRUE;
+       else if (g_strcasecmp(data, "OFF") == 0)
+                set = FALSE;
+       else if (g_strcasecmp(data, "TOGGLE") == 0)
+                set = !active_win->immortal;
+       else {
+               printformat_window(active_win, MSGLEVEL_CLIENTERROR,
+                                  TXT_NOT_TOGGLE);
+               return;
+       }
+
+       if (set) {
+                window_set_immortal(active_win, TRUE);
+               printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
+                                  TXT_WINDOW_SET_IMMORTAL);
+       } else {
+                window_set_immortal(active_win, FALSE);
+               printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
+                                  TXT_WINDOW_UNSET_IMMORTAL);
+       }
+}
+
 /* SYNTAX: WINDOW SERVER [-sticky | -unsticky] <tag> */
 static void cmd_window_server(const char *data)
 {
@@ -224,7 +391,7 @@ static void cmd_window_server(const char *data)
                            "window server", &optlist, &tag))
                return;
 
-       if (*tag == '\0' &&
+       if (*tag == '\0' && active_win->active_server != NULL &&
            (g_hash_table_lookup(optlist, "sticky") != NULL ||
             g_hash_table_lookup(optlist, "unsticky") != NULL)) {
                tag = active_win->active_server->tag;
@@ -233,12 +400,14 @@ static void cmd_window_server(const char *data)
        if (*tag == '\0')
                cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
        server = server_find_tag(tag);
+       if (server == NULL)
+               server = server_find_lookup_tag(tag);
 
        if (g_hash_table_lookup(optlist, "unsticky") != NULL &&
            active_win->servertag != NULL) {
                g_free_and_null(active_win->servertag);
                printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
-                                  TXT_UNSET_SERVER_STICKY, server->tag);
+                                  TXT_UNSET_SERVER_STICKY);
        }
 
        if (active_win->servertag != NULL &&
@@ -268,7 +437,12 @@ static void cmd_window_server(const char *data)
 
 static void cmd_window_item(const char *data, void *server, WI_ITEM_REC *item)
 {
-       command_runsub("window item", data, server, item);
+        while (*data == ' ') data++;
+
+       if (is_numeric(data, '\0'))
+               signal_emit("command window item goto", 3, data, server, item);
+       else
+               command_runsub("window item", data, server, item);
 }
 
 /* SYNTAX: WINDOW ITEM PREV */
@@ -283,32 +457,54 @@ static void cmd_window_item_next(void)
        window_item_next(active_win);
 }
 
-/* SYNTAX: WINDOW ITEM GOTO <name> */
+/* SYNTAX: WINDOW ITEM GOTO <number>|<name> */
 static void cmd_window_item_goto(const char *data, SERVER_REC *server)
 {
-        WI_ITEM_REC *item;
+       WI_ITEM_REC *item;
+       GSList *tmp;
+       void *free_arg;
+       char *target;
+       
+       if (!cmd_get_params(data, &free_arg, 1, &target))
+               return;
+
+       if (is_numeric(target, '\0')) {
+               /* change to specified number */
+               tmp = g_slist_nth(active_win->items, atoi(target)-1);
+               item = tmp == NULL ? NULL : tmp->data;
+       } else {
+               item = window_item_find_window(active_win, server, target);
+       }
 
-        item = window_item_find_window(active_win, server, data);
         if (item != NULL)
                 window_item_set_active(active_win, item);
+
+       cmd_params_free(free_arg);
 }
 
 /* SYNTAX: WINDOW ITEM MOVE <number>|<name> */
 static void cmd_window_item_move(const char *data, SERVER_REC *server,
                                  WI_ITEM_REC *item)
 {
-        WINDOW_REC *window;
+       WINDOW_REC *window;
+       void *free_arg;
+       char *target;
+
+       if (!cmd_get_params(data, &free_arg, 1, &target))
+               return;
 
-        if (is_numeric(data, '\0')) {
+        if (is_numeric(target, '\0')) {
                 /* move current window item to specified window */
-                window = window_find_refnum(atoi(data));
+                window = window_find_refnum(atoi(target));
         } else {
                 /* move specified window item to current window */
-                item = window_item_find(server, data);
+                item = window_item_find(server, target);
                 window = active_win;
         }
         if (window != NULL && item != NULL)
-                window_item_set_active(window, item);
+               window_item_set_active(window, item);
+
+       cmd_params_free(free_arg);
 }
 
 /* SYNTAX: WINDOW NUMBER [-sticky] <number> */
@@ -342,85 +538,108 @@ static void cmd_window_number(const char *data)
 /* SYNTAX: WINDOW NAME <name> */
 static void cmd_window_name(const char *data)
 {
-        window_set_name(active_win, data);
+       WINDOW_REC *win;
+
+       win = window_find_name(data);
+       if (win == NULL || win == active_win)
+               window_set_name(active_win, data);
+       else if (active_win->name == NULL ||
+                strcmp(active_win->name, data) != 0) {
+               printformat_window(active_win, MSGLEVEL_CLIENTERROR,
+                                  TXT_WINDOW_NAME_NOT_UNIQUE, data);
+       }
+}
+
+/* SYNTAX: WINDOW HISTORY <name> */
+void cmd_window_history(const char *data)
+{
+       window_set_history(active_win, data);
 }
 
 /* we're moving the first window to last - move the first contiguous block
    of refnums to left. Like if there's windows 1..5 and 7..10, move 1 to
-   11, 2..5 to 1..4 and leave 7..10 alone  */
-static void windows_move_left(WINDOW_REC *move_window)
+   11, 2..5 to 1..4 and leave 7..10 alone */
+static void window_refnums_move_left(WINDOW_REC *move_window)
 {
        WINDOW_REC *window;
-       int refnum;
+       int refnum, new_refnum;
 
-       window_set_refnum(move_window, windows_refnum_last()+1);
-       for (refnum = 2;; refnum++) {
+        new_refnum = windows_refnum_last();
+       for (refnum = move_window->refnum+1; refnum <= new_refnum; refnum++) {
                window = window_find_refnum(refnum);
-               if (window == NULL) break;
+               if (window == NULL) {
+                        new_refnum++;
+                       break;
+               }
 
                window_set_refnum(window, refnum-1);
        }
+
+       window_set_refnum(move_window, new_refnum);
 }
 
 /* we're moving the last window to first - make some space so we can use the
    refnum 1 */
-static void windows_move_right(WINDOW_REC *move_window)
+static void window_refnums_move_right(WINDOW_REC *move_window)
 {
        WINDOW_REC *window;
-       int refnum;
+       int refnum, new_refnum;
+
+        new_refnum = 1;
+       if (window_find_refnum(new_refnum) == NULL) {
+               window_set_refnum(move_window, new_refnum);
+                return;
+       }
 
        /* find the first unused refnum, like if there's windows
           1..5 and 7..10, we only need to move 1..5 to 2..6 */
-       refnum = 1;
-       while (window_find_refnum(refnum) != NULL) refnum++;
-
+       refnum = new_refnum;
+       while (move_window->refnum == refnum ||
+              window_find_refnum(refnum) != NULL) refnum++;
        refnum--;
-       while (refnum > 0) {
+
+       while (refnum >= new_refnum) {
                window = window_find_refnum(refnum);
-               g_return_if_fail(window != NULL);
-               window_set_refnum(window, window == move_window ? 1 : refnum+1);
+               window_set_refnum(window, refnum+1);
 
                refnum--;
        }
+
+       window_set_refnum(move_window, new_refnum);
 }
 
-static void cmd_window_move_left(void)
+/* SYNTAX: WINDOW MOVE PREV */
+static void cmd_window_move_prev(void)
 {
        int refnum;
 
-       refnum = window_refnum_prev(active_win->refnum, TRUE);
+       refnum = window_refnum_prev(active_win->refnum, FALSE);
        if (refnum != -1) {
                window_set_refnum(active_win, refnum);
                return;
        }
 
-       windows_move_left(active_win);
+       window_refnums_move_left(active_win);
 }
 
-static void cmd_window_move_right(void)
+/* SYNTAX: WINDOW MOVE NEXT */
+static void cmd_window_move_next(void)
 {
        int refnum;
 
-       refnum = window_refnum_next(active_win->refnum, TRUE);
+       refnum = window_refnum_next(active_win->refnum, FALSE);
        if (refnum != -1) {
                window_set_refnum(active_win, refnum);
                return;
        }
 
-        windows_move_right(active_win);
+        window_refnums_move_right(active_win);
 }
 
-/* SYNTAX: WINDOW MOVE <number>|left|right */
-static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+static void active_window_move_to(int new_refnum)
 {
-       int new_refnum, refnum;
-
-       if (!is_numeric(data, 0)) {
-               command_runsub("window move", data, server, item);
-                return;
-       }
+       int refnum;
 
-       new_refnum = atoi(data);
        if (new_refnum > active_win->refnum) {
                for (;;) {
                        refnum = window_refnum_next(active_win->refnum, FALSE);
@@ -440,6 +659,29 @@ static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *i
        }
 }
 
+/* SYNTAX: WINDOW MOVE FIRST */
+static void cmd_window_move_first(void)
+{
+       active_window_move_to(1);
+}
+
+/* SYNTAX: WINDOW MOVE LAST */
+static void cmd_window_move_last(void)
+{
+       active_window_move_to(windows_refnum_last());
+}
+
+/* SYNTAX: WINDOW MOVE <number>|<direction> */
+static void cmd_window_move(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
+{
+       if (!is_numeric(data, 0)) {
+               command_runsub("window move", data, server, item);
+                return;
+       }
+
+       active_window_move_to(atoi(data));
+}
+
 /* SYNTAX: WINDOW LIST */
 static void cmd_window_list(void)
 {
@@ -454,7 +696,7 @@ static void cmd_window_list(void)
                levelstr = bits2level(rec->level);
                printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_WINDOWLIST_LINE,
                            rec->refnum, rec->name == NULL ? "" : rec->name,
-                           rec->active == NULL ? "" : rec->active->name,
+                           rec->active == NULL ? "" : rec->active->visible_name,
                            rec->active_server == NULL ? "" : ((SERVER_REC *) rec->active_server)->tag,
                            levelstr);
                g_free(levelstr);
@@ -463,23 +705,49 @@ static void cmd_window_list(void)
         printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_WINDOWLIST_FOOTER);
 }
 
-/* SYNTAX: WINDOW THEME <name> */
+/* SYNTAX: WINDOW THEME [-delete] [<name>] */
 static void cmd_window_theme(const char *data)
 {
        THEME_REC *theme;
+       GHashTable *optlist;
+        char *name;
+       void *free_arg;
 
-       g_free_not_null(active_win->theme_name);
-       active_win->theme_name = g_strdup(data);
+       if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
+                           "window theme", &optlist, &name))
+               return;
+
+       if (g_hash_table_lookup(optlist, "delete") != NULL) {
+               g_free_and_null(active_win->theme_name);
 
-       active_win->theme = theme = theme_load(data);
-       if (theme != NULL) {
                printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
-                                  TXT_WINDOW_THEME_CHANGED,
-                                  theme->name, theme->path);
+                                  TXT_WINDOW_THEME_REMOVED);
+       } else if (*name == '\0') {
+               if (active_win->theme == NULL) {
+                       printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
+                                          TXT_WINDOW_THEME_DEFAULT);
+               } else {
+                        theme = active_win->theme;
+                       printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
+                                          TXT_WINDOW_THEME,
+                                          theme->name, theme->path);
+               }
        } else {
-               printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
-                                  TXT_THEME_NOT_FOUND, data);
+               g_free_not_null(active_win->theme_name);
+               active_win->theme_name = g_strdup(data);
+
+               active_win->theme = theme = theme_load(data);
+               if (theme != NULL) {
+                       printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
+                                          TXT_WINDOW_THEME_CHANGED,
+                                          theme->name, theme->path);
+               } else {
+                       printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
+                                          TXT_THEME_NOT_FOUND, data);
+               }
        }
+
+       cmd_params_free(free_arg);
 }
 
 static void cmd_layout(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
@@ -491,17 +759,22 @@ static void cmd_layout(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 static void cmd_foreach_window(const char *data)
 {
         WINDOW_REC *old;
-       GSList *tmp;
+        GSList *list;
 
         old = active_win;
-       for (tmp = windows; tmp != NULL; tmp = tmp->next) {
-               WINDOW_REC *rec = tmp->data;
 
-                active_win = rec;
+       list = g_slist_copy(windows);
+       while (list != NULL) {
+               WINDOW_REC *rec = list->data;
+
+               active_win = rec;
                signal_emit("send command", 3, data, rec->active_server,
                            rec->active);
+                list = g_slist_remove(list, list->data);
        }
-        active_win = old;
+
+       if (g_slist_find(windows, old) != NULL)
+               active_win = old;
 }
 
 void window_commands_init(void)
@@ -517,6 +790,7 @@ void window_commands_init(void)
        command_bind("window next", NULL, (SIGNAL_FUNC) cmd_window_next);
        command_bind("window last", NULL, (SIGNAL_FUNC) cmd_window_last);
        command_bind("window level", NULL, (SIGNAL_FUNC) cmd_window_level);
+       command_bind("window immortal", NULL, (SIGNAL_FUNC) cmd_window_immortal);
        command_bind("window item", NULL, (SIGNAL_FUNC) cmd_window_item);
        command_bind("window item prev", NULL, (SIGNAL_FUNC) cmd_window_item_prev);
        command_bind("window item next", NULL, (SIGNAL_FUNC) cmd_window_item_next);
@@ -524,9 +798,12 @@ void window_commands_init(void)
        command_bind("window item move", NULL, (SIGNAL_FUNC) cmd_window_item_move);
        command_bind("window number", NULL, (SIGNAL_FUNC) cmd_window_number);
        command_bind("window name", NULL, (SIGNAL_FUNC) cmd_window_name);
+       command_bind("window history", NULL, (SIGNAL_FUNC) cmd_window_history);
        command_bind("window move", NULL, (SIGNAL_FUNC) cmd_window_move);
-       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 prev", NULL, (SIGNAL_FUNC) cmd_window_move_prev);
+       command_bind("window move next", NULL, (SIGNAL_FUNC) cmd_window_move_next);
+       command_bind("window move first", NULL, (SIGNAL_FUNC) cmd_window_move_first);
+       command_bind("window move last", NULL, (SIGNAL_FUNC) cmd_window_move_last);
        command_bind("window list", NULL, (SIGNAL_FUNC) cmd_window_list);
        command_bind("window theme", NULL, (SIGNAL_FUNC) cmd_window_theme);
        command_bind("layout", NULL, (SIGNAL_FUNC) cmd_layout);
@@ -538,6 +815,7 @@ void window_commands_init(void)
 
        command_set_options("window number", "sticky");
        command_set_options("window server", "sticky unsticky");
+       command_set_options("window theme", "delete");
 }
 
 void window_commands_deinit(void)
@@ -553,6 +831,7 @@ void window_commands_deinit(void)
        command_unbind("window next", (SIGNAL_FUNC) cmd_window_next);
        command_unbind("window last", (SIGNAL_FUNC) cmd_window_last);
        command_unbind("window level", (SIGNAL_FUNC) cmd_window_level);
+       command_unbind("window immortal", (SIGNAL_FUNC) cmd_window_immortal);
        command_unbind("window item", (SIGNAL_FUNC) cmd_window_item);
        command_unbind("window item prev", (SIGNAL_FUNC) cmd_window_item_prev);
        command_unbind("window item next", (SIGNAL_FUNC) cmd_window_item_next);
@@ -560,9 +839,12 @@ void window_commands_deinit(void)
        command_unbind("window item move", (SIGNAL_FUNC) cmd_window_item_move);
        command_unbind("window number", (SIGNAL_FUNC) cmd_window_number);
        command_unbind("window name", (SIGNAL_FUNC) cmd_window_name);
+       command_unbind("window history", (SIGNAL_FUNC) cmd_window_history);
        command_unbind("window move", (SIGNAL_FUNC) cmd_window_move);
-       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 prev", (SIGNAL_FUNC) cmd_window_move_prev);
+       command_unbind("window move next", (SIGNAL_FUNC) cmd_window_move_next);
+       command_unbind("window move first", (SIGNAL_FUNC) cmd_window_move_first);
+       command_unbind("window move last", (SIGNAL_FUNC) cmd_window_move_last);
        command_unbind("window list", (SIGNAL_FUNC) cmd_window_list);
        command_unbind("window theme", (SIGNAL_FUNC) cmd_window_theme);
        command_unbind("layout", (SIGNAL_FUNC) cmd_layout);