diff --git a/data/meson.build b/data/meson.build index 6122e44..0093fff 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,8 +1,12 @@ datadir = get_option('datadir') +sysconfdir = get_option('sysconfdir') # Desktop file install_data('sm.puri.Calls.desktop', install_dir : join_paths(datadir, 'applications')) +install_data('sm.puri.Calls-daemon.desktop', + rename : 'sm.puri.Calls.desktop', + install_dir : join_paths(sysconfdir, 'xdg/autostart')) desktop_utils = find_program('desktop-file-validate', required: false) if desktop_utils.found() @@ -10,6 +14,10 @@ if desktop_utils.found() args: [join_paths(meson.current_source_dir(), 'sm.puri.Calls.desktop') ]) + test('Validate daemon desktop file', desktop_utils, + args: [join_paths(meson.current_source_dir(), + 'sm.puri.Calls-daemon.desktop') + ]) endif # Appdata file diff --git a/data/sm.puri.Calls-daemon.desktop b/data/sm.puri.Calls-daemon.desktop new file mode 100644 index 0000000..5b2b672 --- /dev/null +++ b/data/sm.puri.Calls-daemon.desktop @@ -0,0 +1,16 @@ +[Desktop Entry] +Name=Calls (daemon) +GenericName=Phone +Comment=A phone dialer and call handler (daemon mode) +# Translators: These are desktop search terms. Do not translate semicolons, end line with a semicolon. +Keywords=Telephone;Call;Phone;Dial;Dialer;PTSN; +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=sm.puri.Calls +TryExec=calls +Exec=calls --daemon +Type=Application +StartupNotify=true +NoDisplay=true +Terminal=false +Categories=GNOME;GTK;Telephony; +X-GNOME-AutoRestart=true diff --git a/src/calls-application.c b/src/calls-application.c index b67c5dc..50b3ac3 100644 --- a/src/calls-application.c +++ b/src/calls-application.c @@ -34,6 +34,7 @@ #include "calls-call-window.h" #include "calls-main-window.h" #include "calls-application.h" +#include "session.h" #define HANDY_USE_UNSTABLE_API #include @@ -402,6 +403,8 @@ constructed (GObject *object) actions, G_N_ELEMENTS (actions), self); g_object_unref (action_group); + calls_session_register (APP_ID); + parent_class->constructed (object); } @@ -411,6 +414,8 @@ dispose (GObject *object) { CallsApplication *self = (CallsApplication *)object; + calls_session_unregister (); + g_clear_object (&self->call_window); g_clear_object (&self->main_window); g_clear_object (&self->record_store); diff --git a/src/meson.build b/src/meson.build index 9216028..4b712af 100644 --- a/src/meson.build +++ b/src/meson.build @@ -56,6 +56,7 @@ calls_sources = files(['calls-message-source.c', 'calls-message-source.h', 'calls-call-record.c', 'calls-call-record.h', 'calls-record-store.c', 'calls-record-store.h', 'calls-call-record-row.c', 'calls-call-record-row.h', + 'session.c', 'session.h', ]) calls_config_data = config_data diff --git a/src/session.c b/src/session.c new file mode 100644 index 0000000..60d4cfa --- /dev/null +++ b/src/session.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2018, 2019 Purism SPC + * SPDX-License-Identifier: GPL-3.0+ + * Author: Guido Günther + * + * Copied from phosh and modified for Calls + * by Bob Ham + * + * Based on code from gnome-settings-daemon + */ + +#define G_LOG_DOMAIN "calls-session" + +#include "session.h" + +#include +#include + +#define GNOME_SESSION_DBUS_NAME "org.gnome.SessionManager" +#define GNOME_SESSION_DBUS_OBJECT "/org/gnome/SessionManager" +#define GNOME_SESSION_DBUS_INTERFACE "org.gnome.SessionManager" +#define GNOME_SESSION_CLIENT_PRIVATE_DBUS_INTERFACE "org.gnome.SessionManager.ClientPrivate" + +static GDBusProxy *_proxy; + + +static void +respond_to_end_session (GDBusProxy *proxy) +{ + /* we must answer with "EndSessionResponse" */ + g_dbus_proxy_call (proxy, "EndSessionResponse", + g_variant_new ("(bs)", TRUE, ""), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); +} + + +static void +do_stop (void) +{ + gtk_main_quit (); +} + + +static void +client_proxy_signal_cb (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + if (g_strcmp0 (signal_name, "QueryEndSession") == 0) { + g_debug ("Got QueryEndSession signal"); + respond_to_end_session (proxy); + } else if (g_strcmp0 (signal_name, "EndSession") == 0) { + g_debug ("Got EndSession signal"); + respond_to_end_session (proxy); + } else if (g_strcmp0 (signal_name, "Stop") == 0) { + g_debug ("Got Stop signal"); + do_stop (); + } +} + + +static void +on_client_registered (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GVariant *variant; + GDBusProxy *client_proxy; + GError *error = NULL; + gchar *object_path = NULL; + + variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); + if (!variant) { + g_warning ("Unable to register client: %s", error->message); + g_error_free (error); + return; + } + + g_variant_get (variant, "(o)", &object_path); + + g_debug ("Registered client at path %s", object_path); + + client_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, 0, NULL, + GNOME_SESSION_DBUS_NAME, + object_path, + GNOME_SESSION_CLIENT_PRIVATE_DBUS_INTERFACE, + NULL, + &error); + if (!client_proxy) { + g_warning ("Unable to get the session client proxy: %s", error->message); + g_error_free (error); + return; + } + + g_signal_connect (client_proxy, "g-signal", + G_CALLBACK (client_proxy_signal_cb), NULL); + + g_free (object_path); + g_variant_unref (variant); +} + + +void +calls_session_register (const char *client_id) +{ + const char *startup_id; + GError *err = NULL; + + if (!_proxy) { + _proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION, + NULL, + GNOME_SESSION_DBUS_NAME, + GNOME_SESSION_DBUS_OBJECT, + GNOME_SESSION_DBUS_INTERFACE, + NULL, + &err); + if (!_proxy) { + g_debug ("Failed to contact gnome-session: %s", err->message); + g_clear_error (&err); + return; + } + }; + + startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); + g_dbus_proxy_call (_proxy, + "RegisterClient", + g_variant_new ("(ss)", client_id, startup_id ? startup_id : ""), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) on_client_registered, + NULL); +} + + +void +calls_session_unregister (void) +{ + g_clear_object (&_proxy); +} diff --git a/src/session.h b/src/session.h new file mode 100644 index 0000000..c1717e9 --- /dev/null +++ b/src/session.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2018, 2019 Purism SPC + * SPDX-License-Identifier: GPL-3.0+ + * Author: Guido Günther + * + * Copied from phosh and modified for Calls + * by Bob Ham + */ + +#pragma once + +#include + +void calls_session_register (const char *client_id); +void calls_session_unregister (void);