summaryrefslogtreecommitdiffstats
path: root/src/app_launcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/app_launcher.c')
-rw-r--r--src/app_launcher.c149
1 files changed, 50 insertions, 99 deletions
diff --git a/src/app_launcher.c b/src/app_launcher.c
index 423bf19..417f59a 100644
--- a/src/app_launcher.c
+++ b/src/app_launcher.c
@@ -14,11 +14,8 @@
* limitations under the License.
*/
-#include <gio/gdesktopappinfo.h>
-
#include "app_info.h"
#include "app_launcher.h"
-#include "process_manager.h"
#include "systemd_manager.h"
#include "utils.h"
@@ -29,7 +26,6 @@ typedef struct _AppLauncher {
sd_event *event;
sd_bus *bus;
- ProcessManager *process_manager;
SystemdManager *systemd_manager;
GList *apps_list;
@@ -57,114 +53,87 @@ static void app_launcher_started_cb(AppLauncher *self,
/*
* This function is executed during the object initialization. It goes through
* all available applications on the system and creates a static list
- * containing all the relevant info (ID, name, command, icon...) for further
+ * containing all the relevant info (ID, name, unit, icon...) for further
* processing.
*/
static void app_launcher_update_applications_list(AppLauncher *self)
{
- g_autoptr(GList) app_list = g_app_info_get_all();
g_auto(GStrv) dirlist = NULL;
- guint len = g_list_length(app_list);
char *xdg_data_dirs = getenv("XDG_DATA_DIRS");
if (xdg_data_dirs)
dirlist = g_strsplit(getenv("XDG_DATA_DIRS"), ":", -1);
- for (guint i = 0; i < len; i++) {
- GAppInfo *appinfo = g_list_nth_data(app_list, i);
- const gchar *desktop_id = g_app_info_get_id(appinfo);
- GIcon *icon = g_app_info_get_icon(appinfo);
- g_autoptr(GDesktopAppInfo) desktop_info = g_desktop_app_info_new(desktop_id);
+ GList *units = NULL;
+ if (!systemd_manager_enumerate_app_units(self->systemd_manager, self, &units)) {
+ return;
+ }
+
+ GList *iterator;
+ for (iterator = units; iterator != NULL; iterator = iterator->next) {
g_autofree const gchar *app_id = NULL;
g_autofree const gchar *icon_path = NULL;
AppInfo *app_info = NULL;
- gboolean systemd_activated, graphical;
- if (!desktop_info) {
- g_warning("Unable to find .desktop file for application '%s'", desktop_id);
+ if (!iterator->data)
continue;
- }
- /* Check the application should be part of the apps list */
- if (!g_app_info_should_show(appinfo)) {
- g_debug("Application '%s' shouldn't be shown, skipping...", desktop_id);
- continue;
- }
+ // Parse service and app id out of unit filename
+ gchar *service = g_strrstr(iterator->data, "/");
+ if (!service)
+ service = iterator->data;
+ else
+ service += 1;
- if (g_desktop_app_info_get_is_hidden(desktop_info)) {
- g_debug("Application '%s' is hidden, skipping...", desktop_id);
- continue;
+ g_autofree char *tmp = g_strdup(service);
+ char *end = tmp + strlen(tmp);
+ while (end > tmp && *end != '.') {
+ --end;
}
- if (g_desktop_app_info_get_nodisplay(desktop_info)) {
- g_debug("Application '%s' has NoDisplay set, skipping...", desktop_id);
+ if (end > tmp) {
+ *end = '\0';
+ } else {
+ g_free(tmp);
continue;
}
-
- /*
- * The application ID is usually the .desktop file name. However, a common practice
- * is that .desktop files are named after the executable name, in which case the
- * "StartupWMClass" property indicates the wayland app-id.
- */
- app_id = g_strdup(g_desktop_app_info_get_startup_wm_class(desktop_info));
- if (!app_id) {
- app_id = g_strdup(desktop_id);
- gchar *extension = g_strrstr(app_id, ".desktop");
- if (extension)
- *extension = 0;
+ while (end > tmp && *end != '@') {
+ --end;
}
-
- /*
- * An application can be D-Bus activated if one of those conditions are met:
- * - its .desktop file contains a "DBusActivatable=true" line
- * - it provides a corresponding D-Bus service file
- * HACK: Use "DBusActivatable=true" in .desktop to mark systemd-based service
- */
-
- /* Default to non-DBus-activatable */
- systemd_activated = FALSE;
- if (g_desktop_app_info_get_boolean(desktop_info,
- G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE)) {
- systemd_activated = TRUE;
- } else if (dirlist) {
- const gchar *desktop_filename = g_desktop_app_info_get_filename(desktop_info);
- g_autofree gchar *service_file = g_strconcat(app_id, ".service", NULL);
-
- for (GStrv xdg_data_dir = dirlist; *xdg_data_dir != NULL ; xdg_data_dir++) {
- g_autofree gchar *service_path = NULL;
-
- /* Search only in the XDG_DATA_DIR where the .desktop file is located */
- if (!g_str_has_prefix(desktop_filename, *xdg_data_dir))
- continue;
-
- service_path = g_build_filename(*xdg_data_dir, "dbus-1", "services",
- service_file, NULL);
- if (g_file_test(service_path, G_FILE_TEST_EXISTS)) {
- systemd_activated = TRUE;
- break;
- }
- }
+ if (end > tmp) {
+ app_id = g_strdup(end + 1);
+ }
+ // Potentially handle non-template agl-app-foo.service units here
+
+ // Try getting display name from unit Description property
+ char *name = NULL;
+ if (!systemd_manager_get_app_description(self->systemd_manager,
+ self,
+ service,
+ &name) ||
+ name == NULL) {
+
+ // Fall back to the application ID
+ g_warning("Could not retrieve Description of '%s'", service);
+ name = app_id;
}
-
- /* Applications with "Terminal=True" are not graphical apps */
- graphical = !g_desktop_app_info_get_boolean(desktop_info,
- G_KEY_FILE_DESKTOP_KEY_TERMINAL);
/*
* GAppInfo retrieves the icon data but doesn't provide a way to retrieve
* the corresponding file name, so we have to look it up by ourselves.
*/
- if (icon && dirlist)
- icon_path = applaunchd_utils_get_icon(dirlist, g_icon_to_string(icon));
+ if (app_id && dirlist)
+ icon_path = applaunchd_utils_get_icon(dirlist, app_id);
- app_info = app_info_new(app_id, g_app_info_get_name(appinfo),
+ app_info = app_info_new(app_id,
+ name,
icon_path ? icon_path : "",
- g_app_info_get_commandline(appinfo),
- systemd_activated, graphical);
+ service);
- g_debug("Adding application '%s'", app_id);
+ g_debug("Adding application '%s' with display name '%s'", app_id, name);
self->apps_list = g_list_append(self->apps_list, app_info);
}
+ g_list_free_full(units, g_free);
}
/*
@@ -186,9 +155,6 @@ static GVariant *app_launcher_get_list_variant(AppLauncher *self, gboolean graph
GVariantBuilder app_builder;
AppInfo *app_info = g_list_nth_data(self->apps_list, i);
- if (graphical && !app_info_get_graphical(app_info))
- continue;
-
g_variant_builder_init (&app_builder, G_VARIANT_TYPE("(sss)"));
/* Create application entry */
@@ -229,10 +195,7 @@ static gboolean app_launcher_start_app(AppLauncher *self, AppInfo *app_info)
app_launcher_started_cb(self, app_id, NULL);
return TRUE;
case APP_STATUS_INACTIVE:
- if (app_info_get_systemd_activated(app_info))
- systemd_manager_start_app(self->systemd_manager, app_info);
- else
- process_manager_start_app(self->process_manager, app_info);
+ systemd_manager_start_app(self->systemd_manager, app_info);
return TRUE;
default:
g_critical("Unknown status %d for application '%s'", app_status, app_id);
@@ -257,7 +220,7 @@ static gboolean app_launcher_handle_start(applaunchdAppLaunch *object,
AppLauncher *self = APPLAUNCHD_APP_LAUNCHER(object);
g_return_val_if_fail(APPLAUNCHD_IS_APP_LAUNCHER(self), FALSE);
- /* Seach the apps list for the given app-id */
+ /* Search the apps list for the given app-id */
app = app_launcher_get_app_info(self, app_id);
if (!app) {
g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
@@ -343,7 +306,6 @@ static void app_launcher_dispose(GObject *object)
if (self->apps_list)
g_list_free_full(g_steal_pointer(&self->apps_list), g_object_unref);
- g_clear_object(&self->process_manager);
g_clear_object(&self->systemd_manager);
G_OBJECT_CLASS(app_launcher_parent_class)->dispose(object);
@@ -375,17 +337,6 @@ static void app_launcher_init (AppLauncher *self)
g_source_attach(g_sd_event_create_source(self->event, self->bus), g_main_loop_get_context(main_loop));
/*
- * Create the process manager and connect to its signals
- * so we get notified on app startup/termination
- */
- self->process_manager = g_object_new(APPLAUNCHD_TYPE_PROCESS_MANAGER,
- NULL);
- g_signal_connect_swapped(self->process_manager, "started",
- G_CALLBACK(app_launcher_started_cb), self);
- g_signal_connect_swapped(self->process_manager, "terminated",
- G_CALLBACK(app_launcher_terminated_cb), self);
-
- /*
* Create the systemd manager and connect to its signals
* so we get notified on app startup/termination
*/