Commit 1a3ba212 authored by o9000's avatar o9000 Committed by mrovi9000@gmail.com

Launcher: SVG icon support and icon loading improvements

git-svn-id: http://tint2.googlecode.com/svn/trunk@670 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
parent ec80e09b
......@@ -16,5 +16,5 @@ Contributors:
James Buren <ryuo@frugalware.org> : Frugalware package
Pierre-Emmanuel Andre <pea@raveland.org> : openbsd port
Redroar : arch package
Rene Garcia <garciamx@gmail.com> : launcher SVG support
......@@ -10,7 +10,9 @@ pkg_check_modules( CAIRO REQUIRED cairo )
pkg_check_modules( GLIB2 REQUIRED glib-2.0 )
pkg_check_modules( GOBJECT2 REQUIRED gobject-2.0 )
pkg_check_modules( IMLIB2 REQUIRED imlib2>=1.4.2 )
pkg_check_modules( RSVG librsvg-2.0>=2.36.0 )
pkg_check_modules( SN libstartup-notification-1.0>=0.12 )
find_library( RT_LIBRARY rt )
if( NOT X11_FOUND OR NOT PANGOCAIRO_FOUND OR NOT PANGO_FOUND OR NOT CAIRO_FOUND OR NOT GLIB2_FOUND OR NOT GOBJECT2_FOUND OR NOT IMLIB2_FOUND )
......@@ -40,7 +42,8 @@ include_directories( ${PROJECT_BINARY_DIR}
${GLIB2_INCLUDE_DIRS}
${GOBJECT2_INCLUDE_DIRS}
${IMLIB2_INCLUDE_DIRS}
${SN_INCLUDE_DIRS} )
${RSVG_INCLUDE_DIRS}
${SN_INCLUDE_DIRS} )
set( SOURCES src/config.c
src/panel.c
......@@ -49,6 +52,8 @@ set( SOURCES src/config.c
src/clock/clock.c
src/systray/systraybar.c
src/launcher/launcher.c
src/launcher/apps-common.c
src/launcher/icon-theme-common.c
src/launcher/xsettings-client.c
src/launcher/xsettings-common.c
src/taskbar/task.c
......@@ -63,6 +68,19 @@ set( SOURCES src/config.c
option( ENABLE_BATTERY "Enable battery status plugin" ON )
option( ENABLE_TINT2CONF "Enable tint2conf build, a GTK+2 theme switcher for tint2" ON )
option( ENABLE_EXAMPLES "Install additional tin2rc examples" OFF )
option( ENABLE_RSVG "Rsvg support (launcher only)" ON )
if( ENABLE_BATTERY )
set( SOURCES ${SOURCES} src/battery/battery.c )
add_definitions( -DENABLE_BATTERY )
endif( ENABLE_BATTERY )
if( ENABLE_RSVG )
if( RSVG_FOUND )
add_definitions( -DHAVE_RSVG )
endif( RSVG_FOUND )
endif( ENABLE_RSVG )
option( ENABLE_SN "Startup notification support" ON )
if( ENABLE_SN )
if( SN_FOUND )
......@@ -70,11 +88,6 @@ if( ENABLE_SN )
endif( SN_FOUND )
endif( ENABLE_SN)
if( ENABLE_BATTERY )
set( SOURCES ${SOURCES} src/battery/battery.c )
add_definitions( -DENABLE_BATTERY )
endif( ENABLE_BATTERY )
set( MANDIR share/man CACHE PATH "Directory for man pages" )
set( DATADIR share CACHE PATH "Directory for shared data" )
set( SYSCONFDIR /etc CACHE PATH "Directory for configuration files" )
......@@ -95,7 +108,8 @@ link_directories( ${X11_LIBRARY_DIRS}
${GLIB2_LIBRARY_DIRS}
${GOBJECT2_LIBRARY_DIRS}
${IMLIB2_LIBRARY_DIRS}
${SN_LIBRARY_DIRS} )
${RSVG_LIBRARY_DIRS}
${SN_LIBRARY_DIRS} )
add_executable(tint2 ${SOURCES})
target_link_libraries( tint2 ${X11_LIBRARIES}
${PANGOCAIRO_LIBRARIES}
......@@ -104,7 +118,8 @@ target_link_libraries( tint2 ${X11_LIBRARIES}
${GLIB2_LIBRARIES}
${GOBJECT2_LIBRARIES}
${IMLIB2_LIBRARIES}
${SN_LIBRARIES} )
${RSVG_LIBRARIES}
${SN_LIBRARIES} )
if( RT_LIBRARY )
target_link_libraries( tint2 ${RT_LIBRARY} )
endif( RT_LIBRARY )
......
/**************************************************************************
* Tint2 : .desktop file handling
*
* Copyright (C) 2015 (mrovi9000@gmail.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**************************************************************************/
/* http://standards.freedesktop.org/desktop-entry-spec/ */
#include "apps-common.h"
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int parse_dektop_line(char *line, char **key, char **value)
{
char *p;
int found = 0;
*key = line;
for (p = line; *p; p++) {
if (*p == '=') {
*value = p + 1;
*p = 0;
found = 1;
break;
}
}
if (!found)
return 0;
if (found && (strlen(*key) == 0 || strlen(*value) == 0))
return 0;
return 1;
}
void expand_exec(DesktopEntry *entry, const char *path)
{
// Expand % in exec
// %i -> --icon Icon
// %c -> Name
// %k -> path
if (entry->exec) {
char *exec2 = malloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100);
char *p, *q;
// p will never point to an escaped char
for (p = entry->exec, q = exec2; *p; p++, q++) {
*q = *p; // Copy
if (*p == '\\') {
p++, q++;
// Copy the escaped char
if (*p == '%') // For % we delete the backslash, i.e. write % over it
q--;
*q = *p;
if (!*p) break;
continue;
}
if (*p == '%') {
p++;
if (!*p) break;
if (*p == 'i' && entry->icon != NULL) {
sprintf(q, "--icon '%s'", entry->icon);
q += strlen("--icon ''");
q += strlen(entry->icon);
q--; // To balance the q++ in the for
} else if (*p == 'c' && entry->name != NULL) {
sprintf(q, "'%s'", entry->name);
q += strlen("''");
q += strlen(entry->name);
q--; // To balance the q++ in the for
} else if (*p == 'c') {
sprintf(q, "'%s'", path);
q += strlen("''");
q += strlen(path);
q--; // To balance the q++ in the for
} else {
// We don't care about other expansions
q--; // Delete the last % from q
}
continue;
}
}
*q = '\0';
free(entry->exec);
entry->exec = exec2;
}
}
int read_desktop_file(const char *path, DesktopEntry *entry)
{
FILE *fp;
char *line = NULL;
size_t line_size;
char *key, *value;
int i;
entry->name = entry->icon = entry->exec = NULL;
if ((fp = fopen(path, "rt")) == NULL) {
fprintf(stderr, "Could not open file %s\n", path);
return 0;
}
gchar **languages = (gchar **)g_get_language_names();
// lang_index is the index of the language for the best Name key in the language vector
// lang_index_default is a constant that encodes the Name key without a language
int lang_index, lang_index_default;
#define LANG_DBG 0
if (LANG_DBG) printf("Languages:");
for (i = 0; languages[i]; i++) {
if (LANG_DBG) printf(" %s", languages[i]);
}
if (LANG_DBG) printf("\n");
lang_index_default = i;
// we currently do not know about any Name key at all, so use an invalid index
lang_index = lang_index_default + 1;
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 (line[0] == '[') {
inside_desktop_entry = (strcmp(line, "[Desktop Entry]") == 0);
}
if (inside_desktop_entry && parse_dektop_line(line, &key, &value)) {
if (strstr(key, "Name") == key) {
if (strcmp(key, "Name") == 0 && lang_index > lang_index_default) {
entry->name = strdup(value);
lang_index = lang_index_default;
} else {
for (i = 0; languages[i] && i < lang_index; i++) {
gchar *localized_key = g_strdup_printf("Name[%s]", languages[i]);
if (strcmp(key, localized_key) == 0) {
if (entry->name)
free(entry->name);
entry->name = strdup(value);
lang_index = i;
}
g_free(localized_key);
}
}
} else if (!entry->exec && strcmp(key, "Exec") == 0) {
entry->exec = strdup(value);
} else if (!entry->icon && strcmp(key, "Icon") == 0) {
entry->icon = strdup(value);
}
}
}
fclose (fp);
// From this point:
// entry->name, entry->icon, entry->exec will never be empty strings (can be NULL though)
expand_exec(entry, path);
free(line);
return 1;
}
void free_desktop_entry(DesktopEntry *entry)
{
free(entry->name);
free(entry->icon);
free(entry->exec);
entry->name = entry->icon = entry->exec = NULL;
}
void test_read_desktop_file()
{
fprintf(stdout, "\033[1;33m");
DesktopEntry entry;
read_desktop_file("/usr/share/applications/firefox.desktop", &entry);
printf("Name:%s Icon:%s Exec:%s\n", entry.name, entry.icon, entry.exec);
fprintf(stdout, "\033[0m");
}
/**************************************************************************
* Copyright (C) 2015 (mrovi9000@gmail.com)
*
*
**************************************************************************/
#ifndef APPS_COMMON_H
#define APPS_COMMON_H
typedef struct DesktopEntry {
char *name;
char *exec;
char *icon;
} DesktopEntry;
// Parses a line of the form "key = value". Modifies the line.
// Returns 1 if successful, and parts are not empty.
// Key and value point to the parts.
int parse_dektop_line(char *line, char **key, char **value);
// Reads the .desktop file from the given path into the DesktopEntry entry.
// The DesktopEntry object must be initially empty.
// Returns 1 if successful.
int read_desktop_file(const char *path, DesktopEntry *entry);
// Empties DesktopEntry: releases the memory of the *members* of entry.
void free_desktop_entry(DesktopEntry *entry);
#endif
This diff is collapsed.
/**************************************************************************
* Copyright (C) 2015 (mrovi9000@gmail.com)
*
**************************************************************************/
#ifndef ICON_THEME_COMMON_H
#define ICON_THEME_COMMON_H
#include <glib.h>
typedef struct IconThemeWrapper {
// List of IconTheme*
GSList *themes;
// List of IconTheme*
GSList *themes_fallback;
} IconThemeWrapper;
typedef struct IconTheme {
char *name;
GSList *list_inherits; // each item is a char* (theme name)
GSList *list_directories; // each item is an IconThemeDir*
} IconTheme;
// Parses a line of the form "key = value". Modifies the line.
// Returns 1 if successful, and parts are not empty.
// Key and value point to the parts.
int parse_theme_line(char *line, char **key, char **value);
// Returns an IconThemeWrapper* containing the icon theme identified by the name icon_theme_name, all the
// inherited themes, the hicolor theme and possibly fallback themes.
IconThemeWrapper *load_themes(const char *icon_theme_name);
void free_themes(IconThemeWrapper *themes);
#define DEFAULT_ICON "application-x-executable"
// Returns the full path to an icon file (or NULL) given the list of icon themes to search and the icon name
// Note: needs to be released with free().
char *get_icon_path(IconThemeWrapper *theme, const char *icon_name, int size);
// Returns a list of the directories used to store icons.
// Do not free the result, it is cached.
const GSList *get_icon_locations();
#endif
This diff is collapsed.
......@@ -10,13 +10,14 @@
#include "common.h"
#include "area.h"
#include "xsettings-client.h"
#include "icon-theme-common.h"
typedef struct Launcher {
// always start with area
Area area;
GSList *list_apps; // List of char*, each is a path to a app.desktop file
GSList *list_icons; // List of LauncherIcon*
GSList *list_themes; // List of IconTheme*
IconThemeWrapper *list_themes;
} Launcher;
typedef struct LauncherIcon {
......@@ -33,31 +34,6 @@ typedef struct LauncherIcon {
int x, y;
} LauncherIcon;
typedef struct DesktopEntry {
char *name;
char *exec;
char *icon;
} DesktopEntry;
#define ICON_DIR_TYPE_SCALABLE 0
#define ICON_DIR_TYPE_FIXED 1
#define ICON_DIR_TYPE_THRESHOLD 2
typedef struct IconThemeDir {
char *name;
int size;
int type;
int max_size;
int min_size;
int threshold;
char *context;
} IconThemeDir;
typedef struct IconTheme {
char *name;
GSList *list_inherits; // each item is a char* (theme name)
GSList *list_directories; // each item is an IconThemeDir*
} IconTheme;
extern int launcher_enabled;
extern int launcher_max_icon_size;
extern int launcher_tooltip_enabled;
......@@ -79,10 +55,10 @@ void cleanup_launcher_theme(Launcher *launcher);
int resize_launcher(void *obj);
void draw_launcher (void *obj, cairo_t *c);
// Populates the list_themes list
void launcher_load_themes(Launcher *launcher);
// Populates the list_icons list
void launcher_load_icons(Launcher *launcher);
// Populates the list_themes list
void launcher_load_themes(Launcher *launcher);
void launcher_action(LauncherIcon *icon, XEvent* e);
void test_launcher_read_desktop_file();
......
......@@ -391,8 +391,10 @@ void set_panel_items_order(Panel *p)
}
for (k=0 ; k < strlen(panel_items_order) ; k++) {
if (panel_items_order[k] == 'L')
if (panel_items_order[k] == 'L') {
p->area.list = g_slist_append(p->area.list, &p->launcher);
p->launcher.area.resize = 1;
}
if (panel_items_order[k] == 'T') {
for (j=0 ; j < p->nb_desktop ; j++)
p->area.list = g_slist_append(p->area.list, &p->taskbar[j]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment