|
@@ -58,6 +58,13 @@ typedef enum
|
|
|
static gulong (*g_signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags);
|
|
|
static void (*g_object_unref)(gpointer object);
|
|
|
static gchar *(*g_mkdtemp)(gchar *template);
|
|
|
+gpointer (*g_object_ref_sink)(gpointer object);
|
|
|
+gpointer (*g_object_ref)(gpointer object);
|
|
|
+
|
|
|
+// glib_typeof requires compiler-specific code and includes that are too complex
|
|
|
+// to be worth copy-pasting here
|
|
|
+//#define g_object_ref(Obj) ((glib_typeof (Obj)) (g_object_ref) (Obj))
|
|
|
+//#define g_object_ref_sink(Obj) ((glib_typeof (Obj)) (g_object_ref_sink) (Obj))
|
|
|
|
|
|
#define g_signal_connect(instance, detailed_signal, c_handler, data) \
|
|
|
g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
|
|
@@ -248,6 +255,8 @@ static bool init_gtk(void)
|
|
|
g_mkdtemp = dlsym(libgdk, "g_mkdtemp");
|
|
|
g_signal_connect_data = dlsym(libgdk, "g_signal_connect_data");
|
|
|
g_object_unref = dlsym(libgdk, "g_object_unref");
|
|
|
+ g_object_ref_sink = dlsym(libgdk, "g_object_ref_sink");
|
|
|
+ g_object_ref = dlsym(libgdk, "g_object_ref");
|
|
|
|
|
|
app_indicator_new = dlsym(libappindicator, "app_indicator_new");
|
|
|
app_indicator_set_status = dlsym(libappindicator, "app_indicator_set_status");
|
|
@@ -268,6 +277,8 @@ static bool init_gtk(void)
|
|
|
!gtk_menu_shell_insert ||
|
|
|
!gtk_widget_destroy ||
|
|
|
!g_mkdtemp ||
|
|
|
+ !g_object_ref_sink ||
|
|
|
+ !g_object_ref ||
|
|
|
!g_signal_connect_data ||
|
|
|
!g_object_unref ||
|
|
|
!app_indicator_new ||
|
|
@@ -326,6 +337,8 @@ struct SDL_Tray {
|
|
|
SDL_TrayMenu *menu;
|
|
|
char icon_dir[sizeof(ICON_DIR_TEMPLATE)];
|
|
|
char icon_path[256];
|
|
|
+
|
|
|
+ GtkMenuShell *menu_cached;
|
|
|
};
|
|
|
|
|
|
static void call_callback(GtkMenuItem *item, gpointer ptr)
|
|
@@ -384,6 +397,11 @@ static void DestroySDLMenu(SDL_TrayMenu *menu)
|
|
|
}
|
|
|
SDL_free(menu->entries[i]);
|
|
|
}
|
|
|
+
|
|
|
+ if (menu->menu) {
|
|
|
+ g_object_unref(menu->menu);
|
|
|
+ }
|
|
|
+
|
|
|
SDL_free(menu->entries);
|
|
|
SDL_free(menu);
|
|
|
}
|
|
@@ -435,6 +453,10 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
|
|
|
|
|
|
app_indicator_set_status(tray->indicator, APP_INDICATOR_STATUS_ACTIVE);
|
|
|
|
|
|
+ // The tray icon isn't shown before a menu is created; create one early.
|
|
|
+ tray->menu_cached = (GtkMenuShell *) g_object_ref_sink(gtk_menu_new());
|
|
|
+ app_indicator_set_menu(tray->indicator, GTK_MENU(tray->menu_cached));
|
|
|
+
|
|
|
SDL_RegisterTray(tray);
|
|
|
|
|
|
return tray;
|
|
@@ -478,14 +500,12 @@ SDL_TrayMenu *SDL_CreateTrayMenu(SDL_Tray *tray)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- tray->menu->menu = (GtkMenuShell *)gtk_menu_new();
|
|
|
+ tray->menu->menu = g_object_ref(tray->menu_cached);
|
|
|
tray->menu->parent_tray = tray;
|
|
|
tray->menu->parent_entry = NULL;
|
|
|
tray->menu->nEntries = 0;
|
|
|
tray->menu->entries = NULL;
|
|
|
|
|
|
- app_indicator_set_menu(tray->indicator, GTK_MENU(tray->menu->menu));
|
|
|
-
|
|
|
return tray->menu;
|
|
|
}
|
|
|
|
|
@@ -785,6 +805,10 @@ void SDL_DestroyTray(SDL_Tray *tray)
|
|
|
SDL_RemovePath(tray->icon_dir);
|
|
|
}
|
|
|
|
|
|
+ if (tray->menu_cached) {
|
|
|
+ g_object_unref(tray->menu_cached);
|
|
|
+ }
|
|
|
+
|
|
|
if (tray->indicator) {
|
|
|
g_object_unref(tray->indicator);
|
|
|
}
|