From 642fd48af10ac29e63b33eab4545805e93a195af Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Fri, 14 Jun 2019 06:44:11 -0700 Subject: [PATCH 1/2] fix(tray): restore Activate support for compliant SNI implementation Set ItemIsMenu to true by default because libappindicator supports neither ItemIsMenu nor Activate method and compiant SNI implementations are expected to reset the flag during initial property fetch. To be revisited if anyone finds the implementation that has Activate but does not set ItemIsMenu. --- include/modules/sni/item.hpp | 7 ++++++- src/modules/sni/item.cpp | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp index c8f835b..a6180db 100644 --- a/include/modules/sni/item.hpp +++ b/include/modules/sni/item.hpp @@ -46,7 +46,12 @@ class Item : public sigc::trackable { std::string menu; DbusmenuGtkMenu* dbus_menu = nullptr; Gtk::Menu* gtk_menu = nullptr; - bool item_is_menu = false; + /** + * ItemIsMenu flag means that the item only supports the context menu. + * Default value is true because libappindicator supports neither ItemIsMenu nor Activate method + * while compliant SNI implementation would always reset the flag to desired value. + */ + bool item_is_menu = true; private: void proxyReady(Glib::RefPtr& result); diff --git a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp index 0d7ab69..51f9789 100644 --- a/src/modules/sni/item.cpp +++ b/src/modules/sni/item.cpp @@ -334,7 +334,7 @@ void Item::makeMenu(GdkEventButton* const& ev) { bool Item::handleClick(GdkEventButton* const& ev) { auto parameters = Glib::VariantContainerBase::create_tuple( {Glib::Variant::create(ev->x), Glib::Variant::create(ev->y)}); - if ((ev->button == 1 && (item_is_menu || !menu.empty())) || ev->button == 3) { + if ((ev->button == 1 && item_is_menu) || ev->button == 3) { makeMenu(ev); if (gtk_menu != nullptr) { #if GTK_CHECK_VERSION(3, 22, 0) From 01ad3d96d828d2aed852b719358c3efb8e5cc8d8 Mon Sep 17 00:00:00 2001 From: Aleksei Bavshin Date: Sat, 24 Aug 2019 08:20:32 -0700 Subject: [PATCH 2/2] fix(tray): pre-create dbusmenu for tray items It seems that dbusmenu is not ready to display menu immediately and needs some time to sync data via DBus. Fixes LIBDBUSMENU-GLIB-CRITICAL: dbusmenu_menuitem_send_about_to_show: assertion 'DBUSMENU_IS_MENUITEM(mi)' failed. Also fixes initial render of the menu with layer shell popups support patch. --- include/modules/sni/item.hpp | 2 +- src/modules/sni/item.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/modules/sni/item.hpp b/include/modules/sni/item.hpp index a6180db..fc04673 100644 --- a/include/modules/sni/item.hpp +++ b/include/modules/sni/item.hpp @@ -65,7 +65,7 @@ class Item : public sigc::trackable { Glib::RefPtr extractPixBuf(GVariant* variant); Glib::RefPtr getIconByName(const std::string& name, int size); static void onMenuDestroyed(Item* self, GObject* old_menu_pointer); - void makeMenu(GdkEventButton* const& ev); + void makeMenu(); bool handleClick(GdkEventButton* const& /*ev*/); Glib::RefPtr proxy_; diff --git a/src/modules/sni/item.cpp b/src/modules/sni/item.cpp index 51f9789..bcc66e2 100644 --- a/src/modules/sni/item.cpp +++ b/src/modules/sni/item.cpp @@ -128,6 +128,7 @@ void Item::setProperty(const Glib::ustring& name, Glib::VariantBase& value) { } } else if (name == "Menu") { menu = get_variant(value); + makeMenu(); } else if (name == "ItemIsMenu") { item_is_menu = get_variant(value); } @@ -319,7 +320,7 @@ void Item::onMenuDestroyed(Item* self, GObject* old_menu_pointer) { } } -void Item::makeMenu(GdkEventButton* const& ev) { +void Item::makeMenu() { if (gtk_menu == nullptr && !menu.empty()) { dbus_menu = dbusmenu_gtkmenu_new(bus_name.data(), menu.data()); if (dbus_menu != nullptr) { @@ -335,7 +336,7 @@ bool Item::handleClick(GdkEventButton* const& ev) { auto parameters = Glib::VariantContainerBase::create_tuple( {Glib::Variant::create(ev->x), Glib::Variant::create(ev->y)}); if ((ev->button == 1 && item_is_menu) || ev->button == 3) { - makeMenu(ev); + makeMenu(); if (gtk_menu != nullptr) { #if GTK_CHECK_VERSION(3, 22, 0) gtk_menu->popup_at_pointer(reinterpret_cast(ev));