mirror of
https://gitlab.gnome.org/GNOME/calls.git
synced 2024-11-04 23:51:17 +00:00
Merge branch 'gnome-session' into 'master'
Start up in a new daemon mode when GNOME starts Closes #45 See merge request Librem5/calls!62
This commit is contained in:
commit
8f38e50f8c
6 changed files with 243 additions and 5 deletions
|
@ -1,8 +1,12 @@
|
||||||
datadir = get_option('datadir')
|
datadir = get_option('datadir')
|
||||||
|
sysconfdir = get_option('sysconfdir')
|
||||||
|
|
||||||
# Desktop file
|
# Desktop file
|
||||||
install_data('sm.puri.Calls.desktop',
|
install_data('sm.puri.Calls.desktop',
|
||||||
install_dir : join_paths(datadir, 'applications'))
|
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)
|
desktop_utils = find_program('desktop-file-validate', required: false)
|
||||||
if desktop_utils.found()
|
if desktop_utils.found()
|
||||||
|
@ -10,6 +14,10 @@ if desktop_utils.found()
|
||||||
args: [join_paths(meson.current_source_dir(),
|
args: [join_paths(meson.current_source_dir(),
|
||||||
'sm.puri.Calls.desktop')
|
'sm.puri.Calls.desktop')
|
||||||
])
|
])
|
||||||
|
test('Validate daemon desktop file', desktop_utils,
|
||||||
|
args: [join_paths(meson.current_source_dir(),
|
||||||
|
'sm.puri.Calls-daemon.desktop')
|
||||||
|
])
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Appdata file
|
# Appdata file
|
||||||
|
|
16
data/sm.puri.Calls-daemon.desktop
Normal file
16
data/sm.puri.Calls-daemon.desktop
Normal file
|
@ -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
|
|
@ -34,6 +34,7 @@
|
||||||
#include "calls-call-window.h"
|
#include "calls-call-window.h"
|
||||||
#include "calls-main-window.h"
|
#include "calls-main-window.h"
|
||||||
#include "calls-application.h"
|
#include "calls-application.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
#define HANDY_USE_UNSTABLE_API
|
#define HANDY_USE_UNSTABLE_API
|
||||||
#include <handy.h>
|
#include <handy.h>
|
||||||
|
@ -55,6 +56,7 @@ struct _CallsApplication
|
||||||
{
|
{
|
||||||
GtkApplication parent_instance;
|
GtkApplication parent_instance;
|
||||||
|
|
||||||
|
gboolean daemon;
|
||||||
GString *provider_name;
|
GString *provider_name;
|
||||||
CallsProvider *provider;
|
CallsProvider *provider;
|
||||||
CallsRinger *ringer;
|
CallsRinger *ringer;
|
||||||
|
@ -90,6 +92,14 @@ handle_local_options (GApplication *application,
|
||||||
g_variant_new_string (name));
|
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
|
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[] =
|
static const GActionEntry actions[] =
|
||||||
{
|
{
|
||||||
{ "set-provider-name", set_provider_name_action, "s" },
|
{ "set-provider-name", set_provider_name_action, "s" },
|
||||||
|
{ "set-daemon", set_daemon_action, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,17 +299,29 @@ static void
|
||||||
activate (GApplication *application)
|
activate (GApplication *application)
|
||||||
{
|
{
|
||||||
CallsApplication *self = CALLS_APPLICATION (application);
|
CallsApplication *self = CALLS_APPLICATION (application);
|
||||||
gboolean ok;
|
gboolean present;
|
||||||
|
|
||||||
g_debug ("Activated");
|
g_debug ("Activated");
|
||||||
|
|
||||||
ok = start_proper (self);
|
if (self->main_window)
|
||||||
if (!ok)
|
|
||||||
{
|
{
|
||||||
return;
|
present = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gboolean ok = start_proper (self);
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
present = !self->daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_window_present (GTK_WINDOW (self->main_window));
|
if (present)
|
||||||
|
{
|
||||||
|
gtk_window_present (GTK_WINDOW (self->main_window));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -360,6 +403,8 @@ constructed (GObject *object)
|
||||||
actions, G_N_ELEMENTS (actions), self);
|
actions, G_N_ELEMENTS (actions), self);
|
||||||
g_object_unref (action_group);
|
g_object_unref (action_group);
|
||||||
|
|
||||||
|
calls_session_register (APP_ID);
|
||||||
|
|
||||||
parent_class->constructed (object);
|
parent_class->constructed (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,6 +414,8 @@ dispose (GObject *object)
|
||||||
{
|
{
|
||||||
CallsApplication *self = (CallsApplication *)object;
|
CallsApplication *self = (CallsApplication *)object;
|
||||||
|
|
||||||
|
calls_session_unregister ();
|
||||||
|
|
||||||
g_clear_object (&self->call_window);
|
g_clear_object (&self->call_window);
|
||||||
g_clear_object (&self->main_window);
|
g_clear_object (&self->main_window);
|
||||||
g_clear_object (&self->record_store);
|
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"),
|
_("The name of the plugin to use for the call Provider"),
|
||||||
_("PLUGIN")
|
_("PLUGIN")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"daemon", 'd', G_OPTION_FLAG_NONE,
|
||||||
|
G_OPTION_ARG_NONE, NULL,
|
||||||
|
_("Whether to present the main window on startup"),
|
||||||
|
NULL
|
||||||
|
},
|
||||||
{
|
{
|
||||||
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-call-record.c', 'calls-call-record.h',
|
||||||
'calls-record-store.c', 'calls-record-store.h',
|
'calls-record-store.c', 'calls-record-store.h',
|
||||||
'calls-call-record-row.c', 'calls-call-record-row.h',
|
'calls-call-record-row.c', 'calls-call-record-row.h',
|
||||||
|
'session.c', 'session.h',
|
||||||
])
|
])
|
||||||
|
|
||||||
calls_config_data = config_data
|
calls_config_data = config_data
|
||||||
|
|
145
src/session.c
Normal file
145
src/session.c
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
15
src/session.h
Normal file
15
src/session.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
Loading…
Reference in a new issue