From 2eff5d815d33c0d2005d7cb11ff4a352c3438d4c Mon Sep 17 00:00:00 2001 From: joncruz Date: Mon, 25 Aug 2008 11:41:38 +0000 Subject: [PATCH] Cleanup of named icon background rendering and added pref for workaround --- src/preferences-skeleton.h | 1 + src/ui/dialog/inkscape-preferences.cpp | 3 + src/ui/dialog/inkscape-preferences.h | 2 +- src/widgets/icon.cpp | 87 +++++++++++++++++++------- 4 files changed, 68 insertions(+), 25 deletions(-) diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 6a14b044a..b8ba12af5 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -269,6 +269,7 @@ static char const preferences_skeleton[] = " masks=\"65535\"/>\n" // 0x0000ffff " \n" " \n" +" \n" " \n" " \n" diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 8a2a44ccc..62c8750e2 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1065,6 +1065,9 @@ void InkscapePreferences::initPageMisc() _page_misc.add_line( false, _("Latency skew:"), _misc_latency_skew, _("(requires restart)"), _("Factor by which the event clock is skewed from the actual time (0.9766 on some systems)."), false); + _misc_namedicon_delay.init( _("Pre-render named icons"), "options.iconrender", "named_nodelay", false); + _page_misc.add_line( false, "", _misc_namedicon_delay, "", + _("When on, named icons will be rendered before displaying the ui. This is for working around bugs in GTK+ named icon notification"), true); this->AddPage(_page_misc, _("Misc"), PREFS_PAGE_MISC); } diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 448f30368..2dd0ca4df 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -167,7 +167,7 @@ protected: PrefSpinButton _importexport_export, _misc_recent, _misc_simpl; PrefSpinButton _misc_latency_skew; - PrefCheckButton _misc_comment, _misc_forkvectors, _misc_scripts; + PrefCheckButton _misc_comment, _misc_forkvectors, _misc_scripts, _misc_namedicon_delay; PrefCombo _misc_small_toolbar; PrefCombo _misc_small_secondary; PrefCombo _misc_small_tools; diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index cdd356871..41c4ca5df 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -95,7 +95,6 @@ public: static Glib::RefPtr inkyIcons; static std::map > iconSetCache; -static std::map mapHandlerMap; GtkType sp_icon_get_type() @@ -264,6 +263,7 @@ static void sp_icon_theme_changed( SPIcon *icon ) static void imageMapCB(GtkWidget* widget, gpointer user_data); +static void imageMapNamedCB(GtkWidget* widget, gpointer user_data); static void populate_placeholder_icon(gchar const* name, unsigned lsize); static bool prerender_icon(gchar const *name, unsigned lsize, unsigned psize); static Glib::ustring icon_cache_key(gchar const *name, unsigned lsize, unsigned psize); @@ -297,11 +297,19 @@ sp_icon_new_full( Inkscape::IconSize lsize, gchar const *name ) setupLegacyNaming(); } + bool flagMe = false; if ( legacyNames.find(name) != legacyNames.end() ) { img = gtk_image_new_from_icon_name( name, iconSizeLookup[trySize] ); + flagMe = true; + if ( dump ) { + g_message("gtk_image_new_from_icon_name( '%s', %d ) = %p", name, iconSizeLookup[trySize], img); + GtkImageType thing = gtk_image_get_storage_type(GTK_IMAGE(img)); + g_message(" Type is %d %s", (int)thing, (thing == GTK_IMAGE_EMPTY ? "Empty" : "ok")); + } } else { img = gtk_image_new_from_stock( name, iconSizeLookup[trySize] ); } + if ( img ) { GtkImageType type = gtk_image_get_storage_type( GTK_IMAGE(img) ); if ( type == GTK_IMAGE_STOCK ) { @@ -311,8 +319,7 @@ sp_icon_new_full( Inkscape::IconSize lsize, gchar const *name ) addPreRender( lsize, name ); // Add a hook to render if set visible before prerender is done. - gulong handlerId = g_signal_connect( G_OBJECT(img), "map", G_CALLBACK(imageMapCB), GINT_TO_POINTER(0) ); - mapHandlerMap[img] = handlerId; + g_signal_connect( G_OBJECT(img), "map", G_CALLBACK(imageMapCB), GINT_TO_POINTER(0) ); } widget = GTK_WIDGET(img); img = 0; @@ -322,7 +329,16 @@ sp_icon_new_full( Inkscape::IconSize lsize, gchar const *name ) } else if ( type == GTK_IMAGE_ICON_NAME ) { widget = GTK_WIDGET(img); img = 0; - addPreRender( lsize, name ); + + // Add a hook to render if set visible before prerender is done. + g_signal_connect( G_OBJECT(widget), "map", G_CALLBACK(imageMapNamedCB), GINT_TO_POINTER(0) ); + + if ( prefs_get_int_attribute_limited( "options.iconrender", "named_nodelay", 0, 0, 1 ) ) { + int psize = sp_icon_get_phys_size(lsize); + prerender_icon(name, lsize, psize); + } else { + addPreRender( lsize, name ); + } } else { if ( dump ) { g_message( "skipped gtk '%s' %d (not GTK_IMAGE_STOCK)", name, lsize ); @@ -859,11 +875,14 @@ static void populate_placeholder_icon(gchar const* name, unsigned lsize) } static void addToIconSet(GdkPixbuf* pb, gchar const* name, unsigned lsize, unsigned psize) { + static gint dump = prefs_get_int_attribute_limited( "debug.icons", "dumpGtk", 0, 0, 1 ); GtkStockItem stock; gboolean stockFound = gtk_stock_lookup( name, &stock ); if ( !stockFound ) { Gtk::IconTheme::add_builtin_icon( name, psize, Glib::wrap(pb) ); - //g_message(" set in a builtin for %s:%d:%d", name, lsize, psize); + if (dump) { + g_message(" set in a builtin for %s:%d:%d", name, lsize, psize); + } } for ( std::vector::iterator it = iconSetCache[name].begin(); it != iconSetCache[name].end(); ++it ) { @@ -890,6 +909,7 @@ static void addToIconSet(GdkPixbuf* pb, gchar const* name, unsigned lsize, unsig // returns true if icon needed preloading, false if nothing was done bool prerender_icon(gchar const *name, unsigned lsize, unsigned psize) { + static gint dump = prefs_get_int_attribute_limited( "debug.icons", "dumpGtk", 0, 0, 1 ); Glib::ustring key = icon_cache_key(name, lsize, psize); GdkPixbuf *pb = get_cached_pixbuf(key); if (pb) { @@ -899,6 +919,9 @@ bool prerender_icon(gchar const *name, unsigned lsize, unsigned psize) if ( !px ) { // check for a fallback name if ( legacyNames.find(name) != legacyNames.end() ) { + if ( dump ) { + g_message("load_svg_pixels([%s]=%s, %d, %d)", name, legacyNames[name].c_str(), lsize, psize); + } px = load_svg_pixels(legacyNames[name].c_str(), lsize, psize); } } @@ -909,6 +932,8 @@ bool prerender_icon(gchar const *name, unsigned lsize, unsigned psize) (GdkPixbufDestroyNotify)g_free, NULL); pb_cache[key] = pb; addToIconSet(pb, name, lsize, psize); + } else if (dump) { + g_message("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX error!!! pixels not found for '%s'", name); } return true; } @@ -1005,9 +1030,7 @@ public: }; -#include - -static std::queue pendingRenders; +static std::vector pendingRenders; static bool callbackHooked = false; static void addPreRender( Inkscape::IconSize lsize, gchar const *name ) @@ -1018,7 +1041,7 @@ static void addPreRender( Inkscape::IconSize lsize, gchar const *name ) g_idle_add_full( G_PRIORITY_LOW, &icon_prerender_task, NULL, NULL ); } - pendingRenders.push(preRenderItem(lsize, name)); + pendingRenders.push_back(preRenderItem(lsize, name)); } gboolean icon_prerender_task(gpointer /*data*/) { @@ -1026,7 +1049,7 @@ gboolean icon_prerender_task(gpointer /*data*/) { bool workDone = false; do { preRenderItem single = pendingRenders.front(); - pendingRenders.pop(); + pendingRenders.erase(pendingRenders.begin()); int psize = sp_icon_get_phys_size(single._lsize); workDone = prerender_icon(single._name.c_str(), single._lsize, psize); } while (!pendingRenders.empty() && !workDone); @@ -1040,32 +1063,48 @@ gboolean icon_prerender_task(gpointer /*data*/) { } } -void imageMapCB(GtkWidget* widget, gpointer /*user_data*/) { + +void imageMapCB(GtkWidget* widget, gpointer user_data) { gchar* id = 0; GtkIconSize size = GTK_ICON_SIZE_INVALID; gtk_image_get_stock(GTK_IMAGE(widget), &id, &size); if ( id ) { - int psize = sp_icon_get_phys_size(size); - prerender_icon(id, size, psize); - - std::vector& iconSet = iconSetCache[id]; - for ( std::vector::iterator it = iconSet.begin(); it != iconSet.end(); ++it ) { - GObject* obj = G_OBJECT(it->_pb); - if ( obj ) { + for ( std::vector::iterator it = pendingRenders.begin(); it != pendingRenders.end(); ++it ) { + if ( (it->_name == id) && (it->_lsize == static_cast(size)) ) { + int psize = sp_icon_get_phys_size(size); + prerender_icon(id, size, psize); + pendingRenders.erase(it); + break; } } } + g_signal_handlers_disconnect_by_func(widget, (gpointer)imageMapCB, user_data); +} - std::map::iterator it = mapHandlerMap.find(widget); +static void imageMapNamedCB(GtkWidget* widget, gpointer user_data) { + GtkImage* img = GTK_IMAGE(widget); + gchar const* iconName = 0; + GtkIconSize size = GTK_ICON_SIZE_INVALID; + gtk_image_get_icon_name(img, &iconName, &size); + if ( iconName ) { + GtkImageType type = gtk_image_get_storage_type( GTK_IMAGE(img) ); + if ( type == GTK_IMAGE_ICON_NAME ) { + for ( std::vector::iterator it = pendingRenders.begin(); it != pendingRenders.end(); ++it ) { + if ( (it->_name == iconName) && (it->_lsize == static_cast(size)) ) { + int psize = sp_icon_get_phys_size(size); + prerender_icon(iconName, size, psize); + pendingRenders.erase(it); + break; + } + } - if ( it != mapHandlerMap.end() ) { - gulong handlerId = it->second; - if ( g_signal_handler_is_connected(widget, handlerId) ) { - g_signal_handler_disconnect(widget, handlerId); + } else { + g_warning("UNEXPECTED TYPE of %d", (int)type); } - mapHandlerMap.erase(it); } + + g_signal_handlers_disconnect_by_func(widget, (gpointer)imageMapNamedCB, user_data); } -- 2.30.2