1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:47:44 +00:00

LibGUI: Allow navigating into symlinked directories in FilePicker

If you double-click on a symlink to a directory while browsing with
a FilePicker, you most likely want to open the directory the symlink
points to, not open the symlink itself. So let's do that. :^)
This commit is contained in:
Andreas Kling 2021-04-09 23:02:15 +02:00
parent bcd05e199b
commit 8db4819271
3 changed files with 12 additions and 1 deletions

View file

@ -214,7 +214,7 @@ FilePicker::FilePicker(Window* parent_window, Mode mode, const StringView& file_
const FileSystemModel::Node& node = m_model->node(local_index); const FileSystemModel::Node& node = m_model->node(local_index);
auto path = node.full_path(); auto path = node.full_path();
if (node.is_directory()) { if (node.is_directory() || node.is_symlink_to_directory()) {
set_path(path); set_path(path);
// NOTE: 'node' is invalid from here on // NOTE: 'node' is invalid from here on
} else { } else {

View file

@ -164,6 +164,16 @@ void FileSystemModel::Node::reify_if_needed()
fetch_data(full_path(), parent == nullptr || parent->m_parent_of_root); fetch_data(full_path(), parent == nullptr || parent->m_parent_of_root);
} }
bool FileSystemModel::Node::is_symlink_to_directory() const
{
if (!S_ISLNK(mode))
return false;
struct stat st;
if (lstat(symlink_target.characters(), &st) < 0)
return false;
return S_ISDIR(st.st_mode);
}
String FileSystemModel::Node::full_path() const String FileSystemModel::Node::full_path() const
{ {
Vector<String, 32> lineage; Vector<String, 32> lineage;

View file

@ -79,6 +79,7 @@ public:
mutable RefPtr<Gfx::Bitmap> thumbnail; mutable RefPtr<Gfx::Bitmap> thumbnail;
bool is_directory() const { return S_ISDIR(mode); } bool is_directory() const { return S_ISDIR(mode); }
bool is_symlink_to_directory() const;
bool is_executable() const { return mode & (S_IXUSR | S_IXGRP | S_IXOTH); } bool is_executable() const { return mode & (S_IXUSR | S_IXGRP | S_IXOTH); }
bool is_selected() const { return m_selected; } bool is_selected() const { return m_selected; }