34 #define G_LOG_DOMAIN "Dialogs.Run"
43 #include <sys/types.h>
62 #define RUN_CACHE_FILE "rofi-3.runcache"
81 static void 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 );
136 static int sort_func (
const void *a,
const void *b, G_GNUC_UNUSED
void *data )
138 const char *astr = *(
const char *
const * ) a;
139 const char *bstr = *(
const char *
const * ) b;
141 if ( astr == NULL && bstr == NULL ) {
144 else if ( astr == NULL ) {
147 else if ( bstr == NULL ) {
150 return g_strcmp0 ( astr, bstr );
156 static char **
get_apps_external (
char **retv,
unsigned int *length,
unsigned int num_favorites )
160 FILE *inp = fdopen ( fd,
"r" );
163 size_t buffer_length = 0;
165 while ( getline ( &buffer, &buffer_length, inp ) > 0 ) {
168 if ( buffer[strlen ( buffer ) - 1] ==
'\n' ) {
169 buffer[strlen ( buffer ) - 1] =
'\0';
174 for (
unsigned int j = 0; found == 0 && j < num_favorites; j++ ) {
175 if ( strcasecmp ( buffer, retv[j] ) == 0 ) {
185 retv = g_realloc ( retv, ( ( *length ) + 2 ) *
sizeof (
char* ) );
186 retv[( *length )] = g_strdup ( buffer );
190 if ( buffer != NULL ) {
193 if ( fclose ( inp ) != 0 ) {
194 g_warning (
"Failed to close stdout off executor script: '%s'",
195 g_strerror ( errno ) );
199 retv[( *length ) ] = NULL;
208 GError *error = NULL;
210 unsigned int num_favorites = 0;
213 if ( g_getenv (
"PATH" ) == NULL ) {
221 num_favorites = ( *length );
223 path = g_strdup ( g_getenv (
"PATH" ) );
226 gchar *homedir = g_locale_to_utf8 ( g_get_home_dir (), -1, NULL, &l, &error );
227 if ( error != NULL ) {
228 g_debug (
"Failed to convert homedir to UTF-8: %s", error->message );
229 g_clear_error ( &error );
234 const char *
const sep =
":";
235 char *strtok_savepointer = NULL;
236 for (
const char *dirname = strtok_r ( path, sep, &strtok_savepointer ); dirname != NULL; dirname = strtok_r ( NULL, sep, &strtok_savepointer ) ) {
238 DIR *dir = opendir ( fpath );
239 g_debug (
"Checking path %s for executable.", fpath );
245 gchar *dirn = g_locale_to_utf8 ( dirname, -1, NULL, &dirn_len, &error );
246 if ( error != NULL ) {
247 g_debug (
"Failed to convert directory name to UTF-8: %s", error->message );
248 g_clear_error ( &error );
252 gboolean is_homedir = g_str_has_prefix ( dirn, homedir );
255 while ( ( dent = readdir ( dir ) ) != NULL ) {
256 if ( dent->d_type != DT_REG && dent->d_type != DT_LNK && dent->d_type != DT_UNKNOWN ) {
260 if ( dent->d_name[0] ==
'.' ) {
264 gchar *fpath = g_build_filename ( dirname, dent->d_name, NULL );
265 gboolean b = g_file_test ( fpath, G_FILE_TEST_IS_EXECUTABLE );
273 gchar *name = g_filename_to_utf8 ( dent->d_name, -1, NULL, &name_len, &error );
274 if ( error != NULL ) {
275 g_debug (
"Failed to convert filename to UTF-8: %s", error->message );
276 g_clear_error ( &error );
283 for (
unsigned int j = 0; found == 0 && j < num_favorites; j++ ) {
284 if ( g_strcmp0 ( name, retv[j] ) == 0 ) {
294 retv = g_realloc ( retv, ( ( *length ) + 2 ) *
sizeof (
char* ) );
295 retv[( *length )] = name;
296 retv[( *length ) + 1] = NULL;
310 if ( ( *length ) == 0 ) {
314 if ( ( *length ) > num_favorites ) {
315 g_qsort_with_data ( &retv[num_favorites], ( *length ) - num_favorites,
sizeof (
char* ),
sort_func, NULL );
319 unsigned int removed = 0;
320 for (
unsigned int index = num_favorites; index < ( ( *length ) - 1 ); index++ ) {
321 if ( g_strcmp0 ( retv[index], retv[index + 1] ) == 0 ) {
322 g_free ( retv[index] );
328 if ( ( *length ) > num_favorites ) {
329 g_qsort_with_data ( &retv[num_favorites], ( *length ) - num_favorites,
sizeof (
char* ),
334 ( *length ) -= removed;
353 if ( rmpd != NULL ) {
382 else if ( ( mretv &
MENU_OK ) && rmpd->
cmd_list[selected_line] != NULL ) {
385 else if ( ( mretv &
MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] !=
'\0' ) {
399 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 )
402 return get_entry ? g_strdup ( rmpd->
cmd_list[selected_line] ) : NULL;
415 .cfg_name_key =
"display-run",
423 ._get_completion = NULL,
424 ._preprocess_input = NULL,
425 .private_data = NULL,