]> Dogcows Code - chaz/tint2/blobdiff - src/launcher/launcher.c
Launcher: add icon lookup in ~/.local and /usr/local
[chaz/tint2] / src / launcher / launcher.c
index 87abfc0f7e25bebe152b2a7f8701ea5095b766e1..6915d05b00cd7d445177e827a50c79e9a236b824 100644 (file)
 
 int launcher_enabled;
 int launcher_max_icon_size;
+int launcher_tooltip_enabled;
+int launcher_alpha;
+int launcher_saturation;
+int launcher_brightness;
 char *icon_theme_name; 
 XSettingsClient *xsettings_client;
 
-#define ICON_FALLBACK "exec"
+#define ICON_FALLBACK "application-x-executable"
 
 char *icon_path(Launcher *launcher, const char *icon_name, int size);
 void launcher_load_themes(Launcher *launcher);
@@ -52,6 +56,10 @@ void default_launcher()
 {
        launcher_enabled = 0;
        launcher_max_icon_size = 0;
+       launcher_tooltip_enabled = 0;
+       launcher_alpha = 100;
+       launcher_saturation = 0;
+       launcher_brightness = 0;
        icon_theme_name = 0;
        xsettings_client = NULL;
 }
@@ -73,11 +81,13 @@ void init_launcher_panel(void *p)
 
        launcher->area.parent = p;
        launcher->area.panel = p;
-       launcher->area._draw_foreground = draw_launcher;
+       launcher->area._draw_foreground = NULL;
        launcher->area.size_mode = SIZE_BY_CONTENT;
        launcher->area._resize = resize_launcher;
        launcher->area.resize = 1;
        launcher->area.redraw = 1;
+       if (launcher->area.bg == 0)
+               launcher->area.bg = &g_array_index(backgrounds, Background, 0);
 
        // check consistency
        if (launcher->list_apps == NULL)
@@ -94,6 +104,7 @@ void init_launcher_panel(void *p)
 void cleanup_launcher()
 {
        int i;
+       GSList *l;
 
        if (xsettings_client)
                xsettings_client_destroy(xsettings_client);
@@ -101,15 +112,14 @@ void cleanup_launcher()
                Panel *panel = &panel1[i];
                Launcher *launcher = &panel->launcher;          
                cleanup_launcher_theme(launcher);
-               
-               GSList *l;
-               for (l = launcher->list_apps; l ; l = l->next) {
-                       free(l->data);
-               }
-               g_slist_free(launcher->list_apps);
-               launcher->list_apps = NULL;
        }
-       g_free(icon_theme_name);
+       for (l = panel_config.launcher.list_apps; l ; l = l->next) {
+               free(l->data);
+       }
+       g_slist_free(panel_config.launcher.list_apps);
+       panel_config.launcher.list_apps = NULL;
+       free(icon_theme_name);
+       icon_theme_name = 0;
        launcher_enabled = 0;
 }
 
@@ -126,6 +136,7 @@ void cleanup_launcher_theme(Launcher *launcher)
                        free(launcherIcon->icon_name);
                        free(launcherIcon->icon_path);
                        free(launcherIcon->cmd);
+                       free(launcherIcon->icon_tooltip);
                }
                free(launcherIcon);
        }
@@ -161,6 +172,8 @@ int resize_launcher(void *obj)
                LauncherIcon *launcherIcon = (LauncherIcon *)l->data;
                if (launcherIcon->icon_size != icon_size || !launcherIcon->icon_original) {
                        launcherIcon->icon_size = icon_size;
+                       launcherIcon->area.width = launcherIcon->icon_size;
+                       launcherIcon->area.height = launcherIcon->icon_size;
 
                        // Get the path for an icon file with the new size
                        char *new_icon_path = icon_path(launcher, launcherIcon->icon_name, launcherIcon->icon_size);
@@ -261,27 +274,32 @@ int resize_launcher(void *obj)
        return 1;
 }
 
+// Here we override the default layout of the icons; normally Area layouts its children
+// in a stack; we need to layout them in a kind of table
+void launcher_icon_on_change_layout(void *obj)
+{
+       LauncherIcon *launcherIcon = (LauncherIcon*)obj;
+       launcherIcon->area.posy = ((Area*)launcherIcon->area.parent)->posy + launcherIcon->y;
+       launcherIcon->area.posx = ((Area*)launcherIcon->area.parent)->posx + launcherIcon->x;
+}
 
-void draw_launcher(void *obj, cairo_t *c)
+const char* launcher_icon_get_tooltip_text(void *obj)
 {
-       Launcher *launcher = obj;
-       GSList *l;
-       if (launcher->list_icons == 0) return;
+       LauncherIcon *launcherIcon = (LauncherIcon*)obj;
+       return launcherIcon->icon_tooltip;
+}
 
-       for (l = launcher->list_icons; l ; l = l->next) {
-               LauncherIcon *launcherIcon = (LauncherIcon*)l->data;
-               int pos_x = launcherIcon->x;
-               int pos_y = launcherIcon->y;
-               Imlib_Image icon_scaled = launcherIcon->icon_scaled;
-               // Render
-               imlib_context_set_image (icon_scaled);
-               if (server.real_transparency) {
-                       render_image(launcher->area.pix, pos_x, pos_y, imlib_image_get_width(), imlib_image_get_height() );
-               }
-               else {
-                       imlib_context_set_drawable(launcher->area.pix);
-                       imlib_render_image_on_drawable (pos_x, pos_y);
-               }
+void draw_launcher_icon(void *obj, cairo_t *c)
+{
+       LauncherIcon *launcherIcon = (LauncherIcon*)obj;
+       Imlib_Image icon_scaled = launcherIcon->icon_scaled;
+       // Render
+       imlib_context_set_image (icon_scaled);
+       if (server.real_transparency) {
+               render_image(launcherIcon->area.pix, 0, 0, imlib_image_get_width(), imlib_image_get_height() );
+       } else {
+               imlib_context_set_drawable(launcherIcon->area.pix);
+               imlib_render_image_on_drawable (0, 0);
        }
 }
 
@@ -291,6 +309,11 @@ Imlib_Image scale_icon(Imlib_Image original, int icon_size)
        if (original) {
                imlib_context_set_image (original);
                icon_scaled = imlib_create_cropped_scaled_image(0, 0, imlib_image_get_width(), imlib_image_get_height(), icon_size, icon_size);
+               imlib_context_set_image (icon_scaled);
+               imlib_image_set_has_alpha(1);
+               DATA32* data = imlib_image_get_data();
+               adjust_asb(data, icon_size, icon_size, launcher_alpha, (float)launcher_saturation/100, (float)launcher_brightness/100);
+               imlib_image_put_back_data(data);
        } else {
                icon_scaled = imlib_create_image(icon_size, icon_size);
                imlib_context_set_image (icon_scaled);
@@ -403,7 +426,8 @@ void expand_exec(DesktopEntry *entry, const char *path)
 int launcher_read_desktop_file(const char *path, DesktopEntry *entry)
 {
        FILE *fp;
-       char line[4096];
+       char *line = NULL;
+       size_t line_size;
        char *key, *value;
 
        entry->name = entry->icon = entry->exec = NULL;
@@ -413,17 +437,21 @@ int launcher_read_desktop_file(const char *path, DesktopEntry *entry)
                return 0;
        }
 
-       while (fgets(line, sizeof(line), fp) != NULL) {
+       int inside_desktop_entry = 0;
+       while (getline(&line, &line_size, fp) >= 0) {
                int len = strlen(line);
                if (len == 0)
                        continue;
                line[len - 1] = '\0';
-               if (parse_dektop_line(line, &key, &value)) {
-                       if (strcmp(key, "Name") == 0) {
+               if (line[0] == '[') {
+                       inside_desktop_entry = (strcmp(line, "[Desktop Entry]") == 0);
+               }
+               if (inside_desktop_entry && parse_dektop_line(line, &key, &value)) {
+                       if (!entry->name && strcmp(key, "Name") == 0) {
                                entry->name = strdup(value);
-                       } else if (strcmp(key, "Exec") == 0) {
+                       } else if (!entry->exec && strcmp(key, "Exec") == 0) {
                                entry->exec = strdup(value);
-                       } else if (strcmp(key, "Icon") == 0) {
+                       } else if (!entry->icon && strcmp(key, "Icon") == 0) {
                                entry->icon = strdup(value);
                        }
                }
@@ -434,6 +462,7 @@ int launcher_read_desktop_file(const char *path, DesktopEntry *entry)
 
        expand_exec(entry, path);
        
+       free(line);
        return 1;
 }
 
@@ -463,7 +492,8 @@ IconTheme *load_theme(char *name)
        IconTheme *theme;
        char *file_name;
        FILE *f;
-       char line[2048];
+       char *line = NULL;
+       size_t line_size;
 
        if (name == NULL)
                return NULL;
@@ -500,7 +530,7 @@ IconTheme *load_theme(char *name)
 
        IconThemeDir *current_dir = NULL;
        int inside_header = 1;
-       while (fgets(line, sizeof(line), f) != NULL) {
+       while (getline(&line, &line_size, f) >= 0) {
                char *key, *value;
                
                int line_len = strlen(line);
@@ -594,6 +624,8 @@ IconTheme *load_theme(char *name)
        }
        fclose(f);
        
+       free(line);
+       
        return theme;
 }
 
@@ -654,12 +686,28 @@ void launcher_load_icons(Launcher *launcher)
                launcher_read_desktop_file(app->data, &entry);
                if (entry.exec) {
                        LauncherIcon *launcherIcon = calloc(1, sizeof(LauncherIcon));
+                       launcherIcon->area.parent = launcher;
+                       launcherIcon->area.panel = launcher->area.panel;
+                       launcherIcon->area._draw_foreground = draw_launcher_icon;
+                       launcherIcon->area.size_mode = SIZE_BY_CONTENT;
+                       launcherIcon->area._resize = NULL;
+                       launcherIcon->area.resize = 0;
+                       launcherIcon->area.redraw = 1;
+                       launcherIcon->area.bg = &g_array_index(backgrounds, Background, 0);
+                       launcherIcon->area.on_screen = 1;
+                       launcherIcon->area._on_change_layout = launcher_icon_on_change_layout;
+                       if (launcher_tooltip_enabled) 
+                               launcherIcon->area._get_tooltip_text = launcher_icon_get_tooltip_text;
+                       else
+                               launcherIcon->area._get_tooltip_text = NULL;
                        launcherIcon->is_app_desktop = 1;
                        launcherIcon->cmd = strdup(entry.exec);
                        launcherIcon->icon_name = entry.icon ? strdup(entry.icon) : strdup(ICON_FALLBACK);
                        launcherIcon->icon_size = 1;
+                       launcherIcon->icon_tooltip = entry.name ? strdup(entry.name) : strdup(entry.exec);
                        free_desktop_entry(&entry);
                        launcher->list_icons = g_slist_append(launcher->list_icons, launcherIcon);
+                       add_area(&launcherIcon->area);
                }
                app = g_slist_next(app);
        }
@@ -673,10 +721,10 @@ void launcher_load_themes(Launcher *launcher)
        // avoid inheritance loops
        if (!icon_theme_name) {
                fprintf(stderr, "Missing launcher theme, default to 'hicolor'.\n");
-               icon_theme_name = "hicolor";
-       }
-       else
+               icon_theme_name = strdup("hicolor");
+       } else {
                fprintf(stderr, "Loading %s. Icon theme :", icon_theme_name);
+       }
 
        GSList *queue = g_slist_append(NULL, strdup(icon_theme_name));
        GSList *queued = g_slist_append(NULL, strdup(icon_theme_name));
@@ -775,6 +823,7 @@ int directory_size_distance(IconThemeDir *dir, int size)
        }
 }
 
+#define DEBUG_ICON_SEARCH 0
 // Returns the full path to an icon file (or NULL) given the icon name
 char *icon_path(Launcher *launcher, const char *icon_name, int size)
 {
@@ -792,6 +841,10 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
        GSList *basenames = NULL;
        char *home_icons = g_build_filename(g_get_home_dir(), ".icons", NULL);
        basenames = g_slist_append(basenames, home_icons);
+       char *home_local_icons = g_build_filename(g_get_home_dir(), ".local/share/icons", NULL);
+       basenames = g_slist_append(basenames, home_local_icons);
+       basenames = g_slist_append(basenames, "/usr/local/share/icons");
+       basenames = g_slist_append(basenames, "/usr/local/share/pixmaps");
        basenames = g_slist_append(basenames, "/usr/share/icons");
        basenames = g_slist_append(basenames, "/usr/share/pixmaps");
 
@@ -836,6 +889,7 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
                                                        g_slist_free(basenames);
                                                        g_slist_free(extensions);
                                                        g_free(home_icons);
+                                                       g_free(home_local_icons);
                                                        return file_name;
                                                } else {
                                                        free(file_name);
@@ -879,8 +933,11 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
                                        strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100);
                                        // filename = directory/$(themename)/subdirectory/iconname.extension
                                        sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
+                                       if (DEBUG_ICON_SEARCH)
+                                               printf("checking %s\n", file_name);
                                        if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
-                                               //printf("found: %s\n", file_name);
+                                               if (DEBUG_ICON_SEARCH)
+                                                       printf("found: %s\n", file_name);
                                                // Closest match
                                                if (directory_size_distance((IconThemeDir*)dir->data, size) < minimal_size && (!best_file_theme ? 1 : theme == best_file_theme)) {
                                                        if (best_file_name) {
@@ -890,7 +947,8 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
                                                        best_file_name = strdup(file_name);
                                                        minimal_size = directory_size_distance((IconThemeDir*)dir->data, size);
                                                        best_file_theme = theme;
-                                                       //printf("best_file_name = %s; minimal_size = %d\n", best_file_name, minimal_size);
+                                                       if (DEBUG_ICON_SEARCH)
+                                                               printf("best_file_name = %s; minimal_size = %d\n", best_file_name, minimal_size);
                                                }
                                                // Next larger match
                                                if (((IconThemeDir*)dir->data)->size >= size &&
@@ -903,7 +961,8 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
                                                        next_larger = strdup(file_name);
                                                        next_larger_size = ((IconThemeDir*)dir->data)->size;
                                                        next_larger_theme = theme;
-                                                       //printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size);
+                                                       if (DEBUG_ICON_SEARCH)
+                                                               printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size);
                                                }
                                        }
                                        free(file_name);
