Compare commits

...

15 Commits

Author SHA1 Message Date
Felipe Borges
9d5371fdd5 46.beta.2 2024-02-13 16:05:35 +01:00
Matthijs Velsink
b0ce59a02c po: Remove POTFILES.in entry after GOA changes
Commit 08c51127 (!2039) removed gnome-control-center-goa-helper.c, but
forgot to remove the POTFILES.in entry.

This fixes that.

Fixes #2893
2024-02-13 13:09:10 +00:00
Matthijs Velsink
3ca34ff2dd po: Fix POTFILES.in for the "Remote Login" move
Commit c0c357c3 (!2211) moved the "Remote Login" code to the System
Panel, but did not change the POTFILES.in entries.

This fixes that.
2024-02-13 13:09:10 +00:00
Matthijs Velsink
959f8afde8 sharing: Clean leftover "Remote Login" code
Commit c0c357c3 (!2211) moved the "Remote Login" code to the System
panel. There are some leftover bits of code in the sharing panel though.

This cleans that up.

Closes #2895
2024-02-13 13:06:38 +00:00
Emin Tufan Çetin
7aa057ac27 Update Turkish translation 2024-02-13 12:58:03 +00:00
Felipe Borges
1313831488 46.beta.1 2024-02-12 20:06:56 +01:00
Andy Holmes
0e7a9d91e0 online-accounts: use subtitles for ambiguous providers
Add better titles for providers with names like "IMAP and SMTP",
retaining the GOA-provided string as the row subtitle.
2024-02-12 19:04:00 +01:00
Andy Holmes
3d2e3400b0 online-accounts: sort providers statically
Sorting providers and accounts by features flags makes it difficult to
thme how we like, so hard-code the sorting order based on the
non-localized provider name.
2024-02-12 19:04:00 +01:00
Andy Holmes
6405c255aa online-accounts: avoid a NULL-pointer dereference 2024-02-12 17:58:35 +00:00
Andy Holmes
3dabda4a3d ci: build gnome-online-accounts from git
Due the unstable GOA API, namely the recent port to GTK4, GOA
needs to be built from current `master` to build and run.
2024-02-12 17:58:35 +00:00
Andy Holmes
80fcc8c2f2 online-accounts: port to new API
Port to the new GOA API, with simple async functions.
2024-02-12 17:58:35 +00:00
Andy Holmes
08c51127ac online-accounts: remove goa-helper
Remove the GOA subprocess helper and use GoaClient directly.

The GoaClient is loaded asynchronously, with the panel being marked
insensitive until ready. Any `CcPanel::parameters` passed while loading
are deferred until the client is ready.
2024-02-12 17:58:35 +00:00
Ekaterine Papava
9f5580832f Update Georgian translation 2024-02-12 17:28:17 +00:00
Danial Behzadi
767928d595 Update Persian translation 2024-02-12 16:37:41 +00:00
Felipe Borges
178c7522f6 Post-release version bump 2024-02-12 14:37:34 +01:00
14 changed files with 5329 additions and 5372 deletions

View File

@@ -52,7 +52,7 @@ stages:
# stable branch.
# Could probably also switch away from rawhide,
# to stable fedora branch as well.
FDO_DISTRIBUTION_TAG: '2024-01-31.0-main'
FDO_DISTRIBUTION_TAG: '2024-02-08.0-main'
FDO_DISTRIBUTION_VERSION: rawhide
#############################################
@@ -92,7 +92,6 @@ build.container.fedora@x86_64:
gobject-introspection-devel
gnome-bluetooth-libs-devel
gnome-desktop3-devel
gnome-online-accounts-devel
grilo-devel
gsettings-desktop-schemas-devel
gsound-devel
@@ -178,6 +177,12 @@ build.container.fedora@x86_64:
ninja -C _build && \
ninja -C _build install && \
cd .. && \
git clone https://gitlab.gnome.org/GNOME/gnome-online-accounts.git && \
cd gnome-online-accounts && \
meson . _build --prefix=/usr -Dfedora=true && \
ninja -C _build && \
ninja -C _build install && \
cd .. && \
dnf remove -y systemtap-runtime
##

14
NEWS
View File

@@ -1,3 +1,17 @@
=================
Version 46.beta.1
=================
Exceptional release to fix translations
https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2893
=================
Version 46.beta.1
=================
Exceptional release to include gnome-online-accounts changes
(Freeze break exception https://gitlab.gnome.org/Teams/Releng/freeze-breaks/-/issues/164)
===============
Version 46.beta
===============

View File

@@ -1,6 +1,6 @@
project(
'gnome-control-center', 'c',
version : '46.beta',
version : '46.beta.2',
license : 'GPL2+',
meson_version : '>= 0.58.0'
)
@@ -126,7 +126,7 @@ libgvc = subproject(
)
libgvc_dep = libgvc.get_variable('libgvc_dep')
goa_req_version = '>= 3.25.3'
goa_req_version = '>= 3.49.1'
pulse_req_version = '>= 2.0'
gtk_dep = dependency(

View File

@@ -19,6 +19,10 @@
#include <config.h>
#include <glib/gi18n.h>
#define GOA_API_IS_SUBJECT_TO_CHANGE
#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE
#include <goabackend/goabackend.h>
#include "cc-online-account-provider-row.h"
#include "cc-online-accounts-resources.h"
@@ -28,11 +32,47 @@ struct _CcOnlineAccountProviderRow
GtkImage *icon_image;
GVariant *provider;
GoaProvider *provider;
};
G_DEFINE_TYPE (CcOnlineAccountProviderRow, cc_online_account_provider_row, ADW_TYPE_ACTION_ROW)
static const char *
_goa_provider_get_provider_title (GoaProvider *provider)
{
const char *provider_type = NULL;
g_assert (GOA_IS_PROVIDER (provider));
/* The order here is the same used to sort accounts and providers in the UI,
* The title, if present, should bump the provider name to subtitle.
*/
struct
{
const char *provider;
const char *title;
} goa_metadata[] = {
{"imap_smtp", N_("Email")}, /* IMAP and SMTP */
{"webdav", N_("Calendars, Contacts, Files")}, /* WebDAV */
{"owncloud", NULL}, /* Nextcloud */
{"google", NULL}, /* Google */
{"ms_graph", NULL}, /* Microsoft 365 */
{"exchange", NULL}, /* Microsoft Exchange */
{"windows_live", NULL}, /* Microsoft Personal */
{"kerberos", N_("Enterprise Login")}, /* Enterprise Login (Kerberos) */
{"fedora", NULL}, /* Fedora */
};
provider_type = goa_provider_get_provider_type (provider);
for (size_t i = 0; i < G_N_ELEMENTS (goa_metadata); i++)
{
if (g_str_equal (goa_metadata[i].provider, provider_type))
return goa_metadata[i].title;
}
return NULL;
}
static gboolean
is_gicon_symbolic (GtkWidget *widget,
GIcon *icon)
@@ -56,7 +96,7 @@ cc_online_account_provider_row_dispose (GObject *object)
{
CcOnlineAccountProviderRow *self = CC_ONLINE_ACCOUNT_PROVIDER_ROW (object);
g_clear_pointer (&self->provider, g_variant_unref);
g_clear_object (&self->provider);
G_OBJECT_CLASS (cc_online_account_provider_row_parent_class)->dispose (object);
}
@@ -81,11 +121,12 @@ cc_online_account_provider_row_init (CcOnlineAccountProviderRow *self)
}
CcOnlineAccountProviderRow *
cc_online_account_provider_row_new (GVariant *provider)
cc_online_account_provider_row_new (GoaProvider *provider)
{
CcOnlineAccountProviderRow *self;
g_autoptr(GIcon) icon = NULL;
g_autofree gchar *name = NULL;
const char *title = NULL;
self = g_object_new (cc_online_account_provider_row_get_type (), NULL);
@@ -96,18 +137,10 @@ cc_online_account_provider_row_new (GVariant *provider)
}
else
{
g_autoptr(GVariant) icon_variant = NULL;
self->provider = g_variant_ref (provider);
g_variant_get (provider, "(ssviu)",
NULL,
&name,
&icon_variant,
NULL,
NULL);
icon = g_icon_deserialize (icon_variant);
self->provider = g_object_ref (provider);
icon = goa_provider_get_provider_icon (provider, NULL);
name = goa_provider_get_provider_name (provider, NULL);
title = _goa_provider_get_provider_title (provider);
}
gtk_image_set_from_gicon (self->icon_image, icon);
@@ -122,12 +155,20 @@ cc_online_account_provider_row_new (GVariant *provider)
gtk_widget_add_css_class (GTK_WIDGET (self->icon_image), "lowres-icon");
}
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self), name);
if (title != NULL)
{
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self), title);
adw_action_row_set_subtitle (ADW_ACTION_ROW (self), name);
}
else
{
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self), name);
}
return self;
}
GVariant *
GoaProvider *
cc_online_account_provider_row_get_provider (CcOnlineAccountProviderRow *self)
{
g_return_val_if_fail (CC_IS_ONLINE_ACCOUNT_PROVIDER_ROW (self), NULL);

View File

@@ -21,12 +21,16 @@
#include <gtk/gtk.h>
#include <adwaita.h>
#define GOA_API_IS_SUBJECT_TO_CHANGE
#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE
#include <goabackend/goabackend.h>
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CcOnlineAccountProviderRow, cc_online_account_provider_row, CC, ONLINE_ACCOUNT_PROVIDER_ROW, AdwActionRow)
CcOnlineAccountProviderRow *cc_online_account_provider_row_new (GVariant *provider);
CcOnlineAccountProviderRow *cc_online_account_provider_row_new (GoaProvider *provider);
GVariant *cc_online_account_provider_row_get_provider (CcOnlineAccountProviderRow *row);
GoaProvider *cc_online_account_provider_row_get_provider (CcOnlineAccountProviderRow *row);
G_END_DECLS

