1
0
Fork 0
gnome-control-center/global-shortcuts-provider/cc-global-shortcuts-provider.c
Daniel Baumann 0a49575b51
Adding upstream version 1:48.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 19:52:18 +02:00

190 lines
6 KiB
C

/*
* Copyright (c) 2012 Giovanni Campagna <scampa.giovanni@gmail.com>
* Copyright © 2024 GNOME Foundation Inc.
*
* The Control Center 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.
*
* The Control Center 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 the Control Center; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Contributor: Dorota Czaplejewicz
*/
#include <config.h>
#include <gio/gdesktopappinfo.h>
#include <gio/gio.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <string.h>
#include "cc-keyboard-manager.h"
#include <shell/cc-panel-loader.h>
#include <shell/cc-panel.h>
#include <shell/cc-shell-model.h>
#include "cc-global-shortcut-dialog.h"
#include "cc-global-shortcuts-provider.h"
#include "cc-util.h"
#include "control-center-global-shortcuts-provider.h"
struct _CcGlobalShortcutsProvider
{
GObject parent;
CcSettingsGlobalShortcutsProvider *skeleton;
GtkApplication *app;
GHashTable *dialogs;
};
typedef enum
{
MATCH_NONE,
MATCH_PREFIX,
MATCH_SUBSTRING
} PanelSearchMatch;
G_DEFINE_TYPE (CcGlobalShortcutsProvider,
cc_global_shortcuts_provider,
G_TYPE_OBJECT)
static void
handle_dialog_done (CcGlobalShortcutsProvider *self,
CcGlobalShortcutDialog *shortcut_dialog,
GVariant *response)
{
GDBusMethodInvocation *invocation;
invocation = g_hash_table_lookup (self->dialogs, shortcut_dialog);
if (response)
{
cc_settings_global_shortcuts_provider_complete_bind_shortcuts (self->skeleton,
invocation,
g_variant_ref_sink (response));
}
else
{
g_dbus_method_invocation_return_error (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Access denied");
}
}
static void
on_dialog_done (CcGlobalShortcutDialog *shortcut_dialog,
GVariant *response,
CcGlobalShortcutsProvider *self)
{
handle_dialog_done (self, shortcut_dialog, response);
g_hash_table_remove (self->dialogs, shortcut_dialog);
}
static gboolean
handle_bind_shortcuts (CcGlobalShortcutsProvider *self,
GDBusMethodInvocation *invocation,
const char *app_id,
const char *parent_window,
GVariant *shortcuts)
{
g_autoptr(CcGlobalShortcutDialog) shortcut_dialog = NULL;
shortcut_dialog =
cc_global_shortcut_dialog_new (app_id,
parent_window,
shortcuts);
g_signal_connect (shortcut_dialog, "done",
G_CALLBACK (on_dialog_done),
self);
gtk_application_add_window (self->app, GTK_WINDOW (shortcut_dialog));
g_hash_table_insert (self->dialogs,
g_object_ref (shortcut_dialog),
g_object_ref (invocation));
cc_global_shortcut_dialog_present (shortcut_dialog);
return G_DBUS_METHOD_INVOCATION_HANDLED;
}
static void
cc_global_shortcuts_provider_init (CcGlobalShortcutsProvider *self)
{
self->dialogs = g_hash_table_new_full (NULL, NULL,
(GDestroyNotify) gtk_window_destroy,
(GDestroyNotify) g_object_unref);
self->skeleton = cc_settings_global_shortcuts_provider_skeleton_new ();
g_signal_connect_swapped (self->skeleton, "handle-bind-shortcuts",
G_CALLBACK (handle_bind_shortcuts), self);
}
gboolean
cc_global_shortcuts_provider_dbus_register (CcGlobalShortcutsProvider *self,
GDBusConnection *connection,
const char *object_path,
GError **error)
{
GDBusInterfaceSkeleton *skeleton =
G_DBUS_INTERFACE_SKELETON (self->skeleton);
return g_dbus_interface_skeleton_export (skeleton, connection, object_path, error);
}
void
cc_global_shortcuts_provider_dbus_unregister (CcGlobalShortcutsProvider *self,
GDBusConnection *connection,
const char *object_path)
{
GDBusInterfaceSkeleton *skeleton =
G_DBUS_INTERFACE_SKELETON (self->skeleton);
if (g_dbus_interface_skeleton_has_connection (skeleton, connection))
g_dbus_interface_skeleton_unexport_from_connection (skeleton, connection);
}
static void
cc_global_shortcuts_provider_dispose (GObject *object)
{
CcGlobalShortcutsProvider *self =
CC_GLOBAL_SHORTCUTS_PROVIDER (object);
g_clear_object (&self->skeleton);
g_clear_pointer (&self->dialogs, g_hash_table_unref);
G_OBJECT_CLASS (cc_global_shortcuts_provider_parent_class)->dispose (object);
}
static void
cc_global_shortcuts_provider_class_init (CcGlobalShortcutsProviderClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = cc_global_shortcuts_provider_dispose;
}
CcGlobalShortcutsProvider *
cc_global_shortcuts_provider_new (GtkApplication *app)
{
CcGlobalShortcutsProvider *self;
self = g_object_new (CC_TYPE_GLOBAL_SHORTCUTS_PROVIDER, NULL);
self->app = app;
return self;
}