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
128197int 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+ }
0 commit comments