View File

@@ -32,12 +32,9 @@
#include "cc-online-account-row.h"
#include "cc-online-accounts-resources.h"
#ifdef GDK_WINDOWING_X11
#include <gdk/x11/gdkx.h>
#endif
#ifdef GDK_WINDOWING_WAYLAND
#include <gdk/wayland/gdkwayland.h>
#endif
#define GOA_API_IS_SUBJECT_TO_CHANGE
#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE
#include <goabackend/goabackend.h>
struct _CcOnlineAccountsPanel
{
@@ -45,27 +42,13 @@ struct _CcOnlineAccountsPanel
GtkFrame *accounts_frame;
GtkListBox *accounts_listbox;
GtkWidget *close_notification_button;
GtkDialog *edit_account_dialog;
GtkHeaderBar *edit_account_headerbar;
GtkBox *editor_box;
GtkLabel *notification_label;
GtkRevealer *notification_revealer;
AdwBanner *offline_banner;
GtkListBox *providers_listbox;
GtkButton *remove_account_button;
GtkBox *accounts_vbox;
GoaClient *client;
GoaObject *active_object;
GoaObject *removed_object;
guint remove_account_timeout_id;
gchar *window_export_handle;
GVariant *parameters;
};
static gboolean remove_account_timeout_cb (gpointer user_data);
CC_PANEL_REGISTER (CcOnlineAccountsPanel, cc_online_accounts_panel);
enum {
@@ -77,15 +60,6 @@ enum {
typedef void (*RowForAccountCallback) (CcOnlineAccountsPanel *self, GtkWidget *row, GList *other_rows);
static void
hide_row_for_account_cb (CcOnlineAccountsPanel *self,
GtkWidget *row,
GList *other_rows)
{
gtk_widget_set_visible (row, FALSE);
gtk_widget_set_visible (GTK_WIDGET (self->accounts_frame), other_rows != NULL);
}
static void
remove_row_for_account_cb (CcOnlineAccountsPanel *self,
GtkWidget *row,
@@ -95,15 +69,6 @@ remove_row_for_account_cb (CcOnlineAccountsPanel *self,
gtk_widget_set_visible (GTK_WIDGET (self->accounts_frame), other_rows != NULL);
}
static void
show_row_for_account_cb (CcOnlineAccountsPanel *self,
GtkWidget *row,
GList *other_rows)
{
gtk_widget_set_visible (row, TRUE);
gtk_widget_set_visible (GTK_WIDGET (self->accounts_frame), TRUE);
}
static void
modify_row_for_account (CcOnlineAccountsPanel *self,
GoaObject *object,
@@ -141,365 +106,84 @@ modify_row_for_account (CcOnlineAccountsPanel *self,
g_list_free (children);
}
/* Auxiliary methods */
G_GNUC_NULL_TERMINATED
static char *
run_goa_helper_sync (const char *command,
...)
static void
show_account_cb (GoaProvider *provider,
GAsyncResult *result,
CcOnlineAccountsPanel *self)
{
g_autoptr(GPtrArray) argv = NULL;
g_autofree char *output = NULL;
g_autoptr(GError) error = NULL;
const char *param;
va_list args;
int status;
g_autoptr (GError) error = NULL;
argv = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (argv, g_strdup (LIBEXECDIR "/gnome-control-center-goa-helper"));
g_ptr_array_add (argv, g_strdup (command));
va_start (args, command);
while ((param = va_arg (args, const char*)) != NULL)
g_ptr_array_add (argv, g_strdup (param));
va_end (args);
g_ptr_array_add (argv, NULL);
if (!g_spawn_sync (NULL,
(char **) argv->pdata,
NULL,
0,
NULL,
NULL,
&output,
NULL,
&status,
&error))
if (!goa_provider_show_account_finish (provider, result, &error))
{
g_warning ("Failed to run online accounts helper: %s", error->message);
return NULL;
if (!g_error_matches (error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
g_warning ("Error showing account: %s", error->message);
}
if (!g_spawn_check_wait_status (status, NULL))
return NULL;
if (output == NULL || *output == '\0')
return NULL;
return g_steal_pointer (&output);
}
static void
run_goa_helper_in_thread_func (GTask *task,
gpointer source_object,
gpointer task_data,
GCancellable *cancellable)
{
g_autofree char *output = NULL;
g_autoptr(GError) error = NULL;
GPtrArray *argv = task_data;
int status;
g_spawn_sync (NULL,
(char **) argv->pdata,
NULL, 0, NULL, NULL,
&output,
NULL,
&status,
&error);
if (error)
{
g_task_return_error (task, g_steal_pointer (&error));
return;
}
if (!g_spawn_check_wait_status (status, &error))
{
g_task_return_error (task, g_steal_pointer (&error));
return;
}
g_task_return_pointer (task, g_steal_pointer (&output), g_free);
}
static void
run_goa_helper_async (const gchar *command,
const gchar *param,
const gchar *window_handle,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_autoptr(GPtrArray) argv = NULL;
g_autoptr(GTask) task = NULL;
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
argv = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (argv, g_strdup (LIBEXECDIR "/gnome-control-center-goa-helper"));
g_ptr_array_add (argv, g_strdup (command));
g_ptr_array_add (argv, g_strdup (param));
g_ptr_array_add (argv, g_strdup (window_handle));
g_ptr_array_add (argv, NULL);
task = g_task_new (NULL, cancellable, callback, user_data);
g_task_set_source_tag (task, run_goa_helper_async);
g_task_set_task_data (task, g_steal_pointer (&argv), (GDestroyNotify) g_ptr_array_unref);
g_task_run_in_thread (task, run_goa_helper_in_thread_func);
}
static void
cancel_notification_timeout (CcOnlineAccountsPanel *self)
{
g_clear_handle_id (&self->remove_account_timeout_id, g_source_remove);
self->removed_object = NULL;
}
static void
start_remove_account_timeout (CcOnlineAccountsPanel *self)
{
GoaAccount *account;
g_autofree gchar *id = NULL;
g_autofree gchar *label = NULL;
if (self->active_object == NULL)
return;
if (self->removed_object != NULL)
gtk_widget_activate (self->close_notification_button);
self->removed_object = g_steal_pointer (&self->active_object);
account = goa_object_peek_account (self->removed_object);
id = g_strdup_printf ("<b>%s</b>", goa_account_get_presentation_identity (account));
/* Translators: The %s is the username (eg., debarshi.ray@gmail.com
* or rishi).
*/
label = g_strdup_printf (_("%s removed"), id);
gtk_label_set_markup (self->notification_label, label);
gtk_revealer_set_reveal_child (self->notification_revealer, TRUE);
modify_row_for_account (self, self->removed_object, hide_row_for_account_cb);
self->remove_account_timeout_id = g_timeout_add_seconds (10, remove_account_timeout_cb, self);
}
static void
on_show_account_finish_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
g_autofree char *output = NULL;
g_autoptr(GError) error = NULL;
output = g_task_propagate_pointer (G_TASK (result), &error);
if (error)
{
g_warning ("Error showing account: %s", error->message);
return;
}
if (g_strcmp0 (output, "remove") == 0)
start_remove_account_timeout (self);
self->active_object = NULL;
}
static void
show_account (CcOnlineAccountsPanel *self,
GoaObject *object)
{
g_autoptr (GoaProvider) provider = NULL;
GtkRoot *root;
GoaAccount *account;
const char *provider_type;
if (!self->window_export_handle)
return;
self->active_object = g_object_ref (object);
/* Find the provider with a matching type */
account = goa_object_peek_account (object);
run_goa_helper_async ("show-account",
goa_account_get_id (account),
self->window_export_handle,
cc_panel_get_cancellable (CC_PANEL (self)),
on_show_account_finish_cb,
self);
}
static void
on_create_account_finish_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
g_autofree char *new_account_id = NULL;
g_autoptr(GoaObject) object = NULL;
g_autoptr(GError) error = NULL;
new_account_id = g_task_propagate_pointer (G_TASK (result), &error);
if (error)
provider_type = goa_account_get_provider_type (account);
provider = goa_provider_get_for_provider_type (provider_type);
if (provider == NULL)
{
g_warning ("Error showing account: %s", error->message);
g_warning ("Error showing account: Unsupported provider");
return;
}
if (new_account_id)
object = goa_client_lookup_by_id (self->client, new_account_id);
root = gtk_widget_get_root (GTK_WIDGET (self));
goa_provider_show_account (provider,
self->client,
object,
GTK_WINDOW (root),
cc_panel_get_cancellable (CC_PANEL (self)),
(GAsyncReadyCallback) show_account_cb,
self);
}
if (object)
show_account (self, object);
static void
create_account_cb (GoaProvider *provider,
GAsyncResult *result,
CcOnlineAccountsPanel *self)
{
g_autoptr (GoaObject) object = NULL;
g_autoptr (GError) error = NULL;
object = goa_provider_add_account_finish (provider, result, &error);
if (error != NULL)
{
if (!g_error_matches (error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
g_warning ("Error creating account: %s", error->message);
return;
}
show_account (self, object);
}
static void
create_account (CcOnlineAccountsPanel *self,
GVariant *provider)
GoaProvider *provider)
{
g_autofree char *provider_type = NULL;
GtkRoot *parent;
if (!self->window_export_handle)
return;
g_return_if_fail (GOA_IS_PROVIDER (provider));
g_variant_get (provider, "(ssviu)", &provider_type, NULL, NULL, NULL, NULL);
run_goa_helper_async ("create-account",
provider_type,
self->window_export_handle,
cc_panel_get_cancellable (CC_PANEL (self)),
on_create_account_finish_cb,
self);
}
static void
add_provider_row (CcOnlineAccountsPanel *self,
GVariant *provider)
{
CcOnlineAccountProviderRow *row;
row = cc_online_account_provider_row_new (provider);
gtk_list_box_append (self->providers_listbox, GTK_WIDGET (row));
}
static void
list_providers (CcOnlineAccountsPanel *self)
{
g_autoptr(GVariant) providers_variant = NULL;
g_autoptr(GError) error = NULL;
g_autofree char *providers = NULL;
GVariantIter iter;
GVariant *provider;
providers = run_goa_helper_sync ("list-providers", NULL);
if (!providers)
return;
providers_variant = g_variant_parse (G_VARIANT_TYPE ("a(ssviu)"),
providers,
NULL,
NULL,
&error);
if (error)
{
g_warning ("Error listing providers: %s", error->message);
return;
}
g_variant_iter_init (&iter, providers_variant);
while ((provider = g_variant_iter_next_value (&iter)))
{
add_provider_row (self, provider);
g_variant_unref (provider);
}
}
static void
add_account (CcOnlineAccountsPanel *self,
GoaObject *object)
{
CcOnlineAccountRow *row;
row = cc_online_account_row_new (object);
/* Add to the listbox */
gtk_list_box_append (self->accounts_listbox, GTK_WIDGET (row));
gtk_widget_set_visible (GTK_WIDGET (self->accounts_frame), TRUE);
}
static void
fill_accounts_listbox (CcOnlineAccountsPanel *self)
{
g_autolist(GoaAccount) accounts = NULL;
GList *l;
accounts = goa_client_get_accounts (self->client);
for (l = accounts; l != NULL; l = l->next)
add_account (self, l->data);
}
#ifdef GDK_WINDOWING_WAYLAND
static void
wayland_window_exported_cb (GdkToplevel *toplevel,
const char *handle,
gpointer data)
{
CcOnlineAccountsPanel *self = data;
self->window_export_handle = g_strdup_printf ("wayland:%s", handle);
}
#endif
static void
export_window_handle (CcOnlineAccountsPanel *self)
{
GtkNative *native = gtk_widget_get_native (GTK_WIDGET (self));
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (native))))
{
GdkSurface *surface = gtk_native_get_surface (native);
guint32 xid = (guint32) gdk_x11_surface_get_xid (surface);
self->window_export_handle = g_strdup_printf ("x11:%x", xid);
}
#endif
#ifdef GDK_WINDOWING_WAYLAND
if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (native))))
{
GdkSurface *surface = gtk_native_get_surface (native);
gdk_wayland_toplevel_export_handle (GDK_TOPLEVEL (surface),
wayland_window_exported_cb,
self,
NULL);
}
#endif
}
static void
unexport_window_handle (CcOnlineAccountsPanel *self)
{
if (!self->window_export_handle)
return;
#ifdef GDK_WINDOWING_WAYLAND
GtkNative *native = gtk_widget_get_native (GTK_WIDGET (self));
if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (native))))
{
GdkSurface *surface = gtk_native_get_surface (native);
gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (surface));
}
#endif
g_clear_pointer (&self->window_export_handle, g_free);
parent = gtk_widget_get_root (GTK_WIDGET (self));
goa_provider_add_account (provider,
self->client,
GTK_WINDOW (parent),
cc_panel_get_cancellable (CC_PANEL (self)),
(GAsyncReadyCallback) create_account_cb,
self);
}
static void
@@ -531,7 +215,7 @@ command_add (CcOnlineAccountsPanel *self,
GVariant *parameters)
{
const gchar *provider_name = NULL;
g_autoptr(GVariant) v = NULL;
g_autoptr (GVariant) v = NULL;
g_assert (self != NULL);
g_assert (parameters != NULL);
@@ -555,16 +239,16 @@ command_add (CcOnlineAccountsPanel *self,
if (provider_name != NULL)
{
GtkWidget *child;
GVariant *provider;
GoaProvider *provider;
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->providers_listbox));
child;
child = gtk_widget_get_next_sibling (child))
{
g_autofree gchar *provider_type = NULL;
const char *provider_type = NULL;
provider = cc_online_account_provider_row_get_provider (CC_ONLINE_ACCOUNT_PROVIDER_ROW (child));
g_variant_get (provider, "(ssviu)", &provider_type, NULL, NULL, NULL, NULL);
provider_type = goa_provider_get_provider_type (provider);
if (g_strcmp0 (provider_type, provider_name) == 0)
break;
@@ -583,7 +267,7 @@ command_add (CcOnlineAccountsPanel *self,
static void
load_custom_css (void)
{
g_autoptr(GtkCssProvider) provider = NULL;
g_autoptr (GtkCssProvider) provider = NULL;
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/org/gnome/control-center/online-accounts/online-accounts.css");
@@ -594,55 +278,87 @@ load_custom_css (void)
/* Callbacks */
static gint
static int
goa_provider_priority (const char *provider_type)
{
static const char *goa_priority[] = {
"imap_smtp", /* Email (IMAP and SMTP) */
"webdav", /* Calendars, Contacts, Files (WebDAV) */
"owncloud", /* Nextcloud */
"google", /* Google */
"ms_graph", /* Microsoft 365 */
"exchange", /* Microsoft Exchange */
"windows_live", /* Microsoft Personal */
"kerberos", /* Enterprise Login (Kerberos) */
"fedora", /* Fedora */
};
for (size_t i = 0; i < G_N_ELEMENTS (goa_priority); i++)
{
if (g_str_equal (goa_priority[i], provider_type))
return i;
}
/* New or unknown providers are sorted last */
return G_N_ELEMENTS (goa_priority) + 1;
}
static int
sort_accounts_func (GtkListBoxRow *a,
GtkListBoxRow *b,
gpointer user_data)
gpointer user_data)
{
GoaAccount *a_account, *b_account;
GoaObject *a_object, *b_object;
const char *a_name, *b_name;
a_object = cc_online_account_row_get_object (CC_ONLINE_ACCOUNT_ROW (a));
a_account = goa_object_peek_account (a_object);
a_name = goa_account_get_provider_type (a_account);
b_object = cc_online_account_row_get_object (CC_ONLINE_ACCOUNT_ROW (b));
b_account = goa_object_peek_account (b_object);
b_name = goa_account_get_provider_type (b_account);
return g_strcmp0 (goa_account_get_id (a_account), goa_account_get_id (b_account));
return goa_provider_priority (a_name) - goa_provider_priority (b_name);
}
static gint
static int
sort_providers_func (GtkListBoxRow *a,
GtkListBoxRow *b,
gpointer user_data)
gpointer user_data)
{
GVariant *a_provider, *b_provider;
gboolean a_branded, b_branded;
gint a_features, b_features;
GoaProvider *a_provider, *b_provider;
const char *a_name, *b_name;
a_provider = cc_online_account_provider_row_get_provider (CC_ONLINE_ACCOUNT_PROVIDER_ROW (a));
a_name = goa_provider_get_provider_type (a_provider);
b_provider = cc_online_account_provider_row_get_provider (CC_ONLINE_ACCOUNT_PROVIDER_ROW (b));
b_name = goa_provider_get_provider_type (b_provider);
g_variant_get (a_provider, "(ssviu)", NULL, NULL, NULL, &a_features, NULL);
g_variant_get (b_provider, "(ssviu)", NULL, NULL, NULL, &b_features, NULL);
return goa_provider_priority (a_name) - goa_provider_priority (b_name);
}
/* FIXME: this needs to go away once libgoa-backend is ported to GTK4 */
#define FEATURE_BRANDED (1 << 1)
static void
add_account (CcOnlineAccountsPanel *self,
GoaObject *object)
{
CcOnlineAccountRow *row;
a_branded = (a_features & FEATURE_BRANDED) != 0;
b_branded = (a_features & FEATURE_BRANDED) != 0;
row = cc_online_account_row_new (object);
gtk_list_box_append (self->accounts_listbox, GTK_WIDGET (row));
gtk_widget_set_visible (GTK_WIDGET (self->accounts_frame), TRUE);
}
#undef FEATURE_BRANDED
static void
add_provider (CcOnlineAccountsPanel *self,
GoaProvider *provider)
{
CcOnlineAccountProviderRow *row;
if (a_branded != b_branded)
{
if (a_branded)
return -1;
else
return 1;
}
return gtk_list_box_row_get_index (b) - gtk_list_box_row_get_index (a);
row = cc_online_account_provider_row_new (provider);
gtk_list_box_append (self->providers_listbox, GTK_WIDGET (row));
}
static void
@@ -652,14 +368,6 @@ on_account_added_cb (CcOnlineAccountsPanel *self,
add_account (self, object);
}
static void
on_account_changed_cb (CcOnlineAccountsPanel *self,
GoaObject *object)
{
if (self->active_object == object)
show_account (self, self->active_object);
}
static void
on_account_removed_cb (CcOnlineAccountsPanel *self,
GoaObject *object)
@@ -676,76 +384,85 @@ on_accounts_listbox_row_activated (CcOnlineAccountsPanel *self,
show_account (self, object);
}
static void
on_client_remove_account_finish_cb (GoaAccount *account,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr(CcOnlineAccountsPanel) self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
g_autoptr(GError) error = NULL;
goa_account_call_remove_finish (account, res, &error);
if (error)
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)))),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
_("Error removing account"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s",
error->message);
gtk_window_present (GTK_WINDOW (dialog));
}
}
static void
on_notification_closed_cb (CcOnlineAccountsPanel *self)
{
if (self->removed_object != NULL)
{
goa_account_call_remove (goa_object_peek_account (self->removed_object),
cc_panel_get_cancellable (CC_PANEL (self)),
(GAsyncReadyCallback) on_client_remove_account_finish_cb,
g_object_ref (self));
}
gtk_revealer_set_reveal_child (self->notification_revealer, FALSE);
cancel_notification_timeout (self);
self->removed_object = NULL;
}
static void
on_undo_button_clicked_cb (CcOnlineAccountsPanel *self)
{
/* Simply show the account row and hide the notification */
modify_row_for_account (self, self->removed_object, show_row_for_account_cb);
gtk_revealer_set_reveal_child (self->notification_revealer, FALSE);
cancel_notification_timeout (self);
self->removed_object = NULL;
}
static void
on_provider_row_activated_cb (CcOnlineAccountsPanel *self,
GtkListBoxRow *activated_row)
GtkListBoxRow *activated_row)
{
GVariant *provider = cc_online_account_provider_row_get_provider (CC_ONLINE_ACCOUNT_PROVIDER_ROW (activated_row));
GoaProvider *provider = cc_online_account_provider_row_get_provider (CC_ONLINE_ACCOUNT_PROVIDER_ROW (activated_row));
create_account (self, provider);
}
static gboolean
remove_account_timeout_cb (gpointer user_data)
static void
goa_provider_get_all_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
g_autoptr (CcOnlineAccountsPanel) self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
g_autolist (GoaProvider) providers = NULL;
g_autolist (GoaAccount) accounts = NULL;
g_autoptr (GError) error = NULL;
gtk_widget_activate (self->close_notification_button);
/* goa_provider_get_all() doesn't have a cancellable argument, so check if
* the panel cancellable was triggered.
*/
if (g_cancellable_is_cancelled (cc_panel_get_cancellable (CC_PANEL (self))))
return;
return G_SOURCE_REMOVE;
if (!goa_provider_get_all_finish (&providers, res, &error))
{
g_warning ("Error listing providers: %s", error->message);
return;
}
for (const GList *iter = providers; iter != NULL; iter = iter->next)
add_provider (self, GOA_PROVIDER (iter->data));
/* Load existing accounts */
accounts = goa_client_get_accounts (self->client);
for (const GList *iter = accounts; iter != NULL; iter = iter->next)
add_account (self, GOA_OBJECT (iter->data));
g_signal_connect_swapped (self->client,
"account-added",
G_CALLBACK (on_account_added_cb),
self);
g_signal_connect_swapped (self->client,
"account-removed",
G_CALLBACK (on_account_removed_cb),
self);
/* With the client ready, check if we have a pending command */
gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE);
if (self->parameters != NULL)
{
g_autoptr (GVariant) parameters = NULL;
parameters = g_steal_pointer (&self->parameters);
g_object_set (self, "parameters", parameters, NULL);
}
}
static void
goa_client_new_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
g_autoptr (CcOnlineAccountsPanel) self = CC_ONLINE_ACCOUNTS_PANEL (user_data);
g_autoptr (GError) error = NULL;
self->client = goa_client_new_finish (res, &error);
if (self->client == NULL)
{
g_warning ("Error connect to service: %s", error->message);
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
return;
}
goa_provider_get_all (goa_provider_get_all_cb, g_object_ref (self));
}
/* CcPanel overrides */
@@ -756,24 +473,6 @@ cc_online_accounts_panel_get_help_uri (CcPanel *panel)
return "help:gnome-help/accounts";
}
/* GtkWidget overrides */
static void
cc_online_accounts_panel_realize (GtkWidget *widget)
{
GTK_WIDGET_CLASS (cc_online_accounts_panel_parent_class)->realize (widget);
export_window_handle (CC_ONLINE_ACCOUNTS_PANEL (widget));
}
static void
cc_online_accounts_panel_unrealize (GtkWidget *widget)
{
unexport_window_handle (CC_ONLINE_ACCOUNTS_PANEL (widget));
GTK_WIDGET_CLASS (cc_online_accounts_panel_parent_class)->unrealize (widget);
}
/* GObject overrides */
static void
@@ -782,12 +481,14 @@ cc_online_accounts_panel_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (object);
switch (property_id)
{
case PROP_PARAMETERS:
{
GVariant *parameters;
g_autoptr(GVariant) v = NULL;
g_autoptr (GVariant) v = NULL;
const gchar *first_arg = NULL;
parameters = g_value_get_variant (value);
@@ -804,10 +505,20 @@ cc_online_accounts_panel_set_property (GObject *object,
(gchar *)g_variant_get_type (v));
}
if (g_strcmp0 (first_arg, "add") == 0)
command_add (CC_ONLINE_ACCOUNTS_PANEL (object), parameters);
/* Waiting for the client to load */
if (self->client == NULL)
{
g_clear_pointer (&self->parameters, g_variant_unref);
self->parameters = g_value_dup_variant (value);
}
else if (g_strcmp0 (first_arg, "add") == 0)
{
command_add (CC_ONLINE_ACCOUNTS_PANEL (object), parameters);
}
else if (first_arg != NULL)
select_account_by_id (CC_ONLINE_ACCOUNTS_PANEL (object), first_arg);
{
select_account_by_id (CC_ONLINE_ACCOUNTS_PANEL (object), first_arg);
}
return;
}
@@ -816,38 +527,13 @@ cc_online_accounts_panel_set_property (GObject *object,
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
cc_online_accounts_panel_constructed (GObject *object)
{
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (object);
G_OBJECT_CLASS (cc_online_accounts_panel_parent_class)->constructed (object);
list_providers (self);
}
static void
cc_online_accounts_panel_finalize (GObject *object)
{
CcOnlineAccountsPanel *self = CC_ONLINE_ACCOUNTS_PANEL (object);
if (self->removed_object != NULL)
{
g_autoptr(GError) error = NULL;
goa_account_call_remove_sync (goa_object_peek_account (self->removed_object),
NULL, /* GCancellable */
&error);
if (error != NULL)
{
g_warning ("Error removing account: %s (%s, %d)",
error->message,
g_quark_to_string (error->domain),
error->code);
}
}
g_clear_object (&self->client);
g_clear_pointer (&self->parameters, g_variant_unref);
G_OBJECT_CLASS (cc_online_accounts_panel_parent_class)->finalize (object);
}
@@ -863,10 +549,6 @@ cc_online_accounts_panel_class_init (CcOnlineAccountsPanelClass *klass)
object_class->set_property = cc_online_accounts_panel_set_property;
object_class->finalize = cc_online_accounts_panel_finalize;
object_class->constructed = cc_online_accounts_panel_constructed;
widget_class->realize = cc_online_accounts_panel_realize;
widget_class->unrealize = cc_online_accounts_panel_unrealize;
g_object_class_override_property (object_class, PROP_PARAMETERS, "parameters");
@@ -874,22 +556,16 @@ cc_online_accounts_panel_class_init (CcOnlineAccountsPanelClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, accounts_frame);
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, accounts_listbox);
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, close_notification_button);
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, notification_label);
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, notification_revealer);
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, offline_banner);
gtk_widget_class_bind_template_child (widget_class, CcOnlineAccountsPanel, providers_listbox);
gtk_widget_class_bind_template_callback (widget_class, on_accounts_listbox_row_activated);
gtk_widget_class_bind_template_callback (widget_class, on_notification_closed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_provider_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_undo_button_clicked_cb);
}
static void
cc_online_accounts_panel_init (CcOnlineAccountsPanel *self)
{
g_autoptr(GError) error = NULL;
GNetworkMonitor *monitor;
g_resources_register (cc_online_accounts_get_resource ());
@@ -919,31 +595,11 @@ cc_online_accounts_panel_init (CcOnlineAccountsPanel *self)
"sensitive",
G_BINDING_SYNC_CREATE);
/* TODO: probably want to avoid _sync() ... */
self->client = goa_client_new_sync (cc_panel_get_cancellable (CC_PANEL (self)), &error);
if (self->client == NULL)
{
g_warning ("Error getting a GoaClient: %s (%s, %d)",
error->message, g_quark_to_string (error->domain), error->code);
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
return;
}
g_signal_connect_swapped (self->client,
"account-added",
G_CALLBACK (on_account_added_cb),
self);
g_signal_connect_swapped (self->client,
"account-changed",
G_CALLBACK (on_account_changed_cb),
self);
g_signal_connect_swapped (self->client,
"account-removed",
G_CALLBACK (on_account_removed_cb),
self);
fill_accounts_listbox (self);
load_custom_css ();
/* Disable the panel while we wait for the client */
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
goa_client_new (cc_panel_get_cancellable (CC_PANEL (self)),
goa_client_new_cb,
g_object_ref (self));
}

