From b25b05dd448468daf6ec9374fc7ae36d0bceabba Mon Sep 17 00:00:00 2001 From: luoqing Date: Fri, 15 Sep 2023 09:49:13 +0800 Subject: [PATCH] feature(sn-icon-menu):Support dynamic increase or decrease of sub-item MenuItem in the tray right-click menu and property changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 支持托盘右键菜单中的子项MenuItem动态增减以及属性变化 Closed #15944 --- ...menu-Support-dynamic-increase-or-dec.patch | 188 ++++++++++++++++++ kiran-menu.spec | 6 +- 2 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 0004-feature-sn-icon-menu-Support-dynamic-increase-or-dec.patch diff --git a/0004-feature-sn-icon-menu-Support-dynamic-increase-or-dec.patch b/0004-feature-sn-icon-menu-Support-dynamic-increase-or-dec.patch new file mode 100644 index 0000000..ac8c8ae --- /dev/null +++ b/0004-feature-sn-icon-menu-Support-dynamic-increase-or-dec.patch @@ -0,0 +1,188 @@ +From c7bc43571acc57546cd732e3658be86d308f0256 Mon Sep 17 00:00:00 2001 +From: luoqing +Date: Thu, 14 Sep 2023 17:34:29 +0800 +Subject: [PATCH] feature(sn-icon-menu):Support dynamic increase or decrease of + sub-item MenuItem in the tray right-click menu and property changes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +- 支持托盘右键菜单中的子项MenuItem动态增减以及属性变化 + +Closed #15944 +--- + src/tray/kiran-sn-icon-menu.c | 126 +++++++++++++++++++++++++++++----- + 1 file changed, 109 insertions(+), 17 deletions(-) + +diff --git a/src/tray/kiran-sn-icon-menu.c b/src/tray/kiran-sn-icon-menu.c +index 22e321f..ffae1bb 100644 +--- a/src/tray/kiran-sn-icon-menu.c ++++ b/src/tray/kiran-sn-icon-menu.c +@@ -1,19 +1,20 @@ + /** +- * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. ++ * Copyright (c) 2020 ~ 2021 KylinSec Co., Ltd. + * kiran-cc-daemon is licensed under Mulan PSL v2. +- * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: +- * http://license.coscl.org.cn/MulanPSL2 +- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +- * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +- * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +- * See the Mulan PSL v2 for more details. +- * ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * + * Author: wangxiaoqing + */ + + #include "kiran-sn-icon-menu.h" + #include ++#include + struct _KiranSnIconMenuPrivate + { + gchar *bus_name; +@@ -30,6 +31,7 @@ enum + LAST_PROP + }; + ++#define DATA_KEY_SIGNAL_PROPERTY_CHANGED_IS_CONNECTED "signal_property_changed_is_connected" + static GParamSpec *properties[LAST_PROP] = {NULL}; + + G_DEFINE_TYPE_WITH_PRIVATE(KiranSnIconMenu, kiran_sn_icon_menu, GTK_TYPE_MENU) +@@ -175,6 +177,88 @@ create_widget_from_menuitem(DbusmenuMenuitem *item) + return gmi; + } + ++static void ++kiran_sn_icon_menu_create_widget_from_dbusmenuitem(KiranSnIconMenu *menu, DbusmenuMenuitem *item) ++{ ++ GtkWidget *gmi = create_widget_from_menuitem(item); ++ ++ gtk_menu_shell_append(GTK_MENU_SHELL(menu), gmi); ++ gtk_widget_show(gmi); ++ ++ g_signal_connect(gmi, ++ "activate", ++ G_CALLBACK(activate_cb), ++ item); ++} ++ ++static void ++kiran_sn_icon_menu_remove_widget_all(KiranSnIconMenu *menu) ++{ ++ GList *child; ++ GList *container_children = gtk_container_get_children(GTK_CONTAINER(menu)); ++ for (child = container_children; child; child = child->next) ++ { ++ gtk_container_remove(GTK_CONTAINER(menu), GTK_WIDGET(child->data)); ++ gtk_widget_destroy(GTK_WIDGET(child->data)); ++ } ++} ++ ++static void ++property_changed_cb(DbusmenuMenuitem *item, gchar *property, GVariant *value, gpointer user_data) ++{ ++ GList *child; ++ KiranSnIconMenu *menu = KIRAN_SN_ICON_MENU(user_data); ++ ++ kiran_sn_icon_menu_remove_widget_all(menu); ++ ++ // 遍历MenuItem,以找到root ++ DbusmenuMenuitem *root = dbusmenu_menuitem_get_parent(item); ++ gboolean is_root = dbusmenu_menuitem_get_root(root); ++ ++ while (!is_root) ++ { ++ root = dbusmenu_menuitem_get_parent(root); ++ is_root = dbusmenu_menuitem_get_root(root); ++ } ++ ++ GList *dbus_menuitem_children = dbusmenu_menuitem_get_children(root); ++ for (child = dbus_menuitem_children; child; child = child->next) ++ { ++ kiran_sn_icon_menu_create_widget_from_dbusmenuitem(menu,child->data); ++ } ++} ++ ++static void ++submenu_get_children_to_connect(DbusmenuMenuitem *submenu, gpointer user_data) ++{ ++ KiranSnIconMenu *menu = KIRAN_SN_ICON_MENU(user_data); ++ GList *submenu_children = dbusmenu_menuitem_get_children(submenu); ++ GList *submenu_child; ++ for (submenu_child = submenu_children; submenu_child; submenu_child = submenu_child->next) ++ { ++ const gchar *children_display = dbusmenu_menuitem_property_get(submenu_child->data, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY); ++ if (g_strcmp0(children_display, "submenu") == 0) ++ { ++ submenu_get_children_to_connect(submenu_child->data, menu); ++ } ++ ++ gboolean is_connected = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(submenu_child->data), DATA_KEY_SIGNAL_PROPERTY_CHANGED_IS_CONNECTED)); ++ if (!is_connected) ++ { ++ g_signal_connect(submenu_child->data, DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(property_changed_cb), menu); ++ g_object_set_data(G_OBJECT(submenu_child->data), DATA_KEY_SIGNAL_PROPERTY_CHANGED_IS_CONNECTED, GINT_TO_POINTER(TRUE)); ++ } ++ } ++} ++ ++/** ++ * NOTE: ++ * dbus_menuitem 移除某个menuitem时,没有类似REMOVE_MENUITEM的信号, ++ * 而是会触发 DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED 信号。 ++ * 新增时会触发 DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM 信号 ++ * ++ * 因此layout_updated_cb中还会处理menuitem变化的情况 ++ */ + static void + layout_updated_cb(DbusmenuClient *client, + gpointer user_data) +@@ -182,21 +266,29 @@ layout_updated_cb(DbusmenuClient *client, + KiranSnIconMenu *menu; + DbusmenuMenuitem *root = dbusmenu_client_get_root(client); + GList *child; +- GList *children = dbusmenu_menuitem_get_children(root); + + menu = KIRAN_SN_ICON_MENU(user_data); + +- for (child = children; child; child = child->next) ++ kiran_sn_icon_menu_remove_widget_all(menu); ++ ++ GList *dbus_menuitem_children = dbusmenu_menuitem_get_children(root); ++ for (child = dbus_menuitem_children; child; child = child->next) + { +- GtkWidget *gmi = create_widget_from_menuitem(child->data); ++ kiran_sn_icon_menu_create_widget_from_dbusmenuitem(menu,child->data); + +- gtk_menu_shell_append(GTK_MENU_SHELL(menu), gmi); +- gtk_widget_show(gmi); ++ // NOTE:只修改一个属性,可能会触发多个 PROPERTY_CHANGE 信号 ++ const gchar *children_display = dbusmenu_menuitem_property_get(child->data, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY); ++ if (g_strcmp0(children_display, "submenu") == 0) ++ { ++ submenu_get_children_to_connect(child->data, menu); ++ } + +- g_signal_connect(gmi, +- "activate", +- G_CALLBACK(activate_cb), +- child->data); ++ gboolean is_connected = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(child->data), DATA_KEY_SIGNAL_PROPERTY_CHANGED_IS_CONNECTED)); ++ if (!is_connected) ++ { ++ g_signal_connect(child->data, DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(property_changed_cb), menu); ++ g_object_set_data(G_OBJECT(child->data), DATA_KEY_SIGNAL_PROPERTY_CHANGED_IS_CONNECTED, GINT_TO_POINTER(TRUE)); ++ } + } + } + +-- +2.33.0 + diff --git a/kiran-menu.spec b/kiran-menu.spec index 4675422..9d944e5 100644 --- a/kiran-menu.spec +++ b/kiran-menu.spec @@ -1,6 +1,6 @@ Name: kiran-menu Version: 2.5.1 -Release: 3 +Release: 4 Summary: Applets for mate panel from Kiran Desktop License: MulanPSL-2.0 @@ -9,6 +9,7 @@ Source0: %{name}-%{version}.tar.gz Patch0001: 0001-fix-coredump-Fix-crash-when-clicking-on-the-power-op.patch Patch0002: 0002-fix-tray-Place-all-tray-icons-in-the-panel-and-no-lo.patch Patch0003: 0003-fix-tray-Fixed-a-crash-issue-that-occurred-when-the-.patch +Patch0004: 0004-feature-sn-icon-menu-Support-dynamic-increase-or-dec.patch BuildRequires: cmake > 3.0 BuildRequires: gcc-c++ @@ -100,6 +101,9 @@ gtk-update-icon-cache -f /usr/share/icons/hicolor/ %changelog +* Fri Sep 15 2023 luoqing - 2.5.1-4 +- KYOS-F: Support dynamic increase or decrease of sub-item MenuItem in the tray right-click menu and property changes (#15944) + * Fri Sep 01 2023 luoqing - 2.5.1-3 - KYOS-F: Place all tray icons in the panel and no longer in the tray container for the time being (#12490) - KYOS-F: Fixed a crash issue that occurred when the tray icon was removed from the tray area (#14004)