Skip to content

Commit a1c2a62

Browse files
committed
Parses desktop files when provided as the only argument on unix, making it even easier to configure
1 parent 140057e commit a1c2a62

4 files changed

Lines changed: 99 additions & 7 deletions

File tree

src/image.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ SDL_Surface *load_surface_from_xdg(const char *path){
122122
"64x64",
123123
"32x32"
124124
};
125+
const char* exts[] = {"", ".svg", ".png"};
125126

126-
for(int i = 0; i < sizeof(sizes) / sizeof(void*); i++){
127+
for(int i = 0; i < sizeof(sizes) / sizeof(sizes[0]); i++){
127128
char icon_path[128] = {};
128129
snprintf(icon_path, 127, "/icons/hicolor/%s/apps/", sizes[i]);
129130

@@ -140,9 +141,14 @@ SDL_Surface *load_surface_from_xdg(const char *path){
140141
memcpy(&xdg_path, &xdg_dirs[start_ind], end);
141142
memcpy(&xdg_path[end], icon_path, strlen(icon_path));
142143
memcpy(&xdg_path[end + strlen(icon_path)], path, strlen(path));
143-
surface = IMG_Load(xdg_path);
144-
if (surface != NULL)
145-
return surface;
144+
for(int j = 0; j < sizeof(exts) / sizeof(exts[0]); j++){
145+
memcpy(&xdg_path[end + strlen(icon_path) + strlen(path)], exts[j], strlen(exts[j]));
146+
surface = IMG_Load(xdg_path);
147+
if (surface != NULL)
148+
return surface;
149+
}
150+
151+
146152

147153
last_delim += end + 1;
148154
}

src/launcher.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ static void move_right()
723723
calculate_button_geometry(current_menu->root_entry, (int) buttons);
724724
if (config.highlight)
725725
highlight->rect.x = current_entry->icon_rect.x - config.highlight_hpadding;
726+
highlight->rect.x = current_entry->icon_rect.x - config.highlight_hpadding;
726727
current_menu->page++;
727728
current_menu->highlight_position = 0;
728729
}

src/util.c

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <stddef.h>
12
#include <stdio.h>
23
#include <stdlib.h>
34
#include <stdarg.h>
@@ -124,6 +125,74 @@ void parse_config_file(const char *config_file_path)
124125
log_fatal("Could not parse config file");
125126
}
126127

128+
#ifdef __unix__
129+
int desktop_config_handler(void *user, const char *section, const char *name, const char *value){
130+
Entry* entry = (Entry*)(user);
131+
if(MATCH(section, "Desktop Entry")){
132+
if(MATCH(name, "Icon"))
133+
entry->icon_path = strdup(value);
134+
135+
if(MATCH(name, "Exec")){
136+
ssize_t end = strcspn(value, "%@");
137+
char* cmd = malloc(end + 1);
138+
cmd[end] = '\0';
139+
memcpy(cmd, value, end);
140+
entry->cmd = cmd;
141+
log_error("Parsed command '%s' from desktop file.", cmd);
142+
}
143+
144+
if(MATCH(name, "Name"))
145+
entry->title = strdup(value);
146+
return 0;
147+
}
148+
return 1;
149+
}
150+
151+
152+
Entry parse_possible_desktop_file(const char* name){
153+
const char* xdg_dirs = getenv("XDG_DATA_DIRS");
154+
const char* sizes[] = {
155+
"scalable",
156+
"512x512",
157+
"256x256",
158+
"128x128",
159+
"64x64",
160+
"32x32"
161+
};
162+
163+
const char* app_path = "/applications/";
164+
165+
Entry result = {};
166+
if(xdg_dirs != NULL){
167+
ssize_t last_delim = -1;
168+
ssize_t dirs_len = strlen(xdg_dirs);
169+
while(last_delim < dirs_len){
170+
char xdg_path[4096] = {0};
171+
ssize_t start_ind = last_delim;
172+
if(start_ind < 0)
173+
start_ind = 0;
174+
175+
ssize_t end = strcspn(&xdg_dirs[start_ind], ":");
176+
memcpy(&xdg_path, &xdg_dirs[start_ind], end);
177+
memcpy(&xdg_path[end], app_path, strlen(app_path));
178+
memcpy(&xdg_path[end + strlen(app_path)], name, strlen(name));
179+
180+
FILE *file = fopen(xdg_path, "r");
181+
if(file != NULL){
182+
int error = ini_parse_file(file, desktop_config_handler, &result);
183+
fclose(file);
184+
if(error == 0)
185+
return result;
186+
}
187+
last_delim += end + 1;
188+
}
189+
}
190+
return result;
191+
192+
}
193+
#endif
194+
195+
127196
// A function to handle config file parsing
128197
int config_handler(void *user, const char *section, const char *name, const char *value)
129198
{
@@ -445,8 +514,19 @@ int config_handler(void *user, const char *section, const char *name, const char
445514
// Store data in entry struct
446515
int i;
447516
for (i = 0;i < 3 && token != NULL; i++) {
448-
if (i == 0)
517+
if (i == 0){
449518
entry->title = strdup(token);
519+
#ifdef __unix__
520+
Entry ent = parse_possible_desktop_file(entry->title);
521+
if(ent.cmd != NULL || ent.icon_path != NULL || ent.title != NULL){
522+
entry->cmd = ent.cmd;
523+
entry->icon_path = ent.icon_path;
524+
entry->title = ent.title;
525+
i = 3;
526+
break;
527+
}
528+
#endif
529+
}
450530
else if (i == 1) {
451531
entry->icon_path = strdup(token);
452532
clean_path(entry->icon_path);
@@ -1101,4 +1181,4 @@ void sprintf_alloc(char **buffer, const char *format, ...)
11011181
}
11021182
va_end(args1);
11031183
va_end(args2);
1104-
}
1184+
}

src/util.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ struct gamepad_info {
2323
};
2424

2525
int config_handler(void *user, const char *section, const char *name, const char *value);
26+
#ifdef __unix__
27+
int desktop_config_handler(void *user, const char *section, const char *name, const char *value);
28+
Entry parse_possible_desktop_file(const char* name);
29+
#endif
30+
2631
int convert_percent(const char *string, int max_value);
2732
const char *get_mode_setting(int type, int value);
2833
int utf8_length(const char *string);
@@ -46,4 +51,4 @@ void read_file(const char *path, char **buffer);
4651
void sprintf_alloc(char **buffer, const char *format, ...);
4752
Uint16 get_unicode_code_point(const char *p, int *bytes);
4853
Menu *get_menu(const char *menu_name);
49-
Entry *advance_entries(Entry *entry, int spaces, Direction direction);
54+
Entry *advance_entries(Entry *entry, int spaces, Direction direction);

0 commit comments

Comments
 (0)