changeset 3961:cef19abfbbc9

Automated merge with ssh://hg.atheme.org//hg/audacious
author William Pitcock <nenolod@atheme.org>
date Sat, 17 Nov 2007 03:14:39 -0600
parents f4d7893a16f9 (current diff) a575c29cee05 (diff)
children d5426e967f03
files
diffstat 10 files changed, 220 insertions(+), 203 deletions(-) [+]
line wrap: on
line diff
--- a/src/audacious/glade/prefswin.glade	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/glade/prefswin.glade	Sat Nov 17 03:14:39 2007 -0600
@@ -1990,7 +1990,7 @@
 			      <child>
 				<widget class="GtkRadioButton" id="playlist_metadata_on_display">
 				  <property name="visible">True</property>
-				  <property name="tooltip" translatable="yes">Load metadata on demand when displaying the file in the playlist</property>
+				  <property name="tooltip" translatable="yes">Load metadata on demand when displaying the file in the playlist. You may need to set &quot;Detect file formats on demand&quot; in Audio page for full benefit.</property>
 				  <property name="can_focus">True</property>
 				  <property name="label" translatable="yes">On display</property>
 				  <property name="use_underline">True</property>
@@ -3968,7 +3968,7 @@
 			      <child>
 				<widget class="GtkCheckButton" id="detect_by_extension_cb">
 				  <property name="visible">True</property>
-				  <property name="tooltip" translatable="yes">When checked, Audacious will detect file formats based by extension. This is slightly slower than detection on demand, but still provides a minimal level of format detection.</property>
+				  <property name="tooltip" translatable="yes">When checked, Audacious will detect file formats based by extension. Only files with extensions of supported formats will be loaded.</property>
 				  <property name="can_focus">True</property>
 				  <property name="label" translatable="yes">Detect file formats by extension.</property>
 				  <property name="use_underline">True</property>
--- a/src/audacious/input.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/input.c	Sat Nov 17 03:14:39 2007 -0600
@@ -306,6 +306,60 @@
     }
 }
 
+
+/* do actual probing. this function is called from input_check_file() */
+static ProbeResult *
+input_do_check_file(InputPlugin *ip, VFSFile *fd, gchar *filename_proxy, gboolean loading)
+{
+    ProbeResult *pr = NULL;
+    gint result = 0;
+
+    g_return_val_if_fail(fd != NULL, NULL);
+
+    vfs_rewind(fd);
+
+    if (ip->probe_for_tuple &&
+        cfg.use_pl_metadata &&
+        (!loading || (loading && cfg.get_info_on_load)) ) {
+
+        Tuple *tuple = ip->probe_for_tuple(filename_proxy, fd);
+
+        if (tuple != NULL) {
+            pr = g_new0(ProbeResult, 1);
+            pr->ip = ip;
+            pr->tuple = tuple;
+            tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy));
+
+            return pr;
+        }
+    }
+
+    else if (ip->is_our_file_from_vfs != NULL) {
+        result = ip->is_our_file_from_vfs(filename_proxy, fd);
+
+        if (result > 0) {
+            pr = g_new0(ProbeResult, 1);
+            pr->ip = ip;
+
+            return pr;
+        }
+    }
+
+    else if (ip->is_our_file != NULL) {
+        result = ip->is_our_file(filename_proxy);
+
+        if (result > 0) {
+            pr = g_new0(ProbeResult, 1);
+            pr->ip = ip;
+
+            return pr;
+        }
+    }
+
+    return NULL;
+}
+
+
 /*
  * input_check_file()
  *
@@ -341,9 +395,15 @@
  * Adapted to return ProbeResult structure.
  *
  * --nenolod, Jul 20 2007
+ *
+ * Make use of ext_hash to avoid full scan in input list.
+ *
+ * --yaz, Nov 16 2007
  */
+
+/* if loading is TRUE, tuple probing can be skipped as regards configuration. */
 ProbeResult *
