mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-05 19:08:12 +00:00
tray: linux - use .cache
directory for temporary icon paths
This commit is contained in:

committed by
Sam Lantinga

parent
cd0c660dea
commit
b139821903
@@ -114,8 +114,8 @@ static bool InitGtk(void)
|
|||||||
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_submenu);
|
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_submenu);
|
||||||
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_get_label);
|
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_get_label);
|
||||||
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_label);
|
SDL_GTK_SYM(gtk, libgtk, gtk, menu_item_set_label);
|
||||||
SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_append);
|
SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_append);
|
||||||
SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_insert);
|
SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_insert);
|
||||||
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_new_with_label);
|
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_new_with_label);
|
||||||
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_get_active);
|
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_get_active);
|
||||||
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_set_active);
|
SDL_GTK_SYM(gtk, libgtk, gtk, check_menu_item_set_active);
|
||||||
@@ -127,6 +127,7 @@ static bool InitGtk(void)
|
|||||||
|
|
||||||
SDL_GTK_SYM(gtk, libgdk, g, signal_connect_data);
|
SDL_GTK_SYM(gtk, libgdk, g, signal_connect_data);
|
||||||
SDL_GTK_SYM(gtk, libgdk, g, mkdtemp);
|
SDL_GTK_SYM(gtk, libgdk, g, mkdtemp);
|
||||||
|
SDL_GTK_SYM(gtk, libgdk, g, get_user_cache_dir);
|
||||||
SDL_GTK_SYM(gtk, libgdk, g, object_ref);
|
SDL_GTK_SYM(gtk, libgdk, g, object_ref);
|
||||||
SDL_GTK_SYM(gtk, libgdk, g, object_ref_sink);
|
SDL_GTK_SYM(gtk, libgdk, g, object_ref_sink);
|
||||||
SDL_GTK_SYM(gtk, libgdk, g, object_unref);
|
SDL_GTK_SYM(gtk, libgdk, g, object_unref);
|
||||||
|
@@ -80,6 +80,7 @@ typedef struct SDL_GtkContext
|
|||||||
gulong (*signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, SDL_GConnectFlags connect_flags);
|
gulong (*signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, SDL_GConnectFlags connect_flags);
|
||||||
void (*object_unref)(gpointer object);
|
void (*object_unref)(gpointer object);
|
||||||
gchar *(*mkdtemp)(gchar *template);
|
gchar *(*mkdtemp)(gchar *template);
|
||||||
|
gchar *(*get_user_cache_dir)(void);
|
||||||
gpointer (*object_ref_sink)(gpointer object);
|
gpointer (*object_ref_sink)(gpointer object);
|
||||||
gpointer (*object_ref)(gpointer object);
|
gpointer (*object_ref)(gpointer object);
|
||||||
void (*object_get)(gpointer object, const gchar *first_property_name, ...);
|
void (*object_get)(gpointer object, const gchar *first_property_name, ...);
|
||||||
|
@@ -153,15 +153,11 @@ struct SDL_TrayEntry {
|
|||||||
SDL_TrayMenu *submenu;
|
SDL_TrayMenu *submenu;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Template for g_mkdtemp(). The Xs will get replaced with a random
|
|
||||||
* directory name, which is created safely and atomically. */
|
|
||||||
#define ICON_DIR_TEMPLATE "/tmp/SDL-tray-XXXXXX"
|
|
||||||
|
|
||||||
struct SDL_Tray {
|
struct SDL_Tray {
|
||||||
AppIndicator *indicator;
|
AppIndicator *indicator;
|
||||||
SDL_TrayMenu *menu;
|
SDL_TrayMenu *menu;
|
||||||
char icon_dir[sizeof(ICON_DIR_TEMPLATE)];
|
char *icon_dir;
|
||||||
char icon_path[256];
|
char *icon_path;
|
||||||
|
|
||||||
GtkMenuShell *menu_cached;
|
GtkMenuShell *menu_cached;
|
||||||
};
|
};
|
||||||
@@ -188,13 +184,13 @@ static bool new_tmp_filename(SDL_Tray *tray)
|
|||||||
{
|
{
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
|
|
||||||
int would_have_written = SDL_snprintf(tray->icon_path, sizeof(tray->icon_path), "%s/%d.bmp", tray->icon_dir, count++);
|
int would_have_written = SDL_asprintf(&tray->icon_path, "%s/%d.bmp", tray->icon_dir, count++);
|
||||||
|
|
||||||
if (would_have_written > 0 && ((unsigned) would_have_written) < sizeof(tray->icon_path) - 1) {
|
if (would_have_written >= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tray->icon_path[0] = '\0';
|
tray->icon_path = NULL;
|
||||||
SDL_SetError("Failed to format new temporary filename");
|
SDL_SetError("Failed to format new temporary filename");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -254,29 +250,47 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
|
|||||||
SDL_Tray *tray = NULL;
|
SDL_Tray *tray = NULL;
|
||||||
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
|
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
|
||||||
if (!gtk) {
|
if (!gtk) {
|
||||||
goto error;
|
goto tray_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
tray = (SDL_Tray *)SDL_calloc(1, sizeof(*tray));
|
tray = (SDL_Tray *)SDL_calloc(1, sizeof(*tray));
|
||||||
if (!tray) {
|
if (!tray) {
|
||||||
goto error;
|
goto tray_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gchar *cache_dir = gtk->g.get_user_cache_dir();
|
||||||
|
if (!cache_dir) {
|
||||||
|
SDL_SetError("Cannot get user cache directory: %s", strerror(errno));
|
||||||
|
goto tray_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *sdl_dir;
|
||||||
|
SDL_asprintf(&sdl_dir, "%s/SDL", cache_dir);
|
||||||
|
if (!SDL_GetPathInfo(sdl_dir, NULL)) {
|
||||||
|
if (!SDL_CreateDirectory(sdl_dir)) {
|
||||||
|
SDL_SetError("Cannot create directory for tray icon: %s", strerror(errno));
|
||||||
|
goto sdl_dir_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On success, g_mkdtemp edits its argument in-place to replace the Xs
|
/* On success, g_mkdtemp edits its argument in-place to replace the Xs
|
||||||
* with a random directory name, which it creates safely and atomically.
|
* with a random directory name, which it creates safely and atomically.
|
||||||
* On failure, it sets errno. */
|
* On failure, it sets errno. */
|
||||||
SDL_strlcpy(tray->icon_dir, ICON_DIR_TEMPLATE, sizeof(tray->icon_dir));
|
SDL_asprintf(&tray->icon_dir, "%s/tray-XXXXXX", sdl_dir);
|
||||||
if (!gtk->g.mkdtemp(tray->icon_dir)) {
|
if (!gtk->g.mkdtemp(tray->icon_dir)) {
|
||||||
SDL_SetError("Cannot create directory for tray icon: %s", strerror(errno));
|
SDL_SetError("Cannot create directory for tray icon: %s", strerror(errno));
|
||||||
goto error;
|
goto icon_dir_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
if (!new_tmp_filename(tray)) {
|
if (!new_tmp_filename(tray)) {
|
||||||
goto error;
|
goto icon_dir_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SaveBMP(icon, tray->icon_path);
|
SDL_SaveBMP(icon, tray->icon_path);
|
||||||
|
} else {
|
||||||
|
// allocate a dummy icon path
|
||||||
|
SDL_asprintf(&tray->icon_path, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
tray->indicator = app_indicator_new(get_appindicator_id(), tray->icon_path,
|
tray->indicator = app_indicator_new(get_appindicator_id(), tray->icon_path,
|
||||||
@@ -293,7 +307,13 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
|
|||||||
|
|
||||||
return tray;
|
return tray;
|
||||||
|
|
||||||
error:
|
icon_dir_error:
|
||||||
|
SDL_free(tray->icon_dir);
|
||||||
|
|
||||||
|
sdl_dir_error:
|
||||||
|
SDL_free(sdl_dir);
|
||||||
|
|
||||||
|
tray_error:
|
||||||
if (tray) {
|
if (tray) {
|
||||||
SDL_free(tray);
|
SDL_free(tray);
|
||||||
}
|
}
|
||||||
@@ -311,8 +331,10 @@ void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*tray->icon_path) {
|
if (tray->icon_path) {
|
||||||
SDL_RemovePath(tray->icon_path);
|
SDL_RemovePath(tray->icon_path);
|
||||||
|
SDL_free(tray->icon_path);
|
||||||
|
tray->icon_path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* AppIndicator caches the icon files; always change filename to avoid caching */
|
/* AppIndicator caches the icon files; always change filename to avoid caching */
|
||||||
@@ -321,7 +343,8 @@ void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon)
|
|||||||
SDL_SaveBMP(icon, tray->icon_path);
|
SDL_SaveBMP(icon, tray->icon_path);
|
||||||
app_indicator_set_icon(tray->indicator, tray->icon_path);
|
app_indicator_set_icon(tray->indicator, tray->icon_path);
|
||||||
} else {
|
} else {
|
||||||
*tray->icon_path = '\0';
|
SDL_free(tray->icon_path);
|
||||||
|
tray->icon_path = NULL;
|
||||||
app_indicator_set_icon(tray->indicator, NULL);
|
app_indicator_set_icon(tray->indicator, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -714,12 +737,14 @@ void SDL_DestroyTray(SDL_Tray *tray)
|
|||||||
DestroySDLMenu(tray->menu);
|
DestroySDLMenu(tray->menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*tray->icon_path) {
|
if (tray->icon_path) {
|
||||||
SDL_RemovePath(tray->icon_path);
|
SDL_RemovePath(tray->icon_path);
|
||||||
|
SDL_free(tray->icon_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*tray->icon_dir) {
|
if (tray->icon_dir) {
|
||||||
SDL_RemovePath(tray->icon_dir);
|
SDL_RemovePath(tray->icon_dir);
|
||||||
|
SDL_free(tray->icon_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
|
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
|
||||||
|
Reference in New Issue
Block a user