Avoid delays in starting applications

Only query file info once, and don't do it for non-native files, since
that may cause sync network IO.

Bug http://bugzilla.gnome.org/show_bug.cgi?id=635588
This commit is contained in:
Matthias Clasen 2010-11-27 23:12:09 -05:00
parent 289ad41bd1
commit b0bf2b5202

View File

@ -36,54 +36,43 @@
#include <unistd.h> #include <unistd.h>
static char * static char *
get_display_name (GFile *file) get_display_name (GFile *file,
GFileInfo *info)
{ {
GFileInfo *info;
char *name, *tmp; char *name, *tmp;
/* This does sync I/O, which isn't ideal.
* It should probably use the NautilusFile machinery
*/
name = NULL; name = NULL;
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0, NULL, NULL);
if (info) if (info)
{ name = g_strdup (g_file_info_get_display_name (info));
name = g_strdup (g_file_info_get_display_name (info));
g_object_unref (info);
}
if (name == NULL) if (name == NULL)
{ {
name = g_file_get_basename (file); name = g_file_get_basename (file);
if (!g_utf8_validate (name, -1, NULL)) if (!g_utf8_validate (name, -1, NULL))
{ {
tmp = name; tmp = name;
name = name =
g_uri_escape_string (name, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, g_uri_escape_string (name, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
TRUE); g_free (tmp);
g_free (tmp); }
}
} }
return name; return name;
} }
static GIcon * static GIcon *
get_icon (GFile *file) get_icon (GFile *file,
GFileInfo *info)
{ {
GFileInfo *info;
GIcon *icon; GIcon *icon;
icon = NULL; icon = NULL;
info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_ICON, 0, NULL, NULL);
if (info) if (info)
{ {
icon = g_file_info_get_icon (info); icon = g_file_info_get_icon (info);
if (icon) if (icon)
g_object_ref (icon); g_object_ref (icon);
g_object_unref (info);
} }
return icon; return icon;
@ -99,13 +88,13 @@ gicon_to_string (GIcon *icon)
{ {
file = g_file_icon_get_file (G_FILE_ICON (icon)); file = g_file_icon_get_file (G_FILE_ICON (icon));
if (file) if (file)
return g_file_get_path (file); return g_file_get_path (file);
} }
else if (G_IS_THEMED_ICON (icon)) else if (G_IS_THEMED_ICON (icon))
{ {
names = g_themed_icon_get_names (G_THEMED_ICON (icon)); names = g_themed_icon_get_names (G_THEMED_ICON (icon));
if (names) if (names)
return g_strdup (names[0]); return g_strdup (names[0]);
} }
else if (G_IS_EMBLEMED_ICON (icon)) else if (G_IS_EMBLEMED_ICON (icon))
{ {
@ -121,11 +110,11 @@ gicon_to_string (GIcon *icon)
static void static void
end_startup_notification (GdkDisplay *display, end_startup_notification (GdkDisplay *display,
const char *startup_id) const char *startup_id)
{ {
gdk_x11_display_broadcast_startup_message (display, "remove", gdk_x11_display_broadcast_startup_message (display, "remove",
"ID", startup_id, "ID", startup_id,
NULL); NULL);
} }
@ -210,19 +199,19 @@ startup_timeout (void *data)
next = tmp->next; next = tmp->next;
elapsed = elapsed =
((((double) now.tv_sec - sn_data->time.tv_sec) * G_USEC_PER_SEC + ((((double) now.tv_sec - sn_data->time.tv_sec) * G_USEC_PER_SEC +
(now.tv_usec - sn_data->time.tv_usec))) / 1000.0; (now.tv_usec - sn_data->time.tv_usec))) / 1000.0;
if (elapsed >= STARTUP_TIMEOUT_LENGTH) if (elapsed >= STARTUP_TIMEOUT_LENGTH)
{ {
std->contexts = g_slist_remove (std->contexts, sn_data); std->contexts = g_slist_remove (std->contexts, sn_data);
end_startup_notification (sn_data->display, sn_data->startup_id); end_startup_notification (sn_data->display, sn_data->startup_id);
free_startup_notification_data (sn_data); free_startup_notification_data (sn_data);
} }
else else
{ {
min_timeout = MIN (min_timeout, (STARTUP_TIMEOUT_LENGTH - elapsed)); min_timeout = MIN (min_timeout, (STARTUP_TIMEOUT_LENGTH - elapsed));
} }
tmp = next; tmp = next;
} }
@ -239,7 +228,7 @@ startup_timeout (void *data)
static void static void
add_startup_timeout (GdkScreen *screen, add_startup_timeout (GdkScreen *screen,
const char *startup_id) const char *startup_id)
{ {
StartupTimeoutData *data; StartupTimeoutData *data;
StartupNotificationData *sn_data; StartupNotificationData *sn_data;
@ -253,7 +242,7 @@ add_startup_timeout (GdkScreen *screen,
data->timeout_id = 0; data->timeout_id = 0;
g_object_set_data_full (G_OBJECT (screen), "appinfo-startup-data", g_object_set_data_full (G_OBJECT (screen), "appinfo-startup-data",
data, free_startup_timeout); data, free_startup_timeout);
} }
sn_data = g_new (StartupNotificationData, 1); sn_data = g_new (StartupNotificationData, 1);
@ -265,14 +254,14 @@ add_startup_timeout (GdkScreen *screen,
if (data->timeout_id == 0) if (data->timeout_id == 0)
data->timeout_id = g_timeout_add_seconds (STARTUP_TIMEOUT_LENGTH_SECONDS, data->timeout_id = g_timeout_add_seconds (STARTUP_TIMEOUT_LENGTH_SECONDS,
startup_timeout, data); startup_timeout, data);
} }
char * char *
_gdk_windowing_get_startup_notify_id (GAppLaunchContext *context, _gdk_windowing_get_startup_notify_id (GAppLaunchContext *context,
GAppInfo *info, GAppInfo *info,
GList *files) GList *files)
{ {
static int sequence = 0; static int sequence = 0;
GdkAppLaunchContextPrivate *priv; GdkAppLaunchContextPrivate *priv;
@ -288,6 +277,7 @@ _gdk_windowing_get_startup_notify_id (GAppLaunchContext *context,
GIcon *icon; GIcon *icon;
guint32 timestamp; guint32 timestamp;
char *startup_id; char *startup_id;
GFileInfo *fileinfo;
priv = GDK_APP_LAUNCH_CONTEXT (context)->priv; priv = GDK_APP_LAUNCH_CONTEXT (context)->priv;
@ -307,20 +297,32 @@ _gdk_windowing_get_startup_notify_id (GAppLaunchContext *context,
screen = gdk_display_get_default_screen (display); screen = gdk_display_get_default_screen (display);
} }
fileinfo = NULL;
files_count = g_list_length (files); files_count = g_list_length (files);
if (files_count == 0) if (files_count == 0)
description = g_strdup_printf (_("Starting %s"), g_app_info_get_name (info)); {
description = g_strdup_printf (_("Starting %s"), g_app_info_get_name (info));
}
else if (files_count == 1) else if (files_count == 1)
{ {
gchar *display_name = get_display_name (files->data); gchar *display_name;
if (g_file_is_native (files->data))
fileinfo = g_file_query_info (files->data,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
G_FILE_ATTRIBUTE_STANDARD_ICON,
0, NULL, NULL);
display_name = get_display_name (files->data, fileinfo);
description = g_strdup_printf (_("Opening %s"), display_name); description = g_strdup_printf (_("Opening %s"), display_name);
g_free (display_name); g_free (display_name);
} }
else else
description = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, description = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
"Opening %d Item", "Opening %d Item",
"Opening %d Items", "Opening %d Items",
files_count), files_count); files_count), files_count);
icon_name = NULL; icon_name = NULL;
if (priv->icon_name) if (priv->icon_name)
@ -330,18 +332,18 @@ _gdk_windowing_get_startup_notify_id (GAppLaunchContext *context,
icon = NULL; icon = NULL;
if (priv->icon != NULL) if (priv->icon != NULL)
icon = g_object_ref (priv->icon); icon = g_object_ref (priv->icon);
else if (files_count == 1) else if (files_count == 1)
icon = get_icon (files->data); icon = get_icon (files->data, fileinfo);
if (icon == NULL) if (icon == NULL)
{ {
icon = g_app_info_get_icon (info); icon = g_app_info_get_icon (info);
g_object_ref (icon); g_object_ref (icon);
} }
if (icon) if (icon)
icon_name = gicon_to_string (icon); icon_name = gicon_to_string (icon);
g_object_unref (icon); g_object_unref (icon);
} }
@ -364,30 +366,31 @@ _gdk_windowing_get_startup_notify_id (GAppLaunchContext *context,
application_id = NULL; application_id = NULL;
startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu", startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu",
g_get_prgname (), g_get_prgname (),
(unsigned long)getpid (), (unsigned long)getpid (),
g_get_host_name (), g_get_host_name (),
binary_name, binary_name,
sequence++, sequence++,
(unsigned long)timestamp); (unsigned long)timestamp);
gdk_x11_display_broadcast_startup_message (display, "new", gdk_x11_display_broadcast_startup_message (display, "new",
"ID", startup_id, "ID", startup_id,
"NAME", g_app_info_get_name (info), "NAME", g_app_info_get_name (info),
"SCREEN", screen_str, "SCREEN", screen_str,
"BIN", binary_name, "BIN", binary_name,
"ICON", icon_name, "ICON", icon_name,
"DESKTOP", workspace_str, "DESKTOP", workspace_str,
"DESCRIPTION", description, "DESCRIPTION", description,
"WMCLASS", NULL, /* FIXME */ "WMCLASS", NULL, /* FIXME */
"APPLICATION_ID", application_id, "APPLICATION_ID", application_id,
NULL); NULL);
g_free (description); g_free (description);
g_free (screen_str); g_free (screen_str);
g_free (workspace_str); g_free (workspace_str);
g_free (icon_name); g_free (icon_name);
if (fileinfo)
g_object_unref (fileinfo);
add_startup_timeout (screen, startup_id); add_startup_timeout (screen, startup_id);
@ -397,7 +400,7 @@ _gdk_windowing_get_startup_notify_id (GAppLaunchContext *context,
void void
_gdk_windowing_launch_failed (GAppLaunchContext *context, _gdk_windowing_launch_failed (GAppLaunchContext *context,
const char *startup_notify_id) const char *startup_notify_id)
{ {
GdkAppLaunchContextPrivate *priv; GdkAppLaunchContextPrivate *priv;
GdkScreen *screen; GdkScreen *screen;
@ -419,22 +422,22 @@ _gdk_windowing_launch_failed (GAppLaunchContext *context,
if (data) if (data)
{ {
for (l = data->contexts; l != NULL; l = l->next) for (l = data->contexts; l != NULL; l = l->next)
{ {
sn_data = l->data; sn_data = l->data;
if (strcmp (startup_notify_id, sn_data->startup_id) == 0) if (strcmp (startup_notify_id, sn_data->startup_id) == 0)
{ {
data->contexts = g_slist_remove (data->contexts, sn_data); data->contexts = g_slist_remove (data->contexts, sn_data);
end_startup_notification (sn_data->display, sn_data->startup_id); end_startup_notification (sn_data->display, sn_data->startup_id);
free_startup_notification_data (sn_data); free_startup_notification_data (sn_data);
break; break;
} }
} }
if (data->contexts == NULL) if (data->contexts == NULL)
{ {
g_source_remove (data->timeout_id); g_source_remove (data->timeout_id);
data->timeout_id = 0; data->timeout_id = 0;
} }
} }
} }