GtkRecentManager: Survive without a filename
We were asserting priv->filename != NULL in various places, which leads to apps refusing to work when HOME is set to a nonexisting or nonwritable value. Since it isn't hard, just make GtkRecentManager survive without a filename. We won't save or read any recently used files in this state, but thats ok. https://bugzilla.gnome.org/show_bug.cgi?id=739038
This commit is contained in:
@ -459,8 +459,6 @@ gtk_recent_manager_real_changed (GtkRecentManager *manager)
|
|||||||
/* we are marked as dirty, so we dump the content of our
|
/* we are marked as dirty, so we dump the content of our
|
||||||
* recently used items list
|
* recently used items list
|
||||||
*/
|
*/
|
||||||
g_assert (priv->filename != NULL);
|
|
||||||
|
|
||||||
if (!priv->recent_items)
|
if (!priv->recent_items)
|
||||||
{
|
{
|
||||||
/* if no container object has been defined, we create a new
|
/* if no container object has been defined, we create a new
|
||||||
@ -496,23 +494,24 @@ gtk_recent_manager_real_changed (GtkRecentManager *manager)
|
|||||||
gtk_recent_manager_clamp_to_age (manager, age);
|
gtk_recent_manager_clamp_to_age (manager, age);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_error = NULL;
|
if (priv->filename != NULL)
|
||||||
g_bookmark_file_to_file (priv->recent_items, priv->filename, &write_error);
|
|
||||||
if (write_error)
|
|
||||||
{
|
{
|
||||||
filename_warning ("Attempting to store changes into `%s', "
|
write_error = NULL;
|
||||||
"but failed: %s",
|
g_bookmark_file_to_file (priv->recent_items, priv->filename, &write_error);
|
||||||
priv->filename,
|
if (write_error)
|
||||||
write_error->message);
|
{
|
||||||
g_error_free (write_error);
|
filename_warning ("Attempting to store changes into `%s', but failed: %s",
|
||||||
}
|
priv->filename,
|
||||||
|
write_error->message);
|
||||||
|
g_error_free (write_error);
|
||||||
|
}
|
||||||
|
|
||||||
if (g_chmod (priv->filename, 0600) < 0)
|
if (g_chmod (priv->filename, 0600) < 0)
|
||||||
{
|
{
|
||||||
filename_warning ("Attempting to set the permissions of `%s', "
|
filename_warning ("Attempting to set the permissions of `%s', but failed: %s",
|
||||||
"but failed: %s",
|
priv->filename,
|
||||||
priv->filename,
|
g_strerror (errno));
|
||||||
g_strerror (errno));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark us as clean */
|
/* mark us as clean */
|
||||||
@ -621,28 +620,29 @@ gtk_recent_manager_set_filename (GtkRecentManager *manager,
|
|||||||
priv->filename = g_strdup (filename);
|
priv->filename = g_strdup (filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert (priv->filename != NULL);
|
if (priv->filename != NULL)
|
||||||
file = g_file_new_for_path (priv->filename);
|
|
||||||
|
|
||||||
error = NULL;
|
|
||||||
priv->monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
|
|
||||||
if (error)
|
|
||||||
{
|
{
|
||||||
filename_warning ("Unable to monitor `%s': %s\n"
|
file = g_file_new_for_path (priv->filename);
|
||||||
"The GtkRecentManager will not update its contents "
|
|
||||||
"if the file is changed from other instances",
|
error = NULL;
|
||||||
priv->filename,
|
priv->monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
|
||||||
error->message);
|
if (error)
|
||||||
g_error_free (error);
|
{
|
||||||
|
filename_warning ("Unable to monitor `%s': %s\n"
|
||||||
|
"The GtkRecentManager will not update its contents "
|
||||||
|
"if the file is changed from other instances",
|
||||||
|
priv->filename,
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_signal_connect (priv->monitor, "changed",
|
||||||
|
G_CALLBACK (gtk_recent_manager_monitor_changed),
|
||||||
|
manager);
|
||||||
|
|
||||||
|
g_object_unref (file);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
g_signal_connect (priv->monitor, "changed",
|
|
||||||
G_CALLBACK (gtk_recent_manager_monitor_changed),
|
|
||||||
manager);
|
|
||||||
|
|
||||||
g_object_unref (file);
|
|
||||||
|
|
||||||
priv->is_dirty = FALSE;
|
|
||||||
build_recent_items_list (manager);
|
build_recent_items_list (manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,46 +658,47 @@ build_recent_items_list (GtkRecentManager *manager)
|
|||||||
GError *read_error;
|
GError *read_error;
|
||||||
gint size;
|
gint size;
|
||||||
|
|
||||||
g_assert (priv->filename != NULL);
|
|
||||||
|
|
||||||
if (!priv->recent_items)
|
if (!priv->recent_items)
|
||||||
{
|
{
|
||||||
priv->recent_items = g_bookmark_file_new ();
|
priv->recent_items = g_bookmark_file_new ();
|
||||||
priv->size = 0;
|
priv->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the file exists, and it's valid (we hope); if not, destroy the container
|
if (priv->filename != NULL)
|
||||||
* object and hope for a better result when the next "changed" signal is
|
|
||||||
* fired. */
|
|
||||||
read_error = NULL;
|
|
||||||
g_bookmark_file_load_from_file (priv->recent_items, priv->filename, &read_error);
|
|
||||||
if (read_error)
|
|
||||||
{
|
{
|
||||||
/* if the file does not exist we just wait for the first write
|
/* the file exists, and it's valid (we hope); if not, destroy the container
|
||||||
* operation on this recent manager instance, to avoid creating
|
* object and hope for a better result when the next "changed" signal is
|
||||||
* empty files and leading to spurious file system events (Sabayon
|
* fired. */
|
||||||
* will not be happy about those)
|
read_error = NULL;
|
||||||
*/
|
g_bookmark_file_load_from_file (priv->recent_items, priv->filename, &read_error);
|
||||||
if (read_error->domain == G_FILE_ERROR &&
|
if (read_error)
|
||||||
read_error->code != G_FILE_ERROR_NOENT)
|
|
||||||
filename_warning ("Attempting to read the recently used resources "
|
|
||||||
"file at `%s', but the parser failed: %s.",
|
|
||||||
priv->filename,
|
|
||||||
read_error->message);
|
|
||||||
|
|
||||||
g_bookmark_file_free (priv->recent_items);
|
|
||||||
priv->recent_items = NULL;
|
|
||||||
|
|
||||||
g_error_free (read_error);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size = g_bookmark_file_get_size (priv->recent_items);
|
|
||||||
if (priv->size != size)
|
|
||||||
{
|
{
|
||||||
priv->size = size;
|
/* if the file does not exist we just wait for the first write
|
||||||
|
* operation on this recent manager instance, to avoid creating
|
||||||
|
* empty files and leading to spurious file system events (Sabayon
|
||||||
|
* will not be happy about those)
|
||||||
|
*/
|
||||||
|
if (read_error->domain == G_FILE_ERROR &&
|
||||||
|
read_error->code != G_FILE_ERROR_NOENT)
|
||||||
|
filename_warning ("Attempting to read the recently used resources "
|
||||||
|
"file at `%s', but the parser failed: %s.",
|
||||||
|
priv->filename,
|
||||||
|
read_error->message);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (manager), "size");
|
g_bookmark_file_free (priv->recent_items);
|
||||||
|
priv->recent_items = NULL;
|
||||||
|
|
||||||
|
g_error_free (read_error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = g_bookmark_file_get_size (priv->recent_items);
|
||||||
|
if (priv->size != size)
|
||||||
|
{
|
||||||
|
priv->size = size;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (manager), "size");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user