View File

@@ -8,96 +8,49 @@
</child>
<property name="content">
<object class="GtkOverlay">
<child type="overlay">
<object class="GtkRevealer" id="notification_revealer">
<property name="halign">center</property>
<property name="valign">start</property>
<property name="transition_type">slide-down</property>
<child>
<object class="GtkFrame">
<child>
<object class="GtkBox">
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="notification_label">
<property name="use_markup">True</property>
</object>
</child>
<child>
<object class="GtkButton" id="undo_button">
<property name="label" translatable="yes">Undo</property>
<signal name="clicked" handler="on_undo_button_clicked_cb" object="CcOnlineAccountsPanel" swapped="yes" />
</object>
</child>
<child>
<object class="GtkButton" id="close_notification_button">
<property name="icon-name">window-close-symbolic</property>
<accessibility>
<property name="label" translatable="yes">Close the notification</property>
</accessibility>
<signal name="clicked" handler="on_notification_closed_cb" object="CcOnlineAccountsPanel" swapped="yes" />
<style>
<class name="flat" />
</style>
</object>
</child>
</object>
</child>
<style>
<class name="app-notification" />
</style>
</object>
</child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="AdwBanner" id="offline_banner">
<property name="title" translatable="yes">Offline — unable to connect accounts</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<object class="AdwPreferencesPage">
<property name="description" translatable="yes">Allow apps to access online services by connecting your cloud accounts</property>
<child>
<object class="AdwBanner" id="offline_banner">
<property name="title" translatable="yes">Offline — unable to connect accounts</property>
<object class="AdwPreferencesGroup" id="accounts_frame">
<property name="title" translatable="yes">Your Accounts</property>
<property name="visible">False</property>
<child>
<object class="GtkListBox" id="accounts_listbox">
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
<signal name="row-activated" handler="on_accounts_listbox_row_activated" object="CcOnlineAccountsPanel" swapped="yes" />
<style>
<class name="boxed-list" />
</style>
<accessibility>
<relation name="labelled-by">accounts_frame</relation>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesPage">
<property name="description" translatable="yes">Allow apps to access online services by connecting your cloud accounts</property>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Connect an Account</property>
<child>
<object class="AdwPreferencesGroup" id="accounts_frame">
<property name="title" translatable="yes">Your Accounts</property>
<property name="visible">False</property>
<child>
<object class="GtkListBox" id="accounts_listbox">
<property name="hexpand">True</property>
<property name="selection_mode">none</property>
<signal name="row-activated" handler="on_accounts_listbox_row_activated" object="CcOnlineAccountsPanel" swapped="yes" />
<style>
<class name="boxed-list" />
</style>
<accessibility>
<relation name="labelled-by">accounts_frame</relation>
</accessibility>
</object>
</child>
</object>
</child>
<child>
<object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Connect an Account</property>
<child>
<object class="GtkListBox" id="providers_listbox">
<property name="selection_mode">none</property>
<signal name="row-activated" handler="on_provider_row_activated_cb" object="CcOnlineAccountsPanel" swapped="yes" />
<style>
<class name="boxed-list" />
</style>
</object>
</child>
<object class="GtkListBox" id="providers_listbox">
<property name="selection_mode">none</property>
<signal name="row-activated" handler="on_provider_row_activated_cb" object="CcOnlineAccountsPanel" swapped="yes" />
<style>
<class name="boxed-list" />
</style>
</object>
</child>
</object>

