gtksettings.c 93.4 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * Copyright (C) 2000 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

19

20 21
#define PANGO_ENABLE_BACKEND /* for pango_fc_font_map_cache_clear() */

22
#include "config.h"
23 24 25

#include <string.h>

26
#include "gtkmodules.h"
Havoc Pennington's avatar
Havoc Pennington committed
27
#include "gtksettings.h"
28
#include "gtkrc.h"
Havoc Pennington's avatar
Havoc Pennington committed
29
#include "gtkintl.h"
30
#include "gtkwidget.h"
31
#include "gtktypeutils.h"
32
#include "gtkprivate.h"
33

34 35
#ifdef GDK_WINDOWING_X11
#include "x11/gdkx.h"
36
#include <pango/pangofc-fontmap.h>
37 38
#endif

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

/**
 * SECTION:gtksettings
 * @Short_description: Sharing settings between applications
 * @Title: Settings
 *
 * GtkSettings provide a mechanism to share global settings between applications.
 * On the X window system, this sharing is realized by an
 * <ulink url="http://www.freedesktop.org/wiki/Specifications/xsettings-spec">XSettings</ulink>
 * manager that is usually part of the desktop environment, along with utilities
 * that let the user change these settings. In the absence of an Xsettings manager,
 * settings can also be specified in RC files.
 *
 * Applications can override system-wide settings with gtk_settings_set_string_property(),
 * gtk_settings_set_long_property(), etc. This should be restricted to special
 * cases though; GtkSettings are not meant as an application configuration
 * facility. When doing so, you need to be aware that settings that are specific
 * to individual widgets may not be available before the widget type has been
 * realized at least once. The following example demonstrates a way to do this:
 * <informalexample><programlisting>
 *   gtk_init (&argc, &argv);
 *
 *   /&ast; make sure the type is realized &ast;/
 *   g_type_class_unref (g_type_class_ref (GTK_TYPE_IMAGE_MENU_ITEM));
 *
 *   g_object_set (gtk_settings_get_default (), "gtk-menu-images", FALSE, NULL);
 * </programlisting></informalexample>
 *
 * There is one GtkSettings instance per screen. It can be obtained with
 * gtk_settings_get_for_screen(), but in many cases, it is more convenient
 * to use gtk_widget_get_settings(). gtk_settings_get_default() returns the
 * GtkSettings instance for the default screen.
 */


Yevgen Muntyan's avatar
Yevgen Muntyan committed
74 75 76 77 78 79
#ifdef GDK_WINDOWING_QUARTZ
#define DEFAULT_KEY_THEME "Mac"
#else
#define DEFAULT_KEY_THEME NULL
#endif

80 81
#define DEFAULT_TIMEOUT_INITIAL 200
#define DEFAULT_TIMEOUT_REPEAT   20
82
#define DEFAULT_TIMEOUT_EXPAND  500
83

84 85
typedef struct _GtkSettingsValuePrivate GtkSettingsValuePrivate;

86 87 88 89
typedef enum
{
  GTK_SETTINGS_SOURCE_DEFAULT,
  GTK_SETTINGS_SOURCE_RC_FILE,
90
  GTK_SETTINGS_SOURCE_XSETTING,
91 92 93
  GTK_SETTINGS_SOURCE_APPLICATION
} GtkSettingsSource;

94 95 96
struct _GtkSettingsValuePrivate
{
  GtkSettingsValue public;
97
  GtkSettingsSource source;
98 99 100 101 102
};

struct _GtkSettingsPropertyValue
{
  GValue value;
103
  GtkSettingsSource source;
104 105
};

106 107
enum {
  PROP_0,
108
  PROP_DOUBLE_CLICK_TIME,
109
  PROP_DOUBLE_CLICK_DISTANCE,
110 111
  PROP_CURSOR_BLINK,
  PROP_CURSOR_BLINK_TIME,
112
  PROP_CURSOR_BLINK_TIMEOUT,
113 114
  PROP_SPLIT_CURSOR,
  PROP_THEME_NAME,
115
  PROP_ICON_THEME_NAME,
116
  PROP_FALLBACK_ICON_THEME,
Havoc Pennington's avatar
Havoc Pennington committed
117
  PROP_KEY_THEME_NAME,
Anders Carlsson's avatar
Anders Carlsson committed
118
  PROP_MENU_BAR_ACCEL,
119
  PROP_DND_DRAG_THRESHOLD,
120
  PROP_FONT_NAME,
121
  PROP_ICON_SIZES,
122
  PROP_MODULES,
123
#ifdef GDK_WINDOWING_X11
124 125 126 127
  PROP_XFT_ANTIALIAS,
  PROP_XFT_HINTING,
  PROP_XFT_HINTSTYLE,
  PROP_XFT_RGBA,
128
  PROP_XFT_DPI,
129 130
  PROP_CURSOR_THEME_NAME,
  PROP_CURSOR_THEME_SIZE,
131
#endif
132
  PROP_ALTERNATIVE_BUTTON_ORDER,
133
  PROP_ALTERNATIVE_SORT_ARROWS,
134
  PROP_SHOW_INPUT_METHOD_MENU,
135 136
  PROP_SHOW_UNICODE_MENU,
  PROP_TIMEOUT_INITIAL,
137
  PROP_TIMEOUT_REPEAT,
138
  PROP_TIMEOUT_EXPAND,
139
  PROP_COLOR_SCHEME,
140
  PROP_ENABLE_ANIMATIONS,
141
  PROP_TOUCHSCREEN_MODE,
Kristian Rietveld's avatar
Kristian Rietveld committed
142 143 144
  PROP_TOOLTIP_TIMEOUT,
  PROP_TOOLTIP_BROWSE_TIMEOUT,
  PROP_TOOLTIP_BROWSE_MODE_TIMEOUT,
145 146 147
  PROP_KEYNAV_CURSOR_ONLY,
  PROP_KEYNAV_WRAP_AROUND,
  PROP_ERROR_BELL,
148 149 150
  PROP_COLOR_HASH,
  PROP_FILE_CHOOSER_BACKEND,
  PROP_PRINT_BACKENDS,
151 152
  PROP_PRINT_PREVIEW_COMMAND,
  PROP_ENABLE_MNEMONICS,
153
  PROP_ENABLE_ACCELS,
154
  PROP_RECENT_FILES_LIMIT,
155
  PROP_IM_MODULE,
156
  PROP_RECENT_FILES_MAX_AGE,
157 158 159
  PROP_FONTCONFIG_TIMESTAMP,
  PROP_SOUND_THEME_NAME,
  PROP_ENABLE_INPUT_FEEDBACK_SOUNDS,
160
  PROP_ENABLE_EVENT_SOUNDS,
161 162
  PROP_ENABLE_TOOLTIPS,
  PROP_TOOLBAR_STYLE,
163
  PROP_TOOLBAR_ICON_SIZE,
164
  PROP_AUTO_MNEMONICS,
165 166 167 168 169 170 171 172 173 174 175 176 177 178
  PROP_APPLICATION_PREFER_DARK_THEME,
  PROP_BUTTON_IMAGES,
  PROP_ENTRY_SELECT_ON_FOCUS,
  PROP_ENTRY_PASSWORD_HINT_TIMEOUT,
  PROP_MENU_IMAGES,
  PROP_MENU_BAR_POPUP_DELAY,
  PROP_SCROLLED_WINDOW_PLACEMENT,
  PROP_CAN_CHANGE_ACCELS,
  PROP_MENU_POPUP_DELAY,
  PROP_MENU_POPDOWN_DELAY,
  PROP_LABEL_SELECT_ON_FOCUS,
  PROP_COLOR_PALETTE,
  PROP_IM_PREEDIT_STYLE,
  PROP_IM_STATUS_STYLE
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
};

