Index: widget/src/gtk2/nsWindow.cpp =================================================================== RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.cpp,v retrieving revision 1.145.2.14 diff -u -8 -p -r1.145.2.14 nsWindow.cpp --- widget/src/gtk2/nsWindow.cpp 8 Nov 2007 03:22:32 -0000 1.145.2.14 +++ widget/src/gtk2/nsWindow.cpp 27 Nov 2007 16:16:52 -0000 @@ -1810,16 +1810,24 @@ nsWindow::OnContainerFocusOutEvent(GtkWi gFocusWindow = nsnull; mActivatePending = PR_FALSE; LOGFOCUS(("Done with container focus out [%p]\n", (void *)this)); } +inline PRBool +is_latin_shortcut_key(guint aKeyval) +{ + return ((GDK_0 <= aKeyval && aKeyval <= GDK_9) || + (GDK_A <= aKeyval && aKeyval <= GDK_Z) || + (GDK_a <= aKeyval && aKeyval <= GDK_z)); +} + gboolean nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent) { LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this)); #ifdef USE_XIM // if we are in the middle of composing text, XIM gets to see it // before mozilla does. @@ -1884,16 +1892,72 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWi if (event.charCode) { event.keyCode = 0; // if the control, meta, or alt key is down, then we should leave // the isShift flag alone (probably not a printable character) // if none of the other modifier keys are pressed then we need to // clear isShift so the character can be inserted in the editor if (event.isControl || event.isAlt || event.isMeta) { + GdkEventKey tmpEvent = *aEvent; + + // Fix for bug 69230: + // if modifier key is pressed and key pressed is not latin character, + // we should try other keyboard layouts to find out correct latin + // character corresponding to pressed key; + // that way shortcuts like Ctrl+C will work no matter what + // keyboard layout is selected + // We don't try to fix up punctuation accelerators here, + // because their location differs between latin layouts + if (!is_latin_shortcut_key(event.charCode)) { + // We have a non-latin char, try other keyboard groups + GdkKeymapKey *keys; + guint *keyvals; + gint n_entries; + PRUint32 latinCharCode; + gint level; + + if (gdk_keymap_translate_keyboard_state(NULL, + tmpEvent.hardware_keycode, + (GdkModifierType)tmpEvent.state, + tmpEvent.group, + NULL, NULL, &level, NULL) + && gdk_keymap_get_entries_for_keycode(NULL, + tmpEvent.hardware_keycode, + &keys, &keyvals, + &n_entries)) { + gint n; + for (n=0; n GDK_9)) { - GdkKeymapKey k = { aEvent->hardware_keycode, aEvent->group, 0 }; - guint savedKeyval = aEvent->keyval; - aEvent->keyval = gdk_keymap_lookup_key(gdk_keymap_get_default(), &k); - PRUint32 unshiftedCharCode = nsConvertCharCodeToUnicode(aEvent); + GdkKeymapKey k = { tmpEvent.hardware_keycode, tmpEvent.group, 0 }; + tmpEvent.keyval = gdk_keymap_lookup_key(gdk_keymap_get_default(), &k); + PRUint32 unshiftedCharCode = nsConvertCharCodeToUnicode(&tmpEvent); if (unshiftedCharCode) event.charCode = unshiftedCharCode; - else - aEvent->keyval = savedKeyval; } } } // before we dispatch a key, check if it's the context menu key. // If so, send a context menu key event instead. if (is_context_menu_key(event)) { nsMouseEvent contextMenuEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);