View File

@@ -1,511 +0,0 @@
/*
* Copyright (C) 2022 Endless OS Foundation, LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author:
* Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
*/
#include "config.h"
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#define GOA_API_IS_SUBJECT_TO_CHANGE
#define GOA_BACKEND_API_IS_SUBJECT_TO_CHANGE
#include <goabackend/goabackend.h>
#ifdef HAVE_GTK_X11
#include <gdk/gdkx.h>
#endif
#ifdef HAVE_GTK_WAYLAND
#include <gdk/gdkwayland.h>
#endif
static GdkDisplay *
get_wayland_display (void)
{
static GdkDisplay *wayland_display = NULL;
if (wayland_display)
return wayland_display;
gdk_set_allowed_backends ("wayland");
wayland_display = gdk_display_open (NULL);
gdk_set_allowed_backends (NULL);
if (!wayland_display)
g_warning ("Failed to open Wayland display");
return wayland_display;
}
static GdkDisplay *
get_x11_display (void)
{
static GdkDisplay *x11_display = NULL;
if (x11_display)
return x11_display;
gdk_set_allowed_backends ("x11");
x11_display = gdk_display_open (NULL);
gdk_set_allowed_backends (NULL);
if (!x11_display)
g_warning ("Failed to open X11 display");
return x11_display;
}
static void
set_external_parent_from_handle (GtkApplication *application,
GtkWindow *dialog,
const char *handle_str)
{
GdkDisplay *display;
GtkWindow *fake_parent;
GdkScreen *screen;
#ifdef HAVE_GTK_X11
{
const char *x11_prefix = "x11:";
if (g_str_has_prefix (handle_str, x11_prefix))
{
display = get_x11_display ();
if (!display)
{
g_warning ("No X display connection, ignoring X11 parent");
return;
}
}
}
#endif
#ifdef HAVE_GTK_WAYLAND
{
const char *wayland_prefix = "wayland:";
if (g_str_has_prefix (handle_str, wayland_prefix))
{
display = get_wayland_display ();
if (!display)
{
g_warning ("No Wayland display connection, ignoring Wayland parent");
return;
}
}
}
#endif
screen = gdk_display_get_default_screen (gdk_display_get_default ());
fake_parent = g_object_new (GTK_TYPE_APPLICATION_WINDOW,
"application", application,
"type", GTK_WINDOW_TOPLEVEL,
"screen", screen,
NULL);
g_object_ref_sink (fake_parent);
gtk_window_set_transient_for (dialog, GTK_WINDOW (fake_parent));
gtk_window_set_modal (dialog, TRUE);
gtk_widget_realize (GTK_WIDGET (dialog));
#ifdef HAVE_GTK_X11
{
const char *x11_prefix = "x11:";
if (g_str_has_prefix (handle_str, x11_prefix))
{
GdkWindow *foreign_gdk_window;
int xid;
errno = 0;
xid = strtol (handle_str + strlen (x11_prefix), NULL, 16);
if (errno != 0)
{
g_warning ("Failed to reference external X11 window, invalid XID %s", handle_str);
return;
}
foreign_gdk_window = gdk_x11_window_foreign_new_for_display (display, xid);
if (!foreign_gdk_window)
{
g_warning ("Failed to create foreign window for XID %d", xid);
return;
}
gdk_window_set_transient_for (gtk_widget_get_window (GTK_WIDGET (dialog)),
foreign_gdk_window);
}
}
#endif
#ifdef HAVE_GTK_WAYLAND
{
const char *wayland_prefix = "wayland:";
if (g_str_has_prefix (handle_str, wayland_prefix))
{
const char *wayland_handle_str = handle_str + strlen (wayland_prefix);
if (!gdk_wayland_window_set_transient_for_exported (gtk_widget_get_window (GTK_WIDGET (dialog)),
(char *) wayland_handle_str))
{
g_warning ("Failed to set window transient for external parent");
return;
}
}
}
#endif
gtk_window_present (dialog);
}
/* create-account */
static void
on_application_activate_create_account_cb (GtkApplication *application,
char **argv)
{
g_autoptr(GoaProvider) provider = NULL;
g_autoptr(GoaClient) client = NULL;
g_autoptr(GError) error = NULL;
GoaAccount *account;
GtkWidget *content_area;
GtkWidget *dialog;
GoaObject *object;
client = goa_client_new_sync (NULL, &error);
if (error)
{
g_printerr ("Error retrieving online accounts client");
exit (EXIT_FAILURE);
return;
}
/* Find the provider with a matching type */
provider = goa_provider_get_for_provider_type (argv[2]);
if (!provider)
{
g_printerr ("Provider type not supported");
exit (EXIT_FAILURE);
return;
}
dialog = g_object_new (GTK_TYPE_DIALOG,
"use-header-bar", 1,
"default-width", 500,
"default-height", 350,
NULL);
g_signal_connect_swapped (dialog, "response", G_CALLBACK (g_application_quit), application);
set_external_parent_from_handle (application, GTK_WINDOW (dialog), argv[3]);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
object = goa_provider_add_account (provider,
client,
GTK_DIALOG (dialog),
GTK_BOX (content_area),
&error);
if (error)
{
g_printerr ("Failed to create account: %s", error->message);
exit (EXIT_FAILURE);
return;
}
account = goa_object_peek_account (object);
g_print ("%s", goa_account_get_id (account));
}
static int
create_account (int argc,
char **argv)
{
g_autoptr(GtkApplication) application = NULL;
gtk_init (&argc, &argv);
if (argc != 4)
{
g_printerr ("Not enough arguments");
return EXIT_FAILURE;
}
application = gtk_application_new ("org.gnome.Settings.GoaHelper",
G_APPLICATION_FLAGS_NONE);
g_signal_connect (application, "activate", G_CALLBACK (on_application_activate_create_account_cb), argv);
return g_application_run (G_APPLICATION (application), 0, NULL);
}
/* list-providers */
typedef struct {
GMainLoop *mainloop;
GList *providers;
GError *error;
} GetAllProvidersData;
static void
get_all_providers_cb (GObject *source,
GAsyncResult *res,
gpointer user_data)
{
g_autolist(GoaProvider) providers = NULL;
GetAllProvidersData *data;
data = user_data;
goa_provider_get_all_finish (&providers, res, &data->error);
if (data->error)
goto out;
data->providers = g_steal_pointer (&providers);
out:
g_main_loop_quit (data->mainloop);
}
static GList *
get_all_providers (GError **error)
{
GetAllProvidersData data = (GetAllProvidersData) {
.mainloop = g_main_loop_new (NULL, FALSE),
.providers = NULL,
.error = NULL,
};
goa_provider_get_all (get_all_providers_cb, &data);
g_main_loop_run (data.mainloop);
g_main_loop_unref (data.mainloop);
if (data.error)
g_propagate_error (error, data.error);
return data.providers;
}
static int
list_providers (int argc,
char **argv)
{
g_autofree char *serialized_result = NULL;
g_autolist(GoaProvider) providers = NULL;
g_autoptr(GVariant) result = NULL;
g_autoptr(GError) error = NULL;
GVariantBuilder b;
GList *l;
providers = get_all_providers (&error);
if (error)
{
g_printerr ("%s", error->message);
return EXIT_FAILURE;
}
g_variant_builder_init (&b, G_VARIANT_TYPE ("a(ssviu)"));
for (l = providers; l; l = l->next)
{
GoaProvider *provider = l->data;
g_autofree char *name = NULL;
g_autoptr(GVariant) icon_variant = NULL;
g_autoptr(GIcon) icon = NULL;
name = goa_provider_get_provider_name (provider, NULL);
icon = goa_provider_get_provider_icon (provider, NULL);
icon_variant = g_icon_serialize (icon);
g_variant_builder_add (&b, "(ssviu)",
goa_provider_get_provider_type (provider),
name,
icon_variant,
goa_provider_get_provider_features (provider),
goa_provider_get_credentials_generation (provider));
}
result = g_variant_builder_end (&b);
serialized_result = g_variant_print (result, TRUE);
g_print ("%s", serialized_result);
return EXIT_SUCCESS;
}
/* show-account */
static void
on_remove_button_clicked_cb (GApplication *application)
{
g_print ("remove");
g_application_quit (application);
}
static void
on_application_activate_show_account_cb (GtkApplication *application,
char **argv)
{
g_autoptr(GoaProvider) provider = NULL;
g_autoptr(GoaObject) object = NULL;
g_autoptr(GoaClient) client = NULL;
g_autoptr(GError) error = NULL;
g_autofree char *title = NULL;
GoaAccount *account;
GtkWidget *content_area;
GtkWidget *button;
GtkWidget *dialog;
GtkWidget *box;
const char *provider_type;
client = goa_client_new_sync (NULL, &error);
if (error)
{
g_printerr ("Error retrieving online accounts client");
exit (EXIT_FAILURE);
return;
}
object = goa_client_lookup_by_id (client, argv[2]);
if (!object)
{
g_printerr ("Online account does not exist");
exit (EXIT_FAILURE);
return;
}
/* Find the provider with a matching type */
account = goa_object_get_account (object);
provider_type = goa_account_get_provider_type (account);
provider = goa_provider_get_for_provider_type (provider_type);
if (!provider)
{
g_printerr ("Provider type not supported");
exit (EXIT_FAILURE);
return;
}
dialog = g_object_new (GTK_TYPE_DIALOG,
"use-header-bar", 1,
NULL);
/* Keep account alive so that the switches are still bound to it */
g_object_set_data_full (G_OBJECT (dialog), "goa-account", account, g_object_unref);
g_signal_connect_swapped (dialog, "response", G_CALLBACK (g_application_quit), application);
set_external_parent_from_handle (application, GTK_WINDOW (dialog), argv[3]);
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 42);
gtk_widget_set_margin_bottom (box, 24);
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
gtk_container_add (GTK_CONTAINER (content_area), box);
goa_provider_show_account (provider,
client,
object,
GTK_BOX (box),
NULL,
NULL);
/*
* The above call doesn't set any widgets to visible, so we have to do that.
* https://gitlab.gnome.org/GNOME/gnome-online-accounts/issues/56
*/
gtk_widget_show_all (box);
/* translators: This is the title of the "Show Account" dialog. The
* %s is the name of the provider. e.g., 'Google'. */
title = g_strdup_printf (_("%s Account"), goa_account_get_provider_name (account));
gtk_window_set_title (GTK_WINDOW (dialog), title);
button = gtk_button_new_with_label (_("Remove Account"));
gtk_widget_set_margin_start (box, 24);
gtk_widget_set_margin_end (box, 24);
gtk_widget_set_halign (button, GTK_ALIGN_END);
gtk_widget_set_valign (button, GTK_ALIGN_END);
gtk_widget_set_visible (button, !goa_account_get_is_locked (account));
gtk_style_context_add_class (gtk_widget_get_style_context (button), "destructive-action");
gtk_container_add (GTK_CONTAINER (box), button);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (on_remove_button_clicked_cb), application);
}
static int
show_account (int argc,
char **argv)
{
g_autoptr(GtkApplication) application = NULL;
gtk_init (&argc, &argv);
if (argc != 4)
{
g_printerr ("Not enough arguments");
return EXIT_FAILURE;
}
application = gtk_application_new ("org.gnome.Settings.GoaHelper",
G_APPLICATION_FLAGS_NONE);
g_signal_connect (application, "activate", G_CALLBACK (on_application_activate_show_account_cb), argv);
return g_application_run (G_APPLICATION (application), 0, NULL);
}
struct {
const char *command_name;
int (*command_func) (int argc,
char **argv);
} commands[] = {
{ "create-account", create_account, },
{ "list-providers", list_providers, },
{ "show-account", show_account, },
};
static void
log_handler (const gchar *domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
g_printerr ("%s: %s\n", domain, message);
}
int
main (int argc,
char **argv)
{
gsize i;
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
if (argc < 2)
return EXIT_FAILURE;
/*
* This helper currently communicates to the gnome-control-center parent process
* by writing information to stdout using g_print. Therefore we need
* a custom logging handler, so to not write logs into stdout,
* which would confuse the parent process.
*/
g_log_set_default_handler (log_handler, NULL);
for (i = 0; i < G_N_ELEMENTS (commands); i++)
{
if (g_strcmp0 (commands[i].command_name, argv[1]) == 0)
return commands[i].command_func (argc, argv);
}
return EXIT_SUCCESS;
}

