Skip to content

Commit 2ae75a1

Browse files
authored
Merge pull request #183 from fbrinker/add-linux-submenus
Add submenu support for Linux
2 parents 5f409f9 + cef4562 commit 2ae75a1

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,6 @@ On Linux Mint, `libxapp-dev` is also required .
7878

7979
To build `webview_example`, you also need to install `libwebkit2gtk-4.0-dev` and remove `webview_example/rsrc.syso` which is required on Windows.
8080

81-
* Submenu items are not yet implemented
82-
83-
8481
### Windows
8582

8683
* To avoid opening a console at application startup, use these compile flags:

example/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ func onReady() {
4444

4545
systray.AddMenuItem("Ignored", "Ignored")
4646

47-
subMenuTop := systray.AddMenuItem("SubMenu", "SubMenu Test (top)")
48-
subMenuMiddle := subMenuTop.AddSubMenuItem("SubMenu - Level 2", "SubMenu Test (middle)")
49-
subMenuBottom := subMenuMiddle.AddSubMenuItemCheckbox("SubMenu - Level 3", "SubMenu Test (bottom)", false)
50-
subMenuBottom2 := subMenuMiddle.AddSubMenuItem("Panic!", "SubMenu Test (bottom)")
47+
subMenuTop := systray.AddMenuItem("SubMenuTop", "SubMenu Test (top)")
48+
subMenuMiddle := subMenuTop.AddSubMenuItem("SubMenuMiddle", "SubMenu Test (middle)")
49+
subMenuBottom := subMenuMiddle.AddSubMenuItemCheckbox("SubMenuBottom - Toggle Panic!", "SubMenu Test (bottom) - Hide/Show Panic!", false)
50+
subMenuBottom2 := subMenuMiddle.AddSubMenuItem("SubMenuBottom - Panic!", "SubMenu Test (bottom)")
5151

5252
mUrl := systray.AddMenuItem("Open UI", "my home")
5353
mQuit := systray.AddMenuItem("退出", "Quit the whole app")

systray_linux.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef struct {
1818

1919
typedef struct {
2020
int menu_id;
21+
int parent_menu_id;
2122
char* title;
2223
char* tooltip;
2324
short disabled;
@@ -27,8 +28,7 @@ typedef struct {
2728

2829
void registerSystray(void) {
2930
gtk_init(0, NULL);
30-
global_app_indicator = app_indicator_new("systray", "",
31-
APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
31+
global_app_indicator = app_indicator_new("systray", "", APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
3232
app_indicator_set_status(global_app_indicator, APP_INDICATOR_STATUS_ACTIVE);
3333
global_tray_menu = gtk_menu_new();
3434
app_indicator_set_menu(global_app_indicator, GTK_MENU(global_tray_menu));
@@ -86,6 +86,17 @@ void _systray_menu_item_selected(int *id) {
8686
systray_menu_item_selected(*id);
8787
}
8888

89+
GtkMenuItem* find_menu_by_id(int id) {
90+
GList* it;
91+
for(it = global_menu_items; it != NULL; it = it->next) {
92+
MenuItemNode* item = (MenuItemNode*)(it->data);
93+
if(item->menu_id == id) {
94+
return GTK_MENU_ITEM(item->menu_item);
95+
}
96+
}
97+
return NULL;
98+
}
99+
89100
// runs in main thread, should always return FALSE to prevent gtk to execute it again
90101
gboolean do_add_or_update_menu_item(gpointer data) {
91102
MenuItemInfo *mii = (MenuItemInfo*)data;
@@ -124,7 +135,19 @@ gboolean do_add_or_update_menu_item(gpointer data) {
124135
id
125136
);
126137

127-
gtk_menu_shell_append(GTK_MENU_SHELL(global_tray_menu), menu_item);
138+
if (mii->parent_menu_id == 0) {
139+
gtk_menu_shell_append(GTK_MENU_SHELL(global_tray_menu), menu_item);
140+
} else {
141+
GtkMenuItem* parentMenuItem = find_menu_by_id(mii->parent_menu_id);
142+
GtkWidget* parentMenu = gtk_menu_item_get_submenu(parentMenuItem);
143+
144+
if(parentMenu == NULL) {
145+
parentMenu = gtk_menu_new();
146+
gtk_menu_item_set_submenu(parentMenuItem, parentMenu);
147+
}
148+
149+
gtk_menu_shell_append(GTK_MENU_SHELL(parentMenu), menu_item);
150+
}
128151

129152
MenuItemNode* new_item = malloc(sizeof(MenuItemNode));
130153
new_item->menu_id = mii->menu_id;
@@ -139,8 +162,8 @@ gboolean do_add_or_update_menu_item(gpointer data) {
139162
global_menu_items = new_node;
140163
it = new_node;
141164
}
142-
GtkWidget * menu_item = GTK_WIDGET(((MenuItemNode*)(it->data))->menu_item);
143-
gtk_widget_set_sensitive(menu_item, mii->disabled == 1 ? FALSE : TRUE);
165+
GtkWidget* menu_item = GTK_WIDGET(((MenuItemNode*)(it->data))->menu_item);
166+
gtk_widget_set_sensitive(menu_item, mii->disabled != 1);
144167
gtk_widget_show(menu_item);
145168

146169
free(mii->title);
@@ -211,9 +234,9 @@ void setMenuItemIcon(const char* iconBytes, int length, int menuId, bool templat
211234
}
212235

213236
void add_or_update_menu_item(int menu_id, int parent_menu_id, char* title, char* tooltip, short disabled, short checked, short isCheckable) {
214-
// TODO: add support for sub-menus
215237
MenuItemInfo *mii = malloc(sizeof(MenuItemInfo));
216238
mii->menu_id = menu_id;
239+
mii->parent_menu_id = parent_menu_id;
217240
mii->title = title;
218241
mii->tooltip = tooltip;
219242
mii->disabled = disabled;

0 commit comments

Comments
 (0)