rofi 2.0.0
filebrowser.c
Go to the documentation of this file.
1
26#include "config.h"
27#include <errno.h>
28#include <gio/gio.h>
29#include <gmodule.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <unistd.h>
34
35#include <dirent.h>
36#include <glib/gstdio.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39
40#include "display.h"
41#include "helper.h"
42#include "history.h"
43#include "mode-private.h"
44#include "mode.h"
45#include "modes/filebrowser.h"
46#include "rofi.h"
47#include "theme.h"
48
49#include <stdint.h>
50
51#include "rofi-icon-fetcher.h"
52
53#define FILEBROWSER_CACHE_FILE "rofi3.filebrowsercache"
55#define DEFAULT_OPEN "xdg-open"
56
57#if defined(__APPLE__)
58#define st_atim st_atimespec
59#define st_ctim st_ctimespec
60#define st_mtim st_mtimespec
61#endif
62
72
80
89
91const char *icon_name[NUM_FILE_TYPES] = {"go-up", "folder", "gtk-file"};
92typedef struct {
93 char *name;
94 char *path;
99 gboolean link;
100 time_t time;
101} FBFile;
102
103typedef struct {
104 char *command;
107 unsigned int array_length;
108 unsigned int array_length_real;
110
114struct {
122 gboolean show_hidden;
124 .sorting_method = FB_SORT_NAME,
125 .sorting_time = FB_MTIME,
126 .directories_first = TRUE,
127 .show_hidden = FALSE,
129
131 for (unsigned int i = 0; i < pd->array_length; i++) {
132 FBFile *fb = &(pd->array[i]);
133 g_free(fb->name);
134 g_free(fb->path);
135 }
136 g_free(pd->array);
137 pd->array = NULL;
138 pd->array_length = 0;
139 pd->array_length_real = 0;
140}
141#include <dirent.h>
142#include <sys/types.h>
143
144static gint compare_name(gconstpointer a, gconstpointer b,
145 G_GNUC_UNUSED gpointer data) {
146 FBFile *fa = (FBFile *)a;
147 FBFile *fb = (FBFile *)b;
148
149 if (file_browser_config.directories_first && fa->type != fb->type) {
150 return fa->type - fb->type;
151 }
152
153 return g_strcmp0(fa->name, fb->name);
154}
155
156static gint compare_time(gconstpointer a, gconstpointer b,
157 G_GNUC_UNUSED gpointer data) {
158 FBFile *fa = (FBFile *)a;
159 FBFile *fb = (FBFile *)b;
160
161 if (file_browser_config.directories_first && fa->type != fb->type) {
162 return fa->type - fb->type;
163 }
164
165 if (fa->time < 0) {
166 return -1;
167 }
168
169 if (fb->time < 0) {
170 return 1;
171 }
172
173 return fb->time - fa->time;
174}
175
176static gint compare(gconstpointer a, gconstpointer b, gpointer data) {
177 GCompareDataFunc comparator = NULL;
178
179 switch (file_browser_config.sorting_method) {
180 case FB_SORT_NAME:
181 comparator = compare_name;
182 break;
183 case FB_SORT_TIME:
184 comparator = compare_time;
185 break;
186 default:
187 comparator = compare_name;
188 break;
189 }
190
191 return comparator(a, b, data);
192}
193
194static time_t get_time(const GStatBuf *statbuf) {
195 switch (file_browser_config.sorting_time) {
196 case FB_MTIME:
197 return statbuf->st_mtim.tv_sec;
198 case FB_ATIME:
199 return statbuf->st_atim.tv_sec;
200 case FB_CTIME:
201 return statbuf->st_ctim.tv_sec;
202 default:
203 return 0;
204 }
205}
206
207static void set_time(FBFile *file) {
208 // GError *error = NULL;
209 // gchar *path = g_filename_from_utf8(file->path, -1, NULL, NULL, &error);
210 // if (error) {
211 // g_warning("Failed to convert filename: %s: %s", file->path,
212 // error->message); g_error_free(error); return;
213 // }
214
215 GStatBuf statbuf;
216
217 if (g_lstat(file->path, &statbuf) == 0) {
218 file->time = get_time(&statbuf);
219 } else {
220 g_warning("Failed to stat file: %s, %s", file->path, strerror(errno));
221 }
222
223 // g_free(path);
224}
225
227 if ((pd->array_length + 1) > pd->array_length_real) {
228 pd->array_length_real += 256;
229 pd->array =
230 g_realloc(pd->array, (pd->array_length_real + 1) * sizeof(FBFile));
231 }
232}
233
234static void get_file_browser(Mode *sw) {
241 char *cdir = g_file_get_path(pd->current_dir);
242 DIR *dir = opendir(cdir);
243 if (dir) {
244 struct dirent *rd = NULL;
245 while ((rd = readdir(dir)) != NULL) {
246 if (g_strcmp0(rd->d_name, "..") == 0) {
247 fb_resize_array(pd);
248 // Rofi expects utf-8, so lets convert the filename.
249 pd->array[pd->array_length].name = g_strdup("..");
250 pd->array[pd->array_length].path = NULL;
251 pd->array[pd->array_length].type = UP;
252 pd->array[pd->array_length].icon_fetch_uid = 0;
255 pd->array[pd->array_length].link = FALSE;
256 pd->array[pd->array_length].time = -1;
257 pd->array_length++;
258 continue;
259 }
260 if (g_strcmp0(rd->d_name, ".") == 0) {
261 continue;
262 }
263 if (rd->d_name[0] == '.' && file_browser_config.show_hidden == FALSE) {
264 continue;
265 }
266
267 switch (rd->d_type) {
268 case DT_BLK:
269 case DT_CHR:
270 case DT_FIFO:
271 case DT_UNKNOWN:
272 case DT_SOCK:
273 default:
274 break;
275 case DT_REG:
276 case DT_DIR:
277 fb_resize_array(pd);
278 // Rofi expects utf-8, so lets convert the filename.
279 pd->array[pd->array_length].name =
280 g_filename_to_utf8(rd->d_name, -1, NULL, NULL, NULL);
281 if (pd->array[pd->array_length].name == NULL) {
282 pd->array[pd->array_length].name = rofi_force_utf8(rd->d_name, -1);
283 }
284 pd->array[pd->array_length].path =
285 g_build_filename(cdir, rd->d_name, NULL);
286 pd->array[pd->array_length].type =
287 (rd->d_type == DT_DIR) ? DIRECTORY : RFILE;
288 pd->array[pd->array_length].icon_fetch_uid = 0;
291 pd->array[pd->array_length].link = FALSE;
292
293 if (file_browser_config.sorting_method == FB_SORT_TIME) {
294 set_time(&pd->array[pd->array_length]);
295 }
296
297 pd->array_length++;
298 break;
299 case DT_LNK:
300 fb_resize_array(pd);
301 // Rofi expects utf-8, so lets convert the filename.
302 pd->array[pd->array_length].name =
303 g_filename_to_utf8(rd->d_name, -1, NULL, NULL, NULL);
304 if (pd->array[pd->array_length].name == NULL) {
305 pd->array[pd->array_length].name = rofi_force_utf8(rd->d_name, -1);
306 }
307 pd->array[pd->array_length].path =
308 g_build_filename(cdir, rd->d_name, NULL);
309 pd->array[pd->array_length].icon_fetch_uid = 0;
312 pd->array[pd->array_length].link = TRUE;
313 // Default to file.
314 pd->array[pd->array_length].type = RFILE;
315 {
316 // If we have link, use a stat to fine out what it is, if we fail, we
317 // mark it as file.
318 // TODO have a 'broken link' mode?
319 // Convert full path to right encoding.
320 // DD: Path should be in file encoding, not utf-8
321 // char *file =
322 // g_filename_from_utf8(pd->array[pd->array_length].path,
323 // -1, NULL, NULL, NULL);
324 if (pd->array[pd->array_length].path) {
325 GStatBuf statbuf;
326 if (g_stat(pd->array[pd->array_length].path, &statbuf) == 0) {
327 if (S_ISDIR(statbuf.st_mode)) {
328 pd->array[pd->array_length].type = DIRECTORY;
329 } else if (S_ISREG(statbuf.st_mode)) {
330 pd->array[pd->array_length].type = RFILE;
331 }
332
333 if (file_browser_config.sorting_method == FB_SORT_TIME) {
334 pd->array[pd->array_length].time = get_time(&statbuf);
335 }
336 } else {
337 g_warning("Failed to stat file: %s, %s",
338 pd->array[pd->array_length].path, strerror(errno));
339 }
340
341 // g_free(file);
342 }
343 }
344 pd->array_length++;
345 break;
346 }
347 }
348 closedir(dir);
349 }
350 g_free(cdir);
351 g_qsort_with_data(pd->array, pd->array_length, sizeof(FBFile), compare, NULL);
352}
353
357 char *msg = NULL;
358 gboolean found_error = FALSE;
359
360 ThemeWidget *wid = rofi_config_find_widget(sw->name, NULL, TRUE);
361
362 Property *p = rofi_theme_find_property(wid, P_STRING, "sorting-method", TRUE);
363 if (p != NULL && p->type == P_STRING) {
364 if (g_strcmp0(p->value.s, "name") == 0) {
365 file_browser_config.sorting_method = FB_SORT_NAME;
366 } else if (g_strcmp0(p->value.s, "mtime") == 0) {
367 file_browser_config.sorting_method = FB_SORT_TIME;
368 file_browser_config.sorting_time = FB_MTIME;
369 } else if (g_strcmp0(p->value.s, "atime") == 0) {
370 file_browser_config.sorting_method = FB_SORT_TIME;
371 file_browser_config.sorting_time = FB_ATIME;
372 } else if (g_strcmp0(p->value.s, "ctime") == 0) {
373 file_browser_config.sorting_method = FB_SORT_TIME;
374 file_browser_config.sorting_time = FB_CTIME;
375 } else {
376 found_error = TRUE;
377
378 msg = g_strdup_printf("\"%s\" is not a valid filebrowser sorting method",
379 p->value.s);
380 }
381 }
382
383 p = rofi_theme_find_property(wid, P_BOOLEAN, "directories-first", TRUE);
384 if (p != NULL && p->type == P_BOOLEAN) {
385 file_browser_config.directories_first = p->value.b;
386 }
387
388 p = rofi_theme_find_property(wid, P_BOOLEAN, "show-hidden", TRUE);
389 if (p != NULL && p->type == P_BOOLEAN) {
390 file_browser_config.show_hidden = p->value.b;
391 }
392
393 p = rofi_theme_find_property(wid, P_STRING, "command", TRUE);
394 if (p != NULL && p->type == P_STRING) {
395 pd->command = g_strdup(p->value.s);
396 } else {
397 pd->command = g_strdup(DEFAULT_OPEN);
398 }
399
400 if (found_error) {
401 rofi_view_error_dialog(msg, FALSE);
402
403 g_free(msg);
404 }
405}
406
410
411 ThemeWidget *wid = rofi_config_find_widget(sw->name, NULL, TRUE);
412
413 Property *p = rofi_theme_find_property(wid, P_STRING, "directory", TRUE);
414
415 gboolean config_has_valid_dir = p != NULL && p->type == P_STRING &&
416 g_file_test(p->value.s, G_FILE_TEST_IS_DIR);
417
418 if (config_has_valid_dir) {
419 pd->current_dir = g_file_new_for_path(p->value.s);
420 } else {
421 char *current_dir = NULL;
422 char *cache_file =
423 g_build_filename(cache_dir, FILEBROWSER_CACHE_FILE, NULL);
424
425 if (g_file_get_contents(cache_file, &current_dir, NULL, NULL)) {
426 if (g_file_test(current_dir, G_FILE_TEST_IS_DIR)) {
427 pd->current_dir = g_file_new_for_path(current_dir);
428 }
429
430 g_free(current_dir);
431 }
432
433 // Store it based on the unique identifiers (desktop_id).
434 g_free(cache_file);
435 }
436
437 if (pd->current_dir == NULL) {
438 pd->current_dir = g_file_new_for_path(g_get_home_dir());
439 }
440}
441
446 if (mode_get_private_data(sw) == NULL) {
447 FileBrowserModePrivateData *pd = g_malloc0(sizeof(*pd));
448 mode_set_private_data(sw, (void *)pd);
449
452
453 // Load content.
455 }
456 return TRUE;
457}
458static unsigned int file_browser_mode_get_num_entries(const Mode *sw) {
461 return pd->array_length;
462}
463
464static ModeMode file_browser_mode_result(Mode *sw, int mretv, char **input,
465 unsigned int selected_line) {
466 ModeMode retv = MODE_EXIT;
469
470 if ((mretv & MENU_CANCEL) == MENU_CANCEL) {
471 ThemeWidget *wid = rofi_config_find_widget(sw->name, NULL, TRUE);
472 Property *p =
473 rofi_theme_find_property(wid, P_BOOLEAN, "cancel-returns-1", TRUE);
474 if (p && p->type == P_BOOLEAN && p->value.b == TRUE) {
476 }
477 return MODE_EXIT;
478 }
479 gboolean special_command =
481 if (mretv & MENU_CUSTOM_COMMAND) {
482 retv = (mretv & MENU_LOWER_MASK);
483 } else if ((mretv & MENU_OK)) {
484 if (selected_line < pd->array_length) {
485 if (pd->array[selected_line].type == UP) {
486 GFile *new = g_file_get_parent(pd->current_dir);
487 if (new) {
488 g_object_unref(pd->current_dir);
489 pd->current_dir = new;
490 free_list(pd);
492 return RESET_DIALOG;
493 }
494 } else if ((pd->array[selected_line].type == RFILE) ||
495 (pd->array[selected_line].type == DIRECTORY &&
496 special_command)) {
497 char *d_esc = g_shell_quote(pd->array[selected_line].path);
498 char *cmd = g_strdup_printf("%s %s", pd->command, d_esc);
499 g_free(d_esc);
500 char *cdir = g_file_get_path(pd->current_dir);
501 helper_execute_command(cdir, cmd, FALSE, NULL);
502 g_free(cdir);
503 g_free(cmd);
504 return MODE_EXIT;
505 } else if (pd->array[selected_line].type == DIRECTORY) {
506 char *path = g_build_filename(cache_dir, FILEBROWSER_CACHE_FILE, NULL);
507 g_file_set_contents(path, pd->array[selected_line].path, -1, NULL);
508 g_free(path);
509 GFile *new = g_file_new_for_path(pd->array[selected_line].path);
510 g_object_unref(pd->current_dir);
511 pd->current_dir = new;
512 free_list(pd);
514 return RESET_DIALOG;
515 }
516 }
517 retv = RELOAD_DIALOG;
518 } else if ((mretv & MENU_CUSTOM_INPUT)) {
519 if (special_command) {
520 GFile *new = g_file_get_parent(pd->current_dir);
521 if (new) {
522 g_object_unref(pd->current_dir);
523 pd->current_dir = new;
524 free_list(pd);
526 }
527 return RESET_DIALOG;
528 }
529 if (*input) {
530 char *p = rofi_expand_path(*input);
531 char *dir = g_filename_from_utf8(p, -1, NULL, NULL, NULL);
532 g_free(p);
533 if (g_file_test(dir, G_FILE_TEST_EXISTS)) {
534 if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
535 g_object_unref(pd->current_dir);
536 pd->current_dir = g_file_new_for_path(dir);
537 g_free(dir);
538 free_list(pd);
540 return RESET_DIALOG;
541 }
542 }
543 g_free(dir);
544 retv = RELOAD_DIALOG;
545 }
546 } else if ((mretv & MENU_ENTRY_DELETE) == MENU_ENTRY_DELETE) {
547 file_browser_config.show_hidden = !file_browser_config.show_hidden;
548 free_list(pd);
550 retv = RELOAD_DIALOG;
551 }
552 return retv;
553}
554
558 if (pd != NULL) {
559 g_object_unref(pd->current_dir);
560 g_free(pd->command);
561 free_list(pd);
562 g_free(pd);
563 mode_set_private_data(sw, NULL);
564 }
565}
566
567static char *_get_display_value(const Mode *sw, unsigned int selected_line,
568 G_GNUC_UNUSED int *state,
569 G_GNUC_UNUSED GList **attr_list,
570 int get_entry) {
573
574 // Only return the string if requested, otherwise only set state.
575 if (!get_entry) {
576 return NULL;
577 }
578 if (pd->array[selected_line].type == UP) {
579 return g_strdup(" ..");
580 }
581 if (pd->array[selected_line].link) {
582 return g_strconcat("@", pd->array[selected_line].name, NULL);
583 }
584 return g_strdup(pd->array[selected_line].name);
585}
586
596static int file_browser_token_match(const Mode *sw, rofi_int_matcher **tokens,
597 unsigned int index) {
600
601 // Call default matching function.
602 return helper_token_match(tokens, pd->array[index].name);
603}
604
605static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line,
606 unsigned int height) {
609 const guint scale = display_scale();
610 g_return_val_if_fail(pd->array != NULL, NULL);
611 FBFile *dr = &(pd->array[selected_line]);
614 } else if (dr->type == RFILE) {
615 gchar* _path = g_strconcat("thumbnail://", dr->path, NULL);
616 dr->icon_fetch_uid = rofi_icon_fetcher_query(_path, height);
617 g_free(_path);
618 } else {
620 }
621 dr->icon_fetch_size = height;
622 dr->icon_fetch_scale = scale;
624}
625
626static char *_get_message(const Mode *sw) {
629 if (pd->current_dir) {
630 char *dirname = g_file_get_parse_name(pd->current_dir);
631 char *str =
632 g_markup_printf_escaped("<b>Current directory:</b> %s", dirname);
633 g_free(dirname);
634 return str;
635 }
636 return "n/a";
637}
638
639static char *_get_completion(const Mode *sw, unsigned int index) {
642
643 char *d = g_strescape(pd->array[index].path, NULL);
644 return d;
645}
646
648 Mode *sw = g_malloc0(sizeof(Mode));
649
650 *sw = file_browser_mode;
651
652 sw->private_data = NULL;
653 return sw;
654}
655
656#if 1
657ModeMode file_browser_mode_completer(Mode *sw, int mretv, char **input,
658 unsigned int selected_line, char **path) {
659 ModeMode retv = MODE_EXIT;
662 if ((mretv & MENU_OK)) {
663 if (selected_line < pd->array_length) {
664 if (pd->array[selected_line].type == UP) {
665 GFile *new = g_file_get_parent(pd->current_dir);
666 if (new) {
667 g_object_unref(pd->current_dir);
668 pd->current_dir = new;
669 free_list(pd);
671 return RESET_DIALOG;
672 }
673 } else if (pd->array[selected_line].type == DIRECTORY) {
674 GFile *new = g_file_new_for_path(pd->array[selected_line].path);
675 g_object_unref(pd->current_dir);
676 pd->current_dir = new;
677 free_list(pd);
679 return RESET_DIALOG;
680 } else if (pd->array[selected_line].type == RFILE) {
681 *path = g_strescape(pd->array[selected_line].path, NULL);
682 return MODE_EXIT;
683 }
684 }
685 retv = RELOAD_DIALOG;
686 } else if ((mretv & MENU_CUSTOM_INPUT) && *input) {
687 char *p = rofi_expand_path(*input);
688 char *dir = g_filename_from_utf8(p, -1, NULL, NULL, NULL);
689 g_free(p);
690 if (g_file_test(dir, G_FILE_TEST_EXISTS)) {
691 if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
692 g_object_unref(pd->current_dir);
693 pd->current_dir = g_file_new_for_path(dir);
694 g_free(dir);
695 free_list(pd);
697 return RESET_DIALOG;
698 }
699 }
700 g_free(dir);
701 retv = RELOAD_DIALOG;
702 } else if ((mretv & MENU_ENTRY_DELETE) == MENU_ENTRY_DELETE) {
703 file_browser_config.show_hidden = !file_browser_config.show_hidden;
704 free_list(pd);
706 retv = RELOAD_DIALOG;
707 }
708 return retv;
709}
710#endif
711
712Mode file_browser_mode = {.display_name = NULL,
713 .abi_version = ABI_VERSION,
714 .name = "filebrowser",
715 .cfg_name_key = "display-filebrowser",
716 ._init = file_browser_mode_init,
717 ._get_num_entries = file_browser_mode_get_num_entries,
718 ._result = file_browser_mode_result,
719 ._destroy = file_browser_mode_destroy,
720 ._token_match = file_browser_token_match,
721 ._get_display_value = _get_display_value,
722 ._get_icon = _get_icon,
723 ._get_message = _get_message,
724 ._get_completion = _get_completion,
725 ._preprocess_input = NULL,
726 ._create = create_new_file_browser,
727 ._completer_result = file_browser_mode_completer,
728 .private_data = NULL,
729 .free = NULL,
guint display_scale(void)
Definition display.c:42
static int file_browser_token_match(const Mode *sw, rofi_int_matcher **tokens, unsigned int index)
static char * _get_message(const Mode *sw)
static void free_list(FileBrowserModePrivateData *pd)
static char * _get_completion(const Mode *sw, unsigned int index)
static unsigned int file_browser_mode_get_num_entries(const Mode *sw)
FBFileType
Definition filebrowser.c:66
@ NUM_FILE_TYPES
Definition filebrowser.c:70
@ DIRECTORY
Definition filebrowser.c:68
@ UP
Definition filebrowser.c:67
@ RFILE
Definition filebrowser.c:69
static cairo_surface_t * _get_icon(const Mode *sw, unsigned int selected_line, unsigned int height)
static void file_browser_mode_init_current_dir(Mode *sw)
static void fb_resize_array(FileBrowserModePrivateData *pd)
static void set_time(FBFile *file)
#define FILEBROWSER_CACHE_FILE
Definition filebrowser.c:53
static gint compare_time(gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data)
static void file_browser_mode_destroy(Mode *sw)
enum FBSortingMethod sorting_method
struct @340051107347325142162217323355046040105225200303 file_browser_config
gboolean show_hidden
enum FBSortingTime sorting_time
static gint compare_name(gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data)
FBSortingMethod
Definition filebrowser.c:76
@ FB_SORT_NAME
Definition filebrowser.c:77
@ FB_SORT_TIME
Definition filebrowser.c:78
static char * _get_display_value(const Mode *sw, unsigned int selected_line, G_GNUC_UNUSED int *state, G_GNUC_UNUSED GList **attr_list, int get_entry)
static void get_file_browser(Mode *sw)
FBSortingTime
Definition filebrowser.c:84
@ FB_CTIME
Definition filebrowser.c:87
@ FB_MTIME
Definition filebrowser.c:85
@ FB_ATIME
Definition filebrowser.c:86
static int file_browser_mode_init(Mode *sw)
static ModeMode file_browser_mode_result(Mode *sw, int mretv, char **input, unsigned int selected_line)
static void file_browser_mode_init_config(Mode *sw)
const char * icon_name[NUM_FILE_TYPES]
Definition filebrowser.c:91
#define DEFAULT_OPEN
Definition filebrowser.c:55
gboolean directories_first
static time_t get_time(const GStatBuf *statbuf)
static gint compare(gconstpointer a, gconstpointer b, gpointer data)
Mode file_browser_mode
Mode * create_new_file_browser(void)
ModeMode file_browser_mode_completer(Mode *sw, int mretv, char **input, unsigned int selected_line, char **path)
Property * rofi_theme_find_property(ThemeWidget *wid, PropertyType type, const char *property, gboolean exact)
Definition theme.c:745
gboolean helper_execute_command(const char *wd, const char *cmd, gboolean run_in_term, RofiHelperExecuteContext *context)
Definition helper.c:1072
ThemeWidget * rofi_config_find_widget(const char *name, const char *state, gboolean exact)
Definition theme.c:782
char * rofi_expand_path(const char *input)
Definition helper.c:782
int helper_token_match(rofi_int_matcher *const *tokens, const char *input)
Definition helper.c:541
char * rofi_force_utf8(const gchar *data, ssize_t length)
Definition helper.c:857
gboolean rofi_icon_fetcher_file_is_image(const char *const path)
cairo_surface_t * rofi_icon_fetcher_get(const uint32_t uid)
uint32_t rofi_icon_fetcher_query(const char *name, const int size)
struct rofi_mode Mode
Definition mode.h:49
void * mode_get_private_data(const Mode *mode)
Definition mode.c:176
void mode_set_private_data(Mode *mode, void *pd)
Definition mode.c:181
ModeMode
Definition mode.h:54
@ MENU_CUSTOM_COMMAND
Definition mode.h:84
@ MENU_LOWER_MASK
Definition mode.h:92
@ MENU_CANCEL
Definition mode.h:74
@ MENU_ENTRY_DELETE
Definition mode.h:80
@ MENU_CUSTOM_ACTION
Definition mode.h:90
@ MENU_OK
Definition mode.h:72
@ MENU_CUSTOM_INPUT
Definition mode.h:78
@ MODE_EXIT
Definition mode.h:56
@ RELOAD_DIALOG
Definition mode.h:60
@ RESET_DIALOG
Definition mode.h:64
void rofi_set_return_code(int code)
Definition rofi.c:151
const char * cache_dir
Definition rofi.c:82
int rofi_view_error_dialog(const char *msg, int markup)
Definition view.c:1915
@ MODE_TYPE_COMPLETER
@ MODE_TYPE_SWITCHER
#define ABI_VERSION
Definition mode.h:36
FBFileType
@ P_BOOLEAN
Definition rofi-types.h:18
@ P_STRING
Definition rofi-types.h:16
struct rofi_int_matcher_t rofi_int_matcher
char * path
Definition filebrowser.c:94
guint icon_fetch_scale
Definition filebrowser.c:98
enum FBFileType type
Definition filebrowser.c:95
gboolean link
Definition filebrowser.c:99
uint32_t icon_fetch_size
Definition filebrowser.c:97
char * name
Definition filebrowser.c:93
uint32_t icon_fetch_uid
Definition filebrowser.c:96
time_t time
PropertyValue value
Definition rofi-types.h:293
PropertyType type
Definition rofi-types.h:291
char * name
void * private_data