View File

@@ -29,6 +29,7 @@ sources += gnome.compile_resources(
deps = common_deps + [
goa_dep,
dependency('goa-backend-1.0', version: goa_req_version),
]
panels_libs += static_library(
@@ -39,32 +40,4 @@ panels_libs += static_library(
c_args: cflags
)
goa_helper_deps = [
dependency('goa-backend-1.0', version: goa_req_version),
]
goa_helper_cflags = cflags + [
'-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir),
]
gtk_x11_dep = dependency('gtk+-x11-3.0', required: false)
if gtk_x11_dep.found()
goa_helper_cflags += ['-DHAVE_GTK_X11']
endif
gtk_wayland_dep = dependency('gtk+-wayland-3.0', required: false)
if gtk_wayland_dep.found()
goa_helper_cflags += ['-DHAVE_GTK_WAYLAND']
endif
executable(
'gnome-control-center-goa-helper',
'gnome-control-center-goa-helper.c',
include_directories: [ top_inc ],
dependencies: goa_helper_deps,
c_args: goa_helper_cflags,
install: true,
install_dir: control_center_libexecdir,
)
subdir('icons')

View File

@@ -42,12 +42,6 @@ static GtkWidget *cc_sharing_panel_new_media_sharing_row (const char *uri_or
CcSharingPanel *self);
#define FILE_SHARING_SCHEMA_ID "org.gnome.desktop.file-sharing"
#define GNOME_REMOTE_DESKTOP_SCHEMA_ID "org.gnome.desktop.remote-desktop"
#define GNOME_REMOTE_DESKTOP_RDP_SCHEMA_ID "org.gnome.desktop.remote-desktop.rdp"
#define REMOTE_DESKTOP_STORE_CREDENTIALS_TIMEOUT_S 1
#define REMOTE_DESKTOP_SERVICE "gnome-remote-desktop.service"
struct _CcSharingPanel
{
@@ -134,30 +128,6 @@ cc_sharing_panel_class_init (CcSharingPanelClass *klass)
g_type_ensure (CC_TYPE_HOSTNAME_ENTRY);
}
static gboolean
cc_sharing_panel_switch_to_label_transform_func (GBinding *binding,
const GValue *source_value,
GValue *target_value,
CcSharingPanel *self)
{
gboolean active;
if (!G_VALUE_HOLDS_BOOLEAN (source_value))
return FALSE;
if (!G_VALUE_HOLDS_STRING (target_value))
return FALSE;
active = g_value_get_boolean (source_value);
if (active)
g_value_set_string (target_value, C_("service is enabled", "On"));
else
g_value_set_string (target_value, C_("service is disabled", "Off"));
return TRUE;
}
static gboolean
cc_sharing_panel_networks_to_label_transform_func (GBinding *binding,
const GValue *source_value,
@@ -191,17 +161,6 @@ cc_sharing_panel_networks_to_label_transform_func (GBinding *binding,
return TRUE;
}
static void
cc_sharing_panel_bind_switch_to_label (CcSharingPanel *self,
GtkWidget *gtkswitch,
GtkWidget *row)
{
g_object_bind_property_full (gtkswitch, "active", row, "secondary-label",
G_BINDING_SYNC_CREATE,
(GBindingTransformFunc) cc_sharing_panel_switch_to_label_transform_func,
NULL, self, NULL);
}
static void
cc_sharing_panel_bind_networks_to_label (CcSharingPanel *self,
GtkWidget *networks,

View File

@@ -127,7 +127,6 @@ panels/notifications/gnome-notifications-panel.desktop.in
panels/online-accounts/cc-online-account-provider-row.c
panels/online-accounts/cc-online-accounts-panel.c
panels/online-accounts/cc-online-accounts-panel.ui
panels/online-accounts/gnome-control-center-goa-helper.c
panels/online-accounts/gnome-online-accounts-panel.desktop.in
panels/power/cc-battery-row.c
panels/power/cc-power-panel.c
@@ -191,7 +190,6 @@ panels/sharing/cc-sharing-networks.ui
panels/sharing/cc-sharing-panel.c
panels/sharing/cc-sharing-panel.ui
panels/sharing/gnome-sharing-panel.desktop.in
panels/sharing/org.gnome.controlcenter.remote-login-helper.policy.in.in
panels/sound/cc-alert-chooser-window.c
panels/sound/cc-alert-chooser-window.ui
panels/sound/cc-balance-slider.ui
@@ -223,6 +221,9 @@ panels/system/region/cc-region-page.c
panels/system/region/cc-region-page.ui
panels/system/remote-desktop/cc-remote-desktop-page.c
panels/system/remote-desktop/cc-remote-desktop-page.ui
panels/system/remote-login/cc-remote-login-page.c
panels/system/remote-login/cc-remote-login-page.ui
panels/system/remote-login/org.gnome.controlcenter.remote-login-helper.policy.in.in
panels/system/users/cc-add-user-dialog.c
panels/system/users/cc-add-user-dialog.ui
panels/system/users/cc-avatar-chooser.c

1968
po/fa.po

File diff suppressed because it is too large Load Diff

6623
po/ka.po

File diff suppressed because it is too large Load Diff

539
po/tr.po

File diff suppressed because it is too large Load Diff