summaryrefslogtreecommitdiff
path: root/src/lib/efreet
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-07-05 12:53:14 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2015-07-05 12:53:14 +0900
commit2f4fb3edac63413ed292ebca43bda79bfea378cb (patch)
tree3cfd90cbaa1b86fd26c14432246f379b5dec6015 /src/lib/efreet
parente40c223181ec6b46437796809f6c2a7595bfc9bd (diff)
efreet - improve edstop exec find to use the command with less args
efreet will just match any desktop file (at random basically - whatever is first in the list), thjat has the base command looked at. if you have various desktip files with the same command, like: mycommand mycommand %U mycommand -a -b -c /path/to/file /usr/bin/mycommand etc. - which one does it match? it'll pick the first and the list ordering is arbitrary, so this is pretty bad. this strips off the base command at the start (full path or whatever) and then uses the command with the shortest argument length. this means the generic command is found first if we look for "mycommand" in the above list, whihc ends up the best... ESPECIALLY for steam which does just this.
Diffstat (limited to 'src/lib/efreet')
-rw-r--r--src/lib/efreet/efreet_utils.c111
1 files changed, 107 insertions, 4 deletions
diff --git a/src/lib/efreet/efreet_utils.c b/src/lib/efreet/efreet_utils.c
index 809d738c84..ae3ab17e5a 100644
--- a/src/lib/efreet/efreet_utils.c
+++ b/src/lib/efreet/efreet_utils.c
@@ -5,6 +5,7 @@
5/* TODO: add no_display check, as we might want only displayable items */ 5/* TODO: add no_display check, as we might want only displayable items */
6 6
7#include <fnmatch.h> 7#include <fnmatch.h>
8#include <ctype.h>
8 9
9#include <Ecore_File.h> 10#include <Ecore_File.h>
10 11
@@ -170,11 +171,80 @@ efreet_util_desktop_file_id_find(const char *file_id)
170 return ret; 171 return ret;
171} 172}
172 173
174static char *
175efreet_util_cmd_args_get(const char *cmd)
176{
177 Eina_Strbuf *buf;
178 char *args;
179 const char *p;
180 Eina_Bool in_qout_double = EINA_FALSE;
181 Eina_Bool in_qout_single = EINA_FALSE;
182 Eina_Bool atargs = EINA_FALSE;
183 Eina_Bool ingap = EINA_FALSE;
184
185 buf = eina_strbuf_new();
186 if (!buf) return NULL;
187
188 // get the arguments to the command as a string on its own
189 for (p = cmd; *p; p++)
190 {
191 if (!atargs)
192 {
193 if (in_qout_double)
194 {
195 if (*p == '\\')
196 {
197 if (p[1]) p++;
198 }
199 else if (*p == '"') in_qout_double = EINA_FALSE;
200 }
201 else if (in_qout_single)
202 {
203 if (*p == '\\')
204 {
205 if (p[1]) p++;
206 }
207 else if (*p == '\'') in_qout_single = EINA_FALSE;
208 }
209 else
210 {
211 if (*p == '\\')
212 {
213 if (p[1]) p++;
214 }
215 else if (*p == '"') in_qout_double = EINA_TRUE;
216 else if (*p == '\'') in_qout_single = EINA_TRUE;
217 else
218 {
219 if (isspace((unsigned char)(*p)))
220 {
221 atargs = EINA_TRUE;
222 ingap = EINA_TRUE;
223 }
224 }
225 }
226 }
227 else
228 {
229 if (ingap)
230 {
231 if (!isspace((unsigned char)(*p))) ingap = EINA_FALSE;
232 }
233 if (!ingap) eina_strbuf_append_char(buf, *p);
234 }
235 }
236
237 args = eina_strbuf_string_steal(buf);
238 eina_strbuf_free(buf);
239 if (!args) return strdup("");
240 return args;
241}
242
173EAPI Efreet_Desktop * 243EAPI Efreet_Desktop *
174efreet_util_desktop_exec_find(const char *exec) 244efreet_util_desktop_exec_find(const char *exec)
175{ 245{
176 Efreet_Cache_Hash *hash = NULL; 246 Efreet_Cache_Hash *hash = NULL;
177 Efreet_Desktop *ret = NULL; 247 Efreet_Desktop *ret = NULL, *bestret = NULL;
178 Efreet_Cache_Array_String *names = NULL; 248 Efreet_Cache_Array_String *names = NULL;
179 unsigned int i; 249 unsigned int i;
180 250
@@ -207,11 +277,44 @@ efreet_util_desktop_exec_find(const char *exec)
207 for (j = 0; j < array->array_count; j++) 277 for (j = 0; j < array->array_count; j++)
208 { 278 {
209 ret = efreet_desktop_get(array->array[j]); 279 ret = efreet_desktop_get(array->array[j]);
210 if (ret) break; 280 if (ret)
281 {
282 if (!bestret) bestret = ret;
283 else
284 {
285 if (ret->exec)
286 {
287 // perfect match - best
288 if (!strcmp(ret->exec, exec))
289 {
290 bestret = ret;
291 goto done;
292 }
293 else if (bestret->exec)
294 {
295 char *f1, *f2;
296
297 f1 = efreet_util_cmd_args_get(ret->exec);
298 f2 = efreet_util_cmd_args_get(bestret->exec);
299 if ((f1) && (f2))
300 {
301 // if this is shorter (less arguments) than best
302 // match so far, thewn this is the best match
303 if (strlen(f1) < strlen(f2))
304 {
305 bestret = ret;
306 }
307 }
308 free(f1);
309 free(f2);
310 }
311 }
312 }
313 }
211 } 314 }
212 if (ret) break;
213 } 315 }
214 return ret; 316done:
317 return bestret;
215} 318}
216 319
217EAPI Efreet_Desktop * 320EAPI Efreet_Desktop *