/* --- prototypes --- */
static void	gtk_settings_finalize		 (GObject		*object);
static void	gtk_settings_get_property	 (GObject		*object,
						  guint			 property_id,
						  GValue		*value,
						  GParamSpec		*pspec);
static void	gtk_settings_set_property	 (GObject		*object,
						  guint			 property_id,
						  const GValue		*value,
						  GParamSpec		*pspec);
static void	gtk_settings_notify		 (GObject		*object,
						  GParamSpec		*pspec);
static guint	settings_install_property_parser (GtkSettingsClass      *class,
						  GParamSpec            *pspec,
						  GtkRcPropertyParser    parser);
196
static void    settings_update_double_click      (GtkSettings           *settings);
197 198
static void    settings_update_modules           (GtkSettings           *settings);

199 200
#ifdef GDK_WINDOWING_X11
static void    settings_update_cursor_theme      (GtkSettings           *settings);
201 202
static void    settings_update_resolution        (GtkSettings           *settings);
static void    settings_update_font_options      (GtkSettings           *settings);
203
static gboolean settings_update_fontconfig       (GtkSettings           *settings);
204
#endif
205
static void    settings_update_color_scheme      (GtkSettings *settings);
206

207
static void    merge_color_scheme                (GtkSettings           *settings, 
208
						  const GValue          *value, 
209 210 211
						  GtkSettingsSource      source);
static gchar  *get_color_scheme                  (GtkSettings           *settings);
static GHashTable *get_color_hash                (GtkSettings           *settings);
212

213 214 215 216
/* the default palette for GtkColorSelelection */
static const gchar default_color_palette[] =
  "black:white:gray50:red:purple:blue:light blue:green:yellow:orange:"
  "lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90";
217 218 219 220 221 222 223

/* --- variables --- */
static GQuark		 quark_property_parser = 0;
static GSList           *object_list = NULL;
static guint		 class_n_properties = 0;


Matthias Clasen's avatar
Matthias Clasen committed
224
G_DEFINE_TYPE (GtkSettings, gtk_settings, G_TYPE_OBJECT)
225

Matthias Clasen's avatar
Matthias Clasen committed
226
/* --- functions --- */
227 228 229
static void
gtk_settings_init (GtkSettings *settings)
{
Tim Janik's avatar
Tim Janik committed
230 231
  GParamSpec **pspecs, **p;
  guint i = 0;
232 233 234 235 236 237 238 239
  
  g_datalist_init (&settings->queued_settings);
  object_list = g_slist_prepend (object_list, settings);

  /* build up property array for all yet existing properties and queue
   * notification for them (at least notification for internal properties
   * will instantly be caught)
   */
Tim Janik's avatar
Tim Janik committed
240 241 242 243
  pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (settings), NULL);
  for (p = pspecs; *p; p++)
    if ((*p)->owner_type == G_OBJECT_TYPE (settings))
      i++;
244
  settings->property_values = g_new0 (GtkSettingsPropertyValue, i);
Tim Janik's avatar
Tim Janik committed
245
  i = 0;
Hans Breuer's avatar
Hans Breuer committed
246
  g_object_freeze_notify (G_OBJECT (settings));
Tim Janik's avatar
Tim Janik committed
247
  for (p = pspecs; *p; p++)
248
    {
Tim Janik's avatar
Tim Janik committed
249
      GParamSpec *pspec = *p;
250

Tim Janik's avatar
Tim Janik committed
251 252
      if (pspec->owner_type != G_OBJECT_TYPE (settings))
	continue;
253 254
      g_value_init (&settings->property_values[i].value, G_PARAM_SPEC_VALUE_TYPE (pspec));
      g_param_value_set_default (pspec, &settings->property_values[i].value);
255
      g_object_notify (G_OBJECT (settings), pspec->name);
256
      settings->property_values[i].source = GTK_SETTINGS_SOURCE_DEFAULT;
Tim Janik's avatar
Tim Janik committed
257
      i++;
258
    }
Hans Breuer's avatar
Hans Breuer committed
259
  g_object_thaw_notify (G_OBJECT (settings));
Tim Janik's avatar
Tim Janik committed
260
  g_free (pspecs);
261 262 263 264 265 266
}

static void
gtk_settings_class_init (GtkSettingsClass *class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
Havoc Pennington's avatar
Havoc Pennington committed
267
  guint result;
268 269 270 271 272 273 274
  
  gobject_class->finalize = gtk_settings_finalize;
  gobject_class->get_property = gtk_settings_get_property;
  gobject_class->set_property = gtk_settings_set_property;
  gobject_class->notify = gtk_settings_notify;

  quark_property_parser = g_quark_from_static_string ("gtk-rc-property-parser");
Havoc Pennington's avatar
Havoc Pennington committed
275
  result = settings_install_property_parser (class,
276
                                             g_param_spec_int ("gtk-double-click-time",
277 278
                                                               P_("Double Click Time"),
                                                               P_("Maximum time allowed between two clicks for them to be considered a double click (in milliseconds)"),
279
                                                               0, G_MAXINT, 250,
280
                                                               GTK_PARAM_READWRITE),
Havoc Pennington's avatar
Havoc Pennington committed
281
                                             NULL);
282
  g_assert (result == PROP_DOUBLE_CLICK_TIME);
283 284
  result = settings_install_property_parser (class,
                                             g_param_spec_int ("gtk-double-click-distance",
285 286
                                                               P_("Double Click Distance"),
                                                               P_("Maximum distance allowed between two clicks for them to be considered a double click (in pixels)"),
287
                                                               0, G_MAXINT, 5,
288
                                                               GTK_PARAM_READWRITE),
289 290
                                             NULL);
  g_assert (result == PROP_DOUBLE_CLICK_DISTANCE);
291 292 293 294 295 296

  /**
   * GtkSettings:gtk-cursor-blink:
   *
   * Whether the cursor should blink. 
   *
297 298
   * Also see the #GtkSettings:gtk-cursor-blink-timeout setting, 
   * which allows more flexible control over cursor blinking.
299
   */
300 301
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-cursor-blink",
302 303
								   P_("Cursor Blink"),
								   P_("Whether the cursor should blink"),
304
								   TRUE,
305
								   GTK_PARAM_READWRITE),
306 307 308 309
					     NULL);
  g_assert (result == PROP_CURSOR_BLINK);
  result = settings_install_property_parser (class,
                                             g_param_spec_int ("gtk-cursor-blink-time",
310
                                                               P_("Cursor Blink Time"),
311
                                                               P_("Length of the cursor blink cycle, in milliseconds"),
312
                                                               100, G_MAXINT, 1200,
313
                                                               GTK_PARAM_READWRITE),
314 315
                                             NULL);
  g_assert (result == PROP_CURSOR_BLINK_TIME);
316 317 318 319 320 321 322 323
 
  /**
   * GtkSettings:gtk-cursor-blink-timeout:
   *
   * Time after which the cursor stops blinking, in seconds.
   * The timer is reset after each user interaction.
   *
   * Setting this to zero has the same effect as setting
Matthias Clasen's avatar
Matthias Clasen committed
324
   * #GtkSettings:gtk-cursor-blink to %FALSE. 
325 326 327 328 329 330 331 332 333 334 335
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_int ("gtk-cursor-blink-timeout",
                                                               P_("Cursor Blink Timeout"),
                                                               P_("Time after which the cursor stops blinking, in seconds"),
                                                               1, G_MAXINT, G_MAXINT,
                                                               GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_CURSOR_BLINK_TIMEOUT);
336 337
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-split-cursor",
338 339
								   P_("Split Cursor"),
								   P_("Whether two cursors should be displayed for mixed left-to-right and right-to-left text"),
340
								   TRUE,
341
								   GTK_PARAM_READWRITE),
342 343
                                             NULL);
  g_assert (result == PROP_SPLIT_CURSOR);
344 345
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-theme-name",
346 347
								   P_("Theme Name"),
								   P_("Name of theme RC file to load"),
348
								  "Raleigh",
349
								  GTK_PARAM_READWRITE),
350 351
                                             NULL);
  g_assert (result == PROP_THEME_NAME);
352

353 354
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-icon-theme-name",
355 356
								  P_("Icon Theme Name"),
								  P_("Name of icon theme to use"),
357
								  "hicolor",
358
								  GTK_PARAM_READWRITE),
359
                                             NULL);
Owen Taylor's avatar
Owen Taylor committed
360
  g_assert (result == PROP_ICON_THEME_NAME);
361 362 363 364 365 366 367 368 369

  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-fallback-icon-theme",
								  P_("Fallback Icon Theme Name"),
								  P_("Name of a icon theme to fall back to"),
								  NULL,
								  GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_FALLBACK_ICON_THEME);
Owen Taylor's avatar
Owen Taylor committed
370
  
371 372
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-key-theme-name",
373 374
								  P_("Key Theme Name"),
								  P_("Name of key theme RC file to load"),
Yevgen Muntyan's avatar
Yevgen Muntyan committed
375
								  DEFAULT_KEY_THEME,
376
								  GTK_PARAM_READWRITE),
377
                                             NULL);
Havoc Pennington's avatar
Havoc Pennington committed
378 379 380 381
  g_assert (result == PROP_KEY_THEME_NAME);    

  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-menu-bar-accel",
382 383
                                                                  P_("Menu bar accelerator"),
                                                                  P_("Keybinding to activate the menu bar"),
Havoc Pennington's avatar
Havoc Pennington committed
384
                                                                  "F10",
385
                                                                  GTK_PARAM_READWRITE),
Havoc Pennington's avatar
Havoc Pennington committed
386 387
                                             NULL);
  g_assert (result == PROP_MENU_BAR_ACCEL);
Anders Carlsson's avatar
Anders Carlsson committed
388 389 390

  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-dnd-drag-threshold",
391 392
							       P_("Drag threshold"),
							       P_("Number of pixels the cursor can move before dragging"),
Anders Carlsson's avatar
Anders Carlsson committed
393
							       1, G_MAXINT, 8,
394
                                                               GTK_PARAM_READWRITE),
Anders Carlsson's avatar
Anders Carlsson committed
395 396
					     NULL);
  g_assert (result == PROP_DND_DRAG_THRESHOLD);
397 398 399

  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-font-name",
400 401
								   P_("Font Name"),
								   P_("Name of default font to use"),
402
								  "Sans 10",
403
								  GTK_PARAM_READWRITE),
404 405
                                             NULL);
  g_assert (result == PROP_FONT_NAME);
406

407 408 409 410 411 412 413 414 415 416 417 418 419 420
  /**
   * GtkSettings:gtk-icon-sizes:
   *
   * A list of icon sizes. The list is separated by colons, and
   * item has the form:
   *
   * <replaceable>size-name</replaceable> = <replaceable>width</replaceable> , <replaceable>height</replaceable>
   *
   * E.g. "gtk-menu=16,16:gtk-button=20,20:gtk-dialog=48,48". 
   * GTK+ itself use the following named icon sizes: gtk-menu, 
   * gtk-button, gtk-small-toolbar, gtk-large-toolbar, gtk-dnd, 
   * gtk-dialog. Applications can register their own named icon 
   * sizes with gtk_icon_size_register().
   */
421 422
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-icon-sizes",
423
								   P_("Icon Sizes"),
424
								   P_("List of icon sizes (gtk-menu=16,16:gtk-button=20,20..."),
425
								  NULL,
426
								  GTK_PARAM_READWRITE),
427 428
                                             NULL);
  g_assert (result == PROP_ICON_SIZES);
429

430 431 432 433 434
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-modules",
								  P_("GTK Modules"),
								  P_("List of currently active GTK modules"),
								  NULL,
435
								  GTK_PARAM_READWRITE),
436 437 438
                                             NULL);
  g_assert (result == PROP_MODULES);

439 440 441
#ifdef GDK_WINDOWING_X11
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-xft-antialias",
442 443
 							       P_("Xft Antialias"),
 							       P_("Whether to antialias Xft fonts; 0=no, 1=yes, -1=default"),
444
 							       -1, 1, -1,
445
 							       GTK_PARAM_READWRITE),
446 447 448 449 450 451
					     NULL);
 
  g_assert (result == PROP_XFT_ANTIALIAS);
  
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-xft-hinting",
452 453
 							       P_("Xft Hinting"),
 							       P_("Whether to hint Xft fonts; 0=no, 1=yes, -1=default"),
454
 							       -1, 1, -1,
455
 							       GTK_PARAM_READWRITE),
456 457 458 459 460 461
					     NULL);
  
  g_assert (result == PROP_XFT_HINTING);
  
  result = settings_install_property_parser (class,
					     g_param_spec_string ("gtk-xft-hintstyle",
462
 								  P_("Xft Hint Style"),
463
 								  P_("What degree of hinting to use; hintnone, hintslight, hintmedium, or hintfull"),
464
 								  NULL,
465
 								  GTK_PARAM_READWRITE),
466 467 468 469 470 471
                                              NULL);
  
  g_assert (result == PROP_XFT_HINTSTYLE);
  
  result = settings_install_property_parser (class,
					     g_param_spec_string ("gtk-xft-rgba",
472 473
 								  P_("Xft RGBA"),
 								  P_("Type of subpixel antialiasing; none, rgb, bgr, vrgb, vbgr"),
474
 								  NULL,
475
 								  GTK_PARAM_READWRITE),
476 477 478 479 480 481
					     NULL);
  
  g_assert (result == PROP_XFT_RGBA);
  
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-xft-dpi",
482 483
 							       P_("Xft DPI"),
 							       P_("Resolution for Xft, in 1024 * dots/inch. -1 to use default value"),
