1 --- control-center-2.10.1/capplets/keybindings/gnome-keybinding-properties.glade Thu May 12 16:46:18 2005 2 +++ control-center-2.10.1-new/capplets/keybindings/gnome-keybinding-properties.glade Fri May 13 11:51:17 2005 3 @@ -11,6 +11,11 @@ 4 <property name="modal">False</property> 5 <property name="resizable">True</property> 6 <property name="destroy_with_parent">False</property> 7 + <property name="decorated">True</property> 8 + <property name="skip_taskbar_hint">False</property> 9 + <property name="skip_pager_hint">False</property> 10 + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> 11 + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> 12 <property name="has_separator">False</property> 13 14 <child internal-child="vbox"> 15 @@ -32,6 +37,7 @@ 16 <property name="label">gtk-help</property> 17 <property name="use_stock">True</property> 18 <property name="relief">GTK_RELIEF_NORMAL</property> 19 + <property name="focus_on_click">True</property> 20 <property name="response_id">-11</property> 21 </widget> 22 </child> 23 @@ -44,6 +50,7 @@ 24 <property name="label">gtk-close</property> 25 <property name="use_stock">True</property> 26 <property name="relief">GTK_RELIEF_NORMAL</property> 27 + <property name="focus_on_click">True</property> 28 <property name="response_id">-7</property> 29 </widget> 30 </child> 31 @@ -152,6 +159,362 @@ 32 <property name="padding">0</property> 33 <property name="expand">True</property> 34 <property name="fill">True</property> 35 + </packing> 36 + </child> 37 + 38 + <child> 39 + <widget class="GtkHBox" id="hbox2"> 40 + <property name="border_width">5</property> 41 + <property name="visible">True</property> 42 + <property name="homogeneous">False</property> 43 + <property name="spacing">6</property> 44 + 45 + <child> 46 + <widget class="GtkLabel" id="label13"> 47 + <property name="visible">True</property> 48 + <property name="label" translatable="yes" comments="SUN_BRANDING">Custom Shortcuts:</property> 49 + <property name="use_underline">False</property> 50 + <property name="use_markup">False</property> 51 + <property name="justify">GTK_JUSTIFY_LEFT</property> 52 + <property name="wrap">False</property> 53 + <property name="selectable">False</property> 54 + <property name="xalign">0.5</property> 55 + <property name="yalign">0.5</property> 56 + <property name="xpad">0</property> 57 + <property name="ypad">0</property> 58 + </widget> 59 + <packing> 60 + <property name="padding">0</property> 61 + <property name="expand">False</property> 62 + <property name="fill">False</property> 63 + </packing> 64 + </child> 65 + 66 + <child> 67 + <widget class="GtkButton" id="add_custom_button"> 68 + <property name="width_request">60</property> 69 + <property name="height_request">30</property> 70 + <property name="visible">True</property> 71 + <property name="can_focus">True</property> 72 + <property name="label">gtk-new</property> 73 + <property name="use_stock">True</property> 74 + <property name="relief">GTK_RELIEF_NORMAL</property> 75 + <property name="focus_on_click">True</property> 76 + </widget> 77 + <packing> 78 + <property name="padding">0</property> 79 + <property name="expand">True</property> 80 + <property name="fill">True</property> 81 + </packing> 82 + </child> 83 + 84 + <child> 85 + <widget class="GtkButton" id="edit_custom_button"> 86 + <property name="visible">True</property> 87 + <property name="can_focus">True</property> 88 + <property name="relief">GTK_RELIEF_NORMAL</property> 89 + <property name="focus_on_click">True</property> 90 + 91 + <child> 92 + <widget class="GtkAlignment" id="alignment1"> 93 + <property name="visible">True</property> 94 + <property name="xalign">0.5</property> 95 + <property name="yalign">0.5</property> 96 + <property name="xscale">0</property> 97 + <property name="yscale">0</property> 98 + <property name="top_padding">0</property> 99 + <property name="bottom_padding">0</property> 100 + <property name="left_padding">0</property> 101 + <property name="right_padding">0</property> 102 + 103 + <child> 104 + <widget class="GtkHBox" id="hbox3"> 105 + <property name="visible">True</property> 106 + <property name="homogeneous">False</property> 107 + <property name="spacing">2</property> 108 + 109 + <child> 110 + <widget class="GtkImage" id="image2"> 111 + <property name="visible">True</property> 112 + <property name="stock">gtk-preferences</property> 113 + <property name="icon_size">4</property> 114 + <property name="xalign">0.5</property> 115 + <property name="yalign">0.5</property> 116 + <property name="xpad">0</property> 117 + <property name="ypad">0</property> 118 + </widget> 119 + <packing> 120 + <property name="padding">0</property> 121 + <property name="expand">False</property> 122 + <property name="fill">False</property> 123 + </packing> 124 + </child> 125 + 126 + <child> 127 + <widget class="GtkLabel" id="label14"> 128 + <property name="visible">True</property> 129 + <property name="label" translatable="yes" comments="SUN_BRANDING">_Edit...</property> 130 + <property name="use_underline">True</property> 131 + <property name="use_markup">False</property> 132 + <property name="justify">GTK_JUSTIFY_LEFT</property> 133 + <property name="wrap">False</property> 134 + <property name="selectable">False</property> 135 + <property name="xalign">0.5</property> 136 + <property name="yalign">0.5</property> 137 + <property name="xpad">0</property> 138 + <property name="ypad">0</property> 139 + </widget> 140 + <packing> 141 + <property name="padding">0</property> 142 + <property name="expand">False</property> 143 + <property name="fill">False</property> 144 + </packing> 145 + </child> 146 + </widget> 147 + </child> 148 + </widget> 149 + </child> 150 + </widget> 151 + <packing> 152 + <property name="padding">0</property> 153 + <property name="expand">True</property> 154 + <property name="fill">True</property> 155 + </packing> 156 + </child> 157 + 158 + <child> 159 + <widget class="GtkButton" id="disable_custom_button"> 160 + <property name="visible">True</property> 161 + <property name="can_focus">True</property> 162 + <property name="label">gtk-delete</property> 163 + <property name="use_stock">True</property> 164 + <property name="relief">GTK_RELIEF_NORMAL</property> 165 + <property name="focus_on_click">True</property> 166 + </widget> 167 + <packing> 168 + <property name="padding">0</property> 169 + <property name="expand">True</property> 170 + <property name="fill">True</property> 171 + </packing> 172 + </child> 173 + </widget> 174 + <packing> 175 + <property name="padding">0</property> 176 + <property name="expand">False</property> 177 + <property name="fill">False</property> 178 + <property name="pack_type">GTK_PACK_END</property> 179 + </packing> 180 + </child> 181 + </widget> 182 + <packing> 183 + <property name="padding">0</property> 184 + <property name="expand">True</property> 185 + <property name="fill">True</property> 186 + </packing> 187 + </child> 188 + </widget> 189 + </child> 190 +</widget> 191 + 192 +<widget class="GtkDialog" id="custom-binding-dialog"> 193 + <property name="visible">True</property> 194 + <property name="title" translatable="yes" comments="SUN_BRANDING">Custom Binding</property> 195 + <property name="type">GTK_WINDOW_TOPLEVEL</property> 196 + <property name="window_position">GTK_WIN_POS_NONE</property> 197 + <property name="modal">False</property> 198 + <property name="resizable">True</property> 199 + <property name="destroy_with_parent">False</property> 200 + <property name="decorated">True</property> 201 + <property name="skip_taskbar_hint">False</property> 202 + <property name="skip_pager_hint">False</property> 203 + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> 204 + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> 205 + <property name="has_separator">True</property> 206 + <accessibility> 207 + <atkproperty name="AtkObject::accessible_name" translatable="yes" comments="SUN_BRANDING">Custom Binding</atkproperty> 208 + </accessibility> 209 + 210 + <child internal-child="vbox"> 211 + <widget class="GtkVBox" id="dialog-vbox1"> 212 + <property name="visible">True</property> 213 + <property name="homogeneous">False</property> 214 + <property name="spacing">0</property> 215 + 216 + <child internal-child="action_area"> 217 + <widget class="GtkHButtonBox" id="dialog-action_area2"> 218 + <property name="visible">True</property> 219 + <property name="layout_style">GTK_BUTTONBOX_END</property> 220 + 221 + <child> 222 + <widget class="GtkButton" id="helpbutton2"> 223 + <property name="visible">True</property> 224 + <property name="can_default">True</property> 225 + <property name="can_focus">True</property> 226 + <property name="label">gtk-help</property> 227 + <property name="use_stock">True</property> 228 + <property name="relief">GTK_RELIEF_NORMAL</property> 229 + <property name="focus_on_click">True</property> 230 + <property name="response_id">-11</property> 231 + </widget> 232 + </child> 233 + 234 + <child> 235 + <widget class="GtkButton" id="cancelbutton1"> 236 + <property name="visible">True</property> 237 + <property name="can_default">True</property> 238 + <property name="can_focus">True</property> 239 + <property name="label">gtk-cancel</property> 240 + <property name="use_stock">True</property> 241 + <property name="relief">GTK_RELIEF_NORMAL</property> 242 + <property name="focus_on_click">True</property> 243 + <property name="response_id">-6</property> 244 + </widget> 245 + </child> 246 + 247 + <child> 248 + <widget class="GtkButton" id="okbutton1"> 249 + <property name="visible">True</property> 250 + <property name="can_default">True</property> 251 + <property name="can_focus">True</property> 252 + <property name="label">gtk-ok</property> 253 + <property name="use_stock">True</property> 254 + <property name="relief">GTK_RELIEF_NORMAL</property> 255 + <property name="focus_on_click">True</property> 256 + <property name="response_id">-5</property> 257 + </widget> 258 + </child> 259 + </widget> 260 + <packing> 261 + <property name="padding">0</property> 262 + <property name="expand">False</property> 263 + <property name="fill">True</property> 264 + <property name="pack_type">GTK_PACK_END</property> 265 + </packing> 266 + </child> 267 + 268 + <child> 269 + <widget class="GtkHBox" id="hbox5"> 270 + <property name="visible">True</property> 271 + <property name="homogeneous">False</property> 272 + <property name="spacing">0</property> 273 + 274 + <child> 275 + <widget class="GtkLabel" id="label15"> 276 + <property name="visible">True</property> 277 + <property name="label" translatable="yes" comments="SUN_BRANDING">_New Command: </property> 278 + <property name="use_underline">True</property> 279 + <property name="use_markup">False</property> 280 + <property name="justify">GTK_JUSTIFY_LEFT</property> 281 + <property name="wrap">False</property> 282 + <property name="selectable">False</property> 283 + <property name="xalign">0.5</property> 284 + <property name="yalign">0.5</property> 285 + <property name="xpad">0</property> 286 + <property name="ypad">0</property> 287 + </widget> 288 + <packing> 289 + <property name="padding">0</property> 290 + <property name="expand">False</property> 291 + <property name="fill">False</property> 292 + </packing> 293 + </child> 294 + 295 + <child> 296 + <widget class="GtkEntry" id="action_tf"> 297 + <property name="visible">True</property> 298 + <property name="can_focus">True</property> 299 + <property name="editable">True</property> 300 + <property name="visibility">True</property> 301 + <property name="max_length">0</property> 302 + <property name="text" translatable="yes"></property> 303 + <property name="has_frame">True</property> 304 + <property name="invisible_char" translatable="yes">*</property> 305 + <property name="activates_default">False</property> 306 + <accessibility> 307 + <atkproperty name="AtkObject::accessible_name" translatable="yes">action_tf</atkproperty> 308 + </accessibility> 309 + </widget> 310 + <packing> 311 + <property name="padding">0</property> 312 + <property name="expand">True</property> 313 + <property name="fill">True</property> 314 + </packing> 315 + </child> 316 + 317 + <child> 318 + <widget class="GtkButton" id="browse_button"> 319 + <property name="visible">True</property> 320 + <property name="can_focus">True</property> 321 + <property name="relief">GTK_RELIEF_NORMAL</property> 322 + <property name="focus_on_click">True</property> 323 + <accessibility> 324 + <atkproperty name="AtkObject::accessible_name" translatable="yes" comments="SUN_BRANDING">Browse</atkproperty> 325 + </accessibility> 326 + 327 + <child> 328 + <widget class="GtkAlignment" id="alignment2"> 329 + <property name="visible">True</property> 330 + <property name="xalign">0.5</property> 331 + <property name="yalign">0.5</property> 332 + <property name="xscale">0</property> 333 + <property name="yscale">0</property> 334 + <property name="top_padding">0</property> 335 + <property name="bottom_padding">0</property> 336 + <property name="left_padding">0</property> 337 + <property name="right_padding">0</property> 338 + 339 + <child> 340 + <widget class="GtkHBox" id="hbox6"> 341 + <property name="visible">True</property> 342 + <property name="homogeneous">False</property> 343 + <property name="spacing">2</property> 344 + 345 + <child> 346 + <widget class="GtkImage" id="image3"> 347 + <property name="visible">True</property> 348 + <property name="stock">gtk-open</property> 349 + <property name="icon_size">4</property> 350 + <property name="xalign">0.5</property> 351 + <property name="yalign">0.5</property> 352 + <property name="xpad">0</property> 353 + <property name="ypad">0</property> 354 + </widget> 355 + <packing> 356 + <property name="padding">0</property> 357 + <property name="expand">False</property> 358 + <property name="fill">False</property> 359 + </packing> 360 + </child> 361 + 362 + <child> 363 + <widget class="GtkLabel" id="label16"> 364 + <property name="visible">True</property> 365 + <property name="label" translatable="yes" comments="SUN_BRANDING">_Browse</property> 366 + <property name="use_underline">True</property> 367 + <property name="use_markup">False</property> 368 + <property name="justify">GTK_JUSTIFY_LEFT</property> 369 + <property name="wrap">False</property> 370 + <property name="selectable">False</property> 371 + <property name="xalign">0.5</property> 372 + <property name="yalign">0.5</property> 373 + <property name="xpad">0</property> 374 + <property name="ypad">0</property> 375 + </widget> 376 + <packing> 377 + <property name="padding">0</property> 378 + <property name="expand">False</property> 379 + <property name="fill">False</property> 380 + </packing> 381 + </child> 382 + </widget> 383 + </child> 384 + </widget> 385 + </child> 386 + </widget> 387 + <packing> 388 + <property name="padding">0</property> 389 + <property name="expand">False</property> 390 + <property name="fill">False</property> 391 </packing> 392 </child> 393 </widget> 394 --- gnome-control-center-2.19.91/capplets/keybindings/Makefile.am-clean 2007-05-02 11:42:01.000000000 +0100 395 +++ gnome-control-center-2.19.91/capplets/keybindings/Makefile.am 2007-09-03 15:31:23.316179000 +0100 396 @@ -6,6 +6,8 @@ 397 gnome_keybinding_properties_LDADD = $(GNOMECC_CAPPLETS_LIBS) 398 gnome_keybinding_properties_SOURCES = \ 399 gnome-keybinding-properties.c \ 400 + custom-binding.c \ 401 + custom-binding.h \ 402 eggcellrendererkeys.c \ 403 eggcellrendererkeys.h \ 404 eggaccelerators.c \ 405 406 --- gnome-control-center-2.19.91/capplets/keybindings/custom-binding.c.orig 2007-09-05 14:22:28.103863000 +0100 407 +++ gnome-control-center-2.19.91/capplets/keybindings/custom-binding.c 2007-09-05 14:26:14.588448000 +0100 408 @@ -0,0 +1,516 @@ 409 +/* Erwann Chenede 2002 */ 410 + 411 +#include <config.h> 412 + 413 +#include <string.h> 414 +#include <gtk/gtk.h> 415 +#include <gconf/gconf-client.h> 416 +#include <gdk/gdkx.h> 417 +#include <glade/glade.h> 418 +#include <X11/Xatom.h> 419 + 420 +#include "wm-common.h" 421 +#include "capplet-util.h" 422 +#include "eggcellrendererkeys.h" 423 +#include "activate-settings-daemon.h" 424 +#include "custom-binding.h" 425 + 426 +extern KeyListEntry *custom_binding_list; 427 +extern GladeXML *main_dialog; 428 + 429 +void 430 +my_verbose (const char *format, ...) 431 +{ 432 + va_list args; 433 + gchar *str; 434 + 435 + if (format == NULL) 436 + return; 437 + 438 + if (1) /*DEBUG*/ 439 + return; 440 + 441 + va_start (args, format); 442 + str = g_strdup_vprintf (format, args); 443 + va_end (args); 444 + 445 + fputs (str, stderr); 446 + 447 + fflush (stderr); 448 + 449 + g_free (str); 450 +} 451 + 452 +void 453 +cmd_line_changed (GConfClient *client, 454 + guint cnxn_id, 455 + GConfEntry *entry, 456 + gpointer user_data) 457 +{ 458 + KeyEntry *key_entry; 459 + 460 + my_verbose ("In cmd_line_changed\n"); 461 + 462 + key_entry = (KeyEntry *)user_data; 463 + g_free (key_entry->action); 464 + key_entry->action = g_strdup (gconf_value_get_string (entry->value)); 465 + key_entry->editable = gconf_entry_get_is_writable (entry); 466 + 467 + /* update the model */ 468 + gtk_tree_model_foreach (key_entry->model, keybinding_key_changed_foreach, key_entry); 469 +} 470 + 471 +KeyEntry * 472 +find_keyentry_selected (GtkTreeView *tree_view) 473 +{ 474 + GtkTreeSelection* sel = NULL; 475 + sel = gtk_tree_view_get_selection (tree_view); 476 + 477 + if (sel) 478 + { 479 + GtkTreeIter iter; 480 + GtkTreeModel *model; 481 + if (gtk_tree_selection_get_selected (sel, &model, &iter)) 482 + { 483 + KeyEntry *key_entry; 484 + 485 + gtk_tree_model_get (model, &iter, KEYENTRY_COLUMN, &key_entry, -1); 486 + return key_entry; 487 + } 488 + } 489 + return NULL; 490 +} 491 + 492 +static gboolean key_delete_cleanup (KeyEntry *key_entry) 493 +{ 494 + GConfClient *client = gconf_client_get_default(); 495 + 496 + gconf_client_recursive_unset (client, key_entry->gconf_key, 0, NULL); 497 + 498 + create_custom_bindings_list (); 499 + reload_key_entries (wm_common_get_current_window_manager(), main_dialog); 500 + 501 + return FALSE; 502 +} 503 + 504 +void 505 +disable_custom (GtkWidget *widget, GtkTreeView *tree_view) 506 +{ 507 + KeyEntry *key_entry = find_keyentry_selected (tree_view); 508 + 509 + if (key_entry) 510 + { 511 + if (key_entry->custom_key) 512 + { 513 + GConfClient *client = gconf_client_get_default(); 514 + gchar *binding = g_strdup_printf ("%s/binding", key_entry->gconf_key); 515 + gchar *binding_str; 516 + 517 + gconf_client_notify_remove (client, key_entry->gconf_cnxn); 518 + gconf_client_notify_remove (client, key_entry->cmd_line_cnxn); 519 + 520 + key_entry->gconf_cnxn = 0; 521 + key_entry->cmd_line_cnxn = 0; 522 + 523 + binding_str = gconf_client_get_string (client,binding, NULL); 524 + 525 + if (binding_str && strcmp (binding_str, "disabled")) { 526 + /* This is a neccessery evil. We need to follow a similar 527 + pattern of sequence in setting the binding to disabled state 528 + before deleting it. The timeout is to ensure that when 529 + g-s-d is getting the changes it does not find a key which 530 + is non-existent and crash. 531 + */ 532 + gconf_client_set_string (client, 533 + binding, 534 + "disabled", 535 + NULL); 536 + g_timeout_add (1000, (GSourceFunc) key_delete_cleanup, key_entry); 537 + 538 + g_free (binding_str); 539 + } else 540 + key_delete_cleanup (key_entry); 541 + 542 + g_free (binding); 543 + } 544 + else 545 + gconf_client_set_string (gconf_client_get_default(),key_entry->gconf_key, "", NULL); 546 + } 547 +} 548 + 549 +static int 550 +get_trailing_num (char *str) 551 +{ 552 + char **result = g_strsplit (str, "_", 2); 553 + int i = atoi (result[1]); 554 + g_strfreev (result); 555 + return i; 556 +} 557 + 558 +static char * 559 +find_free_custom_gconf_key () 560 +{ 561 + GConfClient *client; 562 + GSList *list, *li; 563 + int num_bindings = 0; 564 + int max_num = 0; 565 + 566 + client = gconf_client_get_default (); 567 + 568 + list = gconf_client_all_dirs (client, GCONF_CUSTOM_BINDING_DIR, NULL); 569 + 570 + num_bindings = g_slist_length (list); 571 + 572 + custom_binding_list = g_new0 (KeyListEntry, num_bindings+1); 573 + 574 + /*find the highest num */ 575 + 576 + for (li = list; li != NULL; li = li->next) 577 + { 578 + char *subdir = li->data; 579 + char *key = g_path_get_basename(subdir); 580 + li->data = NULL; 581 + 582 + if (g_ascii_strncasecmp(key, "custom_", 7) == 0) 583 + { 584 + int i = get_trailing_num (key); 585 + if (i > max_num) 586 + max_num = i; 587 + } 588 + } 589 + g_slist_free (list); 590 + 591 + return g_strdup_printf ("%s/custom_%d",GCONF_CUSTOM_BINDING_DIR, max_num + 1); 592 +} 593 + 594 + 595 +static void 596 +add_real_key (GtkWidget *widget, GladeXML *dialog) 597 +{ 598 + KeyEntry *entry = NULL; 599 + GError *err = NULL; 600 + GtkWidget *area_tf = WID ("action_tf"); 601 + char *binding_key, *action_key; 602 + char *action = g_strdup (gtk_entry_get_text (GTK_ENTRY (area_tf))); 603 + 604 + entry = g_object_steal_data (G_OBJECT (area_tf), "key_entry"); 605 + 606 + if (!entry) 607 + { 608 + char *new_gconf_key = find_free_custom_gconf_key (); 609 + GConfClient *client = gconf_client_get_default (); 610 + 611 + binding_key = g_strdup_printf ("%s/binding", new_gconf_key); 612 + action_key = g_strdup_printf ("%s/action", new_gconf_key); 613 + 614 + gconf_client_set_string (client, new_gconf_key, "", &err); 615 + 616 + gconf_client_set_string (client, binding_key, "", &err); 617 + 618 + gconf_client_set_string (client, action_key, action, &err); 619 + 620 + create_custom_bindings_list (); 621 + reload_key_entries (wm_common_get_current_window_manager(), main_dialog); 622 + g_free (binding_key); 623 + g_free (new_gconf_key); 624 + } 625 + else 626 + { 627 + action_key = g_strdup_printf ("%s/action", entry->gconf_key); 628 + gconf_client_set_string (gconf_client_get_default (), 629 + action_key, action, &err); 630 + } 631 + 632 + g_free (action); 633 + g_free (action_key); 634 + 635 + custom_cancel (widget, dialog); 636 +} 637 + 638 +void 639 +custom_cancel (GtkWidget *widget, GladeXML *dialog) 640 +{ 641 + gtk_entry_set_text (GTK_ENTRY (WID ("action_tf")), ""); 642 + 643 + gtk_widget_hide (WID ("custom-binding-dialog")); 644 +} 645 + 646 +void 647 +delete_event_cb (GtkWidget *widget, GdkEventAny *event, gpointer *user_data) 648 +{ 649 + GtkWidget *entry = GTK_WIDGET (user_data); 650 + gtk_entry_set_text (GTK_ENTRY (entry), ""); 651 + 652 + gtk_widget_hide (widget); 653 +} 654 + 655 +static void 656 +cb_dialog_response (GtkWidget *widget, GladeXML *dialog) 657 +{ 658 + capplet_help (GTK_WINDOW (gtk_widget_get_toplevel (widget)), 659 + "user-guide.xml", 660 + "goscustdesk-39"); 661 +} 662 + 663 +typedef struct 664 +{ 665 + GtkFileSelection *fs; 666 + GladeXML *dialog; 667 +} FileSelData; 668 + 669 + 670 +static void 671 +command_selection_ok (FileSelData *fs_data) 672 +{ 673 + GtkWidget *action_tf = glade_xml_get_widget (fs_data->dialog, "action_tf"); 674 + gchar **selections; 675 + 676 + selections = gtk_file_selection_get_selections (fs_data->fs); 677 + 678 + gtk_entry_set_text (GTK_ENTRY (action_tf), selections[0]); 679 + gtk_widget_destroy (GTK_WIDGET (fs_data->fs)); 680 +} 681 + 682 +static void 683 +set_command (GtkWidget *widget, GladeXML *dialog) 684 +{ 685 + GtkWidget *window; 686 + FileSelData *fs_data = g_new (FileSelData, 1); 687 + 688 + window = gtk_file_selection_new ("Select Command"); 689 + 690 + gtk_window_set_screen (GTK_WINDOW (window), 691 + gtk_widget_get_screen (widget)); 692 + 693 + gtk_file_selection_set_select_multiple (GTK_FILE_SELECTION (window), 694 + FALSE); 695 + 696 + g_signal_connect (window, "destroy", 697 + G_CALLBACK (gtk_widget_destroyed), 698 + &window); 699 + 700 + fs_data->fs = GTK_FILE_SELECTION (window); 701 + fs_data->dialog = dialog; 702 + 703 + g_signal_connect_swapped (GTK_FILE_SELECTION (window)->ok_button, 704 + "clicked", 705 + G_CALLBACK (command_selection_ok), 706 + fs_data); 707 + 708 + g_signal_connect_swapped (GTK_FILE_SELECTION (window)->cancel_button, 709 + "clicked", 710 + G_CALLBACK (gtk_widget_destroy), 711 + window); 712 + gtk_widget_show (window); 713 +} 714 + 715 +GladeXML * 716 +setup_custom_binding_dialog () 717 +{ 718 + static GladeXML *dialog = NULL; 719 + GtkWidget *widget, *entry; 720 + 721 + if (dialog) 722 + return dialog; 723 + 724 + /* setup dialog */ 725 + dialog = glade_xml_new (GNOMECC_GLADE_DIR "/gnome-keybinding-properties.glade", "custom-binding-dialog", NULL); 726 + 727 + widget = WID ("custom-binding-dialog"); 728 + entry = WID ("action_tf"); 729 + g_signal_connect (G_OBJECT (widget), "delete_event", 730 + G_CALLBACK (delete_event_cb), 731 + entry); 732 + 733 + g_signal_connect (G_OBJECT (WID ("browse_button")), "clicked", 734 + G_CALLBACK (set_command), dialog); 735 + 736 + g_signal_connect (G_OBJECT (WID ("cancelbutton1")), "clicked", 737 + G_CALLBACK (custom_cancel), dialog); 738 + 739 + g_signal_connect (G_OBJECT (WID ("okbutton1")), "clicked", 740 + G_CALLBACK (add_real_key), dialog); 741 + 742 + g_signal_connect (G_OBJECT (WID ("helpbutton2")), "clicked", 743 + G_CALLBACK (cb_dialog_response), NULL); 744 + 745 + /* gtk_widget_hide (WID ("custom-binding-dialog")); */ 746 + return dialog; 747 +} 748 +void 749 +edit_custom (GtkWidget *widget) 750 +{ 751 + KeyEntry *entry = find_keyentry_selected (GTK_TREE_VIEW (glade_xml_get_widget (main_dialog,"shortcut_treeview"))); 752 + if (entry) 753 + { 754 + if (entry->custom_key) 755 + { 756 + GladeXML *dialog = setup_custom_binding_dialog (); 757 + GtkWidget *widget; 758 + widget = WID ("action_tf"); 759 + g_object_set_data (G_OBJECT (widget), "key_entry", entry); 760 + gtk_entry_set_text (GTK_ENTRY (widget), entry->action); 761 + gtk_widget_show_all (WID ("custom-binding-dialog")); 762 + } 763 + } 764 +} 765 +void 766 +add_custom (GtkWidget *widget) 767 +{ 768 + GladeXML *dialog = setup_custom_binding_dialog (); 769 + GtkWidget *action_widget; 770 + action_widget = WID ("action_tf"); 771 + g_object_set_data (G_OBJECT (action_widget), "key_entry", NULL); 772 + gtk_widget_show_all (WID ("custom-binding-dialog")); 773 +} 774 + 775 +void 776 +create_custom_bindings_list () 777 +{ 778 + GConfClient *client; 779 + GSList *list, *li; 780 + int num_bindings = 0, i = 0; 781 + 782 + client = gconf_client_get_default (); 783 + 784 + list = gconf_client_all_dirs (client, GCONF_CUSTOM_BINDING_DIR, NULL); 785 + 786 + num_bindings = g_slist_length (list); 787 + 788 + if (custom_binding_list) 789 + g_free (custom_binding_list); 790 + 791 + 792 + custom_binding_list = g_new0 (KeyListEntry, num_bindings+1); 793 + 794 + for (li = list; li != NULL; li = li->next) 795 + { 796 + char *subdir = li->data; 797 + li->data = NULL; 798 + custom_binding_list[i].name = subdir; 799 + i++; 800 + } 801 + g_slist_free (list); 802 +} 803 + 804 +KeyEntry * 805 +custom_key_new (char *dir) 806 +{ 807 + GConfValue *value; 808 + KeyEntry *new_binding; 809 + GSList *tmp_elem = NULL, *list = NULL, *li; 810 + char *gconf_key; 811 + char *action = NULL; 812 + char *key = NULL; 813 + 814 + g_return_val_if_fail (dir != NULL, NULL); 815 + 816 + /* value = gconf_entry_get_value (entry); */ 817 + gconf_key = dir; 818 + 819 + if (!gconf_key) 820 + return NULL; 821 + 822 + /* Get entries for this binding */ 823 + list = gconf_client_all_entries (gconf_client_get_default (), dir, NULL); 824 + 825 + for (li = list; li != NULL; li = li->next) 826 + { 827 + GConfEntry *entry = li->data; 828 + char *key_name = g_path_get_basename (gconf_entry_get_key (entry)); 829 + if (strcmp (key_name, "action") == 0) 830 + { 831 + if (!action) 832 + { 833 + value = gconf_entry_get_value (entry); 834 + if (value) 835 + { 836 + if (value->type != GCONF_VALUE_STRING) 837 + return NULL; 838 + action = g_strdup (gconf_value_get_string (value)); 839 + } 840 + } 841 + else 842 + /* SUN_BRANDING */ 843 + g_warning (_("Key Binding (%s) has its action defined multiple times\n"), 844 + gconf_key); 845 + } 846 + if (strcmp (key_name, "binding") == 0) 847 + { 848 + if (!key) 849 + { 850 + value = gconf_entry_get_value (entry); 851 + if (value) 852 + { 853 + if (value->type != GCONF_VALUE_STRING) 854 + return NULL; 855 + key = g_strdup (gconf_value_get_string (value)); 856 + } 857 + } 858 + else 859 + /* SUN_BRANDING */ 860 + g_warning (_("Key Binding (%s) has its binding defined multiple times\n"), 861 + gconf_key); 862 + } 863 + } 864 + if (!action || !key) 865 + { 866 + /* SUN_BRANDING */ 867 + g_warning (_("Key Binding (%s) is incomplete\n"), gconf_key); 868 + return NULL; 869 + } 870 + 871 + new_binding = g_new0 (KeyEntry, 1); 872 + 873 + 874 + new_binding->binding = key; 875 + new_binding->action = action; 876 + new_binding->gconf_key = gconf_key; 877 + return new_binding; 878 +} 879 + 880 +gboolean 881 +is_gconf_key_custom_binding (char *key) 882 +{ 883 + char *str = NULL; 884 + 885 + str = g_strrstr (key, "keybindings"); 886 + 887 + if (str) 888 + return TRUE; 889 + return FALSE; 890 +} 891 + 892 +void 893 +cursor_changed_cb (GtkTreeView *tree_view, 894 + GladeXML *dialog) 895 +{ 896 + KeyEntry *key_entry = find_keyentry_selected (tree_view); 897 + GtkWidget *widget; 898 + 899 + my_verbose ("In cursor_changed_cb\n"); 900 + if (key_entry) 901 + { 902 + if (key_entry->custom_key) 903 + { 904 + widget = WID ("edit_custom_button"); 905 + gtk_widget_set_sensitive (widget, TRUE); 906 + widget = WID ("disable_custom_button"); 907 + gtk_widget_set_sensitive (widget, TRUE); 908 + } 909 + else 910 + { 911 + widget = WID ("edit_custom_button"); 912 + gtk_widget_set_sensitive (widget, FALSE); 913 + widget = WID ("disable_custom_button"); 914 + gtk_widget_set_sensitive (widget, FALSE); 915 + } 916 + } 917 + else 918 + { 919 + widget = WID ("edit_custom_button"); 920 + gtk_widget_set_sensitive (widget, FALSE); 921 + widget = WID ("disable_custom_button"); 922 + gtk_widget_set_sensitive (widget, FALSE); 923 + } 924 +} 925 926 927 --- gnome-control-center-2.23.3/capplets/keybindings/custom-binding.h.orig 2008-06-05 10:47:09.696631562 +0100 928 +++ gnome-control-center-2.23.3/capplets/keybindings/custom-binding.h 2008-06-05 10:47:34.138624596 +0100 929 @@ -0,0 +1,120 @@ 930 +/* Erwann Chenede 2002 */ 931 + 932 +#include <config.h> 933 + 934 +#include <string.h> 935 +#include <gtk/gtk.h> 936 +#include <gconf/gconf-client.h> 937 +#include <gdk/gdkx.h> 938 +#include <glade/glade.h> 939 +#include <X11/Xatom.h> 940 + 941 +#include "wm-common.h" 942 +#include "capplet-util.h" 943 +#include "eggcellrendererkeys.h" 944 +#include "activate-settings-daemon.h" 945 + 946 +#ifndef __CUSTOM_BINDING__H__ 947 +#define __CUSTOM_BINDING__H__ 948 + 949 +#define GCONF_CUSTOM_BINDING_DIR "/desktop/gnome/keybindings" 950 + 951 +typedef enum { 952 + ALWAYS_VISIBLE, 953 + N_WORKSPACES_GT 954 +} KeyListEntryVisibility; 955 + 956 +typedef enum { 957 + COMPARISON_NONE = 0, 958 + COMPARISON_GT, 959 + COMPARISON_LT, 960 + COMPARISON_EQ 961 +} Comparison; 962 + 963 +typedef struct 964 +{ 965 + char *name; 966 + int value; 967 + char *key; 968 + char *description_name; 969 + Comparison comparison; 970 +} KeyListEntry; 971 + 972 +enum 973 +{ 974 + DESCRIPTION_COLUMN, 975 + KEYENTRY_COLUMN, 976 + N_COLUMNS 977 +}; 978 + 979 +typedef struct 980 +{ 981 + char *gconf_key; 982 + guint keyval; 983 + guint keycode; 984 + EggVirtualModifierType mask; 985 + gboolean editable; 986 + GtkTreeModel *model; 987 + char *description; 988 + char *desc_gconf_key; 989 + gboolean desc_editable; 990 + guint gconf_cnxn; 991 + guint gconf_cnxn_desc; 992 + /* Custom Key Stuff */ 993 + gboolean custom_key; 994 + guint cmd_line_cnxn; 995 + char *action; 996 + char *binding; 997 +} KeyEntry; 998 + 999 +void 1000 +my_verbose (const char *format, ...); 1001 + 1002 +void 1003 +cmd_line_changed (GConfClient *client, 1004 + guint cnxn_id, 1005 + GConfEntry *entry, 1006 + gpointer user_data); 1007 + 1008 +void 1009 +disable_custom (GtkWidget *widget, GtkTreeView *tree_view); 1010 + 1011 +gboolean 1012 +grab_key_callback (GtkWidget *widget, 1013 + GdkEventKey *event, 1014 + void *data); 1015 +void grab_key (GtkWidget *widget, GladeXML *dialog); 1016 + 1017 +void custom_cancel (GtkWidget *widget, GladeXML *dialog); 1018 + 1019 +void delete_event_cb (GtkWidget *widget, GdkEventAny *event, gpointer *user_data); 1020 +void cursor_changed_cb (GtkTreeView *treeview, GladeXML *dialog); 1021 + 1022 +GladeXML * 1023 +setup_custom_binding_dialog (); 1024 + 1025 +void 1026 +add_custom (GtkWidget *widget); 1027 + 1028 +void 1029 +edit_custom (GtkWidget *widget); 1030 + 1031 +void 1032 +create_custom_bindings_list (); 1033 + 1034 +KeyEntry * 1035 +custom_key_new (char *dir); 1036 + 1037 +gboolean 1038 +is_gconf_key_custom_binding (char *key); 1039 + 1040 +gboolean 1041 +keybinding_key_changed_foreach (GtkTreeModel *model, 1042 + GtkTreePath *path, 1043 + GtkTreeIter *iter, 1044 + gpointer user_data); 1045 + 1046 +void 1047 +reload_key_entries (gpointer wm_name, GladeXML *dialog); 1048 +#endif /*__CUSTOM_BINDING__H__*/ 1049 + 1050 1051 --- gnome-control-center-2.23.6.old/capplets/keybindings/gnome-keybinding-properties.c 2008-08-06 11:19:27.037712000 +0100 1052 +++ gnome-control-center-2.23.6/capplets/keybindings/gnome-keybinding-properties.c 2008-08-06 11:22:50.489019000 +0100 1053 @@ -15,6 +15,7 @@ 1054 #include "capplet-util.h" 1055 #include "eggcellrendererkeys.h" 1056 #include "activate-settings-daemon.h" 1057 +#include "custom-binding.h" 1058 1059 #define GCONF_BINDING_DIR "/desktop/gnome/keybindings" 1060 #define MAX_ELEMENTS_BEFORE_SCROLLING 10 1061 @@ -29,29 +30,7 @@ 1062 GArray *entries; 1063 } KeyList; 1064 1065 -typedef enum { 1066 - COMPARISON_NONE = 0, 1067 - COMPARISON_GT, 1068 - COMPARISON_LT, 1069 - COMPARISON_EQ 1070 -} Comparison; 1071 - 1072 -typedef struct 1073 -{ 1074 - char *name; 1075 - int value; 1076 - char *key; 1077 - char *description_name; 1078 - Comparison comparison; 1079 -} KeyListEntry; 1080 - 1081 -enum 1082 -{ 1083 - DESCRIPTION_COLUMN, 1084 - KEYENTRY_COLUMN, 1085 - N_COLUMNS 1086 -}; 1087 - 1088 +/* 1089 typedef struct 1090 { 1091 char *gconf_key; 1092 @@ -66,14 +45,19 @@ 1093 guint gconf_cnxn; 1094 guint gconf_cnxn_desc; 1095 } KeyEntry; 1096 +*/ 1097 +KeyListEntry *custom_binding_list = NULL; 1098 +GladeXML *main_dialog; 1099 1100 static gboolean block_accels = FALSE; 1101 1102 static GladeXML * 1103 create_dialog (void) 1104 { 1105 - return glade_xml_new (GNOMECC_GLADE_DIR "/gnome-keybinding-properties.glade", 1106 + main_dialog = glade_xml_new (GNOMECC_GLADE_DIR "/gnome-keybinding-properties.glade", 1107 "gnome-keybinding-dialog", NULL); 1108 + 1109 + return main_dialog; 1110 } 1111 1112 static char* 1113 @@ -172,7 +156,7 @@ 1114 NULL); 1115 } 1116 1117 -static gboolean 1118 +gboolean 1119 keybinding_key_changed_foreach (GtkTreeModel *model, 1120 GtkTreePath *path, 1121 GtkTreeIter *iter, 1122 @@ -188,6 +172,11 @@ 1123 1124 if (key_entry == tmp_key_entry) 1125 { 1126 + if (key_entry->custom_key) 1127 + gtk_tree_store_set (GTK_TREE_STORE (key_entry->model), iter, 1128 + DESCRIPTION_COLUMN, key_entry->action, 1129 + -1); 1130 + 1131 gtk_tree_model_row_changed (key_entry->model, path, iter); 1132 return TRUE; 1133 } 1134 @@ -338,6 +327,8 @@ 1135 1136 if (key_entry != NULL) 1137 { 1138 + if (key_entry->custom_key == TRUE) 1139 + gconf_client_notify_remove (client, key_entry->cmd_line_cnxn); 1140 gconf_client_remove_dir (client, key_entry->gconf_key, NULL); 1141 gconf_client_notify_remove (client, key_entry->gconf_cnxn); 1142 if (key_entry->gconf_cnxn_desc != 0) 1143 @@ -422,7 +413,8 @@ 1144 static void 1145 append_keys_to_tree (GladeXML *dialog, 1146 const gchar *title, 1147 - const KeyListEntry *keys_list) 1148 + const KeyListEntry *keys_list, 1149 + gboolean custom_binding) 1150 { 1151 GConfClient *client; 1152 GtkTreeIter parent_iter, iter; 1153 @@ -472,75 +464,121 @@ 1154 1155 for (j = 0; keys_list[j].name != NULL; j++) 1156 { 1157 - GConfEntry *entry; 1158 - KeyEntry *key_entry; 1159 + GConfEntry *entry = NULL; 1160 + KeyEntry *key_entry = NULL; 1161 const gchar *key_string; 1162 gchar *key_value; 1163 gchar *description; 1164 1165 if (!should_show_key (&keys_list[j])) 1166 - continue; 1167 - 1168 - key_string = keys_list[j].name; 1169 + continue; 1170 1171 - entry = gconf_client_get_entry (client, 1172 - key_string, 1173 - NULL, 1174 - TRUE, 1175 - NULL); 1176 - if (entry == NULL) 1177 - { 1178 - /* We don't actually want to popup a dialog - just skip this one */ 1179 - continue; 1180 - } 1181 - 1182 - if (keys_list[j].description_name != NULL) 1183 - { 1184 - description = gconf_client_get_string (client, keys_list[j].description_name, NULL); 1185 - } 1186 - else 1187 - { 1188 - description = NULL; 1189 + if ( !custom_binding ) 1190 + { 1191 + key_string = keys_list[j].name; 1192 + 1193 + entry = gconf_client_get_entry (client, 1194 + key_string, 1195 + NULL, 1196 + TRUE, 1197 + NULL); 1198 + } 1199 + else if (entry == NULL) 1200 + { 1201 + key_entry = custom_key_new ((char *)keys_list[j].name); 1202 + if (!key_entry) 1203 + continue; 1204 + key_string = key_entry->gconf_key; 1205 + } 1206 + 1207 + 1208 + if (!custom_binding) 1209 + { 1210 + if (entry == NULL) 1211 + { 1212 + /* We don't actually want to popup a dialog - just skip this one */ 1213 + continue; 1214 + } 1215 1216 - if (gconf_entry_get_schema_name (entry)) 1217 - { 1218 - GConfSchema *schema; 1219 + if (keys_list[j].description_name != NULL) 1220 + { 1221 + description = gconf_client_get_string (client, keys_list[j].description_name, NULL); 1222 + } 1223 + else 1224 + { 1225 + description = NULL; 1226 1227 - schema = gconf_client_get_schema (client, 1228 - gconf_entry_get_schema_name (entry), 1229 - NULL); 1230 - if (schema != NULL) 1231 - { 1232 - description = g_strdup (gconf_schema_get_short_desc (schema)); 1233 - gconf_schema_free (schema); 1234 - } 1235 - } 1236 - } 1237 + if (gconf_entry_get_schema_name (entry)) 1238 + { 1239 + GConfSchema *schema; 1240 + 1241 + schema = gconf_client_get_schema (client, 1242 + gconf_entry_get_schema_name (entry), 1243 + NULL); 1244 + if (schema != NULL) 1245 + { 1246 + description = g_strdup (gconf_schema_get_short_desc (schema)); 1247 + gconf_schema_free (schema); 1248 + } 1249 + } 1250 + } 1251 + } 1252 1253 - key_entry = g_new0 (KeyEntry, 1); 1254 - key_entry->gconf_key = g_strdup (key_string); 1255 - key_entry->editable = gconf_entry_get_is_writable (entry); 1256 - key_entry->model = model; 1257 - key_entry->description = description; 1258 - if (keys_list[j].description_name != NULL) 1259 + if (!custom_binding) 1260 + { 1261 + key_entry = g_new0 (KeyEntry, 1); 1262 + key_entry->gconf_key = g_strdup (key_string); 1263 + key_entry->editable = gconf_entry_get_is_writable (entry); 1264 + key_entry->model = model; 1265 + key_entry->description = description; 1266 + if (keys_list[j].description_name != NULL) 1267 { 1268 key_entry->desc_gconf_key = g_strdup (keys_list[j].description_name); 1269 - key_entry->desc_editable = gconf_client_key_is_writable (client, key_entry->desc_gconf_key, NULL); 1270 + key_entry->desc_editable = gconf_client_key_is_writable (client, 1271 + key_entry->desc_gconf_key, NULL); 1272 key_entry->gconf_cnxn_desc = gconf_client_notify_add (client, 1273 - key_entry->desc_gconf_key, 1274 - (GConfClientNotifyFunc) &keybinding_description_changed, 1275 - key_entry, NULL, NULL); 1276 + key_entry->desc_gconf_key, 1277 + (GConfClientNotifyFunc) &keybinding_description_changed, 1278 + key_entry, NULL, NULL); 1279 } 1280 1281 - gconf_client_add_dir (client, key_string, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); 1282 - key_entry->gconf_cnxn = gconf_client_notify_add (client, 1283 - key_string, 1284 - (GConfClientNotifyFunc) &keybinding_key_changed, 1285 - key_entry, NULL, NULL); 1286 - 1287 - key_value = gconf_client_get_string (client, key_string, NULL); 1288 - binding_from_string (key_value, &key_entry->keyval, &key_entry->keycode, &key_entry->mask); 1289 - g_free (key_value); 1290 + gconf_client_add_dir (client, key_string, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); 1291 + key_entry->gconf_cnxn = gconf_client_notify_add (client, 1292 + key_string, 1293 + (GConfClientNotifyFunc) &keybinding_key_changed, 1294 + key_entry, NULL, NULL); 1295 + 1296 + key_value = gconf_client_get_string (client, key_string, NULL); 1297 + binding_from_string (key_value, &key_entry->keyval, &key_entry->keycode, &key_entry->mask); 1298 + g_free (key_value); 1299 + } 1300 + else 1301 + { 1302 + char *key_binding = 1303 + g_strdup_printf ("%s/binding", key_entry->gconf_key); 1304 + char *cmd_binding = g_strdup_printf ("%s/action", key_entry->gconf_key); 1305 + key_entry->editable = TRUE; 1306 + key_entry->model = model; 1307 + gconf_client_add_dir (client, key_entry->gconf_key, 1308 + GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); 1309 + 1310 + key_entry->gconf_cnxn = 1311 + gconf_client_notify_add (client, 1312 + key_binding, 1313 + (GConfClientNotifyFunc) &keybinding_key_changed, 1314 + key_entry, NULL, NULL); 1315 + binding_from_string (key_entry->binding, &key_entry->keyval, 1316 + &key_entry->keycode, &key_entry->mask); 1317 + 1318 + key_entry->custom_key = TRUE; 1319 + key_entry->cmd_line_cnxn = gconf_client_notify_add (client, cmd_binding, 1320 + (GConfClientNotifyFunc) &cmd_line_changed, 1321 + key_entry, NULL, NULL); 1322 + key_entry->action = g_strdup (gconf_client_get_string (client, 1323 + cmd_binding, NULL )); 1324 + g_free (key_binding); 1325 + g_free (cmd_binding); 1326 + } 1327 1328 gconf_entry_free (entry); 1329 ensure_scrollbar (dialog, i); 1330 @@ -548,9 +586,22 @@ 1331 ++i; 1332 gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent_iter); 1333 /* we use the DESCRIPTION_COLUMN only for the section headers */ 1334 - gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 1335 - KEYENTRY_COLUMN, key_entry, 1336 - -1); 1337 + 1338 + if (!custom_binding) 1339 + { 1340 + /* we use the DESCRIPTION_COLUMN only for the section headers */ 1341 + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 1342 + KEYENTRY_COLUMN, key_entry, 1343 + -1); 1344 + } 1345 + else 1346 + { 1347 + gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 1348 + DESCRIPTION_COLUMN, key_entry->action, 1349 + KEYENTRY_COLUMN, key_entry, 1350 + -1); 1351 + } 1352 + 1353 gtk_tree_view_expand_all (GTK_TREE_VIEW (WID ("shortcut_treeview"))); 1354 } 1355 1356 @@ -751,7 +802,7 @@ 1357 title = _(keylist->name); 1358 } 1359 1360 - append_keys_to_tree (dialog, title, keys); 1361 + append_keys_to_tree (dialog, title, keys, FALSE); 1362 1363 g_free (keylist->name); 1364 g_free (keylist->package); 1365 @@ -801,7 +852,7 @@ 1366 g_array_append_val (entries, key); 1367 1368 keys = (KeyListEntry *) entries->data; 1369 - append_keys_to_tree (dialog, _("Custom Shortcuts"), keys); 1370 + append_keys_to_tree (dialog, _("Custom Shortcuts"), keys, FALSE); 1371 for (i = 0; i < entries->len; ++i) 1372 { 1373 g_free (keys[i].name); 1374 @@ -812,7 +863,7 @@ 1375 g_array_free (entries, TRUE); 1376 } 1377 1378 -static void 1379 +void 1380 reload_key_entries (gpointer wm_name, GladeXML *dialog) 1381 { 1382 GDir *dir; 1383 @@ -848,6 +899,10 @@ 1384 g_list_free (list); 1385 1386 append_keys_to_tree_from_gconf (dialog, GCONF_BINDING_DIR); 1387 + 1388 + /* SUN_BRANDING */ 1389 + append_keys_to_tree (dialog, _("Custom Shortcuts"), custom_binding_list, 1390 + TRUE); 1391 } 1392 1393 static void 1394 @@ -1120,10 +1175,22 @@ 1395 str = binding_name (keyval, keycode, mask, FALSE); 1396 1397 client = gconf_client_get_default (); 1398 - gconf_client_set_string (client, 1399 - key_entry->gconf_key, 1400 - str, 1401 - &err); 1402 + 1403 + if (!key_entry->custom_key) 1404 + gconf_client_set_string (client, 1405 + key_entry->gconf_key, 1406 + str, 1407 + &err); 1408 + else 1409 + { 1410 + char *key = g_strdup_printf ("%s/binding", key_entry->gconf_key); 1411 + gconf_client_set_string (client, 1412 + key, 1413 + str, 1414 + &err); 1415 + g_free (key); 1416 + } 1417 + 1418 g_free (str); 1419 g_object_unref (client); 1420 1421 @@ -1163,9 +1230,25 @@ 1422 1423 /* Unset the key */ 1424 client = gconf_client_get_default(); 1425 + 1426 + if (!key_entry->custom_key) { 1427 + gconf_client_set_string (gconf_client_get_default(), 1428 + key_entry->gconf_key, 1429 + "disabled", 1430 + &err); 1431 + } else { 1432 + char *key = g_strdup_printf ("%s/binding", key_entry->gconf_key); 1433 + gconf_client_set_string (gconf_client_get_default(), 1434 + key, 1435 + "disabled", 1436 + &err); 1437 + g_free (key); 1438 + 1439 + } 1440 + 1441 gconf_client_set_string (client, 1442 key_entry->gconf_key, 1443 - "", 1444 + "disabled", 1445 &err); 1446 g_object_unref (client); 1447 1448 @@ -1348,10 +1431,10 @@ 1449 1450 client = gconf_client_get_default (); 1451 1452 - g_signal_connect (treeview, "button_press_event", 1453 - G_CALLBACK (start_editing_cb), NULL); 1454 g_signal_connect (treeview, "row-activated", 1455 G_CALLBACK (start_editing_kb_cb), NULL); 1456 + g_signal_connect (treeview, "cursor-changed", 1457 + G_CALLBACK (cursor_changed_cb), dialog); 1458 1459 renderer = gtk_cell_renderer_text_new (); 1460 1461 @@ -1390,12 +1473,15 @@ 1462 1463 gconf_client_add_dir (client, GCONF_BINDING_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); 1464 gconf_client_add_dir (client, "/apps/metacity/general", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); 1465 + gconf_client_add_dir (client, GCONF_CUSTOM_BINDING_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); 1466 gconf_client_notify_add (client, 1467 "/apps/metacity/general/num_workspaces", 1468 (GConfClientNotifyFunc) key_entry_controlling_key_changed, 1469 dialog, NULL, NULL); 1470 g_object_unref (client); 1471 1472 + create_custom_bindings_list (); 1473 + 1474 /* set up the dialog */ 1475 wm_name = wm_common_get_current_window_manager(); 1476 reload_key_entries (wm_name, dialog); 1477 @@ -1407,6 +1493,19 @@ 1478 1479 g_signal_connect (widget, "key_press_event", G_CALLBACK (maybe_block_accels), NULL); 1480 g_signal_connect (widget, "response", G_CALLBACK (cb_dialog_response), dialog); 1481 + 1482 + /* set up custom bindings buttons and dialog*/ 1483 + widget = WID ("disable_custom_button"); 1484 + g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (disable_custom), 1485 + GTK_TREE_VIEW (WID ("shortcut_treeview"))); 1486 + gtk_widget_set_sensitive (widget, FALSE); 1487 + 1488 + widget = WID ("add_custom_button"); 1489 + g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (add_custom), NULL); 1490 + 1491 + widget = WID ("edit_custom_button"); 1492 + g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (edit_custom), NULL); 1493 + gtk_widget_set_sensitive (widget, FALSE); 1494 } 1495 1496 int 1497