static void on_transient_window_title_changed (MetaWindow *window, GParamSpec *spec, ShellWindowTracker *self) { ShellAppSystem *appsys; ShellApp *app; const char *id; /* Check if we now have a mapping using the window title */ id = get_app_id_from_title (window); if (id == NULL) return; appsys = shell_app_system_get_default (); app = shell_app_system_get_app (appsys, id); if (app == NULL) return; g_object_unref (app); /* We found an app, don't listen for further title changes */ g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_transient_window_title_changed), self); /* It's simplest to just treat this as a remove + add. */ disassociate_window (self, window); track_window (self, window); }
/** * get_app_from_window_wmclass: * * Looks only at the given window, and attempts to determine * an application based on WM_CLASS. If one can't be determined, * return %NULL. * * Return value: (transfer full): A newly-referenced #ShellApp, or %NULL */ static ShellApp * get_app_from_window_wmclass (MetaWindow *window) { ShellApp *app; ShellAppSystem *appsys; char *wmclass; char *with_desktop; appsys = shell_app_system_get_default (); wmclass = get_appid_from_window (window); if (!wmclass) return NULL; with_desktop = g_strjoin (NULL, wmclass, ".desktop", NULL); g_free (wmclass); app = shell_app_system_lookup_heuristic_basename (appsys, with_desktop); g_free (with_desktop); if (app == NULL) { const char *id = get_app_id_from_title (window); if (id != NULL) app = shell_app_system_get_app (appsys, id); } return app; }
/** * shell_app_system_get_app_for_path: * @system: a #ShellAppSystem * @desktop_path: (type utf8): UTF-8 encoded absolute file name * * Find or create a #ShellApp corresponding to a given absolute * file name which must be in the standard paths (XDG_DATA_DIRS). * For files outside the datadirs, this function returns %NULL. * * If already cached elsewhere in memory, return that instance. * Otherwise, create a new one. * * Return value: (transfer full): The #ShellApp for id, or %NULL if none */ ShellApp * shell_app_system_get_app_for_path (ShellAppSystem *system, const char *desktop_path) { const char *basename; ShellAppInfo *info; basename = g_strrstr (desktop_path, "/"); if (basename) basename += 1; else basename = desktop_path; info = g_hash_table_lookup (system->priv->app_id_to_info, basename); if (!info) return NULL; if (info->type == SHELL_APP_INFO_TYPE_ENTRY) { const char *full_path = gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry*) info->entry); if (strcmp (desktop_path, full_path) != 0) return NULL; } else return NULL; return shell_app_system_get_app (system, basename); }
/** * shell_app_system_lookup_heuristic_basename: * @system: a #ShellAppSystem * @id: Probable application identifier * * Find a valid application corresponding to a given * heuristically determined application identifier * string, or %NULL if none. * * Returns: (transfer full): A #ShellApp for @name */ ShellApp * shell_app_system_lookup_heuristic_basename (ShellAppSystem *system, const char *name) { ShellApp *result; GSList *prefix; result = shell_app_system_get_app (system, name); if (result != NULL) return result; for (prefix = system->priv->known_vendor_prefixes; prefix; prefix = g_slist_next (prefix)) { char *tmpid = g_strconcat ((char*)prefix->data, name, NULL); result = shell_app_system_get_app (system, tmpid); g_free (tmpid); if (result != NULL) return result; } return NULL; }
/** * shell_app_system_lookup_heuristic_basename: * @name: Probable application identifier * * Find a valid application corresponding to a given * heuristically determined application identifier * string, or %NULL if none. * * Returns: (transfer full): A #ShellApp for name */ ShellApp * shell_app_system_lookup_heuristic_basename (ShellAppSystem *system, const char *name) { ShellApp *result; char **vendor_prefixes; result = shell_app_system_get_app (system, name); if (result != NULL) return result; for (vendor_prefixes = (char**)known_vendor_prefixes; *vendor_prefixes; vendor_prefixes++) { char *tmpid = g_strjoin (NULL, *vendor_prefixes, "-", name, NULL); result = shell_app_system_get_app (system, tmpid); g_free (tmpid); if (result != NULL) return result; } return NULL; }
/** * shell_app_info_launch_full: * @timestamp: Event timestamp, or 0 for current event timestamp * @uris: List of uris to pass to application * @workspace: Start on this workspace, or -1 for default * @startup_id: (out): Returned startup notification ID, or %NULL if none * @error: A #GError */ gboolean shell_app_info_launch_full (ShellAppInfo *info, guint timestamp, GList *uris, int workspace, char **startup_id, GError **error) { ShellApp *shell_app; GDesktopAppInfo *gapp; GdkAppLaunchContext *context; gboolean ret; ShellGlobal *global; MetaScreen *screen; 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; } else if (info->type == SHELL_APP_INFO_TYPE_ENTRY) { /* Can't use g_desktop_app_info_new, see bug 614879 */ const char *filename = gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry *)info->entry); gapp = g_desktop_app_info_new_from_filename (filename); } else { char *filename = shell_app_info_get_desktop_file_path (info); gapp = g_desktop_app_info_new_from_filename (filename); g_free (filename); } if (!gapp) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Not found"); return FALSE; } global = shell_global_get (); screen = shell_global_get_screen (global); if (timestamp == 0) timestamp = clutter_get_current_event_time (); if (workspace < 0) workspace = meta_screen_get_active_workspace_index (screen); context = gdk_app_launch_context_new (); gdk_app_launch_context_set_timestamp (context, timestamp); gdk_app_launch_context_set_desktop (context, workspace); shell_app = shell_app_system_get_app (shell_app_system_get_default (), shell_app_info_get_id (info)); /* In the case where we know an app, we handle reaping the child internally, * in the window tracker. */ if (shell_app != NULL) ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris, G_APP_LAUNCH_CONTEXT (context), G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, _gather_pid_callback, shell_app, error); else ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris, G_APP_LAUNCH_CONTEXT (context), G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, error); g_object_unref (G_OBJECT (gapp)); return ret; }