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_get_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_insert);
|
||||
SDL_GTK_SYM(gtk, libgtk, gtk, menu_shell_append);
|
||||
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_get_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, 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_sink);
|
||||
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);
|
||||
void (*object_unref)(gpointer object);
|
||||
gchar *(*mkdtemp)(gchar *template);
|
||||
gchar *(*get_user_cache_dir)(void);
|
||||
gpointer (*object_ref_sink)(gpointer object);
|
||||
gpointer (*object_ref)(gpointer object);
|
||||
void (*object_get)(gpointer object, const gchar *first_property_name, ...);
|
||||
|
@@ -153,15 +153,11 @@ struct SDL_TrayEntry {
|
||||
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 {
|
||||
AppIndicator *indicator;
|
||||
SDL_TrayMenu *menu;
|
||||
char icon_dir[sizeof(ICON_DIR_TEMPLATE)];
|
||||
char icon_path[256];
|
||||
char *icon_dir;
|
||||
char *icon_path;
|
||||
|
||||
GtkMenuShell *menu_cached;
|
||||
};
|
||||
@@ -188,13 +184,13 @@ static bool new_tmp_filename(SDL_Tray *tray)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
tray->icon_path[0] = '\0';
|
||||
tray->icon_path = NULL;
|
||||
SDL_SetError("Failed to format new temporary filename");
|
||||
return false;
|
||||
}
|
||||
@@ -254,29 +250,47 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
|
||||
SDL_Tray *tray = NULL;
|
||||
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
|
||||
if (!gtk) {
|
||||
goto error;
|
||||
goto tray_error;
|
||||
}
|
||||
|
||||
tray = (SDL_Tray *)SDL_calloc(1, sizeof(*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
|
||||
* with a random directory name, which it creates safely and atomically.
|
||||
* 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)) {
|
||||
SDL_SetError("Cannot create directory for tray icon: %s", strerror(errno));
|
||||
goto error;
|
||||
goto icon_dir_error;
|
||||
}
|
||||
|
||||
if (icon) {
|
||||
if (!new_tmp_filename(tray)) {
|
||||
goto error;
|
||||
goto icon_dir_error;
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -293,7 +307,13 @@ SDL_Tray *SDL_CreateTray(SDL_Surface *icon, const char *tooltip)
|
||||
|
||||
return tray;
|
||||
|
||||
error:
|
||||
icon_dir_error:
|
||||
SDL_free(tray->icon_dir);
|
||||
|
||||
sdl_dir_error:
|
||||
SDL_free(sdl_dir);
|
||||
|
||||
tray_error:
|
||||
if (tray) {
|
||||
SDL_free(tray);
|
||||
}
|
||||
@@ -311,8 +331,10 @@ void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon)
|
||||
return;
|
||||
}
|
||||
|
||||
if (*tray->icon_path) {
|
||||
if (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 */
|
||||
@@ -321,7 +343,8 @@ void SDL_SetTrayIcon(SDL_Tray *tray, SDL_Surface *icon)
|
||||
SDL_SaveBMP(icon, tray->icon_path);
|
||||
app_indicator_set_icon(tray->indicator, tray->icon_path);
|
||||
} else {
|
||||
*tray->icon_path = '\0';
|
||||
SDL_free(tray->icon_path);
|
||||
tray->icon_path = NULL;
|
||||
app_indicator_set_icon(tray->indicator, NULL);
|
||||
}
|
||||
}
|
||||
@@ -714,12 +737,14 @@ void SDL_DestroyTray(SDL_Tray *tray)
|
||||
DestroySDLMenu(tray->menu);
|
||||
}
|
||||
|
||||
if (*tray->icon_path) {
|
||||
if (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_free(tray->icon_dir);
|
||||
}
|
||||
|
||||
SDL_GtkContext *gtk = SDL_Gtk_EnterContext();
|
||||
|
Reference in New Issue
Block a user