mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 14:31:10 +00:00
pathbar: Handle webdav where is the root is a path
Our webdav server has a root which is davs://mynextcloud/remote.php/webdav When once creates a GFile out of or out of a subdirectory, and one call g_file_get_parent(), it recurses too far up and try to query davs://mynextcloud/remote.php which fails, resulting in a broken pathbar. To fix that, before querying the metadata of each element of the path, I query the "enclosing mount", then use it's root to compare the GFile against. With the right GMount, we can also fix the icon drawing code in the pathbar for network drives.
This commit is contained in:
parent
64a1969293
commit
c271cd1a3f
152
gtk/gtkpathbar.c
152
gtk/gtkpathbar.c
@ -125,6 +125,7 @@ struct _ButtonData
|
|||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
guint ignore_changes : 1;
|
guint ignore_changes : 1;
|
||||||
guint file_is_hidden : 1;
|
guint file_is_hidden : 1;
|
||||||
|
GMount *mount;
|
||||||
};
|
};
|
||||||
/* This macro is used to check if a button can be used as a fake root.
|
/* This macro is used to check if a button can be used as a fake root.
|
||||||
* All buttons in front of a fake root are automatically hidden when in a
|
* All buttons in front of a fake root are automatically hidden when in a
|
||||||
@ -417,30 +418,30 @@ set_button_image (GtkPathBar *path_bar,
|
|||||||
ButtonData *button_data)
|
ButtonData *button_data)
|
||||||
{
|
{
|
||||||
struct SetButtonImageData *data;
|
struct SetButtonImageData *data;
|
||||||
GMount *mount;
|
|
||||||
|
|
||||||
switch (button_data->type)
|
switch (button_data->type)
|
||||||
{
|
{
|
||||||
case ROOT_BUTTON:
|
case ROOT_BUTTON:
|
||||||
|
|
||||||
if (path_bar->root_icon != NULL)
|
GIcon *root_icon = NULL;
|
||||||
|
|
||||||
|
if (!button_data->mount && path_bar->root_icon != NULL &&
|
||||||
|
g_file_is_native (button_data->file))
|
||||||
{
|
{
|
||||||
gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mount = g_file_find_enclosing_mount (button_data->file, NULL, NULL);
|
if (!button_data->mount && g_file_is_native (button_data->file))
|
||||||
|
root_icon = path_bar->root_icon = g_object_ref (g_themed_icon_new ("drive-harddisk-symbolic"));
|
||||||
if (!mount && g_file_is_native (button_data->file))
|
else if (button_data->mount)
|
||||||
path_bar->root_icon = g_themed_icon_new ("drive-harddisk-symbolic");
|
root_icon = g_mount_get_symbolic_icon (button_data->mount);
|
||||||
else if (mount)
|
|
||||||
path_bar->root_icon = g_mount_get_symbolic_icon (mount);
|
|
||||||
else
|
else
|
||||||
path_bar->root_icon = NULL;
|
root_icon = NULL;
|
||||||
|
|
||||||
g_clear_object (&mount);
|
gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), root_icon);
|
||||||
|
|
||||||
gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), path_bar->root_icon);
|
g_clear_object (&root_icon);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -515,6 +516,7 @@ static void
|
|||||||
button_data_free (ButtonData *button_data)
|
button_data_free (ButtonData *button_data)
|
||||||
{
|
{
|
||||||
g_clear_object (&button_data->file);
|
g_clear_object (&button_data->file);
|
||||||
|
g_clear_object (&button_data->mount);
|
||||||
g_free (button_data->dir_name);
|
g_free (button_data->dir_name);
|
||||||
g_free (button_data);
|
g_free (button_data);
|
||||||
}
|
}
|
||||||
@ -571,11 +573,11 @@ file_is_recent_uri (GFile *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ButtonType
|
static ButtonType
|
||||||
find_button_type (GtkPathBar *path_bar,
|
find_button_type (GtkPathBar *path_bar,
|
||||||
GFile *file)
|
GFile *file,
|
||||||
|
GFile *root_file)
|
||||||
{
|
{
|
||||||
if (path_bar->root_file != NULL &&
|
if (root_file != NULL && g_file_equal (file, root_file))
|
||||||
g_file_equal (file, path_bar->root_file))
|
|
||||||
return ROOT_BUTTON;
|
return ROOT_BUTTON;
|
||||||
if (path_bar->home_file != NULL &&
|
if (path_bar->home_file != NULL &&
|
||||||
g_file_equal (file, path_bar->home_file))
|
g_file_equal (file, path_bar->home_file))
|
||||||
@ -593,6 +595,8 @@ static ButtonData *
|
|||||||
make_directory_button (GtkPathBar *path_bar,
|
make_directory_button (GtkPathBar *path_bar,
|
||||||
const char *dir_name,
|
const char *dir_name,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
|
GMount *mount,
|
||||||
|
GFile *root_file,
|
||||||
gboolean current_dir,
|
gboolean current_dir,
|
||||||
gboolean file_is_hidden)
|
gboolean file_is_hidden)
|
||||||
{
|
{
|
||||||
@ -604,17 +608,26 @@ make_directory_button (GtkPathBar *path_bar,
|
|||||||
file_is_hidden = !! file_is_hidden;
|
file_is_hidden = !! file_is_hidden;
|
||||||
/* Is it a special button? */
|
/* Is it a special button? */
|
||||||
button_data = g_new0 (ButtonData, 1);
|
button_data = g_new0 (ButtonData, 1);
|
||||||
button_data->type = find_button_type (path_bar, file);
|
button_data->type = find_button_type (path_bar, file, root_file);
|
||||||
button_data->button = gtk_toggle_button_new ();
|
button_data->button = gtk_toggle_button_new ();
|
||||||
gtk_widget_set_focus_on_click (button_data->button, FALSE);
|
gtk_widget_set_focus_on_click (button_data->button, FALSE);
|
||||||
|
|
||||||
switch (button_data->type)
|
switch (button_data->type)
|
||||||
{
|
{
|
||||||
case ROOT_BUTTON:
|
case ROOT_BUTTON:
|
||||||
button_data->image = gtk_image_new ();
|
if (mount)
|
||||||
child = button_data->image;
|
{
|
||||||
button_data->label = NULL;
|
button_data->dir_name = g_mount_get_name (mount);
|
||||||
break;
|
button_data->mount = g_object_ref (mount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button_data->image = gtk_image_new ();
|
||||||
|
child = button_data->image;
|
||||||
|
button_data->label = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
G_GNUC_FALLTHROUGH;
|
||||||
case HOME_BUTTON:
|
case HOME_BUTTON:
|
||||||
case DESKTOP_BUTTON:
|
case DESKTOP_BUTTON:
|
||||||
case RECENT_BUTTON:
|
case RECENT_BUTTON:
|
||||||
@ -631,7 +644,8 @@ make_directory_button (GtkPathBar *path_bar,
|
|||||||
button_data->image = NULL;
|
button_data->image = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
button_data->dir_name = g_strdup (dir_name);
|
if (button_data->dir_name == NULL)
|
||||||
|
button_data->dir_name = g_strdup (dir_name);
|
||||||
button_data->file = g_object_ref (file);
|
button_data->file = g_object_ref (file);
|
||||||
button_data->file_is_hidden = file_is_hidden;
|
button_data->file_is_hidden = file_is_hidden;
|
||||||
|
|
||||||
@ -715,6 +729,8 @@ gtk_path_bar_check_parent_path (GtkPathBar *path_bar,
|
|||||||
struct SetFileInfo
|
struct SetFileInfo
|
||||||
{
|
{
|
||||||
GFile *file;
|
GFile *file;
|
||||||
|
GMount *mount;
|
||||||
|
GFile *root_file;
|
||||||
GFile *parent_file;
|
GFile *parent_file;
|
||||||
GtkPathBar *path_bar;
|
GtkPathBar *path_bar;
|
||||||
GList *new_buttons;
|
GList *new_buttons;
|
||||||
@ -762,10 +778,15 @@ gtk_path_bar_set_file_finish (struct SetFileInfo *info,
|
|||||||
g_object_unref (info->file);
|
g_object_unref (info->file);
|
||||||
if (info->parent_file)
|
if (info->parent_file)
|
||||||
g_object_unref (info->parent_file);
|
g_object_unref (info->parent_file);
|
||||||
|
if (info->root_file)
|
||||||
|
g_object_unref (info->root_file);
|
||||||
|
if (info->mount)
|
||||||
|
g_object_unref (info->mount);
|
||||||
|
|
||||||
g_free (info);
|
g_free (info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_path_bar_get_info_callback (GObject *source,
|
gtk_path_bar_get_info_callback (GObject *source,
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
@ -802,6 +823,8 @@ gtk_path_bar_get_info_callback (GObject *source,
|
|||||||
|
|
||||||
button_data = make_directory_button (file_info->path_bar, display_name,
|
button_data = make_directory_button (file_info->path_bar, display_name,
|
||||||
file_info->file,
|
file_info->file,
|
||||||
|
file_info->mount,
|
||||||
|
file_info->root_file,
|
||||||
file_info->first_directory, is_hidden);
|
file_info->first_directory, is_hidden);
|
||||||
g_clear_object (&file_info->file);
|
g_clear_object (&file_info->file);
|
||||||
|
|
||||||
@ -824,7 +847,54 @@ gtk_path_bar_get_info_callback (GObject *source,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_info->parent_file = g_file_get_parent (file_info->file);
|
if (g_file_equal (file_info->file, file_info->root_file))
|
||||||
|
file_info->parent_file = NULL;
|
||||||
|
else
|
||||||
|
file_info->parent_file = g_file_get_parent (file_info->file);
|
||||||
|
|
||||||
|
/* Recurse asynchronously */
|
||||||
|
file_info->cancellable = g_cancellable_new ();
|
||||||
|
file_info->path_bar->get_info_cancellable = file_info->cancellable;
|
||||||
|
g_file_query_info_async (file_info->file,
|
||||||
|
"standard::display-name,"
|
||||||
|
"standard::is-hidden,"
|
||||||
|
"standard::is-backup",
|
||||||
|
G_FILE_QUERY_INFO_NONE,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
file_info->cancellable,
|
||||||
|
gtk_path_bar_get_info_callback,
|
||||||
|
file_info);
|
||||||
|
add_cancellable (file_info->path_bar, file_info->cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_path_bar_get_mount_callback (GObject *source,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GFile *file = G_FILE (source);
|
||||||
|
struct SetFileInfo *file_info = data;
|
||||||
|
|
||||||
|
file_info->mount = g_file_find_enclosing_mount_finish (file, result, NULL);
|
||||||
|
|
||||||
|
if (file_info->mount)
|
||||||
|
file_info->root_file = g_mount_get_root (file_info->mount);
|
||||||
|
|
||||||
|
g_assert (GTK_IS_PATH_BAR (file_info->path_bar));
|
||||||
|
g_assert (G_OBJECT (file_info->path_bar)->ref_count > 0);
|
||||||
|
|
||||||
|
if (file_info->root_file == NULL)
|
||||||
|
file_info->root_file = g_object_ref (file_info->path_bar->root_file);
|
||||||
|
|
||||||
|
if (g_file_equal (file_info->file, file_info->root_file))
|
||||||
|
file_info->parent_file = NULL;
|
||||||
|
else
|
||||||
|
file_info->parent_file = g_file_get_parent (file_info->file);
|
||||||
|
|
||||||
|
cancellable_async_done (file_info->path_bar, file_info->cancellable);
|
||||||
|
if (file_info->path_bar->get_info_cancellable == file_info->cancellable)
|
||||||
|
file_info->path_bar->get_info_cancellable = NULL;
|
||||||
|
file_info->cancellable = NULL;
|
||||||
|
|
||||||
/* Recurse asynchronously */
|
/* Recurse asynchronously */
|
||||||
file_info->cancellable = g_cancellable_new ();
|
file_info->cancellable = g_cancellable_new ();
|
||||||
@ -861,22 +931,36 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar,
|
|||||||
info->file = g_object_ref (file);
|
info->file = g_object_ref (file);
|
||||||
info->path_bar = path_bar;
|
info->path_bar = path_bar;
|
||||||
info->first_directory = TRUE;
|
info->first_directory = TRUE;
|
||||||
info->parent_file = g_file_get_parent (info->file);
|
|
||||||
|
|
||||||
if (path_bar->get_info_cancellable)
|
if (path_bar->get_info_cancellable)
|
||||||
cancel_cancellable (path_bar, path_bar->get_info_cancellable);
|
cancel_cancellable (path_bar, path_bar->get_info_cancellable);
|
||||||
|
|
||||||
info->cancellable = g_cancellable_new ();
|
info->cancellable = g_cancellable_new ();
|
||||||
path_bar->get_info_cancellable = info->cancellable;
|
path_bar->get_info_cancellable = info->cancellable;
|
||||||
g_file_query_info_async (info->file,
|
|
||||||
"standard::display-name,"
|
if (g_file_is_native (info->file))
|
||||||
"standard::is-hidden,"
|
{
|
||||||
"standard::is-backup",
|
info->root_file = g_object_ref (path_bar->root_file);
|
||||||
G_FILE_QUERY_INFO_NONE,
|
info->parent_file = g_file_get_parent (info->file);
|
||||||
G_PRIORITY_DEFAULT,
|
|
||||||
info->cancellable,
|
g_file_query_info_async (info->file,
|
||||||
gtk_path_bar_get_info_callback,
|
"standard::display-name,"
|
||||||
info);
|
"standard::is-hidden,"
|
||||||
|
"standard::is-backup",
|
||||||
|
G_FILE_QUERY_INFO_NONE,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
info->cancellable,
|
||||||
|
gtk_path_bar_get_info_callback,
|
||||||
|
info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_file_find_enclosing_mount_async (info->file,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
info->cancellable,
|
||||||
|
gtk_path_bar_get_mount_callback,
|
||||||
|
info);
|
||||||
|
}
|
||||||
add_cancellable (path_bar, info->cancellable);
|
add_cancellable (path_bar, info->cancellable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user