484
 							       -1, 1024*1024, -1,
485
 							       GTK_PARAM_READWRITE),
486 487 488
					     NULL);
  
  g_assert (result == PROP_XFT_DPI);
489 490 491 492

  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-cursor-theme-name",
								  P_("Cursor theme name"),
493
								  P_("Name of the cursor theme to use, or NULL to use the default theme"),
494 495 496 497 498 499 500 501
								  NULL,
								  GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_CURSOR_THEME_NAME);

  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-cursor-theme-size",
 							       P_("Cursor theme size"),
502 503
 							       P_("Size to use for cursors, or 0 to use the default size"),
 							       0, 128, 0,
504 505 506 507 508
 							       GTK_PARAM_READWRITE),
					     NULL);
  
  g_assert (result == PROP_CURSOR_THEME_SIZE);

509
#endif  /* GDK_WINDOWING_X11 */
510 511 512 513 514
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-alternative-button-order",
								   P_("Alternative button order"),
								   P_("Whether buttons in dialogs should use the alternative button order"),
								   FALSE,
515
								   GTK_PARAM_READWRITE),
516 517
                                             NULL);
  g_assert (result == PROP_ALTERNATIVE_BUTTON_ORDER);
518

519 520 521 522
  /**
   * GtkSettings:gtk-alternative-sort-arrows:
   *
   * Controls the direction of the sort indicators in sorted list and tree
523 524
   * views. By default an arrow pointing down means the column is sorted
   * in ascending order. When set to %TRUE, this order will be inverted.
525 526 527 528 529 530 531 532 533 534 535 536
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-alternative-sort-arrows",
								   P_("Alternative sort indicator direction"),
								   P_("Whether the direction of the sort indicators in list and tree views is inverted compared to the default (where down means ascending)"),
								   FALSE,
								   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ALTERNATIVE_SORT_ARROWS);

537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
  result = settings_install_property_parser (class,
					     g_param_spec_boolean ("gtk-show-input-method-menu",
								   P_("Show the 'Input Methods' menu"),
								   P_("Whether the context menus of entries and text views should offer to change the input method"),
								   TRUE,
								   GTK_PARAM_READWRITE),
					     NULL);
  g_assert (result == PROP_SHOW_INPUT_METHOD_MENU);

  result = settings_install_property_parser (class,
					     g_param_spec_boolean ("gtk-show-unicode-menu",
								   P_("Show the 'Insert Unicode Control Character' menu"),
								   P_("Whether the context menus of entries and text views should offer to insert control characters"),
								   TRUE,
								   GTK_PARAM_READWRITE),
					     NULL);
  g_assert (result == PROP_SHOW_UNICODE_MENU);

555 556 557 558 559
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-timeout-initial",
 							       P_("Start timeout"),
 							       P_("Starting value for timeouts, when button is pressed"),
 							       0, G_MAXINT, DEFAULT_TIMEOUT_INITIAL,
560
 							       GTK_PARAM_READWRITE),
561 562 563 564 565 566 567 568 569
					     NULL);

  g_assert (result == PROP_TIMEOUT_INITIAL);

  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-timeout-repeat",
 							       P_("Repeat timeout"),
 							       P_("Repeat value for timeouts, when button is pressed"),
 							       0, G_MAXINT, DEFAULT_TIMEOUT_REPEAT,
570
 							       GTK_PARAM_READWRITE),
571 572 573
					     NULL);

  g_assert (result == PROP_TIMEOUT_REPEAT);
574

575 576 577 578 579 580 581 582 583 584
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-timeout-expand",
 							       P_("Expand timeout"),
 							       P_("Expand value for timeouts, when a widget is expanding a new region"),
 							       0, G_MAXINT, DEFAULT_TIMEOUT_EXPAND,
 							       GTK_PARAM_READWRITE),
					     NULL);

  g_assert (result == PROP_TIMEOUT_EXPAND);

585 586 587 588 589 590 591 592 593 594 595 596 597 598
  /**
   * GtkSettings:gtk-color-scheme:
   *
   * A palette of named colors for use in themes. The format of the string is
   * <programlisting>
   * name1: color1
   * name2: color2
   * ...
   * </programlisting>
   * Color names must be acceptable as identifiers in the 
   * <link linkend="gtk-Resource-Files">gtkrc</link> syntax, and
   * color specifications must be in the format accepted by
   * gdk_color_parse().
   * 
599 600 601 602
   * Note that due to the way the color tables from different sources are
   * merged, color specifications will be converted to hexadecimal form
   * when getting this property.
   *
603 604 605 606 607 608
   * Starting with GTK+ 2.12, the entries can alternatively be separated
   * by ';' instead of newlines:
   * <programlisting>
   * name1: color1; name2: color2; ...
   * </programlisting>
   *
609 610
   * Since: 2.10
   */
611 612 613 614
  result = settings_install_property_parser (class,
					     g_param_spec_string ("gtk-color-scheme",
 								  P_("Color scheme"),
 								  P_("A palette of named colors for use in themes"),
615
 								  "",
616 617 618 619
 								  GTK_PARAM_READWRITE),
					     NULL);

  g_assert (result == PROP_COLOR_SCHEME);
620 621 622 623 624 625 626 627 628 629

  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-enable-animations",
                                                                   P_("Enable Animations"),
                                                                   P_("Whether to enable toolkit-wide animations."),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);

  g_assert (result == PROP_ENABLE_ANIMATIONS);
630

631 632 633
  /**
   * GtkSettings:gtk-touchscreen-mode:
   *
634
   * When %TRUE, there are no motion notify events delivered on this screen,
635 636 637 638 639 640 641 642 643 644 645 646 647 648
   * and widgets can't use the pointer hovering them for any essential
   * functionality.
   *
   * Since: 2.10
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-touchscreen-mode",
                                                                   P_("Enable Touchscreen Mode"),
                                                                   P_("When TRUE, there are no motion notify events delivered on this screen"),
                                                                   FALSE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);

  g_assert (result == PROP_TOUCHSCREEN_MODE);
649

Kristian Rietveld's avatar
Kristian Rietveld committed
650 651 652 653 654 655 656 657 658 659
  /**
   * GtkSettings:gtk-tooltip-timeout:
   *
   * Time, in milliseconds, after which a tooltip could appear if the
   * cursor is hovering on top of a widget.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-tooltip-timeout",
660 661 662 663 664
							       P_("Tooltip timeout"),
							       P_("Timeout before tooltip is shown"),
							       0, G_MAXINT,
							       500,
							       GTK_PARAM_READWRITE),
Kristian Rietveld's avatar
Kristian Rietveld committed
665 666 667 668 669 670 671 672 673 674 675
					     NULL);

  g_assert (result == PROP_TOOLTIP_TIMEOUT);

  /**
   * GtkSettings:gtk-tooltip-browse-timeout:
   *
   * Controls the time after which tooltips will appear when
   * browse mode is enabled, in milliseconds.
   *
   * Browse mode is enabled when the mouse pointer moves off an object
676
   * where a tooltip was currently being displayed. If the mouse pointer
Kristian Rietveld's avatar
Kristian Rietveld committed
677
   * hits another object before the browse mode timeout expires (see
678 679
   * #GtkSettings:gtk-tooltip-browse-mode-timeout), it will take the 
   * amount of milliseconds specified by this setting to popup the tooltip
Kristian Rietveld's avatar
Kristian Rietveld committed
680 681 682 683 684 685
   * for the new object.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-tooltip-browse-timeout",
686 687 688 689 690
							       P_("Tooltip browse timeout"),
							       P_("Timeout before tooltip is shown when browse mode is enabled"),
							       0, G_MAXINT,
							       60,
							       GTK_PARAM_READWRITE),
Kristian Rietveld's avatar
Kristian Rietveld committed
691 692 693 694 695 696 697 698 699 700
					     NULL);

  g_assert (result == PROP_TOOLTIP_BROWSE_TIMEOUT);

  /**
   * GtkSettings:gtk-tooltip-browse-mode-timeout:
   *
   * Amount of time, in milliseconds, after which the browse mode
   * will be disabled.
   *
701
   * See #GtkSettings:gtk-tooltip-browse-timeout for more information
Kristian Rietveld's avatar
Kristian Rietveld committed
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
   * about browse mode.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-tooltip-browse-mode-timeout",
 							       P_("Tooltip browse mode timeout"),
 							       P_("Timeout after which browse mode is disabled"),
 							       0, G_MAXINT,
							       500,
 							       GTK_PARAM_READWRITE),
					     NULL);

  g_assert (result == PROP_TOOLTIP_BROWSE_MODE_TIMEOUT);

717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
  /**
   * GtkSettings:gtk-keynav-cursor-only:
   *
   * When %TRUE, keyboard navigation should be able to reach all widgets
   * by using the cursor keys only. Tab, Shift etc. keys can't be expected
   * to be present on the used input device.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-keynav-cursor-only",
                                                                   P_("Keynav Cursor Only"),
                                                                   P_("When TRUE, there are only cursor keys available to navigate widgets"),
                                                                   FALSE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);

  g_assert (result == PROP_KEYNAV_CURSOR_ONLY);

  /**
   * GtkSettings:gtk-keynav-wrap-around:
   *
   * When %TRUE, some widgets will wrap around when doing keyboard
   * navigation, such as menus, menubars and notebooks.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-keynav-wrap-around",
                                                                   P_("Keynav Wrap Around"),
                                                                   P_("Whether to wrap around when keyboard-navigating widgets"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);

  g_assert (result == PROP_KEYNAV_WRAP_AROUND);

  /**
   * GtkSettings:gtk-error-bell:
   *
   * When %TRUE, keyboard navigation and other input-related errors
   * will cause a beep. Since the error bell is implemented using
   * gdk_window_beep(), the windowing system may offer ways to
   * configure the error bell in many ways, such as flashing the
   * window or similar visual effects.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-error-bell",
                                                                   P_("Error Bell"),
                                                                   P_("When TRUE, keyboard navigation and other errors will cause a beep"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);

  g_assert (result == PROP_ERROR_BELL);

775 776 777
  /**
   * GtkSettings:color-hash:
   *
778 779
   * Holds a hash table representation of the #GtkSettings:gtk-color-scheme 
   * setting, mapping color names to #GdkColor<!-- -->s. 
780 781 782
   *
   * Since: 2.10
   */
783 784 785 786 787 788 789 790
  result = settings_install_property_parser (class, 
                                             g_param_spec_boxed ("color-hash",
                                                                 P_("Color Hash"),
                                                                 P_("A hash table representation of the color scheme."),
                                                                 G_TYPE_HASH_TABLE,
                                                                 GTK_PARAM_READABLE),
                                             NULL);
  g_assert (result == PROP_COLOR_HASH);
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805

  result = settings_install_property_parser (class, 
                                             g_param_spec_string ("gtk-file-chooser-backend",
                                                                  P_("Default file chooser backend"),
                                                                  P_("Name of the GtkFileChooser backend to use by default"),
                                                                  NULL,
                                                                  GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_FILE_CHOOSER_BACKEND);

  /**
   * GtkSettings:gtk-print-backends:
   *
   * A comma-separated list of print backends to use in the print
   * dialog. Available print backends depend on the GTK+ installation,
Matthias Clasen's avatar
Matthias Clasen committed
806
   * and may include "file", "cups", "lpr" or "papi".
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823
   *
   * Since: 2.10
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-print-backends",
                                                                  P_("Default print backend"),
                                                                  P_("List of the GtkPrintBackend backends to use by default"),
                                                                  GTK_PRINT_BACKENDS,
                                                                  GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_PRINT_BACKENDS);

  /**
   * GtkSettings:gtk-print-preview-command:
   *
   * A command to run for displaying the print preview. The command
   * should contain a %f placeholder, which will get replaced by
824 825 826 827
   * the path to the pdf file. The command may also contain a %s
   * placeholder, which will get replaced by the path to a file
   * containing the print settings in the format produced by 
   * gtk_print_settings_to_file().
828 829
   *
   * The preview application is responsible for removing the pdf file
830
   * and the print settings file when it is done.
831 832 833 834 835 836 837 838 839 840 841
   *
   * Since: 2.10
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-print-preview-command",
                                                                  P_("Default command to run when displaying a print preview"),
                                                                  P_("Command to run when displaying a print preview"),
                                                                  GTK_PRINT_PREVIEW_COMMAND,
                                                                  GTK_PARAM_READWRITE),
                                             NULL); 
  g_assert (result == PROP_PRINT_PREVIEW_COMMAND);
842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875

  /**
   * GtkSettings:gtk-enable-mnemonics:
   *
   * Whether labels and menu items should have visible mnemonics which
   * can be activated.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-enable-mnemonics",
                                                                   P_("Enable Mnemonics"),
                                                                   P_("Whether labels should have mnemonics"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ENABLE_MNEMONICS);

  /**
   * GtkSettings:gtk-enable-accels:
   *
   * Whether menu items should have visible accelerators which can be
   * activated.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-enable-accels",
                                                                   P_("Enable Accelerators"),
                                                                   P_("Whether menu items should have accelerators"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ENABLE_ACCELS);
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894

  /**
   * GtkSettings:gtk-recent-files-limit:
   *
   * The number of recently used files that should be displayed by default by
   * #GtkRecentChooser implementations and by the #GtkFileChooser. A value of
   * -1 means every recently used file stored.
   *
   * Since: 2.12
   */
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-recent-files-limit",
 							       P_("Recent Files Limit"),
 							       P_("Number of recently used files"),
 							       -1, G_MAXINT,
							       50,
 							       GTK_PARAM_READWRITE),
					     NULL);
  g_assert (result == PROP_RECENT_FILES_LIMIT);
895 896 897 898

  /**
   * GtkSettings:gtk-im-module:
   *
899 900 901 902 903
   * Which IM (input method) module should be used by default. This is the 
   * input method that will be used if the user has not explicitly chosen 
   * another input method from the IM context menu.  
   *
   * See #GtkIMContext and see the #GtkSettings:gtk-show-input-method-menu property.
904 905 906 907 908 909 910 911 912
   */
  result = settings_install_property_parser (class,
					     g_param_spec_string ("gtk-im-module",
								  P_("Default IM module"),
								  P_("Which IM module should be used by default"),
								  NULL,
								  GTK_PARAM_READWRITE),
					     NULL);
  g_assert (result == PROP_IM_MODULE);
913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932

  /**
   * GtkSettings:gtk-recent-files-max-age:
   *
   * The maximum age, in days, of the items inside the recently used
   * resources list. Items older than this setting will be excised
   * from the list. If set to 0, the list will always be empty; if
   * set to -1, no item will be removed.
   *
   * Since: 2.14
   */
  result = settings_install_property_parser (class,
					     g_param_spec_int ("gtk-recent-files-max-age",
 							       P_("Recent Files Max Age"),
 							       P_("Maximum age of recently used files, in days"),
 							       -1, G_MAXINT,
							       30,
 							       GTK_PARAM_READWRITE),
					     NULL);
  g_assert (result == PROP_RECENT_FILES_MAX_AGE);
933 934

  result = settings_install_property_parser (class,
935 936 937 938 939
					     g_param_spec_uint ("gtk-fontconfig-timestamp",
								P_("Fontconfig configuration timestamp"),
								P_("Timestamp of current fontconfig configuration"),
								0, G_MAXUINT, 0,
								GTK_PARAM_READWRITE),
940 941 942
					     NULL);
  
  g_assert (result == PROP_FONTCONFIG_TIMESTAMP);
943

944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
  /**
   * GtkSettings:gtk-sound-theme-name:
   *
   * The XDG sound theme to use for event sounds.
   *
   * See the <ulink url="http://www.freedesktop.org/wiki/Specifications/sound-theme-spec">Sound Theme spec</ulink> 
   * for more information on event sounds and sound themes.
   *
   * GTK+ itself does not support event sounds, you have to use a loadable 
   * module like the one that comes with libcanberra.
   *
   * Since: 2.14
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-sound-theme-name",
                                                                  P_("Sound Theme Name"),
                                                                  P_("XDG sound theme name"),
                                                                  "freedesktop",
                                                                  GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_SOUND_THEME_NAME);

  /**
   * GtkSettings:gtk-enable-input-feedback-sounds:
   *
   * Whether to play event sounds as feedback to user input.
   *
   * See the <ulink url="http://www.freedesktop.org/wiki/Specifications/sound-theme-spec">Sound Theme spec</ulink> 
   * for more information on event sounds and sound themes.
   *
   * GTK+ itself does not support event sounds, you have to use a loadable 
   * module like the one that comes with libcanberra.
   *
   * Since: 2.14
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-enable-input-feedback-sounds",
Matthias Clasen's avatar
Matthias Clasen committed
981
                                                                   /* Translators: this means sounds that are played as feedback to user input */
Matthias Clasen's avatar
Matthias Clasen committed
982
								   P_("Audible Input Feedback"),
983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
								   P_("Whether to play event sounds as feedback to user input"),
								   TRUE,
								   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ENABLE_INPUT_FEEDBACK_SOUNDS);

  /**
   * GtkSettings:gtk-enable-event-sounds:
   *
   * Whether to play any event sounds at all.
   *
   * See the <ulink url="http://www.freedesktop.org/wiki/Specifications/sound-theme-spec">Sound Theme spec</ulink> 
   * for more information on event sounds and sound themes.
   *
   * GTK+ itself does not support event sounds, you have to use a loadable 
   * module like the one that comes with libcanberra.
   *
   * Since: 2.14
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-enable-event-sounds",
								   P_("Enable Event Sounds"),
								   P_("Whether to play any event sounds at all"),
								   TRUE,
								   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ENABLE_EVENT_SOUNDS);
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025

  /**
   * GtkSettings:gtk-enable-tooltips:
   *
   * Whether tooltips should be shown on widgets.
   *
   * Since: 2.14
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-enable-tooltips",
                                                                   P_("Enable Tooltips"),
                                                                   P_("Whether tooltips should be shown on widgets"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ENABLE_TOOLTIPS);
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

  /**
   * GtkSettings:toolbar-style:
   *
   * The size of icons in default toolbars.
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_enum ("gtk-toolbar-style",
                                                                   P_("Toolbar style"),
                                                                   P_("Whether default toolbars have text only, text and icons, icons only, etc."),
                                                                   GTK_TYPE_TOOLBAR_STYLE,
                                                                   GTK_TOOLBAR_BOTH,
                                                                   GTK_PARAM_READWRITE),
1039
                                             gtk_rc_property_parse_enum);
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053
  g_assert (result == PROP_TOOLBAR_STYLE);

  /**
   * GtkSettings:toolbar-icon-size:
   *
   * The size of icons in default toolbars.
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_enum ("gtk-toolbar-icon-size",
                                                                   P_("Toolbar Icon Size"),
                                                                   P_("The size of icons in default toolbars."),
                                                                   GTK_TYPE_ICON_SIZE,
                                                                   GTK_ICON_SIZE_LARGE_TOOLBAR,
                                                                   GTK_PARAM_READWRITE),
1054
                                             gtk_rc_property_parse_enum);
1055
  g_assert (result == PROP_TOOLBAR_ICON_SIZE);
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072

  /**
   * GtkSettings:gtk-auto-mnemonics:
   *
   * Whether mnemonics should be automatically shown and hidden when the user
   * presses the mnemonic activator.
   *
   * Since: 2.20
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-auto-mnemonics",
                                                                   P_("Auto Mnemonics"),
                                                                   P_("Whether mnemonics should be automatically shown and hidden when the user presses the mnemonic activator."),
                                                                   FALSE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_AUTO_MNEMONICS);
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098

  /**
   * GtkSettings:gtk-application-prefer-dark-theme:
   *
   * Whether the application prefers to use a dark theme. If a GTK+ theme
   * includes a dark variant, it will be used instead of the configured
   * theme.
   *
   * Some applications benefit from minimizing the amount of light pollution that
   * interferes with the content. Good candidates for dark themes are photo and
   * video editors that make the actual content get all the attention and minimize
   * the distraction of the chrome.
   *
   * Dark themes should not be used for documents, where large spaces are white/light
   * and the dark chrome creates too much contrast (web browser, text editor...).
   *
   * Since: 2.22
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-application-prefer-dark-theme",
                                                                 P_("Application prefers a dark theme"),
                                                                 P_("Whether the application prefers to have a dark theme."),
                                                                 FALSE,
                                                                 GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_APPLICATION_PREFER_DARK_THEME);
1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246

  /**
   * GtkSettings::gtk-button-images:
   *
   * Whether images should be shown on buttons
   *
   * Since: 2.4
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-button-images",
                                                                   P_("Show button images"),
                                                                   P_("Whether images should be shown on buttons"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_BUTTON_IMAGES);

  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-entry-select-on-focus",
                                                                   P_("Select on focus"),
                                                                   P_("Whether to select the contents of an entry when it is focused"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ENTRY_SELECT_ON_FOCUS);

  /**
   * GtkSettings:gtk-entry-password-hint-timeout:
   *
   * How long to show the last input character in hidden
   * entries. This value is in milliseconds. 0 disables showing the
   * last char. 600 is a good value for enabling it.
   *
   * Since: 2.10
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_uint ("gtk-entry-password-hint-timeout",
                                                                P_("Password Hint Timeout"),
                                                                P_("How long to show the last input character in hidden entries"),
                                                                0, G_MAXUINT,
                                                                0,
                                                                GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_ENTRY_PASSWORD_HINT_TIMEOUT);

  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-menu-images",
                                                                   P_("Show menu images"),
                                                                   P_("Whether images should be shown in menus"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_MENU_IMAGES);

  result = settings_install_property_parser (class,
                                             g_param_spec_int ("gtk-menu-bar-popup-delay",
                                                               P_("Delay before drop down menus appear"),
                                                               P_("Delay before the submenus of a menu bar appear"),
                                                               0, G_MAXINT,
                                                               0,
                                                               GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_MENU_BAR_POPUP_DELAY);

  /**
   * GtkSettings:gtk-scrolled-window-placement:
   *
   * Where the contents of scrolled windows are located with respect to the 
   * scrollbars, if not overridden by the scrolled window's own placement.
   *
   * Since: 2.10
   */
  result = settings_install_property_parser (class,
                                             g_param_spec_enum ("gtk-scrolled-window-placement",
                                                                P_("Scrolled Window Placement"),
                                                                P_("Where the contents of scrolled windows are located with respect to the scrollbars, if not overridden by the scrolled window's own placement."),
                                                                GTK_TYPE_CORNER_TYPE,
                                                                GTK_CORNER_TOP_LEFT,
                                                                GTK_PARAM_READWRITE),
                                             gtk_rc_property_parse_enum);
  g_assert (result == PROP_SCROLLED_WINDOW_PLACEMENT);

  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-can-change-accels",
                                                                   P_("Can change accelerators"),
                                                                   P_("Whether menu accelerators can be changed by pressing a key over the menu item"),
                                                                   FALSE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_CAN_CHANGE_ACCELS);

  result = settings_install_property_parser (class,
                                             g_param_spec_int ("gtk-menu-popup-delay",
                                                               P_("Delay before submenus appear"),
                                                               P_("Minimum time the pointer must stay over a menu item before the submenu appear"),
                                                               0, G_MAXINT,
                                                               225,
                                                               GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_MENU_POPUP_DELAY);

  result = settings_install_property_parser (class,
                                             g_param_spec_int ("gtk-menu-popdown-delay",
                                                               P_("Delay before hiding a submenu"),
                                                               P_("The time before hiding a submenu when the pointer is moving towards the submenu"),
                                                               0, G_MAXINT,
                                                               1000,
                                                               GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_MENU_POPDOWN_DELAY);

  result = settings_install_property_parser (class,
                                             g_param_spec_boolean ("gtk-label-select-on-focus",
                                                                   P_("Select on focus"),
                                                                   P_("Whether to select the contents of a selectable label when it is focused"),
                                                                   TRUE,
                                                                   GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_LABEL_SELECT_ON_FOCUS);

  result = settings_install_property_parser (class,
                                             g_param_spec_string ("gtk-color-palette",
                                                                  P_("Custom palette"),
                                                                  P_("Palette to use in the color selector"),
                                                                  default_color_palette,
                                                                  GTK_PARAM_READWRITE),
                                             NULL);
  g_assert (result == PROP_COLOR_PALETTE);

  result = settings_install_property_parser (class,
                                             g_param_spec_enum ("gtk-im-preedit-style",
                                                                P_("IM Preedit style"),
                                                                P_("How to draw the input method preedit string"),
                                                                GTK_TYPE_IM_PREEDIT_STYLE,
                                                                GTK_IM_PREEDIT_CALLBACK,
                                                                GTK_PARAM_READWRITE),
                                             gtk_rc_property_parse_enum);
  g_assert (result == PROP_IM_PREEDIT_STYLE);

  result = settings_install_property_parser (class,
                                             g_param_spec_enum ("gtk-im-status-style",
                                                                P_("IM Status style"),
                                                                P_("How to draw the input method statusbar"),
                                                                GTK_TYPE_IM_STATUS_STYLE,
                                                                GTK_IM_STATUS_CALLBACK,
                                                                GTK_PARAM_READWRITE),
                                             gtk_rc_property_parse_enum);
  g_assert (result == PROP_IM_STATUS_STYLE);
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
}

static void
gtk_settings_finalize (GObject *object)
{
  GtkSettings *settings = GTK_SETTINGS (object);
  guint i;

  object_list = g_slist_remove (object_list, settings);

Matthias Clasen's avatar
Matthias Clasen committed
1257 1258
  _gtk_rc_context_destroy (settings);

1259
  for (i = 0; i < class_n_properties; i++)
1260
    g_value_unset (&settings->property_values[i].value);
1261
  g_free (settings->property_values);
1262
  
1263 1264
  g_datalist_clear (&settings->queued_settings);

Matthias Clasen's avatar
Matthias Clasen committed
1265
  G_OBJECT_CLASS (gtk_settings_parent_class)->finalize (object);
1266 1267
}

1268 1269
/**
 * gtk_settings_get_for_screen:
1270 1271
 * @screen: a #GdkScreen.
 *
1272 1273
 * Gets the #GtkSettings object for @screen, creating it if necessary.
 *
1274
 * Return value: (transfer none): a #GtkSettings object.
1275 1276
 *
 * Since: 2.2
1277 1278 1279
 */
GtkSettings*
gtk_settings_get_for_screen (GdkScreen *screen)
1280
{
1281
  GtkSettings *settings;
1282

1283
  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
1284

1285 1286
  settings = g_object_get_data (G_OBJECT (screen), "gtk-settings");
  if (!settings)
1287
    {
1288 1289
      settings = g_object_new (GTK_TYPE_SETTINGS, NULL);
      settings->screen = screen;
1290 1291
      g_object_set_data_full (G_OBJECT (screen), I_("gtk-settings"), 
			      settings, g_object_unref);
1292

1293
      gtk_rc_reparse_all_for_settings (settings, TRUE);
1294
      settings_update_double_click (settings);
1295
#ifdef GDK_WINDOWING_X11
1296 1297
      settings_update_cursor_theme (settings);
      settings_update_resolution (settings);
1298 1299
      settings_update_font_options (settings);
#endif
1300
      settings_update_color_scheme (settings);
1301
    }
1302 1303
  
  return settings;
1304 1305
}

1306 1307 1308 1309 1310
/**
 * gtk_settings_get_default:
 * 
 * Gets the #GtkSettings object for the default GDK screen, creating
 * it if necessary. See gtk_settings_get_for_screen().
1311 1312
 *
 * Return value: (transfer none): a #GtkSettings object. If there is no default
1313
 *  screen, then returns %NULL.
1314
 **/
1315
GtkSettings*
1316
gtk_settings_get_default (void)
1317
{
1318 1319 1320 1321 1322 1323
  GdkScreen *screen = gdk_screen_get_default ();

  if (screen)
    return gtk_settings_get_for_screen (screen);
  else
    return NULL;
1324 1325 1326 1327 1328 1329 1330 1331 1332
}

static void
gtk_settings_set_property (GObject      *object,
			   guint	 property_id,
			   const GValue *value,
			   GParamSpec   *pspec)
{
  GtkSettings *settings = GTK_SETTINGS (object);
1333

1334
  g_value_copy (value, &settings->property_values[property_id - 1].value);
1335
  settings->property_values[property_id - 1].source = GTK_SETTINGS_SOURCE_APPLICATION;
1336 1337 1338
  
  if (pspec->param_id == PROP_COLOR_SCHEME)
    merge_color_scheme (settings, value, GTK_SETTINGS_SOURCE_APPLICATION);
1339 1340 1341 1342 1343 1344 1345 1346 1347
}

static void
gtk_settings_get_property (GObject     *object,
			   guint	property_id,
			   GValue      *value,
			   GParamSpec  *pspec)
{
  GtkSettings *settings = GTK_SETTINGS (object);
1348 1349
  GType value_type = G_VALUE_TYPE (value);
  GType fundamental_type = G_TYPE_FUNDAMENTAL (value_type);
1350

1351 1352
  /* handle internal properties */
  switch (property_id)
1353
    {
1354
    case PROP_COLOR_HASH:
1355 1356
      g_value_set_boxed (value, get_color_hash (settings));
      return;
1357 1358 1359 1360
    case PROP_COLOR_SCHEME:
      g_value_take_string (value, get_color_scheme (settings));
      return;
    default: ;
1361 1362
    }

1363 1364 1365 1366 1367 1368
  /* For enums and strings, we need to get the value as a string,
   * not as an int, since we support using names/nicks as the setting
   * value.
   */
  if ((g_value_type_transformable (G_TYPE_INT, value_type) &&
       !(fundamental_type == G_TYPE_ENUM || fundamental_type == G_TYPE_FLAGS)) ||
1369 1370 1371
      g_value_type_transformable (G_TYPE_STRING, G_VALUE_TYPE (value)) ||
      g_value_type_transformable (GDK_TYPE_COLOR, G_VALUE_TYPE (value)))
    {
1372 1373
      if (settings->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION ||
	  !gdk_screen_get_setting (settings->screen, pspec->name, value))
1374
        g_value_copy (&settings->property_values[property_id - 1].value, value);
1375
      else 
1376
        g_param_value_validate (pspec, value);
1377
    }
1378
  else
1379 1380 1381 1382 1383 1384 1385
    {
      GValue val = { 0, };

      /* Try to get xsetting as a string and parse it. */
      
      g_value_init (&val, G_TYPE_STRING);

1386 1387
      if (settings->property_values[property_id - 1].source == GTK_SETTINGS_SOURCE_APPLICATION ||
	  !gdk_screen_get_setting (settings->screen, pspec->name, &val))
1388
        {
1389
          g_value_copy (&settings->property_values[property_id - 1].value, value);
1390 1391 1392 1393 1394
        }
      else
        {
          GValue tmp_value = { 0, };
          GValue gstring_value = { 0, };
1395
          GtkRcPropertyParser parser = (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser);
1396 1397
          
          g_value_init (&gstring_value, G_TYPE_GSTRING);
1398 1399
          g_value_take_boxed (&gstring_value,
                              g_string_new (g_value_get_string (&val)));
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410

          g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));

          if (parser && _gtk_settings_parse_convert (parser, &gstring_value,
                                                     pspec, &tmp_value))
            {
              g_value_copy (&tmp_value, value);
              g_param_value_validate (pspec, value);
            }
          else
            {
1411
              g_value_copy (&settings->property_values[property_id - 1].value, value);
1412 1413 1414 1415 1416 1417 1418 1419
            }

          g_value_unset (&gstring_value);
          g_value_unset (&tmp_value);
        }

      g_value_unset (&val);
    }
1420 1421 1422 1423 1424 1425
}