@@ -916,12 +975,14 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
                g_slist_free(extensions);
                free(best_file_name);
                g_free(home_icons);
+               g_free(home_local_icons);
                return next_larger;
        }
        if (best_file_name) {
                g_slist_free(basenames);
                g_slist_free(extensions);
                g_free(home_icons);
+               g_free(home_local_icons);
                return best_file_name;
        }
 
@@ -937,11 +998,13 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
                                        strlen(extension) + 100);
                                // filename = directory/iconname.extension
                                sprintf(file_name, "%s/%s%s", base_name, icon_name, extension);
-                               //printf("checking %s\n", file_name);
+                               if (DEBUG_ICON_SEARCH)
+                                       printf("checking %s\n", file_name);
                                if (g_file_test(file_name, G_FILE_TEST_EXISTS)) {
                                        g_slist_free(basenames);
                                        g_slist_free(extensions);
                                        g_free(home_icons);
+                                       g_free(home_local_icons);
                                        return file_name;
                                } else {
                                        free(file_name);
@@ -956,6 +1019,7 @@ char *icon_path(Launcher *launcher, const char *icon_name, int size)
        g_slist_free(basenames);
        g_slist_free(extensions);
        g_free(home_icons);
+       g_free(home_local_icons);
        return NULL;
 }
 
This page took 0.031705 seconds and 4 git commands to generate.