-input_check_file(const gchar * filename, gboolean show_warning)
+input_check_file(const gchar *filename, gboolean loading)
 {
     VFSFile *fd;
     GList *node;
@@ -351,20 +411,23 @@
     gchar *filename_proxy;
     gint ret = 1;
     gchar *ext, *tmp, *tmp_uri;
-    gboolean use_ext_filter;
+    gboolean use_ext_filter = FALSE;
     gchar *mimetype;
     ProbeResult *pr = NULL;
+    GList **list_hdr = NULL;
+    extern GHashTable *ext_hash;
 
     filename_proxy = g_strdup(filename);
 
+
     /* Some URIs will end in ?<subsong> to determine the subsong requested. */
     tmp_uri = g_strdup(filename);
-
     tmp = strrchr(tmp_uri, '?');
 
     if (tmp != NULL && g_ascii_isdigit(*(tmp + 1)))
         *tmp = '\0';
 
+
     /* Check for plugins with custom URI:// strings */
     /* cue:// cdda:// tone:// tact:// */
     if ((ip = uri_get_plugin(filename)) != NULL && ip->enabled)
@@ -384,6 +447,8 @@
         return NULL;
     }
 
+
+    // open the file with vfs sub-system
     fd = vfs_buffered_file_new_from_uri(tmp_uri);
     g_free(tmp_uri);
 
@@ -393,149 +458,90 @@
         return NULL;
     }
 
-    ext = strrchr(filename_proxy, '.') + 1;
 
-    use_ext_filter =
-        (fd != NULL && (!g_strncasecmp(filename, "/", 1) ||
-                        !g_strncasecmp(filename, "file://", 7))) ? TRUE : FALSE;
-
+    // apply mimetype check. note that stdio does not support mimetype check.
     mimetype = vfs_get_metadata(fd, "content-type");
