Commit 8f38e50f authored by Bob Ham's avatar Bob Ham

Merge branch 'gnome-session' into 'master'

Start up in a new daemon mode when GNOME starts

Closes #45

See merge request !62
parents 587c3444 646682b8
Pipeline #27595 passed with stages
in 2 minutes and 55 seconds
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
......
[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
......@@ -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 <handy.h>
......@@ -55,6 +56,7 @@ struct _CallsApplication
{
GtkApplication parent_instance;
gboolean daemon;
GString *provider_name;
CallsProvider *provider;
CallsRinger *ringer;
......@@ -90,6 +92,14 @@ handle_local_options (GApplication *application,
g_variant_new_string (name));
}
ok = g_variant_dict_contains (options, "daemon");
if (ok)
{
g_action_group_activate_action (G_ACTION_GROUP (application),
"set-daemon",
NULL);
}
return -1; // Continue processing signal
}
......@@ -120,9 +130,30 @@ set_provider_name_action (GSimpleAction *action,
}
static void
set_daemon_action (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
CallsApplication *self = CALLS_APPLICATION (user_data);
if (self->main_window)
{
g_warning ("Cannot set application as a daemon"
" because application is already started");
return;
}
self->daemon = TRUE;
g_debug ("Application marked as daemon");
}
static const GActionEntry actions[] =
{
{ "set-provider-name", set_provider_name_action, "s" },
{ "set-daemon", set_daemon_action, NULL },
};
......@@ -268,17 +299,29 @@ static void
activate (GApplication *application)
{
CallsApplication *self = CALLS_APPLICATION (application);
gboolean ok;
gboolean present;
g_debug ("Activated");
ok = start_proper (self);
if (!ok)
if (self->main_window)
{
return;
present = TRUE;
}
else
{
gboolean ok = start_proper (self);
if (!ok)
{
return;
}
gtk_window_present (GTK_WINDOW (self->main_window));
present = !self->daemon;
}
if (present)
{
gtk_window_present (GTK_WINDOW (self->main_window));
}
}
......@@ -360,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);
}
......@@ -369,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);
......@@ -426,6 +473,12 @@ calls_application_init (CallsApplication *self)
_("The name of the plugin to use for the call Provider"),
_("PLUGIN")
},
{
"daemon", 'd', G_OPTION_FLAG_NONE,
G_OPTION_ARG_NONE, NULL,
_("Whether to present the main window on startup"),
NULL
},
{
NULL
}
......
......@@ -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
......
/*
* Copyright (C) 2018, 2019 Purism SPC
* SPDX-License-Identifier: GPL-3.0+
* Author: Guido Günther <agx@sigxcpu.org>
*
* Copied from phosh and modified for Calls
* by Bob Ham <bob.ham@puri.sm>
*
* Based on code from gnome-settings-daemon
*/
#define G_LOG_DOMAIN "calls-session"
#include "session.h"
#include <gio/gio.h>
#include <gtk/gtk.h>
#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);
}
/*
* Copyright (C) 2018, 2019 Purism SPC
* SPDX-License-Identifier: GPL-3.0+
* Author: Guido Günther <agx@sigxcpu.org>
*
* Copied from phosh and modified for Calls
* by Bob Ham <bob.ham@puri.sm>
*/
#pragma once
#include <glib-object.h>
void calls_session_register (const char *client_id);
void calls_session_unregister (void);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment