summaryrefslogtreecommitdiff
path: root/src/core/prefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/prefs.c')
-rw-r--r--src/core/prefs.c2229
1 files changed, 0 insertions, 2229 deletions
diff --git a/src/core/prefs.c b/src/core/prefs.c
deleted file mode 100644
index 536d9dd57..000000000
--- a/src/core/prefs.c
+++ /dev/null
@@ -1,2229 +0,0 @@
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/*
- * Copyright (C) 2001 Havoc Pennington, Copyright (C) 2002 Red Hat Inc.
- * Copyright (C) 2006 Elijah Newren
- * Copyright (C) 2008 Thomas Thurman
- * Copyright (C) 2010 Milan Bouchet-Valat, Copyright (C) 2011 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 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, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * SECTION:prefs
- * @title: Preferences
- * @short_description: Mutter preferences
- */
-
-#include "config.h"
-
-#include <glib.h>
-#include <gio/gio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "compositor/meta-plugin-manager.h"
-#include "core/keybindings-private.h"
-#include "core/meta-accel-parse.h"
-#include "core/prefs-private.h"
-#include "core/util-private.h"
-#include "meta/prefs.h"
-#include "x11/meta-x11-display-private.h"
-
-/* If you add a key, it needs updating in init() and in the gsettings
- * notify listener and of course in the .schemas file.
- *
- * Keys which are handled by one of the unified handlers below are
- * not given a name here, because the purpose of the unified handlers
- * is that keys should be referred to exactly once.
- */
-#define KEY_TITLEBAR_FONT "titlebar-font"
-#define KEY_NUM_WORKSPACES "num-workspaces"
-#define KEY_WORKSPACE_NAMES "workspace-names"
-
-/* Keys from "foreign" schemas */
-#define KEY_GNOME_ACCESSIBILITY "toolkit-accessibility"
-#define KEY_GNOME_ANIMATIONS "enable-animations"
-#define KEY_GNOME_CURSOR_THEME "cursor-theme"
-#define KEY_GNOME_CURSOR_SIZE "cursor-size"
-#define KEY_XKB_OPTIONS "xkb-options"
-
-#define KEY_OVERLAY_KEY "overlay-key"
-#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
-#define KEY_LOCATE_POINTER "locate-pointer"
-
-/* These are the different schemas we are keeping
- * a GSettings instance for */
-#define SCHEMA_GENERAL "org.gnome.desktop.wm.preferences"
-#define SCHEMA_MUTTER "org.gnome.mutter"
-#define SCHEMA_INTERFACE "org.gnome.desktop.interface"
-#define SCHEMA_INPUT_SOURCES "org.gnome.desktop.input-sources"
-#define SCHEMA_MOUSE "org.gnome.desktop.peripherals.mouse"
-
-#define SETTINGS(s) g_hash_table_lookup (settings_schemas, (s))
-
-static GList *changes = NULL;
-static guint changed_idle;
-static GList *listeners = NULL;
-static GHashTable *settings_schemas;
-
-static gboolean use_system_font = FALSE;
-static PangoFontDescription *titlebar_font = NULL;
-static MetaVirtualModifier mouse_button_mods = Mod1Mask;
-static MetaKeyCombo overlay_key_combo = { 0, 0, 0 };
-static MetaKeyCombo locate_pointer_key_combo = { 0, 0, 0 };
-static GDesktopFocusMode focus_mode = G_DESKTOP_FOCUS_MODE_CLICK;
-static GDesktopFocusNewWindows focus_new_windows = G_DESKTOP_FOCUS_NEW_WINDOWS_SMART;
-static gboolean raise_on_click = TRUE;
-static gboolean center_new_windows = FALSE;
-static gboolean attach_modal_dialogs = FALSE;
-static int num_workspaces = 4;
-static GDesktopTitlebarAction action_double_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_TOGGLE_MAXIMIZE;
-static GDesktopTitlebarAction action_middle_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_LOWER;
-static GDesktopTitlebarAction action_right_click_titlebar = G_DESKTOP_TITLEBAR_ACTION_MENU;
-static gboolean dynamic_workspaces = FALSE;
-static gboolean disable_workarounds = FALSE;
-static gboolean auto_raise = FALSE;
-static gboolean auto_raise_delay = 500;
-static gboolean focus_change_on_pointer_rest = FALSE;
-static gboolean bell_is_visible = FALSE;
-static gboolean bell_is_audible = TRUE;
-static gboolean gnome_accessibility = FALSE;
-static gboolean gnome_animations = TRUE;
-static gboolean locate_pointer_is_enabled = FALSE;
-static unsigned int check_alive_timeout = 5000;
-static char *cursor_theme = NULL;
-/* cursor_size will, when running as an X11 compositing window manager, be the
- * actual cursor size, multiplied with the global window scaling factor. On
- * Wayland, it will be the actual cursor size retrieved from gsettings.
- */
-static int cursor_size = 24;
-static int draggable_border_width = 10;
-static int drag_threshold;
-static gboolean resize_with_right_button = FALSE;
-static gboolean edge_tiling = FALSE;
-static gboolean force_fullscreen = TRUE;
-static gboolean auto_maximize = TRUE;
-static gboolean show_fallback_app_menu = TRUE;
-
-static GDesktopVisualBellType visual_bell_type = G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH;
-static MetaButtonLayout button_layout;
-
-/* NULL-terminated array */
-static char **workspace_names = NULL;
-
-static gboolean workspaces_only_on_primary = FALSE;
-
-static char *iso_next_group_option = NULL;
-
-static void handle_preference_update_enum (GSettings *settings,
- gchar *key);
-static gboolean update_binding (MetaKeyPref *binding,
- gchar **strokes);
-static gboolean update_key_binding (const char *key,
- gchar **strokes);
-
-static void settings_changed (GSettings *settings,
- gchar *key,
- gpointer data);
-static void bindings_changed (GSettings *settings,
- gchar *key,
- gpointer data);
-
-static void queue_changed (MetaPreference pref);
-
-static void maybe_give_disable_workarounds_warning (void);
-
-static gboolean titlebar_handler (GVariant*, gpointer*, gpointer);
-static gboolean mouse_button_mods_handler (GVariant*, gpointer*, gpointer);
-static gboolean button_layout_handler (GVariant*, gpointer*, gpointer);
-static gboolean overlay_key_handler (GVariant*, gpointer*, gpointer);
-static gboolean locate_pointer_key_handler (GVariant*, gpointer*, gpointer);
-
-static gboolean iso_next_group_handler (GVariant*, gpointer*, gpointer);
-
-static void init_bindings (void);
-
-typedef struct
-{
- MetaPrefsChangedFunc func;
- gpointer data;
-} MetaPrefsListener;
-
-typedef struct
-{
- const char *key;
- const char *schema;
- MetaPreference pref;
-} MetaBasePreference;
-
-typedef struct
-{
- MetaBasePreference base;
- gpointer target;
-} MetaEnumPreference;
-
-typedef struct
-{
- MetaBasePreference base;
- gboolean *target;
-} MetaBoolPreference;
-
-
-/**
- * MetaStringPreference:
- * @handler: (nullable): A handler. Many of the string preferences
- * aren't stored as strings and need parsing; others of them have
- * default values which can't be solved in the general case. If you
- * include a function pointer here, it will be called instead of writing
- * the string value out to the target variable.
- * The function will be passed to g_settings_get_mapped() and should
- * return %TRUE if the mapping was successful and %FALSE otherwise.
- * In the former case the function is expected to handle the result
- * of the conversion itself and call queue_changed() appropriately;
- * in particular the @result (out) parameter as returned by
- * g_settings_get_mapped() will be ignored in all cases.
- * This may be %NULL. If it is, see "target", below.
- * @target: (nullable): Where to write the incoming string.
- * This must be %NULL if the handler is non-%NULL.
- * If the incoming string is %NULL, no change will be made.
- */
-typedef struct
-{
- MetaBasePreference base;
- GSettingsGetMapping handler;
- gchar **target;
-} MetaStringPreference;
-
-typedef struct
-{
- MetaBasePreference base;
- GSettingsGetMapping handler;
- gchar ***target;
-} MetaStringArrayPreference;
-
-typedef struct
-{
- MetaBasePreference base;
- gint *target;
-} MetaIntPreference;
-
-typedef struct
-{
- MetaBasePreference base;
- unsigned int *target;
-} MetaUintPreference;
-
-
-/* All preferences that are not keybindings must be listed here,
- * plus in the GSettings schemas and the MetaPreference enum.
- */
-
-/* FIXMEs: */
-/* @@@ Don't use NULL lines at the end; glib can tell you how big it is */
-
-static MetaEnumPreference preferences_enum[] =
- {
- {
- { "focus-new-windows",
- SCHEMA_GENERAL,
- META_PREF_FOCUS_NEW_WINDOWS,
- },
- &focus_new_windows,
- },
- {
- { "focus-mode",
- SCHEMA_GENERAL,
- META_PREF_FOCUS_MODE,
- },
- &focus_mode,
- },
- {
- { "visual-bell-type",
- SCHEMA_GENERAL,
- META_PREF_VISUAL_BELL_TYPE,
- },
- &visual_bell_type,
- },
- {
- { "action-double-click-titlebar",
- SCHEMA_GENERAL,
- META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
- },
- &action_double_click_titlebar,
- },
- {
- { "action-middle-click-titlebar",
- SCHEMA_GENERAL,
- META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
- },
- &action_middle_click_titlebar,
- },
- {
- { "action-right-click-titlebar",
- SCHEMA_GENERAL,
- META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
- },
- &action_right_click_titlebar,
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static MetaBoolPreference preferences_bool[] =
- {
- {
- { "attach-modal-dialogs",
- SCHEMA_MUTTER,
- META_PREF_ATTACH_MODAL_DIALOGS,
- },
- &attach_modal_dialogs,
- },
- {
- { "center-new-windows",
- SCHEMA_MUTTER,
- META_PREF_CENTER_NEW_WINDOWS,
- },
- &center_new_windows,
- },
- {
- { "raise-on-click",
- SCHEMA_GENERAL,
- META_PREF_RAISE_ON_CLICK,
- },
- &raise_on_click,
- },
- {
- { "titlebar-uses-system-font",
- SCHEMA_GENERAL,
- META_PREF_TITLEBAR_FONT, /* note! shares a pref */
- },
- &use_system_font,
- },
- {
- { "dynamic-workspaces",
- SCHEMA_MUTTER,
- META_PREF_DYNAMIC_WORKSPACES,
- },
- &dynamic_workspaces,
- },
- {
- { "disable-workarounds",
- SCHEMA_GENERAL,
- META_PREF_DISABLE_WORKAROUNDS,
- },
- &disable_workarounds,
- },
- {
- { "auto-raise",
- SCHEMA_GENERAL,
- META_PREF_AUTO_RAISE,
- },
- &auto_raise,
- },
- {
- { "focus-change-on-pointer-rest",
- SCHEMA_MUTTER,
- META_PREF_FOCUS_CHANGE_ON_POINTER_REST,
- },
- &focus_change_on_pointer_rest
- },
- {
- { "visual-bell",
- SCHEMA_GENERAL,
- META_PREF_VISUAL_BELL,
- },
- &bell_is_visible, /* FIXME: change the name: it's confusing */
- },
- {
- { "audible-bell",
- SCHEMA_GENERAL,
- META_PREF_AUDIBLE_BELL,
- },
- &bell_is_audible, /* FIXME: change the name: it's confusing */
- },
- {
- { KEY_GNOME_ACCESSIBILITY,
- SCHEMA_INTERFACE,
- META_PREF_GNOME_ACCESSIBILITY,
- },
- &gnome_accessibility,
- },
- {
- { KEY_GNOME_ANIMATIONS,
- SCHEMA_INTERFACE,
- META_PREF_GNOME_ANIMATIONS,
- },
- &gnome_animations,
- },
- {
- { "resize-with-right-button",
- SCHEMA_GENERAL,
- META_PREF_RESIZE_WITH_RIGHT_BUTTON,
- },
- &resize_with_right_button,
- },
- {
- { "edge-tiling",
- SCHEMA_MUTTER,
- META_PREF_EDGE_TILING,
- },
- &edge_tiling,
- },
- {
- { "workspaces-only-on-primary",
- SCHEMA_MUTTER,
- META_PREF_WORKSPACES_ONLY_ON_PRIMARY,
- },
- &workspaces_only_on_primary,
- },
- {
- { "auto-maximize",
- SCHEMA_MUTTER,
- META_PREF_AUTO_MAXIMIZE,
- },
- &auto_maximize,
- },
- {
- { KEY_LOCATE_POINTER,
- SCHEMA_INTERFACE,
- META_PREF_LOCATE_POINTER,
- },
- &locate_pointer_is_enabled,
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static MetaStringPreference preferences_string[] =
- {
- {
- { "mouse-button-modifier",
- SCHEMA_GENERAL,
- META_PREF_MOUSE_BUTTON_MODS,
- },
- mouse_button_mods_handler,
- NULL,
- },
- {
- { KEY_TITLEBAR_FONT,
- SCHEMA_GENERAL,
- META_PREF_TITLEBAR_FONT,
- },
- titlebar_handler,
- NULL,
- },
- {
- { "button-layout",
- SCHEMA_GENERAL,
- META_PREF_BUTTON_LAYOUT,
- },
- button_layout_handler,
- NULL,
- },
- {
- { "cursor-theme",
- SCHEMA_INTERFACE,
- META_PREF_CURSOR_THEME,
- },
- NULL,
- &cursor_theme,
- },
- {
- { "overlay-key",
- SCHEMA_MUTTER,
- META_PREF_KEYBINDINGS,
- },
- overlay_key_handler,
- NULL,
- },
- {
- { "locate-pointer-key",
- SCHEMA_MUTTER,
- META_PREF_KEYBINDINGS,
- },
- locate_pointer_key_handler,
- NULL,
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static MetaStringArrayPreference preferences_string_array[] =
- {
- {
- { KEY_WORKSPACE_NAMES,
- SCHEMA_GENERAL,
- META_PREF_WORKSPACE_NAMES,
- },
- NULL,
- &workspace_names,
- },
- {
- { KEY_XKB_OPTIONS,
- SCHEMA_INPUT_SOURCES,
- META_PREF_KEYBINDINGS,
- },
- iso_next_group_handler,
- NULL,
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static MetaIntPreference preferences_int[] =
- {
- {
- { KEY_NUM_WORKSPACES,
- SCHEMA_GENERAL,
- META_PREF_NUM_WORKSPACES,
- },
- &num_workspaces
- },
- {
- { "auto-raise-delay",
- SCHEMA_GENERAL,
- META_PREF_AUTO_RAISE_DELAY,
- },
- &auto_raise_delay
- },
- {
- { "draggable-border-width",
- SCHEMA_MUTTER,
- META_PREF_DRAGGABLE_BORDER_WIDTH,
- },
- &draggable_border_width
- },
- {
- { "drag-threshold",
- SCHEMA_MOUSE,
- META_PREF_DRAG_THRESHOLD,
- },
- &drag_threshold
- },
- {
- { "cursor-size",
- SCHEMA_INTERFACE,
- META_PREF_CURSOR_SIZE,
- },
- &cursor_size
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static MetaUintPreference preferences_uint[] =
- {
- {
- { "check-alive-timeout",
- SCHEMA_MUTTER,
- META_PREF_CHECK_ALIVE_TIMEOUT,
- },
- &check_alive_timeout,
- },
- { { NULL, 0, 0 }, NULL },
- };
-
-static void
-handle_preference_init_enum (void)
-{
- MetaEnumPreference *cursor = preferences_enum;
-
- while (cursor->base.key != NULL)
- {
- if (cursor->target==NULL)
- continue;
-
- *((gint *) cursor->target) =
- g_settings_get_enum (SETTINGS (cursor->base.schema), cursor->base.key);
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_init_bool (void)
-{
- MetaBoolPreference *cursor = preferences_bool;
-
- while (cursor->base.key != NULL)
- {
- if (cursor->target!=NULL)
- *cursor->target =
- g_settings_get_boolean (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- ++cursor;
- }
-
- maybe_give_disable_workarounds_warning ();
-}
-
-static void
-handle_preference_init_string (void)
-{
- MetaStringPreference *cursor = preferences_string;
-
- while (cursor->base.key != NULL)
- {
- char *value;
-
- /* Complex keys have a mapping function to check validity */
- if (cursor->handler)
- {
- if (cursor->target)
- meta_bug ("%s has both a target and a handler", cursor->base.key);
-
- g_settings_get_mapped (SETTINGS (cursor->base.schema),
- cursor->base.key, cursor->handler, NULL);
- }
- else
- {
- if (!cursor->target)
- meta_bug ("%s must have handler or target", cursor->base.key);
-
- g_free (*(cursor->target));
-
- value = g_settings_get_string (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- *(cursor->target) = value;
- }
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_init_string_array (void)
-{
- MetaStringArrayPreference *cursor = preferences_string_array;
-
- while (cursor->base.key != NULL)
- {
- char **value;
-
- /* Complex keys have a mapping function to check validity */
- if (cursor->handler)
- {
- if (cursor->target)
- meta_bug ("%s has both a target and a handler", cursor->base.key);
-
- g_settings_get_mapped (SETTINGS (cursor->base.schema),
- cursor->base.key, cursor->handler, NULL);
- }
- else
- {
- if (!cursor->target)
- meta_bug ("%s must have handler or target", cursor->base.key);
-
- if (*(cursor->target))
- g_strfreev (*(cursor->target));
-
- value = g_settings_get_strv (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- *(cursor->target) = value;
- }
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_init_int (void)
-{
- MetaIntPreference *cursor = preferences_int;
-
-
- while (cursor->base.key != NULL)
- {
- if (cursor->target)
- *cursor->target = g_settings_get_int (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_init_uint (void)
-{
- MetaUintPreference *cursor = preferences_uint;
-
- while (cursor->base.key != NULL)
- {
- if (cursor->target)
- *cursor->target = g_settings_get_uint (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- ++cursor;
- }
-}
-
-static void
-handle_preference_update_enum (GSettings *settings,
- gchar *key)
-{
- MetaEnumPreference *cursor = preferences_enum;
- gint old_value;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key == NULL)
- /* Didn't recognise that key. */
- return;
-
- /* We need to know whether the value changes, so
- * store the current value away.
- */
-
- old_value = * ((gint *)cursor->target);
- *((gint *)cursor->target) =
- g_settings_get_enum (SETTINGS (cursor->base.schema), key);
-
- /* Did it change? If so, tell the listeners about it. */
- if (old_value != *((gint *)cursor->target))
- queue_changed (cursor->base.pref);
-}
-
-static void
-handle_preference_update_bool (GSettings *settings,
- gchar *key)
-{
- MetaBoolPreference *cursor = preferences_bool;
- gboolean old_value;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key == NULL || cursor->target == NULL)
- /* Unknown key or no work for us to do. */
- return;
-
- /* We need to know whether the value changes, so
- * store the current value away.
- */
- old_value = *((gboolean *) cursor->target);
-
- /* Now look it up... */
- *((gboolean *) cursor->target) =
- g_settings_get_boolean (SETTINGS (cursor->base.schema), key);
-
- /* Did it change? If so, tell the listeners about it. */
- if (old_value != *((gboolean *)cursor->target))
- queue_changed (cursor->base.pref);
-
- if (cursor->base.pref==META_PREF_DISABLE_WORKAROUNDS)
- maybe_give_disable_workarounds_warning ();
-}
-
-static void
-handle_preference_update_string (GSettings *settings,
- gchar *key)
-{
- MetaStringPreference *cursor = preferences_string;
- char *value;
- gboolean inform_listeners = FALSE;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key==NULL)
- /* Didn't recognise that key. */
- return;
-
- /* Complex keys have a mapping function to check validity */
- if (cursor->handler)
- {
- if (cursor->target)
- meta_bug ("%s has both a target and a handler", cursor->base.key);
-
- g_settings_get_mapped (SETTINGS (cursor->base.schema),
- cursor->base.key, cursor->handler, NULL);
- }
- else
- {
- if (!cursor->target)
- meta_bug ("%s must have handler or target", cursor->base.key);
-
- value = g_settings_get_string (SETTINGS (cursor->base.schema),
- cursor->base.key);
-
- inform_listeners = (g_strcmp0 (value, *(cursor->target)) != 0);
-
- g_free(*(cursor->target));
-
- *(cursor->target) = value;
- }
-
- if (inform_listeners)
- queue_changed (cursor->base.pref);
-}
-
-static void
-handle_preference_update_string_array (GSettings *settings,
- gchar *key)
-{
- MetaStringArrayPreference *cursor = preferences_string_array;
- gboolean inform_listeners = FALSE;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key==NULL)
- /* Didn't recognise that key. */
- return;
-
- /* Complex keys have a mapping function to check validity */
- if (cursor->handler)
- {
- if (cursor->target)
- meta_bug ("%s has both a target and a handler", cursor->base.key);
-
- g_settings_get_mapped (SETTINGS (cursor->base.schema),
- cursor->base.key, cursor->handler, NULL);
- }
- else
- {
- char **values, **previous;
- int n_values, n_previous, i;
-
- if (!cursor->target)
- meta_bug ("%s must have handler or target", cursor->base.key);
-
- values = g_settings_get_strv (SETTINGS (cursor->base.schema),
- cursor->base.key);
- n_values = g_strv_length (values);
- previous = *(cursor->target);
- n_previous = previous ? g_strv_length (previous) : 0;
-
- inform_listeners = n_previous != n_values;
- for (i = 0; i < n_values && !inform_listeners; i++)
- inform_listeners = g_strcmp0 (values[i], previous[i]) != 0;
-
- if (*(cursor->target))
- g_strfreev (*(cursor->target));
- *(cursor->target) = values;
- }
-
- if (inform_listeners)
- queue_changed (cursor->base.pref);
-}
-
-static void
-handle_preference_update_int (GSettings *settings,
- gchar *key)
-{
- MetaIntPreference *cursor = preferences_int;
- gint new_value;
-
- while (cursor->base.key != NULL && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (cursor->base.key == NULL || cursor->target == NULL)
- /* Unknown key or no work for us to do. */
- return;
-
- new_value = g_settings_get_int (SETTINGS (cursor->base.schema), key);
-
- /* Did it change? If so, tell the listeners about it. */
- if (*cursor->target != new_value)
- {
- *cursor->target = new_value;
- queue_changed (cursor->base.pref);
- }
-}
-
-static void
-handle_preference_update_uint (GSettings *settings,
- char *key)
-{
- MetaUintPreference *cursor = preferences_uint;
- unsigned int new_value;
-
- while (cursor->base.key && strcmp (key, cursor->base.key) != 0)
- ++cursor;
-
- if (!cursor->base.key || !cursor->target)
- return;
-
- new_value = g_settings_get_uint (SETTINGS (cursor->base.schema), key);
-
- if (*cursor->target != new_value)
- {
- *cursor->target = new_value;
- queue_changed (cursor->base.pref);
- }
-}
-
-
-/****************************************************************************/
-/* Listeners. */
-/****************************************************************************/
-
-/**
- * meta_prefs_add_listener: (skip)
- * @func: a #MetaPrefsChangedFunc
- * @user_data: data passed to the function
- *
- */
-void
-meta_prefs_add_listener (MetaPrefsChangedFunc func,
- gpointer user_data)
-{
- MetaPrefsListener *l;
-
- l = g_new (MetaPrefsListener, 1);
- l->func = func;
- l->data = user_data;
-
- listeners = g_list_prepend (listeners, l);
-}
-
-/**
- * meta_prefs_remove_listener: (skip)
- * @func: a #MetaPrefsChangedFunc
- * @user_data: data passed to the function
- *
- */
-void
-meta_prefs_remove_listener (MetaPrefsChangedFunc func,
- gpointer user_data)
-{
- GList *tmp;
-
- tmp = listeners;
- while (tmp != NULL)
- {
- MetaPrefsListener *l = tmp->data;
-
- if (l->func == func &&
- l->data == user_data)
- {
- g_free (l);
- listeners = g_list_delete_link (listeners, tmp);
-
- return;
- }
-
- tmp = tmp->next;
- }
-}
-
-static void
-emit_changed (MetaPreference pref)
-{
- GList *tmp;
- GList *copy;
-
- meta_topic (META_DEBUG_PREFS, "Notifying listeners that pref %s changed",
- meta_preference_to_string (pref));
-
- copy = g_list_copy (listeners);
-
- tmp = copy;
-
- while (tmp != NULL)
- {
- MetaPrefsListener *l = tmp->data;
-
- (* l->func) (pref, l->data);
-
- tmp = tmp->next;
- }
-
- g_list_free (copy);
-}
-
-static gboolean
-changed_idle_handler (gpointer data)
-{
- GList *tmp;
- GList *copy;
-
- changed_idle = 0;
-
- copy = g_list_copy (changes); /* reentrancy paranoia */
-
- g_list_free (changes);
- changes = NULL;
-
- tmp = copy;
- while (tmp != NULL)
- {
- MetaPreference pref = GPOINTER_TO_INT (tmp->data);
-
- emit_changed (pref);
-
- tmp = tmp->next;
- }
-
- g_list_free (copy);
-
- return FALSE;
-}
-
-static void
-queue_changed (MetaPreference pref)
-{
- meta_topic (META_DEBUG_PREFS, "Queueing change of pref %s",
- meta_preference_to_string (pref));
-
- if (g_list_find (changes, GINT_TO_POINTER (pref)) == NULL)
- changes = g_list_prepend (changes, GINT_TO_POINTER (pref));
- else
- meta_topic (META_DEBUG_PREFS, "Change of pref %s was already pending",
- meta_preference_to_string (pref));
-
- if (changed_idle == 0)
- {
- changed_idle = g_idle_add_full (META_PRIORITY_PREFS_NOTIFY,
- changed_idle_handler, NULL, NULL);
- g_source_set_name_by_id (changed_idle, "[mutter] changed_idle_handler");
- }
-}
-
-
-/****************************************************************************/
-/* Initialisation. */
-/****************************************************************************/
-
-void
-meta_prefs_init (void)
-{
- GSettings *settings;
-
- settings_schemas = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_object_unref);
-
- settings = g_settings_new (SCHEMA_GENERAL);
- g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
- g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_GENERAL), settings);
-
- settings = g_settings_new (SCHEMA_MUTTER);
- g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
- g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MUTTER), settings);
-
- settings = g_settings_new (SCHEMA_MOUSE);
- g_signal_connect (settings, "changed", G_CALLBACK (settings_changed), NULL);
- g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_MOUSE), settings);
-
- /* Individual keys we watch outside of our schemas */
- settings = g_settings_new (SCHEMA_INTERFACE);
- g_signal_connect (settings, "changed::" KEY_GNOME_ACCESSIBILITY,
- G_CALLBACK (settings_changed), NULL);
- g_signal_connect (settings, "changed::" KEY_GNOME_ANIMATIONS,
- G_CALLBACK (settings_changed), NULL);
- g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_THEME,
- G_CALLBACK (settings_changed), NULL);
- g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_SIZE,
- G_CALLBACK (settings_changed), NULL);
- g_signal_connect (settings, "changed::" KEY_LOCATE_POINTER,
- G_CALLBACK (settings_changed), NULL);
- g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
-
- settings = g_settings_new (SCHEMA_INPUT_SOURCES);
- g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS,
- G_CALLBACK (settings_changed), NULL);
- g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INPUT_SOURCES), settings);
-
- /* Pick up initial values. */
-
- handle_preference_init_enum ();
- handle_preference_init_bool ();
- handle_preference_init_string ();
- handle_preference_init_string_array ();
- handle_preference_init_int ();
- handle_preference_init_uint ();
-
- init_bindings ();
-}
-
-static gboolean
-find_pref (void *prefs,
- size_t pref_size,
- const char *search_key,
- MetaBasePreference **pref)
-{
- void *p = prefs;
-
- while (TRUE)
- {
- char **key = p;
- if (*key == NULL)
- break;
-
- if (strcmp (*key, search_key) == 0)
- {
- *pref = p;
- return TRUE;
- }
-
- p = (guchar *)p + pref_size;
- }
-
- return FALSE;
-}
-
-
-/****************************************************************************/
-/* Updates. */
-/****************************************************************************/
-
-
-static void
-settings_changed (GSettings *settings,
- gchar *key,
- gpointer data)
-{
- GVariant *value;
- const GVariantType *type;
- MetaEnumPreference *cursor;
- gboolean found_enum;
-
- value = g_settings_get_value (settings, key);
- type = g_variant_get_type (value);
-
- if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
- handle_preference_update_bool (settings, key);
- else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
- handle_preference_update_int (settings, key);
- else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
- handle_preference_update_uint (settings, key);
- else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING_ARRAY))
- handle_preference_update_string_array (settings, key);
- else if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
- {
- cursor = preferences_enum;
- found_enum = FALSE;
-
- while (cursor->base.key != NULL)
- {
-
- if (strcmp (key, cursor->base.key) == 0)
- found_enum = TRUE;
-
- cursor++;
- }
-
- if (found_enum)
- handle_preference_update_enum (settings, key);
- else
- handle_preference_update_string (settings, key);
- }
- else
- {
- /* Unknown preference type. This quite likely simply isn't
- * a preference we track changes to. */
- }
-
- g_variant_unref (value);
-}
-
-static void
-bindings_changed (GSettings *settings,
- gchar *key,
- gpointer data)
-{
- gchar **strokes;
- strokes = g_settings_get_strv (settings, key);
-
- if (update_key_binding (key, strokes))
- queue_changed (META_PREF_KEYBINDINGS);
-
- g_strfreev (strokes);
-}
-
-/**
- * maybe_give_disable_workaround_warning:
- *
- * Special case: give a warning the first time disable_workarounds
- * is turned on.
- */
-static void
-maybe_give_disable_workarounds_warning (void)
-{
- static gboolean first_disable = TRUE;
-
- if (first_disable && disable_workarounds)
- {
- first_disable = FALSE;
-
- meta_warning ("Workarounds for broken applications disabled. "
- "Some applications may not behave properly.");
- }
-}
-
-MetaVirtualModifier
-meta_prefs_get_mouse_button_mods (void)
-{
- return mouse_button_mods;
-}
-
-GDesktopFocusMode
-meta_prefs_get_focus_mode (void)
-{
- return focus_mode;
-}
-
-GDesktopFocusNewWindows
-meta_prefs_get_focus_new_windows (void)
-{
- return focus_new_windows;
-}
-
-gboolean
-meta_prefs_get_center_new_windows (void)
-{
- return center_new_windows;
-}
-
-gboolean
-meta_prefs_get_attach_modal_dialogs (void)
-{
- return attach_modal_dialogs;
-}
-
-gboolean
-meta_prefs_get_raise_on_click (void)
-{
- return raise_on_click;
-}
-
-gboolean
-meta_prefs_get_show_fallback_app_menu (void)
-{
- return show_fallback_app_menu;
-}
-
-void
-meta_prefs_set_show_fallback_app_menu (gboolean whether)
-{
- gboolean changed = FALSE;
-
- changed = (show_fallback_app_menu == !whether);
-
- show_fallback_app_menu = whether;
-
- if (changed)
- queue_changed (META_PREF_BUTTON_LAYOUT);
-}
-
-const char*
-meta_prefs_get_cursor_theme (void)
-{
- return cursor_theme;
-}
-
-int
-meta_prefs_get_cursor_size (void)
-{
- return cursor_size;
-}
-
-
-/****************************************************************************/
-/* Handlers for string preferences. */
-/****************************************************************************/
-
-static gboolean
-titlebar_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- PangoFontDescription *desc;
- const gchar *string_value;
-
- *result = NULL; /* ignored */
- string_value = g_variant_get_string (value, NULL);
- desc = pango_font_description_from_string (string_value);
-
- if (desc == NULL)
- {
- meta_warning ("Could not parse font description "
- "\"%s\" from GSettings key %s",
- string_value ? string_value : "(null)",
- KEY_TITLEBAR_FONT);
- return FALSE;
- }
-
- /* Is the new description the same as the old? */
- if (titlebar_font &&
- pango_font_description_equal (desc, titlebar_font))
- {
- pango_font_description_free (desc);
- }
- else
- {
- if (titlebar_font)
- pango_font_description_free (titlebar_font);
-
- titlebar_font = desc;
- queue_changed (META_PREF_TITLEBAR_FONT);
- }
-
- return TRUE;
-}
-
-static gboolean
-mouse_button_mods_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- MetaVirtualModifier mods;
- const gchar *string_value;
-
- *result = NULL; /* ignored */
- string_value = g_variant_get_string (value, NULL);
-
- if (!string_value || !meta_parse_modifier (string_value, &mods))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse new GSettings value");
-
- meta_warning ("\"%s\" found in configuration database is "
- "not a valid value for mouse button modifier",
- string_value);
-
- return FALSE;
- }
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Mouse button modifier has new GSettings value \"%s\"",
- string_value);
-
- if (mods != mouse_button_mods)
- {
- mouse_button_mods = mods;
- queue_changed (META_PREF_MOUSE_BUTTON_MODS);
- }
-
- return TRUE;
-}
-
-static gboolean
-button_layout_equal (const MetaButtonLayout *a,
- const MetaButtonLayout *b)
-{
- int i;
-
- i = 0;
- while (i < MAX_BUTTONS_PER_CORNER)
- {
- if (a->left_buttons[i] != b->left_buttons[i])
- return FALSE;
- if (a->right_buttons[i] != b->right_buttons[i])
- return FALSE;
- if (a->left_buttons_has_spacer[i] != b->left_buttons_has_spacer[i])
- return FALSE;
- if (a->right_buttons_has_spacer[i] != b->right_buttons_has_spacer[i])
- return FALSE;
- ++i;
- }
-
- return TRUE;
-}
-
-/*
- * This conversion cannot be handled by GSettings since
- * several values are stored in the same key (as a string).
- */
-static MetaButtonFunction
-button_function_from_string (const char *str)
-{
- if (strcmp (str, "menu") == 0)
- return META_BUTTON_FUNCTION_MENU;
- else if (strcmp (str, "minimize") == 0)
- return META_BUTTON_FUNCTION_MINIMIZE;
- else if (strcmp (str, "maximize") == 0)
- return META_BUTTON_FUNCTION_MAXIMIZE;
- else if (strcmp (str, "close") == 0)
- return META_BUTTON_FUNCTION_CLOSE;
- else
- /* don't know; give up */
- return META_BUTTON_FUNCTION_LAST;
-}
-
-static gboolean
-button_layout_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- MetaButtonLayout new_layout;
- const gchar *string_value;
- char **sides = NULL;
- int i;
-
- /* We need to ignore unknown button functions, for
- * compat with future versions
- */
-
- *result = NULL; /* ignored */
- string_value = g_variant_get_string (value, NULL);
-
- if (string_value)
- sides = g_strsplit (string_value, ":", 2);
-
- i = 0;
- if (sides != NULL && sides[0] != NULL)
- {
- char **buttons;
- int b;
- gboolean used[META_BUTTON_FUNCTION_LAST];
-
- while (i < META_BUTTON_FUNCTION_LAST)
- {
- used[i] = FALSE;
- new_layout.left_buttons_has_spacer[i] = FALSE;
- ++i;
- }
-
- buttons = g_strsplit (sides[0], ",", -1);
- i = 0;
- b = 0;
- while (buttons[b] != NULL)
- {
- MetaButtonFunction f = button_function_from_string (buttons[b]);
- if (i > 0 && strcmp("spacer", buttons[b]) == 0)
- {
- new_layout.left_buttons_has_spacer[i-1] = TRUE;
- }
- else
- {
- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
- {
- new_layout.left_buttons[i] = f;
- used[f] = TRUE;
- ++i;
- }
- else
- {
- meta_topic (META_DEBUG_PREFS,
- "Ignoring unknown or already-used button name \"%s\"",
- buttons[b]);
- }
- }
-
- ++b;
- }
-
- g_strfreev (buttons);
- }
-
- for (; i < MAX_BUTTONS_PER_CORNER; i++)
- {
- new_layout.left_buttons[i] = META_BUTTON_FUNCTION_LAST;
- new_layout.left_buttons_has_spacer[i] = FALSE;
- }
-
- i = 0;
- if (sides != NULL && sides[0] != NULL && sides[1] != NULL)
- {
- char **buttons;
- int b;
- gboolean used[META_BUTTON_FUNCTION_LAST];
-
- while (i < META_BUTTON_FUNCTION_LAST)
- {
- used[i] = FALSE;
- new_layout.right_buttons_has_spacer[i] = FALSE;
- ++i;
- }
-
- buttons = g_strsplit (sides[1], ",", -1);
- i = 0;
- b = 0;
- while (buttons[b] != NULL)
- {
- MetaButtonFunction f = button_function_from_string (buttons[b]);
- if (i > 0 && strcmp("spacer", buttons[b]) == 0)
- {
- new_layout.right_buttons_has_spacer[i-1] = TRUE;
- }
- else
- {
- if (f != META_BUTTON_FUNCTION_LAST && !used[f])
- {
- new_layout.right_buttons[i] = f;
- used[f] = TRUE;
- ++i;
- }
- else
- {
- meta_topic (META_DEBUG_PREFS,
- "Ignoring unknown or already-used button name \"%s\"",
- buttons[b]);
- }
- }
-
- ++b;
- }
-
- g_strfreev (buttons);
- }
-
- for (; i < MAX_BUTTONS_PER_CORNER; i++)
- {
- new_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
- new_layout.right_buttons_has_spacer[i] = FALSE;
- }
-
- g_strfreev (sides);
-
- /* Invert the button layout for RTL languages */
- if (meta_get_locale_direction() == META_LOCALE_DIRECTION_RTL)
- {
- MetaButtonLayout rtl_layout;
- int j;
-
- for (i = 0; new_layout.left_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
- for (j = 0; j < i; j++)
- {
- rtl_layout.right_buttons[j] = new_layout.left_buttons[i - j - 1];
- if (j == 0)
- rtl_layout.right_buttons_has_spacer[i - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
- else
- rtl_layout.right_buttons_has_spacer[j - 1] = new_layout.left_buttons_has_spacer[i - j - 1];
- }
- for (; j < MAX_BUTTONS_PER_CORNER; j++)
- {
- rtl_layout.right_buttons[j] = META_BUTTON_FUNCTION_LAST;
- rtl_layout.right_buttons_has_spacer[j] = FALSE;
- }
-
- for (i = 0; new_layout.right_buttons[i] != META_BUTTON_FUNCTION_LAST; i++);
- for (j = 0; j < i; j++)
- {
- rtl_layout.left_buttons[j] = new_layout.right_buttons[i - j - 1];
- if (j == 0)
- rtl_layout.left_buttons_has_spacer[i - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
- else
- rtl_layout.left_buttons_has_spacer[j - 1] = new_layout.right_buttons_has_spacer[i - j - 1];
- }
- for (; j < MAX_BUTTONS_PER_CORNER; j++)
- {
- rtl_layout.left_buttons[j] = META_BUTTON_FUNCTION_LAST;
- rtl_layout.left_buttons_has_spacer[j] = FALSE;
- }
-
- new_layout = rtl_layout;
- }
-
- if (!button_layout_equal (&button_layout, &new_layout))
- {
- button_layout = new_layout;
- emit_changed (META_PREF_BUTTON_LAYOUT);
- }
-
- return TRUE;
-}
-
-static gboolean
-overlay_key_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- MetaKeyCombo combo;
- const gchar *string_value;
-
- *result = NULL; /* ignored */
- string_value = g_variant_get_string (value, NULL);
-
- if (string_value && meta_parse_accelerator (string_value, &combo))
- ;
- else
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse value for overlay-key");
- return FALSE;
- }
-
- combo.modifiers = 0;
-
- if (overlay_key_combo.keysym != combo.keysym ||
- overlay_key_combo.keycode != combo.keycode)
- {
- overlay_key_combo = combo;
- queue_changed (META_PREF_KEYBINDINGS);
- }
-
- return TRUE;
-}
-
-static gboolean
-locate_pointer_key_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- MetaKeyCombo combo;
- const gchar *string_value;
-
- *result = NULL; /* ignored */
- string_value = g_variant_get_string (value, NULL);
-
- if (!string_value || !meta_parse_accelerator (string_value, &combo))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse value for locate-pointer-key");
- return FALSE;
- }
-
- combo.modifiers = 0;
-
- if (locate_pointer_key_combo.keysym != combo.keysym ||
- locate_pointer_key_combo.keycode != combo.keycode)
- {
- locate_pointer_key_combo = combo;
- queue_changed (META_PREF_KEYBINDINGS);
- }
-
- return TRUE;
-}
-
-static gboolean
-iso_next_group_handler (GVariant *value,
- gpointer *result,
- gpointer data)
-{
- const char **xkb_options, **p;
- const char *option = NULL;
- gboolean changed = FALSE;
-
- *result = NULL; /* ignored */
- xkb_options = g_variant_get_strv (value, NULL);
-
- for (p = xkb_options; p && *p; ++p)
- if (g_str_has_prefix (*p, "grp:"))
- {
- option = (*p + 4);
- break;
- }
-
- changed = (g_strcmp0 (option, iso_next_group_option) != 0);
-
- if (changed)
- {
- g_free (iso_next_group_option);
- iso_next_group_option = g_strdup (option);
- queue_changed (META_PREF_KEYBINDINGS);
- }
-
- g_free (xkb_options);
-
- return TRUE;
-}
-
-const PangoFontDescription*
-meta_prefs_get_titlebar_font (void)
-{
- if (use_system_font)
- return NULL;
- else
- return titlebar_font;
-}
-
-int
-meta_prefs_get_num_workspaces (void)
-{
- return num_workspaces;
-}
-
-gboolean
-meta_prefs_get_dynamic_workspaces (void)
-{
- return dynamic_workspaces;
-}
-
-gboolean
-meta_prefs_get_disable_workarounds (void)
-{
- return disable_workarounds;
-}
-
-#ifdef WITH_VERBOSE_MODE
-const char*
-meta_preference_to_string (MetaPreference pref)
-{
- /* TODO: better handled via GLib enum nicknames */
- switch (pref)
- {
- case META_PREF_MOUSE_BUTTON_MODS:
- return "MOUSE_BUTTON_MODS";
-
- case META_PREF_FOCUS_MODE:
- return "FOCUS_MODE";
-
- case META_PREF_FOCUS_NEW_WINDOWS:
- return "FOCUS_NEW_WINDOWS";
-
- case META_PREF_CENTER_NEW_WINDOWS:
- return "CENTER_NEW_WINDOWS";
-
- case META_PREF_ATTACH_MODAL_DIALOGS:
- return "ATTACH_MODAL_DIALOGS";
-
- case META_PREF_RAISE_ON_CLICK:
- return "RAISE_ON_CLICK";
-
- case META_PREF_TITLEBAR_FONT:
- return "TITLEBAR_FONT";
-
- case META_PREF_NUM_WORKSPACES:
- return "NUM_WORKSPACES";
-
- case META_PREF_KEYBINDINGS:
- return "KEYBINDINGS";
-
- case META_PREF_DISABLE_WORKAROUNDS:
- return "DISABLE_WORKAROUNDS";
-
- case META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR:
- return "ACTION_DOUBLE_CLICK_TITLEBAR";
-
- case META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR:
- return "ACTION_MIDDLE_CLICK_TITLEBAR";
-
- case META_PREF_ACTION_RIGHT_CLICK_TITLEBAR:
- return "ACTION_RIGHT_CLICK_TITLEBAR";
-
- case META_PREF_AUTO_RAISE:
- return "AUTO_RAISE";
-
- case META_PREF_AUTO_RAISE_DELAY:
- return "AUTO_RAISE_DELAY";
-
- case META_PREF_FOCUS_CHANGE_ON_POINTER_REST:
- return "FOCUS_CHANGE_ON_POINTER_REST";
-
- case META_PREF_BUTTON_LAYOUT:
- return "BUTTON_LAYOUT";
-
- case META_PREF_WORKSPACE_NAMES:
- return "WORKSPACE_NAMES";
-
- case META_PREF_VISUAL_BELL:
- return "VISUAL_BELL";
-
- case META_PREF_AUDIBLE_BELL:
- return "AUDIBLE_BELL";
-
- case META_PREF_VISUAL_BELL_TYPE:
- return "VISUAL_BELL_TYPE";
-
- case META_PREF_GNOME_ACCESSIBILITY:
- return "GNOME_ACCESSIBILTY";
-
- case META_PREF_GNOME_ANIMATIONS:
- return "GNOME_ANIMATIONS";
-
- case META_PREF_CURSOR_THEME:
- return "CURSOR_THEME";
-
- case META_PREF_CURSOR_SIZE:
- return "CURSOR_SIZE";
-
- case META_PREF_RESIZE_WITH_RIGHT_BUTTON:
- return "RESIZE_WITH_RIGHT_BUTTON";
-
- case META_PREF_EDGE_TILING:
- return "EDGE_TILING";
-
- case META_PREF_FORCE_FULLSCREEN:
- return "FORCE_FULLSCREEN";
-
- case META_PREF_WORKSPACES_ONLY_ON_PRIMARY:
- return "WORKSPACES_ONLY_ON_PRIMARY";
-
- case META_PREF_DRAGGABLE_BORDER_WIDTH:
- return "DRAGGABLE_BORDER_WIDTH";
-
- case META_PREF_DRAG_THRESHOLD:
- return "DRAG_THRESHOLD";
-
- case META_PREF_DYNAMIC_WORKSPACES:
- return "DYNAMIC_WORKSPACES";
-
- case META_PREF_AUTO_MAXIMIZE:
- return "AUTO_MAXIMIZE";
-
- case META_PREF_LOCATE_POINTER:
- return "LOCATE_POINTER";
-
- case META_PREF_CHECK_ALIVE_TIMEOUT:
- return "CHECK_ALIVE_TIMEOUT";
- }
-
- return "(unknown)";
-}
-#endif /* WITH_VERBOSE_MODE */
-
-void
-meta_prefs_set_num_workspaces (int n_workspaces)
-{
- MetaBasePreference *pref;
-
- if (find_pref (preferences_int, sizeof(MetaIntPreference),
- KEY_NUM_WORKSPACES, &pref))
- {
- g_settings_set_int (SETTINGS (pref->schema),
- KEY_NUM_WORKSPACES,
- n_workspaces);
- }
-}
-
-static GHashTable *key_bindings;
-
-static void
-meta_key_pref_free (MetaKeyPref *pref)
-{
- update_binding (pref, NULL);
-
- g_free (pref->name);
- g_object_unref (pref->settings);
-
- g_free (pref);
-}
-
-
-static void
-init_bindings (void)
-{
- MetaKeyPref *pref;
-
- key_bindings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- (GDestroyNotify)meta_key_pref_free);
-
- pref = g_new0 (MetaKeyPref, 1);
- pref->name = g_strdup ("overlay-key");
- pref->action = META_KEYBINDING_ACTION_OVERLAY_KEY;
- pref->combos = g_slist_prepend (pref->combos, &overlay_key_combo);
- pref->builtin = 1;
-
- g_hash_table_insert (key_bindings, g_strdup (pref->name), pref);
-
- pref = g_new0 (MetaKeyPref, 1);
- pref->name = g_strdup ("locate-pointer-key");
- pref->action = META_KEYBINDING_ACTION_LOCATE_POINTER_KEY;
- pref->combos = g_slist_prepend (pref->combos, &locate_pointer_key_combo);
- pref->builtin = 1;
-
- g_hash_table_insert (key_bindings, g_strdup (pref->name), pref);
-}
-
-static gboolean
-update_binding (MetaKeyPref *binding,
- gchar **strokes)
-{
- GSList *old_combos, *a, *b;
- gboolean changed;
- int i;
-
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Binding \"%s\" has new GSettings value",
- binding->name);
-
- old_combos = binding->combos;
- binding->combos = NULL;
-
- for (i = 0; strokes && strokes[i]; i++)
- {
- MetaKeyCombo *combo;
-
- combo = g_malloc0 (sizeof (MetaKeyCombo));
-
- if (!meta_parse_accelerator (strokes[i], combo))
- {
- meta_topic (META_DEBUG_KEYBINDINGS,
- "Failed to parse new GSettings value");
- meta_warning ("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"",
- strokes[i], binding->name);
-
- g_free (combo);
-
- /* Value is kept and will thus be removed next time we save the key.
- * Changing the key in response to a modification could lead to cyclic calls. */
- continue;
- }
-
- binding->combos = g_slist_prepend (binding->combos, combo);
- }
-
- binding->combos = g_slist_reverse (binding->combos);
-
- a = old_combos;
- b = binding->combos;
- while (TRUE)
- {
- if ((!a && b) || (a && !b))
- {
- changed = TRUE;
- break;
- }
- else if (!a && !b)
- {
- changed = FALSE;
- break;
- }
- else if (memcmp (a->data, b->data, sizeof (MetaKeyCombo)) != 0)
- {
- changed = TRUE;
- break;
- }
- else
- {
- a = a->next;
- b = b->next;
- }
- }
-
- g_slist_free_full (old_combos, g_free);
-
- return changed;
-}
-
-static gboolean
-update_key_binding (const char *key,
- gchar **strokes)
-{
- MetaKeyPref *pref = g_hash_table_lookup (key_bindings, key);
-
- if (pref)
- return update_binding (pref, strokes);
- else
- return FALSE;
-}
-
-const char*
-meta_prefs_get_workspace_name (int i)
-{
- const char *name;
-
- if (!workspace_names ||
- g_strv_length (workspace_names) < (guint)i + 1 ||
- !*workspace_names[i])
- {
- char *generated_name = g_strdup_printf (_("Workspace %d"), i + 1);
- name = g_intern_string (generated_name);
- g_free (generated_name);
- }
- else
- name = workspace_names[i];
-
- meta_topic (META_DEBUG_PREFS,
- "Getting name of workspace %d: \"%s\"", i, name);
-
- return name;
-}
-
-void
-meta_prefs_change_workspace_name (int num,
- const char *name)
-{
- GVariantBuilder builder;
- int n_workspace_names, i;
-
- g_return_if_fail (num >= 0);
-
- meta_topic (META_DEBUG_PREFS,
- "Changing name of workspace %d to %s",
- num, name ? name : "none");
-
- /* NULL and empty string both mean "default" here,
- * and we also need to match the name against its default value
- * to avoid saving it literally. */
- if (g_strcmp0 (name, meta_prefs_get_workspace_name (num)) == 0)
- {
- if (!name || !*name)
- meta_topic (META_DEBUG_PREFS,
- "Workspace %d already uses default name", num);
- else
- meta_topic (META_DEBUG_PREFS,
- "Workspace %d already has name %s", num, name);
- return;
- }
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY);
- n_workspace_names = workspace_names ? g_strv_length (workspace_names) : 0;
-
- for (i = 0; i < MAX (num + 1, n_workspace_names); i++)
- {
- const char *value;
-
- if (i == num)
- value = name ? name : "";
- else if (i < n_workspace_names)
- value = workspace_names[i] ? workspace_names[i] : "";
- else
- value = "";
-
- g_variant_builder_add (&builder, "s", value);
- }
-
- g_settings_set_value (SETTINGS (SCHEMA_GENERAL), KEY_WORKSPACE_NAMES,
- g_variant_builder_end (&builder));
-}
-
-/**
- * meta_prefs_get_button_layout:
- * @button_layout: (out):
- */
-void
-meta_prefs_get_button_layout (MetaButtonLayout *button_layout_p)
-{
- *button_layout_p = button_layout;
-}
-
-gboolean
-meta_prefs_get_visual_bell (void)
-{
- return bell_is_visible;
-}
-
-gboolean
-meta_prefs_bell_is_audible (void)
-{
- return bell_is_audible;
-}
-
-GDesktopVisualBellType
-meta_prefs_get_visual_bell_type (void)
-{
- return visual_bell_type;
-}
-
-gboolean
-meta_prefs_add_keybinding (const char *name,
- GSettings *settings,
- MetaKeyBindingAction action,
- MetaKeyBindingFlags flags)
-{
- MetaKeyPref *pref;
- char **strokes;
- guint id;
-
- if (g_hash_table_lookup (key_bindings, name))
- {
- meta_warning ("Trying to re-add keybinding \"%s\".", name);
- return FALSE;
- }
-
- pref = g_new0 (MetaKeyPref, 1);
- pref->name = g_strdup (name);
- pref->settings = g_object_ref (settings);
- pref->action = action;
- pref->combos = NULL;
- pref->builtin = (flags & META_KEY_BINDING_BUILTIN) != 0;
-
- if (pref->builtin)
- {
- if (g_object_get_data (G_OBJECT (settings), "changed-signal") == NULL)
- {
- id = g_signal_connect (settings, "changed",
- G_CALLBACK (bindings_changed), NULL);
- g_object_set_data (G_OBJECT (settings), "changed-signal", GUINT_TO_POINTER (id));
- }
- }
- else
- {
- char *changed_signal = g_strdup_printf ("changed::%s", name);
- id = g_signal_connect (settings, changed_signal,
- G_CALLBACK (bindings_changed), NULL);
- g_free (changed_signal);
-
- g_object_set_data (G_OBJECT (settings), name, GUINT_TO_POINTER (id));
-
- queue_changed (META_PREF_KEYBINDINGS);
- }
-
- strokes = g_settings_get_strv (settings, name);
- update_binding (pref, strokes);
- g_strfreev (strokes);
-
- g_hash_table_insert (key_bindings, g_strdup (name), pref);
-
- return TRUE;
-}
-
-gboolean
-meta_prefs_remove_keybinding (const char *name)
-{
- MetaKeyPref *pref;
- gulong id;
-
- pref = g_hash_table_lookup (key_bindings, name);
- if (!pref)
- {
- meta_warning ("Trying to remove non-existent keybinding \"%s\".", name);
- return FALSE;
- }
-
- if (pref->builtin)
- {
- meta_warning ("Trying to remove builtin keybinding \"%s\".", name);
- return FALSE;
- }
-
- id = GPOINTER_TO_UINT (g_object_steal_data (G_OBJECT (pref->settings), name));
- g_clear_signal_handler (&id, pref->settings);
-
- g_hash_table_remove (key_bindings, name);
-
- queue_changed (META_PREF_KEYBINDINGS);
-
- return TRUE;
-}
-
-GList *
-meta_prefs_get_keybindings (void)
-{
- return g_hash_table_get_values (key_bindings);
-}
-
-void
-meta_prefs_get_overlay_binding (MetaKeyCombo *combo)
-{
- *combo = overlay_key_combo;
-}
-
-void
-meta_prefs_get_locate_pointer_binding (MetaKeyCombo *combo)
-{
- *combo = locate_pointer_key_combo;
-}
-
-gboolean
-meta_prefs_is_locate_pointer_enabled (void)
-{
- return locate_pointer_is_enabled;
-}
-
-unsigned int
-meta_prefs_get_check_alive_timeout (void)
-{
- return check_alive_timeout;
-}
-
-const char *
-meta_prefs_get_iso_next_group_option (void)
-{
- return iso_next_group_option;
-}
-
-GDesktopTitlebarAction
-meta_prefs_get_action_double_click_titlebar (void)
-{
- return action_double_click_titlebar;
-}
-
-GDesktopTitlebarAction
-meta_prefs_get_action_middle_click_titlebar (void)
-{
- return action_middle_click_titlebar;
-}
-
-GDesktopTitlebarAction
-meta_prefs_get_action_right_click_titlebar (void)
-{
- return action_right_click_titlebar;
-}
-
-gboolean
-meta_prefs_get_auto_raise (void)
-{
- return auto_raise;
-}
-
-int
-meta_prefs_get_auto_raise_delay (void)
-{
- return auto_raise_delay;
-}
-
-gboolean
-meta_prefs_get_focus_change_on_pointer_rest (void)
-{
- return focus_change_on_pointer_rest;
-}
-
-gboolean
-meta_prefs_get_gnome_accessibility (void)
-{
- return gnome_accessibility;
-}
-
-gboolean
-meta_prefs_get_gnome_animations (void)
-{
- return gnome_animations;
-}
-
-gboolean
-meta_prefs_get_edge_tiling (void)
-{
- return edge_tiling;
-}
-
-gboolean
-meta_prefs_get_auto_maximize (void)
-{
- return auto_maximize;
-}
-
-MetaKeyBindingAction
-meta_prefs_get_keybinding_action (const char *name)
-{
- MetaKeyPref *pref = g_hash_table_lookup (key_bindings, name);
-
- return pref ? pref->action
- : META_KEYBINDING_ACTION_NONE;
-}
-
-gint
-meta_prefs_get_mouse_button_resize (void)
-{
- return resize_with_right_button ? 3: 2;
-}
-
-gint
-meta_prefs_get_mouse_button_menu (void)
-{
- return resize_with_right_button ? 2: 3;
-}
-
-gboolean
-meta_prefs_get_force_fullscreen (void)
-{
- return force_fullscreen;
-}
-
-gboolean
-meta_prefs_get_workspaces_only_on_primary (void)
-{
- return workspaces_only_on_primary;
-}
-
-int
-meta_prefs_get_draggable_border_width (void)
-{
- return draggable_border_width;
-}
-
-int
-meta_prefs_get_drag_threshold (void)
-{
- return drag_threshold;
-}
-
-void
-meta_prefs_set_force_fullscreen (gboolean whether)
-{
- force_fullscreen = whether;
-}