mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
[RecursiveBrowser] Make implementation not recursive.
Do stat when DT_UNKNOWN is given back when reading directory. Issue: #1954
This commit is contained in:
parent
5b9939b287
commit
9580c4a191
1 changed files with 127 additions and 73 deletions
|
@ -178,81 +178,134 @@ static void recursive_browser_mode_init_current_dir(Mode *sw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scan_dir(FileBrowserModePrivateData *pd, GFile *path) {
|
static void scan_dir(FileBrowserModePrivateData *pd, GFile *path) {
|
||||||
char *cdir = g_file_get_path(path);
|
GQueue *dirs_to_scan = g_queue_new();
|
||||||
DIR *dir = opendir(cdir);
|
g_queue_push_tail(dirs_to_scan, g_object_ref(path));
|
||||||
if (dir) {
|
GFile *dir_to_scan = NULL;
|
||||||
struct dirent *rd = NULL;
|
while ( (dir_to_scan = g_queue_pop_head(dirs_to_scan)) != NULL) {
|
||||||
while (pd->end_thread == FALSE && (rd = readdir(dir)) != NULL) {
|
char *cdir = g_file_get_path(dir_to_scan);
|
||||||
if (g_strcmp0(rd->d_name, "..") == 0) {
|
DIR *dir = opendir(cdir);
|
||||||
continue;
|
g_object_unref(dir_to_scan);
|
||||||
}
|
if (dir) {
|
||||||
if (g_strcmp0(rd->d_name, ".") == 0) {
|
struct dirent *rd = NULL;
|
||||||
continue;
|
while (pd->end_thread == FALSE && (rd = readdir(dir)) != NULL) {
|
||||||
}
|
if (g_strcmp0(rd->d_name, "..") == 0) {
|
||||||
if (pd->filter_regex &&
|
continue;
|
||||||
g_regex_match(pd->filter_regex, rd->d_name, 0, NULL)) {
|
}
|
||||||
continue;
|
if (g_strcmp0(rd->d_name, ".") == 0) {
|
||||||
}
|
continue;
|
||||||
switch (rd->d_type) {
|
}
|
||||||
case DT_BLK:
|
if (pd->filter_regex &&
|
||||||
case DT_CHR:
|
g_regex_match(pd->filter_regex, rd->d_name, 0, NULL)) {
|
||||||
case DT_FIFO:
|
continue;
|
||||||
case DT_UNKNOWN:
|
}
|
||||||
case DT_SOCK:
|
switch (rd->d_type) {
|
||||||
default:
|
case DT_BLK:
|
||||||
break;
|
case DT_CHR:
|
||||||
case DT_REG: {
|
case DT_FIFO:
|
||||||
FBFile *f = g_malloc0(sizeof(FBFile));
|
case DT_SOCK:
|
||||||
// Rofi expects utf-8, so lets convert the filename.
|
default:
|
||||||
f->path = g_build_filename(cdir, rd->d_name, NULL);
|
break;
|
||||||
f->name = g_filename_to_utf8(f->path, -1, NULL, NULL, NULL);
|
case DT_REG: {
|
||||||
if (f->name == NULL) {
|
FBFile *f = g_malloc0(sizeof(FBFile));
|
||||||
f->name = rofi_force_utf8(rd->d_name, -1);
|
// Rofi expects utf-8, so lets convert the filename.
|
||||||
}
|
f->path = g_build_filename(cdir, rd->d_name, NULL);
|
||||||
f->type = (rd->d_type == DT_DIR) ? DIRECTORY : RFILE;
|
f->name = g_filename_to_utf8(f->path, -1, NULL, NULL, NULL);
|
||||||
f->icon_fetch_uid = 0;
|
if (f->name == NULL) {
|
||||||
f->icon_fetch_size = 0;
|
f->name = rofi_force_utf8(rd->d_name, -1);
|
||||||
f->link = FALSE;
|
}
|
||||||
|
if (f->name == NULL) {
|
||||||
|
f->name = g_strdup("n/a");
|
||||||
|
}
|
||||||
|
f->type = (rd->d_type == DT_DIR) ? DIRECTORY : RFILE;
|
||||||
|
f->icon_fetch_uid = 0;
|
||||||
|
f->icon_fetch_size = 0;
|
||||||
|
f->link = FALSE;
|
||||||
|
|
||||||
g_async_queue_push(pd->async_queue, f);
|
g_async_queue_push(pd->async_queue, f);
|
||||||
if (g_async_queue_length(pd->async_queue) > 10000) {
|
if (g_async_queue_length(pd->async_queue) > 10000) {
|
||||||
write(pd->pipefd2[1], "r", 1);
|
write(pd->pipefd2[1], "r", 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DT_DIR: {
|
case DT_DIR: {
|
||||||
char *d = g_build_filename(cdir, rd->d_name, NULL);
|
char *d = g_build_filename(cdir, rd->d_name, NULL);
|
||||||
GFile *dirp = g_file_new_for_path(d);
|
GFile *dirp = g_file_new_for_path(d);
|
||||||
scan_dir(pd, dirp);
|
g_queue_push_tail(dirs_to_scan, dirp);
|
||||||
g_object_unref(dirp);
|
g_free(d);
|
||||||
g_free(d);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case DT_UNKNOWN:
|
||||||
case DT_LNK: {
|
case DT_LNK: {
|
||||||
FBFile *f = g_malloc0(sizeof(FBFile));
|
FBFile *f = g_malloc0(sizeof(FBFile));
|
||||||
// Rofi expects utf-8, so lets convert the filename.
|
// Rofi expects utf-8, so lets convert the filename.
|
||||||
f->path = g_build_filename(cdir, rd->d_name, NULL);
|
f->path = g_build_filename(cdir, rd->d_name, NULL);
|
||||||
f->name = g_filename_to_utf8(f->path, -1, NULL, NULL, NULL);
|
f->name = g_filename_to_utf8(f->path, -1, NULL, NULL, NULL);
|
||||||
if (f->name == NULL) {
|
if (f->name == NULL) {
|
||||||
f->name = rofi_force_utf8(rd->d_name, -1);
|
f->name = rofi_force_utf8(rd->d_name, -1);
|
||||||
}
|
}
|
||||||
f->icon_fetch_uid = 0;
|
if (f->name == NULL) {
|
||||||
f->icon_fetch_size = 0;
|
f->name = g_strdup("n/a");
|
||||||
f->link = TRUE;
|
}
|
||||||
// Default to file.
|
f->icon_fetch_uid = 0;
|
||||||
f->type = RFILE;
|
f->icon_fetch_size = 0;
|
||||||
g_async_queue_push(pd->async_queue, f);
|
// Default to file.
|
||||||
if (g_async_queue_length(pd->async_queue) > 10000) {
|
f->type = RFILE;
|
||||||
write(pd->pipefd2[1], "r", 1);
|
if (rd->d_type == DT_LNK) {
|
||||||
}
|
f->link = TRUE;
|
||||||
break;
|
} else {
|
||||||
}
|
f->link = FALSE;
|
||||||
}
|
}
|
||||||
}
|
{
|
||||||
closedir(dir);
|
// If we have link, use a stat to fine out what it is, if we fail, we
|
||||||
|
// mark it as file.
|
||||||
|
// TODO have a 'broken link' mode?
|
||||||
|
// Convert full path to right encoding.
|
||||||
|
// DD: Path should be in file encoding, not utf-8
|
||||||
|
// char *file =
|
||||||
|
// g_filename_from_utf8(pd->array[pd->array_length].path,
|
||||||
|
// -1, NULL, NULL, NULL);
|
||||||
|
// TODO: How to handle loops in links.
|
||||||
|
if (f->path) {
|
||||||
|
GStatBuf statbuf;
|
||||||
|
if (g_stat(f->path, &statbuf) == 0) {
|
||||||
|
if (S_ISDIR(statbuf.st_mode)) {
|
||||||
|
char *new_full_path = g_build_filename(cdir, rd->d_name, NULL);
|
||||||
|
g_free(f->path);
|
||||||
|
g_free(f->name);
|
||||||
|
g_free(f);
|
||||||
|
f = NULL;
|
||||||
|
GFile *dirp = g_file_new_for_path(new_full_path);
|
||||||
|
g_queue_push_tail(dirs_to_scan, dirp);
|
||||||
|
g_free(new_full_path);
|
||||||
|
break;
|
||||||
|
} else if (S_ISREG(statbuf.st_mode)) {
|
||||||
|
f->type = RFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
g_warning("Failed to stat file: %s, %s", f->path,
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
// g_free(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (f != NULL) {
|
||||||
|
g_async_queue_push(pd->async_queue, f);
|
||||||
|
if (g_async_queue_length(pd->async_queue) > 10000) {
|
||||||
|
write(pd->pipefd2[1], "r", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
g_free(cdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(cdir);
|
g_queue_free(dirs_to_scan);
|
||||||
}
|
}
|
||||||
static gpointer recursive_browser_input_thread(gpointer userdata) {
|
static gpointer recursive_browser_input_thread(gpointer userdata) {
|
||||||
FileBrowserModePrivateData *pd = (FileBrowserModePrivateData *)userdata;
|
FileBrowserModePrivateData *pd = (FileBrowserModePrivateData *)userdata;
|
||||||
|
@ -335,7 +388,8 @@ static unsigned int recursive_browser_mode_get_num_entries(const Mode *sw) {
|
||||||
return pd->array_length;
|
return pd->array_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ModeMode recursive_browser_mode_result(Mode *sw, int mretv, G_GNUC_UNUSED char **input,
|
static ModeMode recursive_browser_mode_result(Mode *sw, int mretv,
|
||||||
|
G_GNUC_UNUSED char **input,
|
||||||
unsigned int selected_line) {
|
unsigned int selected_line) {
|
||||||
ModeMode retv = MODE_EXIT;
|
ModeMode retv = MODE_EXIT;
|
||||||
FileBrowserModePrivateData *pd =
|
FileBrowserModePrivateData *pd =
|
||||||
|
|
Loading…
Reference in a new issue