190 lines
6 KiB
C
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;
|
|
}
|