diff --git a/patches/dbus/dbus.patch b/patches/dbus/dbus.patch index 23f041d..c4bb4be 100644 --- a/patches/dbus/dbus.patch +++ b/patches/dbus/dbus.patch @@ -1,12 +1,12 @@ -From 62f3e56dee9471403addc6e8741aaf19e561dce3 Mon Sep 17 00:00:00 2001 +From b8dd8095b721de71d36baeb0a8af7395f25a9cdd Mon Sep 17 00:00:00 2001 From: icedman -Date: Mon, 30 Dec 2024 00:03:36 +0800 -Subject: [PATCH 1/4] add dbus service +Date: Wed, 1 Jan 2025 09:38:05 +0800 +Subject: [PATCH] add dbus patch --- Makefile | 2 +- - dwl.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 282 insertions(+), 1 deletion(-) + dwl.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 322 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 578194f..5df8984 100644 @@ -22,7 +22,7 @@ index 578194f..5df8984 100644 LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS) diff --git a/dwl.c b/dwl.c -index 0eba3e9..46d25cb 100644 +index 0eba3e9..c4a07d0 100644 --- a/dwl.c +++ b/dwl.c @@ -68,6 +68,9 @@ @@ -35,7 +35,7 @@ index 0eba3e9..46d25cb 100644 #include "util.h" /* macros */ -@@ -243,6 +246,50 @@ typedef struct { +@@ -243,6 +246,58 @@ typedef struct { struct wl_listener destroy; } SessionLock; @@ -62,6 +62,14 @@ index 0eba3e9..46d25cb 100644 + " " + " " + " " ++ " " ++ " " ++ " " ++ " " ++ " " ++ " " ++ " " ++ " " + " " + " " + " " @@ -86,7 +94,7 @@ index 0eba3e9..46d25cb 100644 /* function declarations */ static void applybounds(Client *c, struct wlr_box *bbox); static void applyrules(Client *c); -@@ -356,6 +403,39 @@ static void xytonode(double x, double y, struct wlr_surface **psurface, +@@ -356,6 +411,39 @@ static void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny); static void zoom(const Arg *arg); @@ -126,7 +134,7 @@ index 0eba3e9..46d25cb 100644 /* variables */ static pid_t child_pid = -1; static int locked; -@@ -424,6 +504,13 @@ static struct wlr_xwayland *xwayland; +@@ -424,6 +512,13 @@ static struct wlr_xwayland *xwayland; static xcb_atom_t netatom[NetLast]; #endif @@ -140,7 +148,7 @@ index 0eba3e9..46d25cb 100644 /* configuration, allows nested code to access above variables */ #include "config.h" -@@ -670,6 +757,8 @@ checkidleinhibitor(struct wlr_surface *exclude) +@@ -670,6 +765,8 @@ checkidleinhibitor(struct wlr_surface *exclude) void cleanup(void) { @@ -149,7 +157,7 @@ index 0eba3e9..46d25cb 100644 #ifdef XWAYLAND wlr_xwayland_destroy(xwayland); xwayland = NULL; -@@ -1404,6 +1493,8 @@ focusclient(Client *c, int lift) +@@ -1404,6 +1501,8 @@ focusclient(Client *c, int lift) /* Activate the new client */ client_activate_surface(client_surface(c), 1); @@ -158,7 +166,7 @@ index 0eba3e9..46d25cb 100644 } void -@@ -1737,6 +1828,8 @@ mapnotify(struct wl_listener *listener, void *data) +@@ -1737,6 +1836,8 @@ mapnotify(struct wl_listener *listener, void *data) } printstatus(); @@ -167,7 +175,7 @@ index 0eba3e9..46d25cb 100644 unset_fullscreen: m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); wl_list_for_each(w, &clients, link) { -@@ -2604,6 +2697,8 @@ setup(void) +@@ -2604,6 +2705,8 @@ setup(void) fprintf(stderr, "failed to setup XWayland X server, continuing without it\n"); } #endif @@ -176,7 +184,7 @@ index 0eba3e9..46d25cb 100644 } void -@@ -2755,6 +2850,7 @@ unmapnotify(struct wl_listener *listener, void *data) +@@ -2755,6 +2858,7 @@ unmapnotify(struct wl_listener *listener, void *data) { /* Called when the surface is unmapped, and should no longer be shown. */ Client *c = wl_container_of(listener, c, unmap); @@ -184,7 +192,7 @@ index 0eba3e9..46d25cb 100644 if (c == grabc) { cursor_mode = CurNormal; grabc = NULL; -@@ -3151,6 +3247,191 @@ xwaylandready(struct wl_listener *listener, void *data) +@@ -3151,6 +3255,223 @@ xwaylandready(struct wl_listener *listener, void *data) } #endif @@ -241,6 +249,38 @@ index 0eba3e9..46d25cb 100644 + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", window)); + g_free(window); + ++ } else if (g_strcmp0(method_name, "CloseWindow") == 0) { ++ const gchar *window; ++ g_variant_get(parameters, "(s)", &window); ++ ++ uintptr_t address = strtol(window, NULL, 16); // Base 16 for hexadecimal ++ Client *c = NULL; ++ wl_list_for_each(c, &clients, link) { ++ if ((uintptr_t)c == address) { ++ client_send_close(c); ++ } ++ } ++ ++ // g_print("focus %s\n", window); ++ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", window)); ++ g_free(window); ++ ++ } else if (g_strcmp0(method_name, "QuitApp") == 0) { ++ const gchar *appid; ++ g_variant_get(parameters, "(s)", &appid); ++ ++ Client *c = NULL; ++ wl_list_for_each(c, &clients, link) { ++ const char *c_appid = client_get_appid(c); ++ g_print("[%s] [%s]", appid, c_appid); ++ if (g_strcmp0(appid, c_appid) == 0) { ++ client_send_close(c); ++ } ++ } ++ ++ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", appid)); ++ g_free(appid); ++ + } else { + g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, @@ -379,525 +419,3 @@ index 0eba3e9..46d25cb 100644 -- 2.47.1 - -From 735481c04d7caed712990e7b005badbeb8a622b0 Mon Sep 17 00:00:00 2001 -From: icedman -Date: Mon, 30 Dec 2024 00:33:15 +0800 -Subject: [PATCH 2/4] add patch - ---- - patches/dbus/README.md | 8 + - patches/dbus/dbus.patch | 381 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 389 insertions(+) - create mode 100644 patches/dbus/README.md - create mode 100644 patches/dbus/dbus.patch - -diff --git a/patches/dbus/README.md b/patches/dbus/README.md -new file mode 100644 -index 0000000..234223b ---- /dev/null -+++ b/patches/dbus/README.md -@@ -0,0 +1,8 @@ -+### Description -+Implements a dbus service provider for Gnome-based enviroment. -+ -+### Download -+- [main 2024-12-30](/icedman/dwl/raw/branch/dbus-patch/patches/dbus/dbus.patch) -+ -+### Author -+- [icedman](https://codeberg.org/icedman) -diff --git a/patches/dbus/dbus.patch b/patches/dbus/dbus.patch -new file mode 100644 -index 0000000..3f8e984 ---- /dev/null -+++ b/patches/dbus/dbus.patch -@@ -0,0 +1,381 @@ -+From 62f3e56dee9471403addc6e8741aaf19e561dce3 Mon Sep 17 00:00:00 2001 -+From: icedman -+Date: Mon, 30 Dec 2024 00:03:36 +0800 -+Subject: [PATCH] add dbus service -+ -+--- -+ Makefile | 2 +- -+ dwl.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ -+ 2 files changed, 282 insertions(+), 1 deletion(-) -+ -+diff --git a/Makefile b/Makefile -+index 578194f..5df8984 100644 -+--- a/Makefile -++++ b/Makefile -+@@ -12,7 +12,7 @@ DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \ -+ -Wfloat-conversion -+ -+ # CFLAGS / LDFLAGS -+-PKGS = wayland-server xkbcommon libinput $(XLIBS) -++PKGS = wayland-server xkbcommon libinput gio-2.0 glib-2.0 $(XLIBS) -+ DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(WLR_INCS) $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) -+ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS) -+ -+diff --git a/dwl.c b/dwl.c -+index 0eba3e9..46d25cb 100644 -+--- a/dwl.c -++++ b/dwl.c -+@@ -68,6 +68,9 @@ -+ #include -+ #endif -+ -++#include -++#include -++ -+ #include "util.h" -+ -+ /* macros */ -+@@ -243,6 +246,50 @@ typedef struct { -+ struct wl_listener destroy; -+ } SessionLock; -+ -++typedef struct { -++ GMainContext *context; -++ GMainLoop *loop; -++ guint owner_id; -++ void* timer; -++ int interval; -++ -++ GDBusConnection *connection; -++ gchar *property_message; -++ gint property_count; -++} DBusService; -++ -++static DBusService *dbus; -++ -++static GDBusNodeInfo *introspection_data = NULL; -++ -++const gchar *introspection_xml = -++ "" -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ " " -++ ""; -++ -++#define SERVICE_NAME "com.dwl.DBus" -++#define OBJECT_PATH "/com/dwl/DBus" -++#define INTERFACE_NAME "com.dwl.DBus.Interface" -++ -+ /* function declarations */ -+ static void applybounds(Client *c, struct wlr_box *bbox); -+ static void applyrules(Client *c); -+@@ -356,6 +403,39 @@ static void xytonode(double x, double y, struct wlr_surface **psurface, -+ Client **pc, LayerSurface **pl, double *nx, double *ny); -+ static void zoom(const Arg *arg); -+ -++ -++static void dbus_on_name_acquired(GDBusConnection *connection, const gchar *name, -++ gpointer user_data); -++static void dbus_on_name_lost(GDBusConnection *connection, const gchar *name, -++ gpointer user_data); -++static void dbus_on_bus_acquired(GDBusConnection *connection, const gchar *name, -++ gpointer user_data); -++static int dbus_service_update(void *data); -++static int dbus_service_init(void); -++static void dbus_service_cleanup(void); -++ -++// Method handler -++static void dbus_handle_method_call(GDBusConnection *connection, const gchar *sender, -++ const gchar *object_path, -++ const gchar *interface_name, -++ const gchar *method_name, GVariant *parameters, -++ GDBusMethodInvocation *invocation, -++ gpointer user_data); -++// Property handlers -++static GVariant *dbus_get_property(GDBusConnection *connection, const gchar *sender, -++ const gchar *object_path, -++ const gchar *interface_name, -++ const gchar *property_name, GError **error, -++ gpointer user_data); -++static gboolean dbus_set_property(GDBusConnection *connection, const gchar *sender, -++ const gchar *object_path, -++ const gchar *interface_name, -++ const gchar *property_name, GVariant *value, -++ GError **error, gpointer user_data); -++ -++// Emit the MessageChanged signal -++static void dbus_emit_client_signal(GDBusConnection *connection, const char* signal, Client *c); -++ -+ /* variables */ -+ static pid_t child_pid = -1; -+ static int locked; -+@@ -424,6 +504,13 @@ static struct wlr_xwayland *xwayland; -+ static xcb_atom_t netatom[NetLast]; -+ #endif -+ -++// VTable -++static const GDBusInterfaceVTable interface_vtable = { -++ .method_call = dbus_handle_method_call, -++ .get_property = dbus_get_property, -++ .set_property = dbus_set_property, -++}; -++ -+ /* configuration, allows nested code to access above variables */ -+ #include "config.h" -+ -+@@ -670,6 +757,8 @@ checkidleinhibitor(struct wlr_surface *exclude) -+ void -+ cleanup(void) -+ { -++ dbus_service_cleanup(); -++ -+ #ifdef XWAYLAND -+ wlr_xwayland_destroy(xwayland); -+ xwayland = NULL; -+@@ -1404,6 +1493,8 @@ focusclient(Client *c, int lift) -+ -+ /* Activate the new client */ -+ client_activate_surface(client_surface(c), 1); -++ -++ dbus_emit_client_signal(dbus->connection, "WindowFocused", c); -+ } -+ -+ void -+@@ -1737,6 +1828,8 @@ mapnotify(struct wl_listener *listener, void *data) -+ } -+ printstatus(); -+ -++ dbus_emit_client_signal(dbus->connection, "WindowOpened", c); -++ -+ unset_fullscreen: -+ m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); -+ wl_list_for_each(w, &clients, link) { -+@@ -2604,6 +2697,8 @@ setup(void) -+ fprintf(stderr, "failed to setup XWayland X server, continuing without it\n"); -+ } -+ #endif -++ -++ dbus_service_init(); -+ } -+ -+ void -+@@ -2755,6 +2850,7 @@ unmapnotify(struct wl_listener *listener, void *data) -+ { -+ /* Called when the surface is unmapped, and should no longer be shown. */ -+ Client *c = wl_container_of(listener, c, unmap); -++ dbus_emit_client_signal(dbus->connection, "WindowClosed", c); -+ if (c == grabc) { -+ cursor_mode = CurNormal; -+ grabc = NULL; -+@@ -3151,6 +3247,191 @@ xwaylandready(struct wl_listener *listener, void *data) -+ } -+ #endif -+ -++GString* gstring_append_client_json(GString *gstring, Client *c) { -++ const char *appid, *title; -++ const char *fmt = "{ \"id\": \"0x%x\", \"title\": \"%s\", \"app_id\": \"%s\" }"; -++ -++ GString *gstringTemp = g_string_new(""); -++ appid = client_get_appid(c); -++ title = client_get_title(c); -++ g_string_assign(gstringTemp, title); -++ g_string_replace(gstringTemp, "\"", "'", 0); -++ g_string_append_printf(gstring, fmt, c, gstringTemp->str, appid); -++ -++ g_string_free(gstringTemp, TRUE); -++ return gstring; -++} -++ -++static void dbus_handle_method_call(GDBusConnection *connection, const gchar *sender, -++ const gchar *object_path, -++ const gchar *interface_name, -++ const gchar *method_name, GVariant *parameters, -++ GDBusMethodInvocation *invocation, -++ gpointer user_data) { -++ if (g_strcmp0(method_name, "GetWindows") == 0) { -++ const char *response = "Hello from D-Bus!"; -++ g_print("HelloWorld method called by %s\n", sender); -++ -++ Client *c = NULL; -++ GString *gstring = g_string_new("["); -++ wl_list_for_each(c, &clients, link) { -++ gstring_append_client_json(gstring, c); -++ if (c->link.next != &clients) { -++ g_string_append_printf(gstring, ","); -++ } -++ } -++ g_string_append_printf(gstring, "]"); -++ g_dbus_method_invocation_return_value(invocation, -++ g_variant_new("(s)", gstring->str)); -++ g_string_free(gstring, TRUE); -++ } else if (g_strcmp0(method_name, "FocusWindow") == 0) { -++ const gchar *window; -++ g_variant_get(parameters, "(s)", &window); -++ -++ uintptr_t address = strtol(window, NULL, 16); // Base 16 for hexadecimal -++ Client *c = NULL; -++ wl_list_for_each(c, &clients, link) { -++ if ((uintptr_t)c == address) { -++ focusclient(c, true); -++ } -++ } -++ -++ // g_print("focus %s\n", window); -++ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", window)); -++ g_free(window); -++ -++ } else { -++ g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, -++ G_DBUS_ERROR_UNKNOWN_METHOD, -++ "Unknown method: %s", method_name); -++ } -++} -++ -++static GVariant *dbus_get_property(GDBusConnection *connection, const gchar *sender, -++ const gchar *object_path, -++ const gchar *interface_name, -++ const gchar *property_name, GError **error, -++ gpointer user_data) { -++ if (g_strcmp0(property_name, "Message") == 0) { -++ return g_variant_new_string(dbus->property_message ? dbus->property_message -++ : "Default Message"); -++ } else if (g_strcmp0(property_name, "Count") == 0) { -++ dbus->property_count = 0; -++ // Monitor *m = NULL; -++ // wl_list_for_each(m, &mons, link) { -++ // dbus->property_count++; -++ // } -++ -++ Client *c = NULL; -++ wl_list_for_each(c, &clients, link) { -++ dbus->property_count++; -++ } -++ -++ return g_variant_new_int32(dbus->property_count); -++ } -++ return NULL; // Property not found -++} -++ -++static gboolean dbus_set_property(GDBusConnection *connection, const gchar *sender, -++ const gchar *object_path, -++ const gchar *interface_name, -++ const gchar *property_name, GVariant *value, -++ GError **error, gpointer user_data) { -++ if (g_strcmp0(property_name, "Message") == 0) { -++ g_free(dbus->property_message); -++ dbus->property_message = g_strdup(g_variant_get_string(value, NULL)); -++ return TRUE; -++ } -++ g_set_error(error, G_DBUS_ERROR, G_DBUS_ERROR_PROPERTY_READ_ONLY, -++ "The 'Count' property is read-only."); -++ return FALSE; -++} -++ -++static void dbus_emit_client_signal(GDBusConnection *connection, const char* signal, Client *c) { -++ g_print("emit %s\n", signal); -++ GString *gstring = g_string_new(""); -++ gstring_append_client_json(gstring, c); -++ -++ g_dbus_connection_emit_signal(connection, -++ NULL, // No sender (broadcast to all clients) -++ OBJECT_PATH, // Object path -++ INTERFACE_NAME, // Interface name -++ signal, // Signal name -++ g_variant_new("(s)", gstring->str), // Arguments -++ NULL); // No error -++ g_string_free(gstring, TRUE); -++} -++ -++static void dbus_on_name_acquired(GDBusConnection *connection, const gchar *name, -++ gpointer user_data) { -++ g_print("Service name '%s' acquired.\n", SERVICE_NAME); -++} -++ -++static void dbus_on_name_lost(GDBusConnection *connection, const gchar *name, -++ gpointer user_data) { -++ g_print("Service name '%s' lost.\n", SERVICE_NAME); -++} -++ -++static void dbus_on_bus_acquired(GDBusConnection *connection, const gchar *name, -++ gpointer user_data) { -++ GError *error = NULL; -++ -++ // Register the object -++ guint registration_id = g_dbus_connection_register_object( -++ connection, OBJECT_PATH, introspection_data->interfaces[0], -++ &interface_vtable, -++ NULL, // user data -++ NULL, // user data free function -++ &error); -++ -++ if (registration_id == 0) { -++ g_printerr("Failed to register object: %s\n", error->message); -++ g_error_free(error); -++ } -++ -++ dbus->connection = connection; -++ -++} -++ -++static int dbus_service_update(void *data) -++{ -++ g_main_context_iteration(dbus->context, FALSE); -++ wl_event_source_timer_update(dbus->timer, dbus->interval); -++ return 0; -++} -++ -++static int dbus_service_init(void) { -++ dbus = ecalloc(1, sizeof(DBusService)); -++ DBusService *d = dbus; -++ d->interval = 150; -++ d->property_message = NULL; -++ d->property_count = 0; -++ -++ d->loop = g_main_loop_new(NULL, FALSE); -++ d->context = g_main_loop_get_context(d->loop); -++ -++ dbus->timer = wl_event_loop_add_timer(event_loop, dbus_service_update, dbus); -++ -++ // Create introspection data -++ introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL); -++ -++ // Acquire the bus name -++ d->owner_id = g_bus_own_name(G_BUS_TYPE_SESSION, SERVICE_NAME, -++ G_BUS_NAME_OWNER_FLAGS_NONE, dbus_on_bus_acquired, -++ dbus_on_name_acquired, dbus_on_name_lost, NULL, NULL); -++ -++ wl_event_source_timer_update(dbus->timer, dbus->interval); -++ return 0; -++} -++ -++static void dbus_service_cleanup(void) { -++ g_bus_unown_name(dbus->owner_id); -++ g_main_loop_unref(dbus->loop); -++ g_dbus_node_info_unref(introspection_data); -++ free(dbus); -++ dbus = NULL; -++} -++ -+ int -+ main(int argc, char *argv[]) -+ { -+-- -+2.47.1 -+ --- -2.47.1 - - -From 958933eeb575fb59c5555cb2c37a296c42bdcd52 Mon Sep 17 00:00:00 2001 -From: icedman -Date: Mon, 30 Dec 2024 00:38:13 +0800 -Subject: [PATCH 3/4] update README with some dbus info - ---- - patches/dbus/README.md | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/patches/dbus/README.md b/patches/dbus/README.md -index 234223b..2cbab54 100644 ---- a/patches/dbus/README.md -+++ b/patches/dbus/README.md -@@ -6,3 +6,16 @@ Implements a dbus service provider for Gnome-based enviroment. - - ### Author - - [icedman](https://codeberg.org/icedman) -+ -+### DBus Methods -+- GetWindows() -> windows -+- FocusWindow(window) -+ -+### Signals -+- WindowOpen -> window -+- WindowFocused -> window -+- WindowClosed -> window -+ -+### Properties -+- Count (number of active windows) -+ --- -2.47.1 - - -From 421fef1f0d1c583e92bb73b41b75397d9ae89e93 Mon Sep 17 00:00:00 2001 -From: icedman -Date: Tue, 31 Dec 2024 10:35:30 +0800 -Subject: [PATCH 4/4] add closeWindow and quitApp - ---- - dwl.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/dwl.c b/dwl.c -index 46d25cb..c4a07d0 100644 ---- a/dwl.c -+++ b/dwl.c -@@ -269,6 +269,14 @@ const gchar *introspection_xml = - " " - " " - " " -+ " " -+ " " -+ " " -+ " " -+ " " -+ " " -+ " " -+ " " - " " - " " - " " -@@ -3300,6 +3308,38 @@ static void dbus_handle_method_call(GDBusConnection *connection, const gchar *se - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", window)); - g_free(window); - -+ } else if (g_strcmp0(method_name, "CloseWindow") == 0) { -+ const gchar *window; -+ g_variant_get(parameters, "(s)", &window); -+ -+ uintptr_t address = strtol(window, NULL, 16); // Base 16 for hexadecimal -+ Client *c = NULL; -+ wl_list_for_each(c, &clients, link) { -+ if ((uintptr_t)c == address) { -+ client_send_close(c); -+ } -+ } -+ -+ // g_print("focus %s\n", window); -+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", window)); -+ g_free(window); -+ -+ } else if (g_strcmp0(method_name, "QuitApp") == 0) { -+ const gchar *appid; -+ g_variant_get(parameters, "(s)", &appid); -+ -+ Client *c = NULL; -+ wl_list_for_each(c, &clients, link) { -+ const char *c_appid = client_get_appid(c); -+ g_print("[%s] [%s]", appid, c_appid); -+ if (g_strcmp0(appid, c_appid) == 0) { -+ client_send_close(c); -+ } -+ } -+ -+ g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", appid)); -+ g_free(appid); -+ - } else { - g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, - G_DBUS_ERROR_UNKNOWN_METHOD, --- -2.47.1 -