Merge authors: Mirco Müller (macslow) ------------------------------------------------------------ revno: 408 [merge] committer: Mirco Müller <[email protected]> branch nick: notify-osd timestamp: Fri 2010-02-05 09:33:33 -0800 message: Merge changes and fixes from the karmic branch back into trunk. modified: configure.in src/bubble.c src/bubble.h src/defaults.c src/dialog.c src/display.c src/stack.c src/util.c src/util.h tests/test-text-filtering.c
-- lp:notify-osd https://code.launchpad.net/~notify-osd-developers/notify-osd/main Your team ayatana-commits is subscribed to branch lp:notify-osd. To unsubscribe from this branch go to https://code.launchpad.net/~notify-osd-developers/notify-osd/main/+edit-subscription.
=== modified file 'configure.in' --- configure.in 2009-10-01 08:59:24 +0000 +++ configure.in 2009-10-20 08:52:44 +0000 @@ -1,4 +1,4 @@ -AC_INIT(notify-osd, 0.9.23, [email protected]) +AC_INIT(notify-osd, 0.9.24, [email protected]) AC_CONFIG_SRCDIR(src/main.c) AC_CONFIG_HEADERS(config.h) === modified file 'src/bubble.c' --- src/bubble.c 2009-10-01 08:34:39 +0000 +++ src/bubble.c 2009-10-20 08:51:11 +0000 @@ -113,6 +113,12 @@ A }; +#define TEMPORARY_ICON_PREFIX_WORKAROUND 1 +#ifdef TEMPORARY_ICON_PREFIX_WORKAROUND +#warning "--== Using the icon-name-substitution! This is a temp. workaround not going to be maintained for long! ==--" +#define NOTIFY_OSD_ICON_PREFIX "notification" +#endif + // FIXME: this is in class Defaults already, but not yet hooked up so for the // moment we use the macros here, these values reflect the visual-guideline // for jaunty notifications @@ -965,21 +971,19 @@ // create pango desc/layout layout = pango_cairo_create_layout (cr); - desc = pango_font_description_new (); + text_font_face = defaults_get_text_font_face (d); + desc = pango_font_description_from_string (text_font_face); + g_free ((gpointer) text_font_face); pango_font_description_set_size (desc, defaults_get_system_font_size (d) * defaults_get_text_title_size (d) * PANGO_SCALE); - text_font_face = defaults_get_text_font_face (d); - pango_font_description_set_family_static (desc, text_font_face); pango_font_description_set_weight (desc, defaults_get_text_title_weight (d)); - pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); - g_free ((gpointer) text_font_face); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); @@ -1008,6 +1012,7 @@ TEXT_SHADOW_COLOR_G, TEXT_SHADOW_COLOR_B, TEXT_SHADOW_COLOR_A); + pango_cairo_show_layout (cr, layout); // ... blur it blur = raico_blur_create (RAICO_BLUR_QUALITY_HIGH); @@ -1071,21 +1076,19 @@ // create pango desc/layout layout = pango_cairo_create_layout (cr); - desc = pango_font_description_new (); + text_font_face = defaults_get_text_font_face (d); + desc = pango_font_description_from_string (text_font_face); + g_free ((gpointer) text_font_face); pango_font_description_set_size (desc, defaults_get_system_font_size (d) * defaults_get_text_body_size (d) * PANGO_SCALE); - text_font_face = defaults_get_text_font_face (d); - pango_font_description_set_family_static (desc, text_font_face); pango_font_description_set_weight (desc, defaults_get_text_body_weight (d)); - pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); - g_free ((gpointer) text_font_face); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); @@ -2381,11 +2384,39 @@ } void +bubble_set_icon_from_path (Bubble* self, + const gchar* filepath) +{ + Defaults* d; + BubblePrivate* priv; + + if (!self || !IS_BUBBLE (self) || !g_strcmp0 (filepath, "")) + return; + + priv = GET_PRIVATE (self); + + if (priv->icon_pixbuf) + { + g_object_unref (priv->icon_pixbuf); + priv->icon_pixbuf = NULL; + } + + d = self->defaults; + priv->icon_pixbuf = load_icon (filepath, + EM2PIXELS (defaults_get_icon_size (d), d)); + + _refresh_icon (self); +} + +void bubble_set_icon (Bubble* self, const gchar* filename) { Defaults* d; BubblePrivate* priv; +#ifdef TEMPORARY_ICON_PREFIX_WORKAROUND + gchar* notify_osd_iconname; +#endif if (!self || !IS_BUBBLE (self) || !g_strcmp0 (filename, "")) return; @@ -2399,9 +2430,20 @@ } d = self->defaults; - priv->icon_pixbuf = load_icon (filename, + +#ifdef TEMPORARY_ICON_PREFIX_WORKAROUND + notify_osd_iconname = g_strdup_printf (NOTIFY_OSD_ICON_PREFIX "-%s", + filename); + priv->icon_pixbuf = load_icon (notify_osd_iconname, EM2PIXELS (defaults_get_icon_size (d), d)); + g_free (notify_osd_iconname); +#endif + + // fallback to non-notify-osd name + if (!priv->icon_pixbuf) + priv->icon_pixbuf = load_icon (filename, + EM2PIXELS (defaults_get_icon_size (d), d)); _refresh_icon (self); } @@ -2420,8 +2462,11 @@ max_edge = MAX (w, h); - new_width = size * (w / max_edge); - new_height = size * (h / max_edge); + // temporarily cast to float so we don't end up missing fractional parts + // from the division, especially nasty for 0.something :) + // e.g.: 99 / 100 = 0 but 99.0 / 100.0 = 0.99 + new_width = size * ((gfloat) w / (gfloat) max_edge); + new_height = size * ((gfloat) h / (gfloat) max_edge); /* Scale the pixbuf down, preserving the aspect ratio */ scaled_icon = gdk_pixbuf_scale_simple (pixbuf, @@ -2490,7 +2535,6 @@ { scaled = scale_pixbuf (pixbuf, EM2PIXELS (defaults_get_icon_size (d), d)); g_object_unref (pixbuf); - pixbuf = scaled; } @@ -2835,7 +2879,7 @@ gtk_window_set_opacity (bubble_get_window (bubble), WINDOW_MAX_OPACITY); - bubble_start_timer (bubble); + bubble_start_timer (bubble, TRUE); } void @@ -2853,7 +2897,7 @@ || msecs == 0) { bubble_show (self); - bubble_start_timer (self); + bubble_start_timer (self, TRUE); return; } @@ -3006,7 +3050,8 @@ } void -bubble_start_timer (Bubble* self) +bubble_start_timer (Bubble* self, + gboolean trigger) { guint timer_id; BubblePrivate* priv; @@ -3032,8 +3077,9 @@ /* if the bubble is displaying a value that is out of bounds trigger a dim/glow animation */ - if (priv->value == -1 || priv->value == 101) - bubble_start_glow_effect (self, 500); + if (trigger) + if (priv->value == -1 || priv->value == 101) + bubble_start_glow_effect (self, 500); } void @@ -3109,7 +3155,9 @@ } layout = pango_cairo_create_layout (cr); - desc = pango_font_description_new (); + text_font_face = defaults_get_text_font_face (d); + desc = pango_font_description_from_string (text_font_face); + g_free ((gpointer) text_font_face); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account @@ -3126,17 +3174,12 @@ defaults_get_text_title_size (d) * PANGO_SCALE); - text_font_face = defaults_get_text_font_face (d); - pango_font_description_set_family_static (desc, text_font_face); - pango_font_description_set_weight ( desc, defaults_get_text_title_weight (d)); - pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); - g_free ((gpointer) text_font_face); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); @@ -3180,7 +3223,9 @@ } layout = pango_cairo_create_layout (cr); - desc = pango_font_description_new (); + text_font_face = defaults_get_text_font_face (d); + desc = pango_font_description_from_string (text_font_face); + g_free ((gpointer) text_font_face); // make sure system-wide font-options like hinting, antialiasing etc. // are taken into account @@ -3197,14 +3242,10 @@ defaults_get_text_body_size (d) * PANGO_SCALE); - text_font_face = defaults_get_text_font_face (d); - pango_font_description_set_family_static (desc, text_font_face); - pango_font_description_set_weight ( desc, defaults_get_text_body_weight (d)); - pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); pango_layout_set_font_description (layout, desc); pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); @@ -3259,7 +3300,6 @@ body_height = PANGO_PIXELS (log_rect.height); pango_font_description_free (desc); - g_free ((gpointer) text_font_face); g_object_unref (layout); cairo_destroy (cr); @@ -3639,39 +3679,52 @@ bubble_append_message_body (Bubble* self, const gchar* append_body) { - gboolean result; - gchar* text; - GError* error = NULL; + gboolean result = FALSE; + gchar* text = NULL; + GError* error = NULL; + BubblePrivate* priv = NULL; - if (!self || !IS_BUBBLE (self)) + if (!self || !IS_BUBBLE (self) || !append_body) return; - /* filter out any HTML/markup if possible */ + priv = GET_PRIVATE (self); + + // filter out any HTML/markup if possible result = pango_parse_markup (append_body, -1, - 0, /* no accel-marker needed */ - NULL, /* no PangoAttr needed */ + 0, // no accel-marker needed + NULL, // no PangoAttr needed &text, - NULL, /* no accel-marker-return needed */ + NULL, // no accel-marker-return needed &error); - if (error) + if (error && !result) { - g_warning ("bubble_append_message_body(): Got error \"%s\"\n", - error->message); + g_warning ("%s(): Got error \"%s\"\n", + G_STRFUNC, + error->message); g_error_free (error); error = NULL; - } - - /* append text to current message-body */ - g_string_append (GET_PRIVATE (self)->message_body, text); - - g_signal_emit (self, g_bubble_signals[MESSAGE_BODY_INSERTED], 0, text); - - g_object_notify ( - G_OBJECT (gtk_widget_get_accessible (GET_PRIVATE(self)->widget)), - "accessible-description"); - - g_free ((gpointer) text); + + if (text) + g_free (text); + } + + if (text) + { + // append text to current message-body + g_string_append (priv->message_body, text); + + g_signal_emit (self, + g_bubble_signals[MESSAGE_BODY_INSERTED], + 0, + text); + + g_object_notify ( + G_OBJECT (gtk_widget_get_accessible (priv->widget)), + "accessible-description"); + + g_free (text); + } } void @@ -3682,6 +3735,6 @@ bubble_set_timeout (self, bubble_get_timeout (other)); - bubble_start_timer (self); - bubble_start_timer (other); + bubble_start_timer (self, FALSE); + bubble_start_timer (other, FALSE); } === modified file 'src/bubble.h' --- src/bubble.h 2009-08-27 09:52:34 +0000 +++ src/bubble.h 2009-10-20 08:51:11 +0000 @@ -109,6 +109,10 @@ bubble_get_message_body (Bubble* self); void +bubble_set_icon_from_path (Bubble* self, + const gchar* filepath); + +void bubble_set_icon (Bubble* self, const gchar* filename); @@ -185,7 +189,8 @@ bubble_is_visible (Bubble* self); void -bubble_start_timer (Bubble* self); +bubble_start_timer (Bubble* self, + gboolean trigger); void bubble_get_position (Bubble* self, === modified file 'src/defaults.c' --- src/defaults.c 2009-09-29 09:52:49 +0000 +++ src/defaults.c 2009-10-19 17:59:53 +0000 @@ -41,6 +41,7 @@ #include <libwnck/workspace.h> #include "defaults.h" +#include "util.h" G_DEFINE_TYPE (Defaults, defaults, G_TYPE_OBJECT); @@ -171,15 +172,13 @@ static void _get_font_size_dpi (Defaults* self) { - GString* string = NULL; - GError* error = NULL; - GScanner* scanner = NULL; - GTokenType token = G_TOKEN_NONE; - gint points = 0; - GString* font_face = NULL; - gdouble dpi = 0.0f; - gdouble pixels_per_em = 0; - gchar* font_name = NULL; + GString* string = NULL; + GError* error = NULL; + guint points = 0; + GString* font_face = NULL; + gdouble dpi = 0.0f; + gdouble pixels_per_em = 0; + gchar* font_name = NULL; if (!IS_DEFAULTS (self)) return; @@ -192,7 +191,7 @@ string = g_string_new (font_name); if (error) { - /* if something went wrong, assume "Sans 10" and continue */ + // if something went wrong, assume "Sans 10" and continue string = g_string_assign (string, "Sans 10"); g_warning ("_get_font_size_dpi(): Got error \"%s\"\n", @@ -201,41 +200,12 @@ } g_free ((gpointer) font_name); - /* extract font-family-name and font-size */ - scanner = g_scanner_new (NULL); - if (scanner) - { - g_scanner_input_text (scanner, string->str, string->len); - for (token = g_scanner_get_next_token (scanner); - token != G_TOKEN_EOF; - token = g_scanner_get_next_token (scanner)) - { - switch (token) - { - case G_TOKEN_INT: - points = (gint) scanner->value.v_int; - break; - - case G_TOKEN_IDENTIFIER: - if (!font_face) - font_face = g_string_new (scanner->value.v_string); - else - { - g_string_append (font_face, - " "); - g_string_append (font_face, - scanner->value.v_string); - } - break; - - default: - break; - } - } - g_scanner_destroy (scanner); - } - - /* clean up */ + // extract text point-size + points = extract_point_size (string->str); + + // extract font-face-name/style + font_face = extract_font_face (string->str); + if (string != NULL) g_string_free (string, TRUE); === modified file 'src/dialog.c' --- src/dialog.c 2009-08-26 11:17:55 +0000 +++ src/dialog.c 2009-10-16 12:39:14 +0000 @@ -153,10 +153,10 @@ GtkWidget* title; GtkWidget* body; GtkWidget* image; - gchar* body_message; - gchar* new_body_message; + gchar* body_message = NULL; + gchar* new_body_message = NULL; guint gap = EM2PIXELS (defaults_get_margin_size (d), d); - gboolean success; + gboolean success = FALSE; GError* error = NULL; if (!IS_DEFAULTS (d) || @@ -201,25 +201,34 @@ body = gtk_label_new (NULL); body_message = filter_text (_body_message); - success = pango_parse_markup (body_message, - -1, - 0, - NULL, - &new_body_message, - NULL, - &error); - - if (error) - { - g_warning ("fallback_dialog_show(): Got error \"%s\"\n", - error->message); - g_error_free (error); - error = NULL; - } - - gtk_label_set_text (GTK_LABEL (body), new_body_message); + if (body_message) + { + success = pango_parse_markup (body_message, + -1, + 0, + NULL, + &new_body_message, + NULL, + &error); + + if (error && !success) + { + g_warning ("fallback_dialog_show(): Got error \"%s\"\n", + error->message); + g_error_free (error); + error = NULL; + } + } + + if (new_body_message) + { + gtk_label_set_text (GTK_LABEL (body), new_body_message); + g_free (new_body_message); + } + else + gtk_label_set_text (GTK_LABEL (body), body_message); + g_free (body_message); - g_free (new_body_message); gtk_label_set_line_wrap (GTK_LABEL (body), TRUE); === modified file 'src/display.c' --- src/display.c 2009-09-23 13:14:20 +0000 +++ src/display.c 2009-10-20 08:51:11 +0000 @@ -215,7 +215,7 @@ /* is the notification reusing the current bubble? */ if (sync_bubble == bubble) { - bubble_start_timer (bubble); + bubble_start_timer (bubble, TRUE); bubble_refresh (bubble); return; } === modified file 'src/stack.c' --- src/stack.c 2009-09-24 12:59:26 +0000 +++ src/stack.c 2009-10-20 08:51:11 +0000 @@ -389,7 +389,7 @@ /* check if this is just an update */ if (find_bubble_by_id (self, bubble_get_id (bubble))) { - bubble_start_timer (bubble); + bubble_start_timer (bubble, TRUE); bubble_refresh (bubble); /* resync the synchronous bubble if it's at the top */ @@ -725,7 +725,7 @@ { g_debug("Using image_path hint\n"); if ((data && G_VALUE_HOLDS_STRING (data))) - bubble_set_icon (bubble, g_value_get_string(data)); + bubble_set_icon_from_path (bubble, g_value_get_string(data)); else g_warning ("image_path hint is not a string\n"); } === modified file 'src/util.c' --- src/util.c 2009-10-06 20:22:08 +0000 +++ src/util.c 2009-10-19 04:57:25 +0000 @@ -257,3 +257,84 @@ return (gchar*) buffer; } + +guint +extract_point_size (const gchar* string) +{ + guint point_size = 0; + GRegex* regex = NULL; + GMatchInfo* match_info = NULL; + + // sanity check + if (!string) + return 0; + + // setup regular expression to extract an integer from the end of string + regex = g_regex_new ("\\d+$", 0, 0, NULL); + if (!regex) + return 0; + + // walk the string + g_regex_match (regex, string, 0, &match_info); + while (g_match_info_matches (match_info)) + { + gchar* word = NULL; + + word = g_match_info_fetch (match_info, 0); + if (word) + { + sscanf (word, "%d", &point_size); + g_free (word); + } + + g_match_info_next (match_info, NULL); + } + + // clean up + g_match_info_free (match_info); + g_regex_unref (regex); + + return point_size; +} + +GString* +extract_font_face (const gchar* string) +{ + GRegex* regex = NULL; + GMatchInfo* match_info = NULL; + GString* font_face = NULL; + + // sanity check + if (!string) + return NULL; + + // extract font-face-name/style + font_face = g_string_new (""); + if (!font_face) + return NULL; + + // setup regular expression to extract leading text before trailing int + regex = g_regex_new ("([A-Z a-z])+", 0, 0, NULL); + + // walk the string + g_regex_match (regex, string, 0, &match_info); + while (g_match_info_matches (match_info)) + { + gchar* word = NULL; + + word = g_match_info_fetch (match_info, 0); + if (word) + { + g_string_append (font_face, word); + g_free (word); + } + + g_match_info_next (match_info, NULL); + } + + // clean up + g_match_info_free (match_info); + g_regex_unref (regex); + + return font_face; +} === modified file 'src/util.h' --- src/util.h 2009-10-01 08:34:39 +0000 +++ src/util.h 2009-10-19 04:57:25 +0000 @@ -52,3 +52,8 @@ gchar* get_wm_name (Display* dpy); +guint +extract_point_size (const gchar* string); + +GString* +extract_font_face (const gchar* string); === modified file 'tests/test-text-filtering.c' --- tests/test-text-filtering.c 2009-10-01 08:43:26 +0000 +++ tests/test-text-filtering.c 2009-10-19 04:57:25 +0000 @@ -34,6 +34,11 @@ const gchar *expected; } TextComparisons; +typedef struct { + const gchar* before; + guint expected; +} IntegerExtraction; + static void test_text_filter () { @@ -69,8 +74,8 @@ { "<tt>Testing tag</tt>", "Testing tag" }, { "<html>Surrounded by html</html>", "Surrounded by html" }, { "<qt>Surrounded by qt</qt>", "Surrounded by qt" }, - { "First line <br dumb> \r \n Second line", "First line Second line" }, - { "First line\n<br /> <br>\n2nd line\r\n3rd line", "First line 2nd line 3rd line" }, + { "First line <br dumb> \r \n Second line", "First line\nSecond line" }, + { "First line\n<br /> <br>\n2nd line\r\n3rd line", "First line\n2nd line\n3rd line" }, { NULL, NULL } }; @@ -97,6 +102,49 @@ } } +static void +test_extract_point_size () +{ + static const IntegerExtraction tests[] = { + { "", 0 }, + { "foobar", 0 }, + { "Bla Fasel -12.0", 0 }, + { "Sans 10", 10 }, + { "Candara 9", 9 }, + { "Bitstream Vera Serif Italic 1", 1 }, + { "Calibri Italic 100", 100 }, + { "Century Schoolbook L Italic 42", 42 }, + { NULL, 0 } + }; + + for (int i = 0; tests[i].before != NULL; i++) + { + guint extracted = extract_point_size (tests[i].before); + g_assert_cmpuint (extracted, ==, tests[i].expected); + } +} + +static void +test_extract_font_face () +{ + static const TextComparisons tests[] = { + { "", "" }, + { "Sans 10", "Sans " }, + { "Candara 9", "Candara " }, + { "Bitstream Vera Serif Italic 1", "Bitstream Vera Serif Italic " }, + { "Calibri Italic 100", "Calibri Italic " }, + { "Century Schoolbook L Italic 10", "Century Schoolbook L Italic " }, + { NULL, NULL } + }; + + for (int i = 0; tests[i].before != NULL; i++) + { + GString* filtered = extract_font_face (tests[i].before); + g_assert_cmpstr (filtered->str, ==, tests[i].expected); + g_string_free (filtered, TRUE); + } +} + GTestSuite * test_filtering_create_test_suite (void) { @@ -108,6 +156,8 @@ g_test_suite_add(ts, TC(test_text_filter)); g_test_suite_add(ts, TC(test_newline_to_space)); + g_test_suite_add(ts, TC(test_extract_point_size)); + g_test_suite_add(ts, TC(test_extract_font_face)); return ts; }
_______________________________________________ Mailing list: https://launchpad.net/~ayatana-commits Post to : [email protected] Unsubscribe : https://launchpad.net/~ayatana-commits More help : https://help.launchpad.net/ListHelp

