Applied fixed from cras to fix crashes in irssi.
[silc.git] / apps / irssi / src / fe-common / core / fe-windows.c
index d3f068e5826f2795892bd77b24517455dce479ac..2370facb239552247a1f1c926c627935141bc0ea 100644 (file)
@@ -70,6 +70,7 @@ WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic)
 
        rec = g_new0(WINDOW_REC, 1);
        rec->refnum = window_get_new_refnum();
+       rec->level = level2bits(settings_get_str("window_default_level"));
 
        windows = g_slist_prepend(windows, rec);
        signal_emit("window created", 2, rec, GINT_TO_POINTER(automatic));
@@ -159,6 +160,9 @@ void window_set_active(WINDOW_REC *window)
 
 void window_change_server(WINDOW_REC *window, void *server)
 {
+        if (server != NULL && SERVER(server)->disconnected)
+                return;
+
        window->active_server = server;
        signal_emit("window server changed", 2, window, server);
 }
@@ -237,36 +241,43 @@ char *window_get_active_name(WINDOW_REC *window)
        return window->name;
 }
 
+#define WINDOW_LEVEL_MATCH(window, server, level) \
+       (((window)->level & level) && \
+        (server == NULL || (window)->active_server == server))
+
 WINDOW_REC *window_find_level(void *server, int level)
 {
-       WINDOW_REC *match;
        GSList *tmp;
 
-       match = NULL;
+        /* prefer active window if possible */
+       if (active_win != NULL &&
+           WINDOW_LEVEL_MATCH(active_win, server, level))
+                return active_win;
+
        for (tmp = windows; tmp != NULL; tmp = tmp->next) {
                WINDOW_REC *rec = tmp->data;
 
-               if ((server == NULL || rec->active_server == server) &&
-                   (rec->level & level)) {
-                       if (server == NULL || rec->active_server == server)
-                               return rec;
-                       match = rec;
-               }
+               if (WINDOW_LEVEL_MATCH(rec, server, level))
+                        return rec;
        }
 
-       return match;
+       return NULL;
 }
 
 WINDOW_REC *window_find_closest(void *server, const char *name, int level)
 {
-       WINDOW_REC *window;
+       WINDOW_REC *window,*namewindow=NULL;
        WI_ITEM_REC *item;
 
        /* match by name */
        item = name == NULL ? NULL :
                window_item_find(server, name);
-       if (item != NULL)
-                return window_item_window(item);
+       if (item != NULL) {
+               namewindow = window_item_window(item);
+               if (namewindow != NULL && ((namewindow->level & level) != 0 ||
+                   !settings_get_bool("window_check_level_first")))
+                 return namewindow;
+       }
 
        /* match by level */
        if (level != MSGLEVEL_HILIGHT)
@@ -278,6 +289,9 @@ WINDOW_REC *window_find_closest(void *server, const char *name, int level)
        window = window_find_level(NULL, level);
        if (window != NULL) return window;
 
+       /* still return item's window if we didnt find anything */
+       if (namewindow != NULL) return namewindow;
+
        /* fallback to active */
        return active_win;
 }
@@ -602,6 +616,8 @@ void windows_init(void)
        daycheck = 0; daytag = -1;
        settings_add_bool("lookandfeel", "window_auto_change", FALSE);
        settings_add_bool("lookandfeel", "windows_auto_renumber", TRUE);
+       settings_add_bool("lookandfeel", "window_check_level_first", FALSE);
+       settings_add_str("lookandfeel", "window_default_level", "NONE");
 
        read_settings();
        signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);