gnome-control-center/panels/common/cc-permission-infobar.c
Christopher Davis d25c0e345d general: Use AdwBanner in CcPermissionInfobar
AdwBanner is a new adaptive widget that replaces GtkInfoBar.
AdwBanner adapts better to mobile sizes and has an API
that fits with how we use infobars.

This commit changes CcPermissionInfobar to use an AdwBanner
internally instead of a GtkInfoBar. It also re-implements
part of GtkLockButton, as AdwBanner does not support adding
arbitrary widgets.
2023-04-11 12:23:16 +00:00

197 lines
5.4 KiB
C

/* cc-permission-infobar.c
*
* Copyright (C) 2020 Red Hat, Inc
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
* Author(s):
* Felipe Borges <felipeborges@gnome.org>
*
*/
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "cc-permission-infobar"
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <glib/gi18n.h>
#include <adwaita.h>
#include "cc-permission-infobar.h"
struct _CcPermissionInfobar
{
AdwBin parent_instance;
AdwBanner *banner;
GPermission *permission;
GCancellable *cancellable;
};
G_DEFINE_TYPE (CcPermissionInfobar, cc_permission_infobar, ADW_TYPE_BIN)
static void
on_permission_changed (CcPermissionInfobar *self)
{
gboolean is_authorized = g_permission_get_allowed (self->permission);
adw_banner_set_revealed (self->banner, !is_authorized);
}
static void
acquire_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
CcPermissionInfobar *self = CC_PERMISSION_INFOBAR (user_data);
g_autoptr (GError) error = NULL;
if (!g_permission_acquire_finish (self->permission, result, &error))
{
g_warning ("Error acquiring permission: %s", error->message);
}
g_clear_object (&self->cancellable);
}
static void
release_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
CcPermissionInfobar *self = CC_PERMISSION_INFOBAR (user_data);
g_autoptr (GError) error = NULL;
if (!g_permission_release_finish (self->permission, result, &error))
{
g_warning ("Error releasing permission: %s", error->message);
g_error_free (error);
}
g_clear_object (&self->cancellable);
}
static void
banner_button_clicked_cb (CcPermissionInfobar *self)
{
/* if we already have a pending interactive check or permission is not set,
* then do nothing
*/
if (self->cancellable != NULL || self->permission == NULL)
return;
if (g_permission_get_allowed (self->permission))
{
if (g_permission_get_can_release (self->permission))
{
self->cancellable = g_cancellable_new ();
g_permission_release_async (self->permission,
self->cancellable,
release_cb,
self);
}
}
else
{
if (g_permission_get_can_acquire (self->permission))
{
self->cancellable = g_cancellable_new ();
g_permission_acquire_async (self->permission,
self->cancellable,
acquire_cb,
self);
}
}
}
static void
cc_permission_infobar_dispose (GObject *object)
{
CcPermissionInfobar *self = CC_PERMISSION_INFOBAR (object);
if (self->cancellable != NULL)
{
g_cancellable_cancel (self->cancellable);
}
g_clear_object (&self->cancellable);
G_OBJECT_CLASS (cc_permission_infobar_parent_class)->dispose (object);
}
static void
cc_permission_infobar_class_init (CcPermissionInfobarClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = cc_permission_infobar_dispose;
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/control-center/"
"common/cc-permission-infobar.ui");
gtk_widget_class_bind_template_child (widget_class, CcPermissionInfobar, banner);
gtk_widget_class_bind_template_callback (widget_class,
banner_button_clicked_cb);
}
static void
cc_permission_infobar_init (CcPermissionInfobar *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
/* Set the default title. */
cc_permission_infobar_set_title (self, NULL);
}
void
cc_permission_infobar_set_permission (CcPermissionInfobar *self,
GPermission *permission)
{
g_return_if_fail (CC_IS_PERMISSION_INFOBAR (self));
g_return_if_fail (G_IS_PERMISSION (permission));
self->permission = permission;
g_signal_connect_object (permission, "notify",
G_CALLBACK (on_permission_changed),
self,
G_CONNECT_SWAPPED);
on_permission_changed (self);
}
/**
* cc_permission_infobar_set_title:
* @self: a #CcPermissionInfobar
* @title: (nullable): title to display in the infobar, or %NULL for the default
*
* Set the title text to display in the infobar.
*/
void
cc_permission_infobar_set_title (CcPermissionInfobar *self,
const gchar *title)
{
g_return_if_fail (CC_IS_PERMISSION_INFOBAR (self));
if (title == NULL)
title = _("Unlock to Change Settings");
adw_banner_set_title (self->banner, title);
}