-    if ((ip = mime_get_plugin(mimetype)) != NULL && ip->enabled)
-    {
-        if (ip->probe_for_tuple != NULL)
-        {
-            Tuple *tuple = ip->probe_for_tuple(filename_proxy, fd);
+    if ((ip = mime_get_plugin(mimetype)) != NULL && ip->enabled) {
+        while(1) {
+            if (!ip || !ip->enabled)
+                continue;
 
-            if (tuple != NULL)
-            {
+            pr = input_do_check_file(ip, fd, filename_proxy, loading);
+
+            if(pr) {
                 g_free(filename_proxy);
                 vfs_fclose(fd);
-
-                pr = g_new0(ProbeResult, 1);
-                pr->ip = ip;
-                pr->tuple = tuple;
-                tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy));
-
-                return pr;
-            }
-        }
-        else if (fd && ip->is_our_file_from_vfs != NULL)
-        {
-            ret = ip->is_our_file_from_vfs(filename_proxy, fd);
-
-            if (ret > 0)
-            {
-                g_free(filename_proxy);
-                vfs_fclose(fd);
-
-                pr = g_new0(ProbeResult, 1);
-                pr->ip = ip;
-
-                return pr;
-            }
-        }
-        else if (ip->is_our_file != NULL)
-        {
-            ret = ip->is_our_file(filename_proxy);
-
-            if (ret > 0)
-            {
-                g_free(filename_proxy);
-                vfs_fclose(fd);
-
-                pr = g_new0(ProbeResult, 1);
-                pr->ip = ip;
-
                 return pr;
             }
         }
     }
 
-    for (node = get_input_list(); node != NULL; node = g_list_next(node))
-    {
+
+    // apply ext_hash check
+    if(cfg.use_extension_probing) {
+        use_ext_filter =
+            (fd != NULL && (!g_strncasecmp(filename, "/", 1) ||
+                            !g_strncasecmp(filename, "file://", 7))) ? TRUE : FALSE;
+    }
+
+    if(use_ext_filter) {
+        gchar *base, *lext;
+        gchar *tmp2 = g_filename_from_uri(filename_proxy, NULL, NULL);
+        gchar *realfn = g_strdup(tmp2 ? tmp2 : filename_proxy);
+        g_free(tmp2);
+
+        base = g_path_get_basename(realfn);
+        g_free(realfn);
+        ext = strrchr(base, '.');
+    
+        if(ext) {
+            lext = g_ascii_strdown(ext+1, -1);
+            list_hdr = g_hash_table_lookup(ext_hash, lext);
+            g_free(lext);
+        }
+        g_free(base);
+
+        if(list_hdr) {
+            for(node = *list_hdr; node != NULL; node = g_list_next(node)) {
+                ip = INPUT_PLUGIN(node->data);
+
+                if (!ip || !ip->enabled)
+                    continue;
+
+                pr = input_do_check_file(ip, fd, filename_proxy, loading);
+
+                if(pr) {
+                    g_free(filename_proxy);
+                    vfs_fclose(fd);
+                    return pr;
+                }
+            }
+        }
+
+        return NULL; // no plugin found.
+    }
+
+
+    // do full scan when extension match isn't specified.
+    for (node = get_input_list(); node != NULL; node = g_list_next(node)) {
         ip = INPUT_PLUGIN(node->data);
 
         if (!ip || !ip->enabled)
             continue;
 
-        vfs_rewind(fd);
-
-        if (cfg.use_extension_probing == TRUE && ip->vfs_extensions != NULL &&
-            ext != NULL && ext != (gpointer) 0x1 && use_ext_filter == TRUE)
-        {
-            gint i;
-            gboolean is_our_ext = FALSE;
-
-            for (i = 0; ip->vfs_extensions[i] != NULL; i++)
-            {
-                if (str_has_prefix_nocase(ext, ip->vfs_extensions[i]))
-                {
-                    is_our_ext = TRUE;
-                    break;
-                }
-            }
-
-            /* not a plugin that supports this extension */
-            if (is_our_ext == FALSE) 
-                continue;
-        }
-
-        if (fd && ip->probe_for_tuple != NULL)
-        {
-            Tuple *tuple = ip->probe_for_tuple(filename_proxy, fd);
-
-            if (tuple != NULL)
-            {
-                g_free(filename_proxy);
-                vfs_fclose(fd);
-
-                pr = g_new0(ProbeResult, 1);
-                pr->ip = ip;
-                pr->tuple = tuple;
-                tuple_associate_int(pr->tuple, FIELD_MTIME, NULL, input_get_mtime(filename_proxy));
+        pr = input_do_check_file(ip, fd, filename_proxy, loading);
 
-                return pr;
-            }
-        }
-        else if (fd && ip->is_our_file_from_vfs != NULL)
-        {
-            ret = ip->is_our_file_from_vfs(filename_proxy, fd);
-
-            if (ret > 0)
-            {
-                g_free(filename_proxy);
-                vfs_fclose(fd);
-
-                pr = g_new0(ProbeResult, 1);
-                pr->ip = ip;
-
-                return pr;
-            }
+        if(pr) {
+            g_free(filename_proxy);
+            vfs_fclose(fd);
+            return pr;
         }
-        else if (ip->is_our_file != NULL)
-        {
-            ret = ip->is_our_file(filename_proxy);
-
-            if (ret > 0)
-            {
-                g_free(filename_proxy);
-                vfs_fclose(fd);
-
-                pr = g_new0(ProbeResult, 1);
-                pr->ip = ip;
-
-                return pr;
-            }
-        }
-
-        if (ret <= -1)
-            break;
     }
 
+
+    // all probing failed. return NULL
     g_free(filename_proxy);
-
     vfs_fclose(fd);
-
     return NULL;
 }
 
--- a/src/audacious/input.h	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/input.h	Sat Nov 17 03:14:39 2007 -0600
@@ -47,7 +47,7 @@
 InputVisType input_get_vis_type();
 void free_vis_data(void);
 
-ProbeResult *input_check_file(const gchar * filename, gboolean show_warning);
+ProbeResult *input_check_file(const gchar * filename, gboolean loading);
 Tuple *input_get_song_tuple(const gchar * filename);
 
 void input_play(gchar * filename);
--- a/src/audacious/main.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/main.c	Sat Nov 17 03:14:39 2007 -0600
@@ -207,8 +207,8 @@
     TRUE,                       /* show seperators in pl */
     NULL,           /* chardet_detector */
     NULL,           /* chardet_fallback */
-    500,           /* audio buffer size */
-    FALSE,          /* whether or not to postpone format detection on initial add */
+    500,            /* audio buffer size */
+    TRUE,           /* whether or not to postpone format detection on initial add */
     TRUE,           /* show filepopup for tuple */
     NULL,           /* words identifying covers */
     NULL,           /* words that might not show up in cover names */
--- a/src/audacious/playlist.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/playlist.c	Sat Nov 17 03:14:39 2007 -0600
@@ -777,6 +777,7 @@
     g_return_val_if_fail(playlist != NULL, FALSE);
     g_return_val_if_fail(filename != NULL, FALSE);
 
+    /* load playlist */
     if (is_playlist_name(filename)) {
         playlist->loading_playlist = TRUE;
         playlist_load_ins(playlist, filename, pos);
@@ -784,13 +785,20 @@
         return TRUE;
     }
 
-    if (playlist->loading_playlist == TRUE || cfg.playlist_detect == TRUE) {
+    /* audio file or uri */
+    if (playlist->loading_playlist == TRUE)
         dec = NULL;
-        if(!filter_by_extension(filename))
+
+    /* on demand probing is on */
+    if (cfg.playlist_detect == TRUE) { 
+        dec = NULL;
+        if(cfg.use_extension_probing && !filter_by_extension(filename))
             return FALSE;
     }
+    /* find decorder for non-remote uri i.e. local file */
     else if (!str_has_prefix_nocase(filename, "http://") && 
-             !str_has_prefix_nocase(filename, "https://")) {
+        !str_has_prefix_nocase(filename, "https://")) {
+
         pr = input_check_file(filename, TRUE);
 
         if (pr) {
@@ -800,13 +808,15 @@
         g_free(pr);
     }
 
-    if (cfg.playlist_detect == TRUE || playlist->loading_playlist == TRUE ||
+    /* add filename to playlist */
+    if (cfg.playlist_detect == TRUE ||
+        playlist->loading_playlist == TRUE ||
        (playlist->loading_playlist == FALSE && dec != NULL) ||
        (playlist->loading_playlist == FALSE && !is_playlist_name(filename) &&
         str_has_prefix_nocase(filename, "http"))) {
-        if(!filter_by_extension(filename))
-            return FALSE;
+
         __playlist_ins_with_info_tuple(playlist, filename, pos, tuple, dec);
+
         playlist_generate_shuffle_list(playlist);
         playlistwin_update_list(playlist);
         playlist_manager_update();
@@ -957,7 +967,7 @@
         filename = g_filename_to_uri(tmp, NULL, NULL);
         g_free(tmp);
 
-        if (vfs_file_test(filename, G_FILE_TEST_IS_DIR)) {
+        if (vfs_file_test(filename, G_FILE_TEST_IS_DIR)) { /* directory */
             GList *sub;
             gchar *dirfilename = g_filename_from_uri(filename, NULL, NULL);
             sub = playlist_dir_find_files(dirfilename, background, htab);
@@ -965,10 +975,13 @@
             g_free(filename);
             list = g_list_concat(list, sub);
         }
-        else if (cfg.playlist_detect == TRUE) {
-            if(filter_by_extension(filename)) {
+        else if (cfg.playlist_detect) { /* local file, no probing */
+            if(cfg.use_extension_probing) {
+                if(filter_by_extension(filename))
+                    list = g_list_prepend(list, filename);
+            }
+            else
                 list = g_list_prepend(list, filename);
-            }
         }
         else if ((pr = input_check_file(filename, TRUE)) != NULL)
         {
@@ -1725,16 +1738,16 @@
         if ((tmp = strrchr(path, '/')))
             *tmp = '\0';
         else {
-	    if ((playlist->loading_playlist == TRUE ||
-             cfg.playlist_detect == TRUE)) {
+            if ((playlist->loading_playlist == TRUE ||
+                 cfg.playlist_detect == TRUE)) {
                 pr = NULL;
                 if(!filter_by_extension(filename))
                     return;
-        }
-	    else if (!str_has_prefix_nocase(filename, "http://") && 
-	        !str_has_prefix_nocase(filename, "https://"))
-		pr = input_check_file(filename, FALSE);
-
+            }
+            else if (!str_has_prefix_nocase(filename, "http://") && 
+                     !str_has_prefix_nocase(filename, "https://")) {
+                pr = input_check_file(filename, TRUE);
+            }
             __playlist_ins_with_info(playlist, filename, pos, title, len, pr ? pr->ip : NULL);
             g_free(pr);
             return;
@@ -1746,9 +1759,10 @@
             if(!filter_by_extension(filename))
                 return;
         }
-    else if (!str_has_prefix_nocase(tmp, "http://") && 
-	    !str_has_prefix_nocase(tmp, "https://"))
-	    pr = input_check_file(tmp, FALSE);
+        else if (!str_has_prefix_nocase(tmp, "http://") && 
+                 !str_has_prefix_nocase(tmp, "https://")) {
+            pr = input_check_file(tmp, TRUE);
+        }
 
         __playlist_ins_with_info(playlist, tmp, pos, title, len, pr ? pr->ip : NULL);
         g_free(tmp);
@@ -1760,13 +1774,13 @@
         if ((playlist->loading_playlist == TRUE ||
              cfg.playlist_detect == TRUE)) {
             pr = NULL;
-        if(!filter_by_extension(filename))
-            return;
+            if(!filter_by_extension(filename))
+                return;
         }
-	else if (!str_has_prefix_nocase(filename, "http://") && 
-	    !str_has_prefix_nocase(filename, "https://"))
-	    pr = input_check_file(filename, FALSE);
-
+        else if (!str_has_prefix_nocase(filename, "http://") && 
+                 !str_has_prefix_nocase(filename, "https://")) {
+            pr = input_check_file(filename, TRUE);
+        }
         __playlist_ins_with_info(playlist, filename, pos, title, len, pr ? pr->ip : NULL);
         g_free(pr);
     }
@@ -1808,7 +1822,7 @@
             }
 	    else if (!str_has_prefix_nocase(filename, "http://") && 
 	        !str_has_prefix_nocase(filename, "https://"))
-	        pr = input_check_file(filename, FALSE);
+	        pr = input_check_file(filename, TRUE);
 
             __playlist_ins_with_info_tuple(playlist, filename, pos, tuple, pr ? pr->ip : NULL);
             g_free(pr);
@@ -1824,7 +1838,7 @@
         }
         else if (!str_has_prefix_nocase(filename, "http://") && 
             !str_has_prefix_nocase(filename, "https://"))
-            pr = input_check_file(filename, FALSE); //here! --yaz
+            pr = input_check_file(filename, TRUE);
 
         __playlist_ins_with_info_tuple(playlist, tmp, pos, tuple, pr ? pr->ip : NULL);
         g_free(tmp);
@@ -1841,7 +1855,7 @@
         }
         else if (!str_has_prefix_nocase(filename, "http://") && 
             !str_has_prefix_nocase(filename, "https://"))
-            pr = input_check_file(filename, FALSE);
+            pr = input_check_file(filename, TRUE);
 
         __playlist_ins_with_info_tuple(playlist, filename, pos, tuple, pr ? pr->ip : NULL);
         g_free(pr);
@@ -2611,28 +2625,6 @@
 }
 
 
-static gboolean
-playlist_get_info_scanning(void)
-{
-    gboolean result;
-
-    g_mutex_lock(mutex_scan);
-    result = playlist_get_info_scan_active;
-    g_mutex_unlock(mutex_scan);
-
-    return result;
-}
-
-
-static gboolean
-playlist_request_win_update(gpointer unused)
-{
-    Playlist *playlist = playlist_get_active();
-    playlistwin_update_list(playlist);
-    return FALSE; /* to be called only once */
-}
-
-
 static gpointer
 playlist_get_info_func(gpointer arg)
 {
@@ -2645,7 +2637,7 @@
 
         // on_load
         if (cfg.use_pl_metadata && cfg.get_info_on_load &&
-            playlist_get_info_scanning()) {
+            playlist_get_info_scan_active) {
 
             for (node = playlist->entries; node; node = g_list_next(node)) {
                 entry = node->data;
@@ -2695,7 +2687,7 @@
 
                  entry = node->data;
 
-                 if(playlist->attribute & PLAYLIST_STATIC || // live lock fix
+                 if(playlist->attribute & PLAYLIST_STATIC ||
                    (entry->tuple && tuple_get_int(entry->tuple, FIELD_LENGTH, NULL) > -1 &&
                     tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1)) {
                     update_playlistwin = TRUE;
@@ -2713,7 +2705,6 @@
                      tuple_get_int(entry->tuple, FIELD_LENGTH, NULL) > -1 &&
                      tuple_get_int(entry->tuple, FIELD_MTIME, NULL) != -1) {
                      update_playlistwin = TRUE;
-                     break;
                  }
             }
         } // on_demand
@@ -2733,13 +2724,11 @@
         }
 
         if (update_playlistwin) {
-            /* we are in a different thread, so we can't do UI updates directly;
-               instead, schedule a playlist update in the main loop --giacomo */
-            g_idle_add_full(G_PRIORITY_HIGH_IDLE, playlist_request_win_update, NULL, NULL);
+            event_queue("playlistwin update list", playlist_get_active());
             update_playlistwin = FALSE;
         }
 
-        if (playlist_get_info_scanning()) {
+        if (playlist_get_info_scan_active) {
             continue;
         }
 
@@ -3479,14 +3468,15 @@
     g_free(tmp);
 
     base = g_path_get_basename(filename);
-    ext = g_strrstr(base, ".");
+    ext = strrchr(base, '.');
 
     if(!ext) {
         g_free(base);
         return FALSE;
     }
 
-    lext = g_utf8_strdown(ext+1, -1);
+    lext = g_ascii_strdown(ext+1, -1);
+    g_free(base);
 
     if(g_hash_table_lookup(ext_hash, lext))
         rv = TRUE;
@@ -3494,6 +3484,5 @@
         rv = FALSE;
 
     g_free(lext);
-    g_free(base);
     return rv;
 }
--- a/src/audacious/playlist_evlisteners.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/playlist_evlisteners.c	Sat Nov 17 03:14:39 2007 -0600
@@ -26,6 +26,7 @@
 #include "playlist_evlisteners.h"
 
 #include "ui_main.h"
+#include "ui_playlist.h"
 
 static void
 playlist_evlistener_playlist_info_change(gpointer hook_data, gpointer user_data)
@@ -37,8 +38,16 @@
      g_free(msg);
 }
 
+static void
+playlist_evlistener_playlistwin_update_list(gpointer hook_data, gpointer user_data)
+{
+     Playlist *playlist = (Playlist *) hook_data;
+
+     playlistwin_update_list(playlist);
+}
+
 void playlist_evlistener_init(void)
 {
      hook_associate("playlist info change", playlist_evlistener_playlist_info_change, NULL);
+     hook_associate("playlistwin update list", playlist_evlistener_playlistwin_update_list, NULL);
 }
-
--- a/src/audacious/pluginenum.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/pluginenum.c	Sat Nov 17 03:14:39 2007 -0600
@@ -524,7 +524,16 @@
     gint i;
     if(p->vfs_extensions) {
         for(i = 0; p->vfs_extensions[i] != NULL; i++) {
-            g_hash_table_replace(ext_hash, g_strdup(p->vfs_extensions[i]), g_strdup(p->description));
+            GList *hdr = NULL;
+            GList **handle = NULL; //allocated as auto in stack.
+            GList **handle2 = g_malloc(sizeof(GList **));
+
+            handle = g_hash_table_lookup(ext_hash, p->vfs_extensions[i]);
+            if(handle)
+                hdr = *handle;
+            hdr = g_list_append(hdr, p); //returned hdr is non-volatile
+            *handle2 = hdr;
+            g_hash_table_replace(ext_hash, g_strdup(p->vfs_extensions[i]), handle2);
         }
     }
 }
--- a/src/audacious/ui_main.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/ui_main.c	Sat Nov 17 03:14:39 2007 -0600
@@ -593,9 +593,11 @@
     gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_info), bmp_active_skin->properties.mainwin_text_x,
         bmp_active_skin->properties.mainwin_text_y);
 
-    if (bmp_active_skin->properties.mainwin_text_width)
-    gtk_widget_set_size_request(mainwin_info, bmp_active_skin->properties.mainwin_text_width*(1+cfg.doublesize),
-        UI_SKINNED_TEXTBOX(mainwin_info)->height*(1+cfg.doublesize));
+    if (bmp_active_skin->properties.mainwin_text_width) {
+        UI_SKINNED_TEXTBOX(mainwin_info)->width = bmp_active_skin->properties.mainwin_text_width;
+        gtk_widget_set_size_request(mainwin_info, bmp_active_skin->properties.mainwin_text_width*(1+cfg.doublesize),
+                                    UI_SKINNED_TEXTBOX(mainwin_info)->height*(1+cfg.doublesize));
+    }
 
     if (bmp_active_skin->properties.mainwin_infobar_x && bmp_active_skin->properties.mainwin_infobar_y)
     gtk_fixed_move(GTK_FIXED(SKINNED_WINDOW(mainwin)->fixed), GTK_WIDGET(mainwin_othertext), bmp_active_skin->properties.mainwin_infobar_x,
--- a/src/audacious/ui_playlist.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/ui_playlist.c	Sat Nov 17 03:14:39 2007 -0600
@@ -225,10 +225,10 @@
 gboolean
 playlistwin_item_visible(gint index)
 {
-    if (index >= UI_SKINNED_PLAYLIST(playlistwin_list)->first
-        && index <
-        (UI_SKINNED_PLAYLIST(playlistwin_list)->first + UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible))
+    if (index >= UI_SKINNED_PLAYLIST(playlistwin_list)->first &&
+        index < (UI_SKINNED_PLAYLIST(playlistwin_list)->first + UI_SKINNED_PLAYLIST(playlistwin_list)->num_visible) ) {
         return TRUE;
+    }
     return FALSE;
 }
 
@@ -996,7 +996,7 @@
         playlistwin_scroll(-cfg.scroll_pl_by);
 
     // deactivating this fixed a gui freeze when scrolling. -- mf0102
-    //g_cond_signal(cond_scan);
+    g_cond_signal(cond_scan);
 
 }
 
@@ -1269,7 +1269,7 @@
 
     if (refresh) {
         // fixes keyboard scrolling gui freeze for me. -- mf0102
-        //g_cond_signal(cond_scan);
+        g_cond_signal(cond_scan);
         playlistwin_update_list(playlist_get_active());
     }
 
--- a/src/audacious/ui_skinned_textbox.c	Sat Nov 17 03:14:18 2007 -0600
+++ b/src/audacious/ui_skinned_textbox.c	Sat Nov 17 03:14:39 2007 -0600
@@ -363,6 +363,8 @@
             } else
                 g_signal_emit(widget, textbox_signals[CLICKED], 0);
 
+        } else if (event->button == 3) {
+            g_signal_emit(widget, textbox_signals[RIGHT_CLICKED], 0);
         } else
             priv->is_dragging = FALSE;
     } else if (event->type == GDK_2BUTTON_PRESS) {
@@ -382,8 +384,6 @@
 
     if (event->button == 1) {
         priv->is_dragging = FALSE;
-    } else if (event->button == 3) {
-        g_signal_emit(widget, textbox_signals[RIGHT_CLICKED], 0);
     }
 
     return TRUE;
@@ -591,10 +591,12 @@
                 if (priv->offset >= (priv->pixmap_width - textbox->width)) {
                     priv->scroll_back = TRUE;
                     priv->scroll_dummy = 0;
+                    priv->offset = priv->pixmap_width - textbox->width;
                 }
                 if (priv->offset <= 0) {
                     priv->scroll_back = FALSE;
                     priv->scroll_dummy = 0;
+                    priv->offset = 0;
                 }
             }
             else { // oneway scroll