Index: widget/src/gtk2/nsWindow.cpp =================================================================== RCS file: /cvsroot/mozilla/widget/src/gtk2/nsWindow.cpp,v retrieving revision 1.233 diff -u -8 -p -r1.233 nsWindow.cpp --- widget/src/gtk2/nsWindow.cpp 12 Oct 2007 03:02:26 -0000 1.233 +++ widget/src/gtk2/nsWindow.cpp 12 Oct 2007 10:18:34 -0000 @@ -2176,16 +2176,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. @@ -2252,16 +2260,65 @@ 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) { + // 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 + guint savedKeyval = aEvent->keyval; + guint8 savedGroup = aEvent->group; + 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; + if (gdk_keymap_get_entries_for_keycode(NULL, + aEvent->hardware_keycode, + &keys, &keyvals, + &n_entries)) { + gint n; + for (n=0; ngroup) { + // Skip keys from the same group + continue; + } + if (is_latin_shortcut_key(keyvals[n])) { + // Latin character found + if (event.isShift) + aEvent->keyval = gdk_keyval_to_upper(keyvals[n]); + else + aEvent->keyval = gdk_keyval_to_lower(keyvals[n]); + aEvent->group = keys[n].group; + latinCharCode = nsConvertCharCodeToUnicode(aEvent); + if (latinCharCode) { + event.charCode = latinCharCode; + break; + } + else { + aEvent->keyval = savedKeyval; + aEvent->group = savedGroup; + } + } + } + g_free(keys); + g_free(keyvals); + } + } + // make Ctrl+uppercase functional as same as Ctrl+lowercase // when Ctrl+uppercase(eg.Ctrl+C) is pressed,convert the charCode // from uppercase to lowercase(eg.Ctrl+c),so do Alt and Meta Key // It is hack code for bug 61355, there is same code snip for // Windows platform in widget/src/windows/nsWindow.cpp: See bug 16486 // Note: if Shift is pressed at the same time, do not to_lower() // Because Ctrl+Shift has different function with Ctrl if (!event.isShift && @@ -2278,16 +2335,19 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWi guint savedKeyval = aEvent->keyval; aEvent->keyval = gdk_keymap_lookup_key(gdk_keymap_get_default(), &k); PRUint32 unshiftedCharCode = nsConvertCharCodeToUnicode(aEvent); if (unshiftedCharCode) event.charCode = unshiftedCharCode; else aEvent->keyval = savedKeyval; } + + aEvent->keyval = savedKeyval; + aEvent->group = savedGroup; } } // 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); key_event_to_context_menu_event(&event, &contextMenuEvent);