void vfs_dir_unload_thumbnails( VFSDir* dir, gboolean is_big ) { GList* l; VFSFileInfo* file; char* file_path; g_mutex_lock( dir->mutex ); if( is_big ) { for( l = dir->file_list; l; l = l->next ) { file = (VFSFileInfo*)l->data; if( file->big_thumbnail ) { g_object_unref( file->big_thumbnail ); file->big_thumbnail = NULL; } /* This is a desktop entry file, so the icon needs reload FIXME: This is not a good way to do things, but there is no better way now. */ if( file->flags & VFS_FILE_INFO_DESKTOP_ENTRY ) { file_path = g_build_filename( dir->path, file->name, NULL ); vfs_file_info_load_special_info( file, file_path ); g_free( file_path ); } } } else { for( l = dir->file_list; l; l = l->next ) { file = (VFSFileInfo*)l->data; if( file->small_thumbnail ) { g_object_unref( file->small_thumbnail ); file->small_thumbnail = NULL; } /* This is a desktop entry file, so the icon needs reload FIXME: This is not a good way to do things, but there is no better way now. */ if( file->flags & VFS_FILE_INFO_DESKTOP_ENTRY ) { file_path = g_build_filename( dir->path, file->name, NULL ); vfs_file_info_load_special_info( file, file_path ); g_free( file_path ); } } } g_mutex_unlock( dir->mutex ); /* Ensuring free space at the end of the heap is freed to the OS, * mainly to deal with the possibility thousands of large thumbnails * have been freed but the memory not actually released by SpaceFM */ #if defined (__GLIBC__) malloc_trim(0); #endif }
void vfs_dir_unload_thumbnails( VFSDir* dir, gboolean is_big ) { GList* l; VFSFileInfo* file; char* file_path; g_mutex_lock( dir->mutex ); if( is_big ) { for( l = dir->file_list; l; l = l->next ) { file = (VFSFileInfo*)l->data; if( file->big_thumbnail ) { g_object_unref( file->big_thumbnail ); file->big_thumbnail = NULL; } /* This is a desktop entry file, so the icon needs reload FIXME: This is not a good way to do things, but there is no better way now. */ if( file->flags & VFS_FILE_INFO_DESKTOP_ENTRY ) { file_path = g_build_filename( dir->path, file->name, NULL ); vfs_file_info_load_special_info( file, file_path ); g_free( file_path ); } } } else { for( l = dir->file_list; l; l = l->next ) { file = (VFSFileInfo*)l->data; if( file->small_thumbnail ) { g_object_unref( file->small_thumbnail ); file->small_thumbnail = NULL; } /* This is a desktop entry file, so the icon needs reload FIXME: This is not a good way to do things, but there is no better way now. */ if( file->flags & VFS_FILE_INFO_DESKTOP_ENTRY ) { file_path = g_build_filename( dir->path, file->name, NULL ); vfs_file_info_load_special_info( file, file_path ); g_free( file_path ); } } } g_mutex_unlock( dir->mutex ); }
/* called on every VFSDir when icon theme got changed */ static void reload_icons( const char* path, VFSDir* dir, gpointer user_data ) { GList* l; for( l = dir->file_list; l; l = l->next ) { VFSFileInfo* fi = (VFSFileInfo*)l->data; /* It's a desktop entry file */ if( fi->flags & VFS_FILE_INFO_DESKTOP_ENTRY ) { char* file_path = g_build_filename( path, fi->name,NULL ); if( fi->big_thumbnail ) { g_object_unref( fi->big_thumbnail ); fi->big_thumbnail = NULL; } if( fi->small_thumbnail ) { g_object_unref( fi->small_thumbnail ); fi->small_thumbnail = NULL; } vfs_file_info_load_special_info( fi, file_path ); g_free( file_path ); } } }
void vfs_file_info_reload_mime_type( VFSFileInfo* fi, const char* full_path ) { VFSMimeType * old_mime_type; struct stat64 file_stat; /* convert VFSFileInfo to struct stat */ /* In current implementation, only st_mode is used in mime-type detection, so let's save some CPU cycles and don't copy unused fields. */ file_stat.st_mode = fi->mode; /* file_stat.st_dev = fi->dev; file_stat.st_uid = fi->uid; file_stat.st_gid = fi->gid; file_stat.st_size = fi->size; file_stat.st_mtime = fi->mtime; file_stat.st_atime = fi->atime; file_stat.st_blksize = fi->blksize; file_stat.st_blocks = fi->blocks; */ old_mime_type = fi->mime_type; fi->mime_type = vfs_mime_type_get_from_file( full_path, fi->name, &file_stat ); vfs_file_info_load_special_info( fi, full_path ); vfs_mime_type_unref( old_mime_type ); /* FIXME: is vfs_mime_type_unref needed ?*/ }
void update_created_files( gpointer key, gpointer data, gpointer user_data ) { VFSDir* dir = (VFSDir*)data; GSList* l; char* full_path; VFSFileInfo* file; GList* ll; if ( dir->created_files ) { g_mutex_lock( dir->mutex ); for ( l = dir->created_files; l; l = l->next ) { if ( !( ll = vfs_dir_find_file( dir, (char*)l->data, NULL ) ) ) { // file is not in dir file_list full_path = g_build_filename( dir->path, (char*)l->data, NULL ); file = vfs_file_info_new(); if ( vfs_file_info_get( file, full_path, NULL ) ) { // add new file to dir file_list vfs_file_info_load_special_info( file, full_path ); dir->file_list = g_list_prepend( dir->file_list, vfs_file_info_ref( file ) ); ++dir->n_files; g_signal_emit( dir, signals[ FILE_CREATED_SIGNAL ], 0, file ); } // else file doesn't exist in filesystem vfs_file_info_unref( file ); g_free( full_path ); } else { // file already exists in dir file_list file = vfs_file_info_ref( (VFSFileInfo*)ll->data ); if ( update_file_info( dir, file ) ) { g_signal_emit( dir, signals[ FILE_CHANGED_SIGNAL ], 0, file ); vfs_file_info_unref( file ); } // else was deleted, signaled, and unrefed in update_file_info } g_free( (char*)l->data ); // free file_name string } g_slist_free( dir->created_files ); dir->created_files = NULL; g_mutex_unlock( dir->mutex ); } }
gboolean update_file_info( VFSDir* dir, VFSFileInfo* file ) { char* full_path; char* file_name; gboolean ret = FALSE; /* gboolean is_desktop = is_dir_desktop(dir->path); */ /* FIXME: Dirty hack: steal the string to prevent memory allocation */ file_name = file->name; if( file->name == file->disp_name ) file->disp_name = NULL; file->name = NULL; full_path = g_build_filename( dir->path, file_name, NULL ); if ( G_LIKELY( full_path ) ) { if( G_LIKELY( vfs_file_info_get( file, full_path, file_name ) ) ) { ret = TRUE; /* if( G_UNLIKELY(is_desktop) ) */ vfs_file_info_load_special_info( file, full_path ); } else /* The file doesn't exist */ { GList* l; l = g_list_find( dir->file_list, file ); if( G_UNLIKELY(l) ) { dir->file_list = g_list_delete_link( dir->file_list, l ); --dir->n_files; if ( file ) { g_signal_emit( dir, signals[ FILE_DELETED_SIGNAL ], 0, file ); vfs_file_info_unref( file ); } } ret = FALSE; } g_free( full_path ); } g_free( file_name ); return ret; }
gpointer vfs_dir_load_thread( VFSAsyncTask* task, VFSDir* dir ) { const gchar * file_name; char* full_path; GDir* dir_content; VFSFileInfo* file; char* hidden = NULL; //MOD added dir->file_listed = 0; dir->load_complete = 0; dir->xhidden_count = 0; //MOD if ( dir->path ) { /* Install file alteration monitor */ dir->monitor = vfs_file_monitor_add_dir( dir->path, vfs_dir_monitor_callback, dir ); dir_content = g_dir_open( dir->path, 0, NULL ); if ( dir_content ) { GKeyFile* kf; if( G_UNLIKELY(dir->is_trash) ) kf = g_key_file_new(); // MOD dir contains .hidden file? hidden = gethidden( dir->path ); while ( ! vfs_async_task_is_cancelled( dir->task ) && ( file_name = g_dir_read_name( dir_content ) ) ) { full_path = g_build_filename( dir->path, file_name, NULL ); if ( !full_path ) continue; //MOD ignore if in .hidden if ( hidden && ishidden( hidden, file_name ) ) { dir->xhidden_count++; continue; } /* FIXME: Is locking GDK needed here? */ /* GDK_THREADS_ENTER(); */ file = vfs_file_info_new(); if ( G_LIKELY( vfs_file_info_get( file, full_path, file_name ) ) ) { g_mutex_lock( dir->mutex ); /* Special processing for desktop folder */ vfs_file_info_load_special_info( file, full_path ); /* FIXME: load info, too when new file is added to trash dir */ if( G_UNLIKELY( dir->is_trash ) ) /* load info of trashed files */ { gboolean info_loaded; char* info = g_strconcat( home_trash_dir, "/info/", file_name, ".trashinfo", NULL ); info_loaded = g_key_file_load_from_file( kf, info, 0, NULL ); g_free( info ); if( info_loaded ) { char* ori_path = g_key_file_get_string( kf, "Trash Info", "Path", NULL ); if( ori_path ) { /* Thanks to the stupid freedesktop.org spec, the filename is encoded * like a URL, which is insane. This add nothing more than overhead. */ char* fake_uri = g_strconcat( "file://", ori_path, NULL ); g_free( ori_path ); ori_path = g_filename_from_uri( fake_uri, NULL, NULL ); /* g_debug( ori_path ); */ if( file->disp_name && file->disp_name != file->name ) g_free( file->disp_name ); file->disp_name = g_filename_display_basename( ori_path ); g_free( ori_path ); } } } dir->file_list = g_list_prepend( dir->file_list, file ); g_mutex_unlock( dir->mutex ); ++dir->n_files; } else { vfs_file_info_unref( file ); } /* GDK_THREADS_LEAVE(); */ g_free( full_path ); } g_dir_close( dir_content ); if ( hidden ) g_free( hidden ); if( G_UNLIKELY(dir->is_trash) ) g_key_file_free( kf ); } } return NULL; }