[gnome-shell] Add shell_app_system_create_from_window
- From: Colin Walters <walters src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-shell] Add shell_app_system_create_from_window
- Date: Wed, 19 Aug 2009 03:10:59 +0000 (UTC)
commit d94606587bf8fab284f1bfb2f26a07f30c09a525
Author: Colin Walters <walters verbum org>
Date: Fri Aug 14 04:34:28 2009 -0400
Add shell_app_system_create_from_window
For various cases such as when we don't know a .desktop file
for a window, it's desirable to "fake" an application from
the contents of a MetaWindow*.
src/shell-app-system.c | 148 +++++++++++++++++++++++++++++++++++++++---------
src/shell-app-system.h | 6 ++-
2 files changed, 125 insertions(+), 29 deletions(-)
---
diff --git a/src/shell-app-system.c b/src/shell-app-system.c
index d4ee4cb..05060c2 100644
--- a/src/shell-app-system.c
+++ b/src/shell-app-system.c
@@ -57,7 +57,8 @@ G_DEFINE_TYPE(ShellAppSystem, shell_app_system, G_TYPE_OBJECT);
typedef enum {
SHELL_APP_INFO_TYPE_ENTRY,
- SHELL_APP_INFO_TYPE_DESKTOP_FILE
+ SHELL_APP_INFO_TYPE_DESKTOP_FILE,
+ SHELL_APP_INFO_TYPE_WINDOW
} ShellAppInfoType;
struct _ShellAppInfo {
@@ -75,6 +76,9 @@ struct _ShellAppInfo {
GKeyFile *keyfile;
char *keyfile_path;
+
+ MetaWindow *window;
+ char *window_id;
};
ShellAppInfo*
@@ -97,6 +101,9 @@ shell_app_info_unref (ShellAppInfo *info)
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
g_key_file_free (info->keyfile);
g_free (info->keyfile_path);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ g_object_unref (info->window);
+ g_free (info->window_id);
break;
}
g_slice_free (ShellAppInfo, info);
@@ -118,6 +125,23 @@ shell_app_info_new_from_tree_item (GMenuTreeItem *item)
}
static ShellAppInfo *
+shell_app_info_new_from_window (MetaWindow *window)
+{
+ ShellAppInfo *info;
+
+ info = g_slice_alloc (sizeof (ShellAppInfo));
+ info->type = SHELL_APP_INFO_TYPE_WINDOW;
+ info->refcount = 1;
+ info->window = g_object_ref (window);
+ /* For windows, its id is simply its pointer address as a string.
+ * There are various other alternatives, but the address is unique
+ * and unchanging, which is pretty much the best we can do.
+ */
+ info->window_id = g_strdup_printf ("window:%p", window);
+ return info;
+}
+
+static ShellAppInfo *
shell_app_info_new_from_keyfile_take_ownership (GKeyFile *keyfile,
const char *path)
{
@@ -574,8 +598,6 @@ set_gconf_value_string_list (GConfValue *val, GList *items)
g_slist_free (tmp);
}
-
-
void
shell_app_system_add_favorite (ShellAppSystem *system, const char *id)
{
@@ -671,6 +693,21 @@ shell_app_system_load_from_desktop_file (ShellAppSystem *system,
}
/**
+ * shell_app_system_create_from_window:
+ *
+ * In the case where we can't otherwise determine an application
+ * associated with a window, this function can create a "fake"
+ * application just backed by information from the window itself.
+ *
+ * Return value: (transfer full): A new #ShellAppInfo
+ */
+ShellAppInfo *
+shell_app_system_create_from_window (ShellAppSystem *system, MetaWindow *window)
+{
+ return shell_app_info_new_from_window (window);
+}
+
+/**
* shell_app_system_lookup_heuristic_basename:
* @name: Probable application identifier
*
@@ -719,6 +756,8 @@ shell_app_info_get_id (ShellAppInfo *info)
return gmenu_tree_entry_get_desktop_file_id ((GMenuTreeEntry*)info->entry);
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return info->keyfile_path;
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return info->window_id;
}
g_assert_not_reached ();
return NULL;
@@ -735,6 +774,12 @@ shell_app_info_get_name (ShellAppInfo *info)
return g_strdup (gmenu_tree_entry_get_name ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Name", NULL, NULL);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ {
+ char *title;
+ g_object_get (info->window, "title", &title, NULL);
+ return title;
+ }
}
g_assert_not_reached ();
return NULL;
@@ -749,6 +794,8 @@ shell_app_info_get_description (ShellAppInfo *info)
return g_strdup (gmenu_tree_entry_get_comment ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Comment", NULL, NULL);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
}
g_assert_not_reached ();
return NULL;
@@ -763,6 +810,8 @@ shell_app_info_get_executable (ShellAppInfo *info)
return g_strdup (gmenu_tree_entry_get_exec ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
return g_key_file_get_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Exec", NULL);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
}
g_assert_not_reached ();
return NULL;
@@ -776,45 +825,29 @@ shell_app_info_get_desktop_file_path (ShellAppInfo *info)
case SHELL_APP_INFO_TYPE_ENTRY:
return g_strdup (gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry*)info->entry));
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
- return g_strdup (info->keyfile_path);;
+ return g_strdup (info->keyfile_path);
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
}
g_assert_not_reached ();
return NULL;
}
-GIcon *
-shell_app_info_get_icon (ShellAppInfo *info)
+static GIcon *
+themed_icon_from_name (const char *iconname)
{
- char *iconname = NULL;
GIcon *icon;
- /* This code adapted from gdesktopappinfo.c
- * Copyright (C) 2006-2007 Red Hat, Inc.
- * Copyright © 2007 Ryan Lortie
- * LGPL
- */
-
- switch (info->type)
- {
- case SHELL_APP_INFO_TYPE_ENTRY:
- iconname = g_strdup (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry));
- break;
- case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
- iconname = g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Icon", NULL, NULL);
- break;
- }
-
if (!iconname)
- return NULL;
+ return NULL;
if (g_path_is_absolute (iconname))
{
GFile *file;
-
file = g_file_new_for_path (iconname);
icon = G_ICON (g_file_icon_new (file));
g_object_unref (file);
- }
+ }
else
{
char *tmp_name, *p;
@@ -827,15 +860,42 @@ shell_app_info_get_icon (ShellAppInfo *info)
{
*p = 0;
}
-
icon = g_themed_icon_new (tmp_name);
g_free (tmp_name);
}
- g_free (iconname);
return icon;
}
+static GIcon *
+shell_app_info_get_icon (ShellAppInfo *info)
+{
+ char *iconname = NULL;
+ GIcon *icon;
+
+ /* This code adapted from gdesktopappinfo.c
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ * Copyright © 2007 Ryan Lortie
+ * LGPL
+ */
+
+ switch (info->type)
+ {
+ case SHELL_APP_INFO_TYPE_ENTRY:
+ return themed_icon_from_name (gmenu_tree_entry_get_icon ((GMenuTreeEntry*)info->entry));
+ case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
+ iconname = g_key_file_get_locale_string (info->keyfile, DESKTOP_ENTRY_GROUP, "Icon", NULL, NULL);
+ icon = themed_icon_from_name (iconname);
+ g_free (iconname);
+ return icon;
+ break;
+ case SHELL_APP_INFO_TYPE_WINDOW:
+ return NULL;
+ }
+ g_assert_not_reached ();
+ return NULL;
+}
+
GSList *
shell_app_info_get_categories (ShellAppInfo *info)
{
@@ -850,6 +910,7 @@ shell_app_info_get_is_nodisplay (ShellAppInfo *info)
case SHELL_APP_INFO_TYPE_ENTRY:
return gmenu_tree_entry_get_is_nodisplay ((GMenuTreeEntry*)info->entry);
case SHELL_APP_INFO_TYPE_DESKTOP_FILE:
+ case SHELL_APP_INFO_TYPE_WINDOW:
return FALSE;
}
g_assert_not_reached ();
@@ -857,6 +918,19 @@ shell_app_info_get_is_nodisplay (ShellAppInfo *info)
}
/**
+ * shell_app_info_is_transient:
+ *
+ * A "transient" application is one which represents
+ * just an open window, i.e. we don't know how to launch it
+ * again.
+ */
+gboolean
+shell_app_info_is_transient (ShellAppInfo *info)
+{
+ return info->type == SHELL_APP_INFO_TYPE_WINDOW;
+}
+
+/**
* shell_app_info_create_icon_texture:
*
* Look up the icon for this application, and create a #ClutterTexture
@@ -870,6 +944,13 @@ shell_app_info_create_icon_texture (ShellAppInfo *info, float size)
GIcon *icon;
ClutterActor *ret;
+ if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
+ {
+ return shell_texture_cache_bind_pixbuf_property (shell_texture_cache_get_default (),
+ G_OBJECT (info->window),
+ "icon");
+ }
+
icon = shell_app_info_get_icon (info);
if (!icon)
{
@@ -908,6 +989,17 @@ shell_app_info_launch_full (ShellAppInfo *info,
if (startup_id)
*startup_id = NULL;
+ if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
+ {
+ /* We can't pass URIs into a window; shouldn't hit this
+ * code path. If we do, fix the caller to disallow it.
+ */
+ g_return_val_if_fail (uris == NULL, TRUE);
+
+ meta_window_activate (info->window, timestamp);
+ return TRUE;
+ }
+
filename = shell_app_info_get_desktop_file_path (info);
gapp = g_desktop_app_info_new_from_filename (filename);
g_free (filename);
diff --git a/src/shell-app-system.h b/src/shell-app-system.h
index 7691eaf..b8d20f9 100644
--- a/src/shell-app-system.h
+++ b/src/shell-app-system.h
@@ -4,6 +4,8 @@
#include <gio/gio.h>
#include <clutter/clutter.h>
+#include "window.h"
+
#define SHELL_TYPE_APP_SYSTEM (shell_app_system_get_type ())
#define SHELL_APP_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHELL_TYPE_APP_SYSTEM, ShellAppSystem))
#define SHELL_APP_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_APP_SYSTEM, ShellAppSystemClass))
@@ -58,10 +60,10 @@ char *shell_app_info_get_name (ShellAppInfo *info);
char *shell_app_info_get_description (ShellAppInfo *info);
char *shell_app_info_get_executable (ShellAppInfo *info);
char *shell_app_info_get_desktop_file_path (ShellAppInfo *info);
-GIcon *shell_app_info_get_icon (ShellAppInfo *info);
ClutterActor *shell_app_info_create_icon_texture (ShellAppInfo *info, float size);
GSList *shell_app_info_get_categories (ShellAppInfo *info);
gboolean shell_app_info_get_is_nodisplay (ShellAppInfo *info);
+gboolean shell_app_info_is_transient (ShellAppInfo *info);
gboolean shell_app_info_launch_full (ShellAppInfo *info,
guint timestamp,
GList *uris,
@@ -77,6 +79,8 @@ ShellAppInfo *shell_app_system_lookup_cached_app (ShellAppSystem *system, const
ShellAppInfo *shell_app_system_lookup_heuristic_basename (ShellAppSystem *system, const char *id);
+ShellAppInfo *shell_app_system_create_from_window (ShellAppSystem *system, MetaWindow *window);
+
GSList *shell_app_system_get_menus (ShellAppSystem *system);
GSList *shell_app_system_get_all_settings (ShellAppSystem *system);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]