diff --git a/src/dbusmenu.vala b/src/dbusmenu.vala index 09219e3..5ec1daf 100644 --- a/src/dbusmenu.vala +++ b/src/dbusmenu.vala @@ -43,6 +43,7 @@ namespace DBusMenu [DBus (signature="a(ias)")] Variant removed_props); public abstract signal void layout_updated(uint revision, int parent); public abstract signal void item_activation_requested(int id, uint timestamp); + public abstract signal void x_valapanel_item_value_changed(int id, uint timestamp); } public class PropertyStore : Object @@ -239,6 +240,7 @@ namespace DBusMenu iface.layout_updated.connect((rev,parent)=>{request_layout_update();}); iface.items_properties_updated.connect(props_updated_cb); iface.item_activation_requested.connect(request_activation_cb); + iface.x_valapanel_item_value_changed.connect(request_value_cb); requested_props_ids = {}; } public Item? get_root_item() @@ -253,6 +255,10 @@ namespace DBusMenu { get_item(id).handle_event("clicked",new Variant.int32(0),timestamp); } + private void request_value_cb(int id, uint timestamp) + { + get_item(id).handle_event("value-changed",new Variant.double(get_item(id).get_variant_property("x-valapanel-current-value").get_double()),timestamp); + } private void request_layout_update() { if(layout_update_in_progress) @@ -270,7 +276,7 @@ namespace DBusMenu Variant layout; try{ iface.get_layout(0,-1,props,out rev, out layout); - } catch (Error e) {stderr.printf("Cannot update layout. Error: %s",e.message);} + } catch (Error e) {stderr.printf("Cannot update layout. Error: %s",e.message); return;} parse_layout(rev,layout); clean_items(); if (layout_update_required) @@ -610,13 +616,15 @@ namespace DBusMenu } public class GtkSeparatorItem: SeparatorMenuItem, GtkItemIface { + private static const string[] allowed_properties = {"visible","enabled"}; public Item item {get; protected set;} public GtkSeparatorItem(Item item) { this.item = item; - item.property_changed.connect(on_prop_changed_cb); this.show_all(); + this.init(); + item.property_changed.connect(on_prop_changed_cb); } private void on_prop_changed_cb(string name, Variant? val) { @@ -630,9 +638,18 @@ namespace DBusMenu break; } } + private void init() + { + foreach (var prop in allowed_properties) + on_prop_changed_cb(prop,item.get_variant_property(prop)); + } } public class GtkSliderItem: Gtk.MenuItem, GtkItemIface { + private static const string[] allowed_properties = {"visible","enabled","icon-name","x-valapanel-secondary-icon-name", + "x-valapanel-min-value","x-valapanel-current-value","x-valapanel-max-value", + "x-valapanel-step-increment","x-valapanel-page-increment","x-valapanel-draw-value", + "x-valapanel-format-value"}; public Item item {get; protected set;} private Box box; @@ -653,11 +670,12 @@ namespace DBusMenu box.add(slider); box.add(secondary); this.add(box); + this.show_all(); + this.init(); item.property_changed.connect(on_prop_changed_cb); adj.value_changed.connect(on_value_changed_cb); slider.format_value.connect(on_value_format_cb); slider.value_pos = PositionType.RIGHT; - this.show_all(); } private void on_prop_changed_cb(string name, Variant? val) { @@ -714,6 +732,11 @@ namespace DBusMenu { return item_format.printf(val); } + private void init() + { + foreach (var prop in allowed_properties) + on_prop_changed_cb(prop,item.get_variant_property(prop)); + } } public class GtkClient : Client { @@ -733,6 +756,8 @@ namespace DBusMenu } public void attach_to_menu(Gtk.Menu menu) { + foreach (var path in iface.icon_theme_path) + IconTheme.get_default().prepend_search_path(path); root_menu = menu; root_menu.foreach((c)=>{menu.remove(c);}); root_menu.realize.connect(open_cb); @@ -744,7 +769,7 @@ namespace DBusMenu root_menu.append(new_item(ch) as Gtk.MenuItem); foreach(var path in iface.icon_theme_path) IconTheme.get_default().append_search_path(path); - root_menu.show_all(); + root_menu.show(); } private void open_cb() { diff --git a/src/qrichtextparser.vala b/src/qrichtextparser.vala index 76f5181..4c1f9f0 100644 --- a/src/qrichtextparser.vala +++ b/src/qrichtextparser.vala @@ -27,6 +27,7 @@ public class QRichTextParser : Object private StringBuilder pango_markup_builder; private ListType list_type; private int list_order; + private int table_depth; public string pango_markup {get; private set;} public Icon? icon @@ -37,6 +38,7 @@ public class QRichTextParser : Object context = new MarkupParseContext (parser, 0, this, null); init_sets(); icon = null; + table_depth = 0; } public QRichTextParser (string markup) { @@ -86,7 +88,6 @@ public class QRichTextParser : Object special_spans.insert("h5","span size=\"larger\" style=\"italic\""); special_spans.insert("h6","span size=\"larger\""); newline_at_end = new GenericSet(str_hash,str_equal); - newline_at_end.add("br"); newline_at_end.add("hr"); newline_at_end.add("tr"); newline_at_end.add("li"); @@ -161,6 +162,10 @@ public class QRichTextParser : Object i++; } } + if (name == "br") + pango_markup_builder.append_printf("\n"); + if (name == "table") + table_depth++; } // @@ -179,13 +184,18 @@ public class QRichTextParser : Object pango_markup_builder.append_printf("\n"); if (name == "td") pango_markup_builder.append_printf(" "); + if (name == "table") + table_depth--; if (name in lists) list_type = ListType.NONE; } private void visit_text (MarkupParseContext context, string text, size_t text_len) throws MarkupError { - pango_markup_builder.append_printf("%s",text.replace("\n","").strip()); + string new_text = text.replace("\n",""); + if (table_depth > 0) + new_text = text.replace("\n","").strip(); + pango_markup_builder.append_printf("%s",new_text); } private string parse_size(string size) { diff --git a/src/snitem.vala b/src/snitem.vala index 3c42609..b1ddc66 100644 --- a/src/snitem.vala +++ b/src/snitem.vala @@ -292,16 +292,16 @@ namespace StatusNotifier var markup_parser = new QRichTextParser(str); markup_parser.translate_markup(); markup = (markup_parser.pango_markup.length > 0) ? markup_parser.pango_markup: tooltip_markup; - var res_icon = change_icon(tooltip.icon_name, tooltip.pixmap); + var res_icon = change_icon(tooltip.icon_name, tooltip.pixmap,48); icon = (markup_parser.icon != null) ? markup_parser.icon: res_icon; } else { markup = raw_text; - icon = change_icon(tooltip.icon_name, tooltip.pixmap); + icon = change_icon(tooltip.icon_name, tooltip.pixmap,48); } } - private Icon? change_icon(string? icon_name, IconPixmap[] pixmaps) + private Icon? change_icon(string? icon_name, IconPixmap[] pixmaps, int icon_size) { var new_name = (use_symbolic) ? icon_name+"-symbolic" : icon_name; if (icon_name != null && icon_name.length > 0) @@ -315,9 +315,37 @@ namespace StatusNotifier return new ThemedIcon.with_default_fallbacks(new_name); else return find_file_icon(icon_name,iface.icon_theme_path); } - /* FIXME: Choose pixmap size */ - else if (pixmaps.length > 0 && pixmaps[0].bytes.length > 0) - return new BytesIcon(new Bytes(pixmaps[0].bytes)); + else if (pixmaps.length > 0) + { + Gdk.Pixbuf? pixbuf = null; + foreach (var pixmap in pixmaps) + { + uint[] new_bytes = (uint[]) pixmap.bytes; + for (int i = 0; i < new_bytes.length; i++) { + new_bytes[i] = new_bytes[i].to_big_endian(); + } + + pixmap.bytes = (uint8[]) new_bytes; + for (int i = 0; i < pixmap.bytes.length; i = i+4) { + uint8 red = pixmap.bytes[i]; + pixmap.bytes[i] = pixmap.bytes[i+2]; + pixmap.bytes[i+2] = red; + } + pixbuf = new Gdk.Pixbuf.from_data(pixmap.bytes, + Gdk.Colorspace.RGB, + true, + 8, + pixmap.width, + pixmap.height, + Cairo.Format.ARGB32.stride_for_width(pixmap.width)); + if (pixmap.height >= icon_size && pixmap.width >= icon_size) + break; + } + if (pixbuf.width > icon_size) { + pixbuf = pixbuf.scale_simple(icon_size, icon_size, Gdk.InterpType.BILINEAR); + } + return pixbuf; + } return null; } private Icon? find_file_icon(string? icon_name, string? path) @@ -354,9 +382,9 @@ namespace StatusNotifier try { ItemIface item = Bus.get_proxy_sync(BusType.SESSION, object_name, object_path); - var main_icon = change_icon(item.icon_name,item.icon_pixmap); - var attention_icon = change_icon(item.attention_icon_name,item.attention_icon_pixmap); - var overlay_icon = change_icon(item.overlay_icon_name,item.overlay_icon_pixmap); + var main_icon = change_icon(item.icon_name,item.icon_pixmap,image.pixel_size); + var attention_icon = change_icon(item.attention_icon_name,item.attention_icon_pixmap,image.pixel_size); + var overlay_icon = change_icon(item.overlay_icon_name,item.overlay_icon_pixmap,image.pixel_size/4); if (overlay_icon != null) overlay_icon = new Emblem(overlay_icon); var icon = new EmblemedIcon(attention_icon ?? main_icon ?? (image.gicon as EmblemedIcon).gicon,overlay_icon as Emblem);