static void
gtk_settings_notify (GObject    *object,
		     GParamSpec *pspec)
{
1426
  GtkSettings *settings = GTK_SETTINGS (object);
Tim Janik's avatar
Tim Janik committed
1427
  guint property_id = pspec->param_id;
1428 1429 1430

  if (settings->screen == NULL) /* initialization */
    return;
1431 1432 1433

  switch (property_id)
    {
1434 1435 1436
    case PROP_MODULES:
      settings_update_modules (settings);
      break;
1437
    case PROP_DOUBLE_CLICK_TIME:
1438 1439
    case PROP_DOUBLE_CLICK_DISTANCE:
      settings_update_double_click (settings);
1440
      break;
1441 1442 1443
    case PROP_COLOR_SCHEME:
      settings_update_color_scheme (settings);
      break;
1444 1445
#ifdef GDK_WINDOWING_X11
    case PROP_XFT_DPI:
1446
      settings_update_resolution (settings);
1447 1448 1449 1450
      /* This is a hack because with gtk_rc_reset_styles() doesn't get
       * widgets with gtk_widget_style_set(), and also causes more
       * recomputation than necessary.
       */
1451 1452
      gtk_rc_reset_styles (GTK_SETTINGS (object));
      break;
1453 1454 1455 1456 1457 1458 1459
    case PROP_XFT_ANTIALIAS:
    case PROP_XFT_HINTING:
    case PROP_XFT_HINTSTYLE:
    case PROP_XFT_RGBA:
      settings_update_font_options (settings);
      gtk_rc_reset_styles (GTK_SETTINGS (object));
      break;
1460 1461 1462 1463
    case PROP_FONTCONFIG_TIMESTAMP:
      if (settings_update_fontconfig (settings))
	gtk_rc_reset_styles (GTK_SETTINGS (object));
      break;
1464 1465 1466 1467
    case PROP_CURSOR_THEME_NAME:
    case PROP_CURSOR_THEME_SIZE:
      settings_update_cursor_theme (settings);
      break;
1468
#endif /* GDK_WINDOWING_X11 */
1469 1470 1471
    }
}

1472 1473 1474 1475 1476
gboolean
_gtk_settings_parse_convert (GtkRcPropertyParser parser,
			     const GValue       *src_value,
			     GParamSpec         *pspec,
			     GValue	        *dest_value)
1477
{
1478
  gboolean success = FALSE;
1479

1480
  g_return_val_if_fail (G_VALUE_HOLDS (dest_value, G_PARAM_SPEC_VALUE_TYPE (pspec)), FALSE);