rofi  1.7.3
filebrowser.c
Go to the documentation of this file.
1 
26 #include <errno.h>
27 #include <gio/gio.h>
28 #include <gmodule.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 
34 #include <dirent.h>
35 #include <glib/gstdio.h>
36 #include <sys/stat.h>
37 #include <sys/types.h>
38 
39 #include "dialogs/filebrowser.h"
40 #include "helper.h"
41 #include "history.h"
42 #include "mode-private.h"
43 #include "mode.h"
44 #include "rofi.h"
45 #include "theme.h"
46 
47 #include <stdint.h>
48 
49 #include "rofi-icon-fetcher.h"
50 
51 #define FILEBROWSER_CACHE_FILE "rofi3.filebrowsercache"
52 
56 enum FBFileType {
57  UP,
61 };
62 
69 };
70 
78 };
79 
81 const char *icon_name[NUM_FILE_TYPES] = {"go-up", "folder", "gtk-file"};
82 typedef struct {
83  char *name;
84  char *path;
85  enum FBFileType type;
86  uint32_t icon_fetch_uid;
87  gboolean link;
88  time_t time;
89 } FBFile;
90 
91 typedef struct {
92  GFile *current_dir;
94  unsigned int array_length;
95  unsigned int array_length_real;
97 
101 struct {
109  .sorting_method = FB_SORT_NAME,
110  .sorting_time = FB_MTIME,
111  .directories_first = TRUE,
112 };
113 
115  for (unsigned int i = 0; i < pd->array_length; i++) {
116  FBFile *fb = &(pd->array[i]);
117  g_free(fb->name);
118  g_free(fb->path);
119  }
120  g_free(pd->array);
121  pd->array = NULL;
122  pd->array_length = 0;
123  pd->array_length_real = 0;
124 }
125 #include <dirent.h>
126 #include <sys/types.h>
127 
128 static gint compare_name(gconstpointer a, gconstpointer b,
129  G_GNUC_UNUSED gpointer data) {
130  FBFile *fa = (FBFile *)a;
131  FBFile *fb = (FBFile *)b;
132 
133  if (file_browser_config.directories_first && fa->type != fb->type) {
134  return fa->type - fb->type;
135  }
136 
137  return g_strcmp0(fa->name, fb->name);
138 }
139 
140 static gint compare_time(gconstpointer a, gconstpointer b,
141  G_GNUC_UNUSED gpointer data) {
142  FBFile *fa = (FBFile *)a;
143  FBFile *fb = (FBFile *)b;
144 
145  if (file_browser_config.directories_first && fa->type != fb->type) {
146  return fa->type - fb->type;
147  }
148 
149  if (fa->time < 0) {
150  return -1;
151  }
152 
153  if (fb->time < 0) {
154  return 1;
155  }
156 
157  return fb->time - fa->time;
158 }
159 
160 static gint compare(gconstpointer a, gconstpointer b, gpointer data) {
161  GCompareDataFunc comparator = NULL;
162 
163  switch (file_browser_config.sorting_method) {
164  case FB_SORT_NAME:
165  comparator = compare_name;
166  break;
167  case FB_SORT_TIME:
168  comparator = compare_time;
169  break;
170  default:
171  comparator = compare_name;
172  break;
173  }
174 
175  return comparator(a, b, data);
176 }
177 
178 static time_t get_time(const GStatBuf *statbuf) {
179  switch (file_browser_config.sorting_time) {
180  case FB_MTIME:
181  return statbuf->st_mtim.tv_sec;
182  case FB_ATIME:
183  return statbuf->st_atim.tv_sec;
184  case FB_CTIME:
185  return statbuf->st_ctim.tv_sec;
186  default:
187  return 0;
188  }
189 }
190 
191 static void set_time(FBFile *file) {
192  // GError *error = NULL;
193  // gchar *path = g_filename_from_utf8(file->path, -1, NULL, NULL, &error);
194  // if (error) {
195  // g_warning("Failed to convert filename: %s: %s", file->path,
196  // error->message); g_error_free(error); return;
197  // }
198 
199  GStatBuf statbuf;
200 
201  if (g_lstat(file->path, &statbuf) == 0) {
202  file->time = get_time(&statbuf);
203  } else {
204  g_warning("Failed to stat file: %s, %s", file->path, strerror(errno));
205  }
206 
207  // g_free(path);
208 }
209 
211  if ((pd->array_length + 1) > pd->array_length_real) {
212  pd->array_length_real += 256;
213  pd->array =
214  g_realloc(pd->array, (pd->array_length_real + 1) * sizeof(FBFile));
215  }
216 }
217 
218 static void get_file_browser(Mode *sw) {
225  char *cdir = g_file_get_path(pd->current_dir);
226  DIR *dir = opendir(cdir);
227  if (dir) {
228  struct dirent *rd = NULL;
229  while ((rd = readdir(dir)) != NULL) {
230  if (g_strcmp0(rd->d_name, "..") == 0) {
231  fb_resize_array(pd);
232  // Rofi expects utf-8, so lets convert the filename.
233  pd->array[pd->array_length].name = g_strdup("..");
234  pd->array[pd->array_length].path = NULL;
235  pd->array[pd->array_length].type = UP;
236  pd->array[pd->array_length].icon_fetch_uid = 0;
237  pd->array[pd->array_length].link = FALSE;
238  pd->array[pd->array_length].time = -1;
239  pd->array_length++;
240  continue;
241  }
242  if (rd->d_name[0] == '.') {
243  continue;
244  }
245 
246  switch (rd->d_type) {
247  case DT_BLK:
248  case DT_CHR:
249  case DT_FIFO:
250  case DT_UNKNOWN:
251  case DT_SOCK:
252  default:
253  break;
254  case DT_REG:
255  case DT_DIR:
256  fb_resize_array(pd);
257  // Rofi expects utf-8, so lets convert the filename.
258  pd->array[pd->array_length].name =
259  g_filename_to_utf8(rd->d_name, -1, NULL, NULL, NULL);
260  if (pd->array[pd->array_length].name == NULL) {
261  pd->array[pd->array_length].name = rofi_force_utf8(rd->d_name, -1);
262  }
263  pd->array[pd->array_length].path =
264  g_build_filename(cdir, rd->d_name, NULL);
265  pd->array[pd->array_length].type =
266  (rd->d_type == DT_DIR) ? DIRECTORY : RFILE;
267  pd->array[pd->array_length].icon_fetch_uid = 0;
268  pd->array[pd->array_length].link = FALSE;
269 
270  if (file_browser_config.sorting_method == FB_SORT_TIME) {
271  set_time(&pd->array[pd->array_length]);
272  }
273 
274  pd->array_length++;
275  break;
276  case DT_LNK:
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].icon_fetch_uid = 0;
287  pd->array[pd->array_length].link = TRUE;
288  // Default to file.
289  pd->array[pd->array_length].type = RFILE;
290  {
291  // If we have link, use a stat to fine out what it is, if we fail, we
292  // mark it as file.
293  // TODO have a 'broken link' mode?
294  // Convert full path to right encoding.
295  // DD: Path should be in file encoding, not utf-8
296  // char *file =
297  // g_filename_from_utf8(pd->array[pd->array_length].path,
298  // -1, NULL, NULL, NULL);
299  if (pd->array[pd->array_length].path) {
300  GStatBuf statbuf;
301  if (g_stat(pd->array[pd->array_length].path, &statbuf) == 0) {
302  if (S_ISDIR(statbuf.st_mode)) {
303  pd->array[pd->array_length].type = DIRECTORY;
304  } else if (S_ISREG(statbuf.st_mode)) {
305  pd->array[pd->array_length].type = RFILE;
306  }
307 
308  if (file_browser_config.sorting_method == FB_SORT_TIME) {
309  pd->array[pd->array_length].time = get_time(&statbuf);
310  }
311  } else {
312  g_warning("Failed to stat file: %s, %s",
313  pd->array[pd->array_length].path, strerror(errno));
314  }
315 
316  // g_free(file);
317  }
318  }
319  pd->array_length++;
320  break;
321  }
322  }
323  closedir(dir);
324  }
325  g_free(cdir);
326  g_qsort_with_data(pd->array, pd->array_length, sizeof(FBFile), compare, NULL);
327 }
328 
330  char *msg = NULL;
331  gboolean found_error = FALSE;
332 
333  ThemeWidget *wid = rofi_config_find_widget(sw->name, NULL, TRUE);
334 
335  Property *p = rofi_theme_find_property(wid, P_STRING, "sorting-method", TRUE);
336  if (p != NULL && p->type == P_STRING) {
337  if (g_strcmp0(p->value.s, "name") == 0) {
338  file_browser_config.sorting_method = FB_SORT_NAME;
339  } else if (g_strcmp0(p->value.s, "mtime") == 0) {
340  file_browser_config.sorting_method = FB_SORT_TIME;
341  file_browser_config.sorting_time = FB_MTIME;
342  } else if (g_strcmp0(p->value.s, "atime") == 0) {
343  file_browser_config.sorting_method = FB_SORT_TIME;
344  file_browser_config.sorting_time = FB_ATIME;
345  } else if (g_strcmp0(p->value.s, "ctime") == 0) {
346  file_browser_config.sorting_method = FB_SORT_TIME;
347  file_browser_config.sorting_time = FB_CTIME;
348  } else {
349  found_error = TRUE;
350 
351  msg = g_strdup_printf("\"%s\" is not a valid filebrowser sorting method",
352  p->value.s);
353  }
354  }
355 
356  p = rofi_theme_find_property(wid, P_BOOLEAN, "directories-first", TRUE);
357  if (p != NULL && p->type == P_BOOLEAN) {
358  file_browser_config.directories_first = p->value.b;
359  }
360 
361  if (found_error) {
362  rofi_view_error_dialog(msg, FALSE);
363 
364  g_free(msg);
365  }
366 }
367 
371 
372  ThemeWidget *wid = rofi_config_find_widget(sw->name, NULL, TRUE);
373 
374  Property *p = rofi_theme_find_property(wid, P_STRING, "directory", TRUE);
375 
376  gboolean config_has_valid_dir = p != NULL && p->type == P_STRING &&
377  g_file_test(p->value.s, G_FILE_TEST_IS_DIR);
378 
379  if (config_has_valid_dir) {
380  pd->current_dir = g_file_new_for_path(p->value.s);
381  } else {
382  char *current_dir = NULL;
383  char *cache_file =
384  g_build_filename(cache_dir, FILEBROWSER_CACHE_FILE, NULL);
385 
386  if (g_file_get_contents(cache_file, &current_dir, NULL, NULL)) {
387  if (g_file_test(current_dir, G_FILE_TEST_IS_DIR)) {
388  pd->current_dir = g_file_new_for_path(current_dir);
389  }
390 
391  g_free(current_dir);
392  }
393 
394  // Store it based on the unique identifiers (desktop_id).
395  g_free(cache_file);
396  }
397 
398  if (pd->current_dir == NULL) {
399  pd->current_dir = g_file_new_for_path(g_get_home_dir());
400  }
401 }
402 
403 static int file_browser_mode_init(Mode *sw) {
407  if (mode_get_private_data(sw) == NULL) {
408  FileBrowserModePrivateData *pd = g_malloc0(sizeof(*pd));
409  mode_set_private_data(sw, (void *)pd);
410 
413 
414  // Load content.
415  get_file_browser(sw);
416  }
417  return TRUE;
418 }
419 static unsigned int file_browser_mode_get_num_entries(const Mode *sw) {
420  const FileBrowserModePrivateData *pd =
422  return pd->array_length;
423 }
424 
425 static ModeMode file_browser_mode_result(Mode *sw, int mretv, char **input,
426  unsigned int selected_line) {
427  ModeMode retv = MODE_EXIT;
430  if (mretv & MENU_NEXT) {
431  retv = NEXT_DIALOG;
432  } else if (mretv & MENU_PREVIOUS) {
433  retv = PREVIOUS_DIALOG;
434  } else if (mretv & MENU_QUICK_SWITCH) {
435  retv = (mretv & MENU_LOWER_MASK);
436  } else if (mretv & MENU_CUSTOM_COMMAND) {
437  retv = (mretv & MENU_LOWER_MASK);
438  } else if ((mretv & MENU_OK)) {
439  if (selected_line < pd->array_length) {
440  if (pd->array[selected_line].type == UP) {
441  GFile *new = g_file_get_parent(pd->current_dir);
442  if (new) {
443  g_object_unref(pd->current_dir);
444  pd->current_dir = new;
445  free_list(pd);
446  get_file_browser(sw);
447  return RESET_DIALOG;
448  }
449  } else if (pd->array[selected_line].type == DIRECTORY) {
450  char *path = g_build_filename(cache_dir, FILEBROWSER_CACHE_FILE, NULL);
451  g_file_set_contents(path, pd->array[selected_line].path, -1, NULL);
452  g_free(path);
453  GFile *new = g_file_new_for_path(pd->array[selected_line].path);
454  g_object_unref(pd->current_dir);
455  pd->current_dir = new;
456  free_list(pd);
457  get_file_browser(sw);
458  return RESET_DIALOG;
459  } else if (pd->array[selected_line].type == RFILE) {
460  // char *d = g_filename_from_utf8(pd->array[selected_line].path,
461  // -1, NULL,
462  // NULL, NULL);
463  char *d_esc = g_shell_quote(pd->array[selected_line].path);
464  char *cmd = g_strdup_printf("xdg-open %s", d_esc);
465  g_free(d_esc);
466  char *cdir = g_file_get_path(pd->current_dir);
467  helper_execute_command(cdir, cmd, FALSE, NULL);
468  g_free(cdir);
469  g_free(cmd);
470  return MODE_EXIT;
471  }
472  }
473  retv = RELOAD_DIALOG;
474  } else if ((mretv & MENU_CUSTOM_INPUT) && *input) {
475  char *p = rofi_expand_path(*input);
476  char *dir = g_filename_from_utf8(p, -1, NULL, NULL, NULL);
477  g_free(p);
478  if (g_file_test(dir, G_FILE_TEST_EXISTS)) {
479  if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
480  g_object_unref(pd->current_dir);
481  pd->current_dir = g_file_new_for_path(dir);
482  g_free(dir);
483  free_list(pd);
484  get_file_browser(sw);
485  return RESET_DIALOG;
486  }
487  }
488  g_free(dir);
489  retv = RELOAD_DIALOG;
490  } else if ((mretv & MENU_ENTRY_DELETE) == MENU_ENTRY_DELETE) {
491  retv = RELOAD_DIALOG;
492  }
493  return retv;
494 }
495 
496 static void file_browser_mode_destroy(Mode *sw) {
499  if (pd != NULL) {
500  g_object_unref(pd->current_dir);
501  free_list(pd);
502  g_free(pd);
503  mode_set_private_data(sw, NULL);
504  }
505 }
506 
507 static char *_get_display_value(const Mode *sw, unsigned int selected_line,
508  G_GNUC_UNUSED int *state,
509  G_GNUC_UNUSED GList **attr_list,
510  int get_entry) {
513 
514  // Only return the string if requested, otherwise only set state.
515  if (!get_entry) {
516  return NULL;
517  }
518  if (pd->array[selected_line].type == UP) {
519  return g_strdup(" ..");
520  }
521  if (pd->array[selected_line].link) {
522  return g_strconcat("@", pd->array[selected_line].name, NULL);
523  }
524  return g_strdup(pd->array[selected_line].name);
525 }
526 
536 static int file_browser_token_match(const Mode *sw, rofi_int_matcher **tokens,
537  unsigned int index) {
540 
541  // Call default matching function.
542  return helper_token_match(tokens, pd->array[index].name);
543 }
544 
545 static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line,
546  int height) {
549  g_return_val_if_fail(pd->array != NULL, NULL);
550  FBFile *dr = &(pd->array[selected_line]);
551  if (dr->icon_fetch_uid > 0) {
553  }
555  dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->path, height);
556  } else {
558  }
560 }
561 
562 static char *_get_message(const Mode *sw) {
565  if (pd->current_dir) {
566  char *dirname = g_file_get_parse_name(pd->current_dir);
567  char *str =
568  g_markup_printf_escaped("<b>Current directory:</b> %s", dirname);
569  g_free(dirname);
570  return str;
571  }
572  return "n/a";
573 }
574 
575 static char *_get_completion(const Mode *sw, unsigned int index) {
578 
579  char *d = g_strescape(pd->array[index].path, NULL);
580  return d;
581 }
582 
584  Mode *sw = g_malloc0(sizeof(Mode));
585 
586  *sw = file_browser_mode;
587 
588  sw->private_data = NULL;
589  return sw;
590 }
591 
592 #if 1
593 ModeMode file_browser_mode_completer(Mode *sw, int mretv, char **input,
594  unsigned int selected_line, char **path) {
595  ModeMode retv = MODE_EXIT;
598  if (mretv & MENU_NEXT) {
599  retv = NEXT_DIALOG;
600  } else if (mretv & MENU_PREVIOUS) {
601  retv = PREVIOUS_DIALOG;
602  } else if (mretv & MENU_QUICK_SWITCH) {
603  retv = (mretv & MENU_LOWER_MASK);
604  } else if ((mretv & MENU_OK)) {
605  if (selected_line < pd->array_length) {
606  if (pd->array[selected_line].type == UP) {
607  GFile *new = g_file_get_parent(pd->current_dir);
608  if (new) {
609  g_object_unref(pd->current_dir);
610  pd->current_dir = new;
611  free_list(pd);
612  get_file_browser(sw);
613  return RESET_DIALOG;
614  }
615  } else if (pd->array[selected_line].type == DIRECTORY) {
616  GFile *new = g_file_new_for_path(pd->array[selected_line].path);
617  g_object_unref(pd->current_dir);
618  pd->current_dir = new;
619  free_list(pd);
620  get_file_browser(sw);
621  return RESET_DIALOG;
622  } else if (pd->array[selected_line].type == RFILE) {
623  *path = g_strescape(pd->array[selected_line].path, NULL);
624  return MODE_EXIT;
625  }
626  }
627  retv = RELOAD_DIALOG;
628  } else if ((mretv & MENU_CUSTOM_INPUT) && *input) {
629  char *p = rofi_expand_path(*input);
630  char *dir = g_filename_from_utf8(p, -1, NULL, NULL, NULL);
631  g_free(p);
632  if (g_file_test(dir, G_FILE_TEST_EXISTS)) {
633  if (g_file_test(dir, G_FILE_TEST_IS_DIR)) {
634  g_object_unref(pd->current_dir);
635  pd->current_dir = g_file_new_for_path(dir);
636  g_free(dir);
637  free_list(pd);
638  get_file_browser(sw);
639  return RESET_DIALOG;
640  }
641  }
642  g_free(dir);
643  retv = RELOAD_DIALOG;
644  } else if ((mretv & MENU_ENTRY_DELETE) == MENU_ENTRY_DELETE) {
645  retv = RELOAD_DIALOG;
646  }
647  return retv;
648 }
649 #endif
650 
652  .display_name = NULL,
653  .abi_version = ABI_VERSION,
654  .name = "filebrowser",
655  .cfg_name_key = "display-filebrowser",
656  ._init = file_browser_mode_init,
657  ._get_num_entries = file_browser_mode_get_num_entries,
658  ._result = file_browser_mode_result,
659  ._destroy = file_browser_mode_destroy,
660  ._token_match = file_browser_token_match,
661  ._get_display_value = _get_display_value,
662  ._get_icon = _get_icon,
663  ._get_message = _get_message,
664  ._get_completion = _get_completion,
665  ._preprocess_input = NULL,
666  .private_data = NULL,
667  .free = NULL,
668 };
static int file_browser_token_match(const Mode *sw, rofi_int_matcher **tokens, unsigned int index)
Definition: filebrowser.c:536
static void free_list(FileBrowserModePrivateData *pd)
Definition: filebrowser.c:114
static cairo_surface_t * _get_icon(const Mode *sw, unsigned int selected_line, int height)
Definition: filebrowser.c:545
struct @0 file_browser_config
static unsigned int file_browser_mode_get_num_entries(const Mode *sw)
Definition: filebrowser.c:419
static char * _get_message(const Mode *sw)
Definition: filebrowser.c:562
FBFileType
Definition: filebrowser.c:56
@ NUM_FILE_TYPES
Definition: filebrowser.c:60
@ DIRECTORY
Definition: filebrowser.c:58
@ UP
Definition: filebrowser.c:57
@ RFILE
Definition: filebrowser.c:59
static char * _get_completion(const Mode *sw, unsigned int index)
Definition: filebrowser.c:575
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)
Definition: filebrowser.c:507
static void file_browser_mode_init_current_dir(Mode *sw)
Definition: filebrowser.c:368
static void fb_resize_array(FileBrowserModePrivateData *pd)
Definition: filebrowser.c:210
static void set_time(FBFile *file)
Definition: filebrowser.c:191
#define FILEBROWSER_CACHE_FILE
Definition: filebrowser.c:51
static gint compare_time(gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data)
Definition: filebrowser.c:140
static void file_browser_mode_destroy(Mode *sw)
Definition: filebrowser.c:496
enum FBSortingMethod sorting_method
Definition: filebrowser.c:103
enum FBSortingTime sorting_time
Definition: filebrowser.c:105
static gint compare_name(gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer data)
Definition: filebrowser.c:128
FBSortingMethod
Definition: filebrowser.c:66
@ FB_SORT_NAME
Definition: filebrowser.c:67
@ FB_SORT_TIME
Definition: filebrowser.c:68
static void get_file_browser(Mode *sw)
Definition: filebrowser.c:218
FBSortingTime
Definition: filebrowser.c:74
@ FB_CTIME
Definition: filebrowser.c:77
@ FB_MTIME
Definition: filebrowser.c:75
@ FB_ATIME
Definition: filebrowser.c:76
static int file_browser_mode_init(Mode *sw)
Definition: filebrowser.c:403
static ModeMode file_browser_mode_result(Mode *sw, int mretv, char **input, unsigned int selected_line)
Definition: filebrowser.c:425
static void file_browser_mode_init_config(Mode *sw)
Definition: filebrowser.c:329
const char * icon_name[NUM_FILE_TYPES]
Definition: filebrowser.c:81
gboolean directories_first
Definition: filebrowser.c:107
static time_t get_time(const GStatBuf *statbuf)
Definition: filebrowser.c:178
static gint compare(gconstpointer a, gconstpointer b, gpointer data)
Definition: filebrowser.c:160
Mode file_browser_mode
Definition: filebrowser.c:651
ModeMode file_browser_mode_completer(Mode *sw, int mretv, char **input, unsigned int selected_line, char **path)
Definition: filebrowser.c:593
Mode * create_new_file_browser(void)
Definition: filebrowser.c:583
gboolean helper_execute_command(const char *wd, const char *cmd, gboolean run_in_term, RofiHelperExecuteContext *context)
Definition: helper.c:1007
char * rofi_expand_path(const char *input)
Definition: helper.c:717
int helper_token_match(rofi_int_matcher *const *tokens, const char *input)
Definition: helper.c:495
char * rofi_force_utf8(const gchar *data, ssize_t length)
Definition: helper.c:791
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)
void mode_set_private_data(Mode *mode, void *pd)
Definition: mode.c:136
void * mode_get_private_data(const Mode *mode)
Definition: mode.c:131
ModeMode
Definition: mode.h:49
@ MENU_CUSTOM_COMMAND
Definition: mode.h:79
@ MENU_LOWER_MASK
Definition: mode.h:87
@ MENU_PREVIOUS
Definition: mode.h:81
@ MENU_QUICK_SWITCH
Definition: mode.h:77
@ MENU_ENTRY_DELETE
Definition: mode.h:75
@ MENU_NEXT
Definition: mode.h:71
@ MENU_OK
Definition: mode.h:67
@ MENU_CUSTOM_INPUT
Definition: mode.h:73
@ MODE_EXIT
Definition: mode.h:51
@ NEXT_DIALOG
Definition: mode.h:53
@ RELOAD_DIALOG
Definition: mode.h:55
@ PREVIOUS_DIALOG
Definition: mode.h:57
@ RESET_DIALOG
Definition: mode.h:59
const char * cache_dir
Definition: rofi.c:83
int rofi_view_error_dialog(const char *msg, int markup)
Definition: view.c:2077
#define ABI_VERSION
Definition: mode-private.h:34
@ P_BOOLEAN
Definition: rofi-types.h:20
@ P_STRING
Definition: rofi-types.h:16
enum FBFileType type
Definition: filebrowser.c:85
gboolean link
Definition: filebrowser.c:87
char * path
Definition: filebrowser.c:84
char * name
Definition: filebrowser.c:83
uint32_t icon_fetch_uid
Definition: filebrowser.c:86
time_t time
Definition: filebrowser.c:88
unsigned int array_length_real
Definition: filebrowser.c:95
PropertyValue value
Definition: rofi-types.h:293
PropertyType type
Definition: rofi-types.h:291
char * display_name
Definition: mode-private.h:165
char * name
Definition: mode-private.h:163
void * private_data
Definition: mode-private.h:192
ThemeWidget * rofi_config_find_widget(const char *name, const char *state, gboolean exact)
Definition: theme.c:766
Property * rofi_theme_find_property(ThemeWidget *widget, PropertyType type, const char *property, gboolean exact)
Definition: theme.c:728
gboolean b
Definition: rofi-types.h:262