34 #define G_LOG_DOMAIN "Dialogs.Run"
43 #include <sys/types.h>
62 #define RUN_CACHE_FILE "rofi-3.runcache"
81 static gboolean
exec_cmd (
const char *cmd,
int run_in_term )
84 if ( !cmd || !cmd[0] ) {
87 gsize lf_cmd_size = 0;
88 gchar *lf_cmd = g_locale_from_utf8 ( cmd, -1, NULL, &lf_cmd_size, &error );
89 if ( error != NULL ) {
90 g_warning (
"Failed to convert command to locale encoding: %s", error->message );
91 g_error_free ( error );
140 static int sort_func (
const void *a,
const void *b, G_GNUC_UNUSED
void *data )
142 const char *astr = *(
const char *
const * ) a;
143 const char *bstr = *(
const char *
const * ) b;
145 if ( astr == NULL && bstr == NULL ) {
148 else if ( astr == NULL ) {
151 else if ( bstr == NULL ) {
154 return g_strcmp0 ( astr, bstr );
160 static char **
get_apps_external (
char **retv,
unsigned int *length,
unsigned int num_favorites )
164 FILE *inp = fdopen ( fd,
"r" );
167 size_t buffer_length = 0;
169 while ( getline ( &buffer, &buffer_length, inp ) > 0 ) {
172 if ( buffer[strlen ( buffer ) - 1] ==
'\n' ) {
173 buffer[strlen ( buffer ) - 1] =
'\0';
178 for (
unsigned int j = 0; found == 0 && j < num_favorites; j++ ) {
179 if ( strcasecmp ( buffer, retv[j] ) == 0 ) {
189 retv = g_realloc ( retv, ( ( *length ) + 2 ) *
sizeof (
char* ) );
190 retv[( *length )] = g_strdup ( buffer );
194 if ( buffer != NULL ) {
197 if ( fclose ( inp ) != 0 ) {
198 g_warning (
"Failed to close stdout off executor script: '%s'",
199 g_strerror ( errno ) );
203 retv[( *length ) ] = NULL;
212 GError *error = NULL;
214 unsigned int num_favorites = 0;
217 if ( g_getenv (
"PATH" ) == NULL ) {
225 num_favorites = ( *length );
227 path = g_strdup ( g_getenv (
"PATH" ) );
230 gchar *homedir = g_locale_to_utf8 ( g_get_home_dir (), -1, NULL, &l, &error );
231 if ( error != NULL ) {
232 g_debug (
"Failed to convert homedir to UTF-8: %s", error->message );
233 g_clear_error ( &error );
238 const char *
const sep =
":";
239 char *strtok_savepointer = NULL;
240 for (
const char *dirname = strtok_r ( path, sep, &strtok_savepointer ); dirname != NULL; dirname = strtok_r ( NULL, sep, &strtok_savepointer ) ) {
242 DIR *dir = opendir ( fpath );
243 g_debug (
"Checking path %s for executable.", fpath );
249 gchar *dirn = g_locale_to_utf8 ( dirname, -1, NULL, &dirn_len, &error );
250 if ( error != NULL ) {
251 g_debug (
"Failed to convert directory name to UTF-8: %s", error->message );
252 g_clear_error ( &error );
256 gboolean is_homedir = g_str_has_prefix ( dirn, homedir );
259 while ( ( dent = readdir ( dir ) ) != NULL ) {
260 if ( dent->d_type != DT_REG && dent->d_type != DT_LNK && dent->d_type != DT_UNKNOWN ) {
264 if ( dent->d_name[0] ==
'.' ) {
268 gchar *fpath = g_build_filename ( dirname, dent->d_name, NULL );
269 gboolean b = g_file_test ( fpath, G_FILE_TEST_IS_EXECUTABLE );
277 gchar *name = g_filename_to_utf8 ( dent->d_name, -1, NULL, &name_len, &error );
278 if ( error != NULL ) {
279 g_debug (
"Failed to convert filename to UTF-8: %s", error->message );
280 g_clear_error ( &error );
287 for (
unsigned int j = 0; found == 0 && j < num_favorites; j++ ) {
288 if ( g_strcmp0 ( name, retv[j] ) == 0 ) {
298 retv = g_realloc ( retv, ( ( *length ) + 2 ) *
sizeof (
char* ) );
299 retv[( *length )] = name;
300 retv[( *length ) + 1] = NULL;
314 if ( ( *length ) == 0 ) {
318 if ( ( *length ) > num_favorites ) {
319 g_qsort_with_data ( &retv[num_favorites], ( *length ) - num_favorites,
sizeof (
char* ),
sort_func, NULL );
323 unsigned int removed = 0;
324 for (
unsigned int index = num_favorites; index < ( ( *length ) - 1 ); index++ ) {
325 if ( g_strcmp0 ( retv[index], retv[index + 1] ) == 0 ) {
326 g_free ( retv[index] );
332 if ( ( *length ) > num_favorites ) {
333 g_qsort_with_data ( &retv[num_favorites], ( *length ) - num_favorites,
sizeof (
char* ),
338 ( *length ) -= removed;
357 if ( rmpd != NULL ) {
382 else if ( ( mretv &
MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] !=
'\0' ) {
383 if ( !
exec_cmd ( *input, run_in_term ) ) {
398 static char *
_get_display_value (
const Mode *sw,
unsigned int selected_line, G_GNUC_UNUSED
int *state, G_GNUC_UNUSED GList **list,
int get_entry )
401 return get_entry ? g_strdup ( rmpd->
cmd_list[selected_line] ) : NULL;
414 .cfg_name_key =
"display-run",
422 ._get_completion = NULL,
423 ._preprocess_input = NULL,
424 .private_data = NULL,