Source: http://sisyphus.ru/ru/srpm/Sisyphus/qt4/patches/2
diff -Naur qt-all-opensource-src-4.5.2-orig/src/gui/kernel/qkeymapper_x11.cpp qt-all-opensource-src-4.5.2/src/gui/kernel/qkeymapper_x11.cpp
--- qt-all-opensource-src-4.5.2-orig/src/gui/kernel/qkeymapper_x11.cpp	2009-08-13 19:38:02 +0400
+++ qt-all-opensource-src-4.5.2/src/gui/kernel/qkeymapper_x11.cpp	2009-08-26 00:45:35 +0400
@@ -302,6 +302,7 @@
         return QList<int>();
 
     QList<int> result;
+    QList<int> codes;
 
     // translate sym -> code
     Qt::KeyboardModifiers baseModifiers = 0;
@@ -318,6 +319,7 @@
     if (baseCode && baseCode < 0xfffe)
         baseCode = QChar(baseCode).toUpper().unicode();
     result += (baseCode | baseModifiers);
+    codes += baseCode;
 
     int pos1Bits[MaxBits];
     int num1Bits = 0;
@@ -360,11 +362,41 @@
 
         if (code && code < 0xfffe)
             code = QChar(code).toUpper().unicode();
-        if (code == baseCode)
+        if (codes.contains(code))
+            continue;
+
+        result += (code | modifiers);
+        codes += code;
+    }
+
+    XkbDescRec *xkb = XkbGetMap(X11->display, XkbKeySymsMask|XkbKeyTypesMask, XkbUseCoreKbd);
+    KeySym *entry = XkbKeySymsPtr(xkb, xkeycode);
+    int total_syms = XkbKeyNumSyms (xkb, xkeycode);
+    int i = 0;
+
+    for (i=0; i < total_syms; i++) {
+        // translate sym -> code
+        Qt::KeyboardModifiers modifiers = 0;
+        int code = -1;
+        chars.clear();
+        count = 0;
+        // mask out the modifiers needed to translate keycode
+        text = translateKeySym(entry[i], xmodifiers, code, modifiers, chars, count);
+        if (code == -1) {
+            if (text.isEmpty())
+                continue;
+            code = text.at(0).unicode();
+        }
+
+        if (code && code < 0xfffe)
+            code = QChar(code).toUpper().unicode();
+        if (codes.contains(code) || !QChar(code).isLetter())
             continue;
 
         result += (code | modifiers);
+        codes += code;
     }
+    XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
 
 #if 0
     qDebug() << "possibleKeysXKB()" << hex << result;
diff -Naur qt-all-opensource-src-4.5.2-orig/src/gui/widgets/qmenubar.cpp qt-all-opensource-src-4.5.2/src/gui/widgets/qmenubar.cpp
--- qt-all-opensource-src-4.5.2-orig/src/gui/widgets/qmenubar.cpp	2009-08-13 19:38:02 +0400
+++ qt-all-opensource-src-4.5.2/src/gui/widgets/qmenubar.cpp	2009-08-26 00:44:04 +0400
@@ -513,6 +513,8 @@
 //         emit q->highlighted(action);
 }
 
+#include <private/qkeymapper_p.h>
+
 
 void QMenuBarPrivate::_q_actionTriggered()
 {
@@ -1205,20 +1207,30 @@
         QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
         {
             QChar c = e->text()[0].toUpper();
+            QList<int> possibleKeys = qt_keymapper_private()->possibleKeys(e);
+            if(!possibleKeys.contains(c.unicode()))
+                possibleKeys += c.unicode(); 
+
             for(int i = 0; i < d->actionList.size(); ++i) {
                 register QAction *act = d->actionList.at(i);
                 QString s = act->text();
                 if(!s.isEmpty()) {
                     int ampersand = s.indexOf(QLatin1Char('&'));
                     if(ampersand >= 0) {
-                        if(s[ampersand+1].toUpper() == c) {
-                            clashCount++;
-                            if(!first)
-                                first = act;
-                            if(act == d->currentAction)
-                                currentSelected = act;
-                            else if (!firstAfterCurrent && currentSelected)
-                                firstAfterCurrent = act;
+                        QListIterator<int> k(possibleKeys);
+                        while (k.hasNext()) {
+                            int key_e = k.next();
+
+                            if(s[ampersand+1].toUpper().unicode() == key_e) {
+                                clashCount++;
+                                if(!first)
+                                    first = act;
+                                if(act == d->currentAction)
+                                    currentSelected = act;
+                                else if (!firstAfterCurrent && currentSelected)
+                                    firstAfterCurrent = act;
+                                break;
+                            }
                         }
                     }
                 }
diff -Naur qt-all-opensource-src-4.5.2-orig/src/gui/widgets/qmenu.cpp qt-all-opensource-src-4.5.2/src/gui/widgets/qmenu.cpp
--- qt-all-opensource-src-4.5.2-orig/src/gui/widgets/qmenu.cpp	2009-08-13 19:38:02 +0400
+++ qt-all-opensource-src-4.5.2/src/gui/widgets/qmenu.cpp	2009-08-26 00:44:04 +0400
@@ -79,6 +79,7 @@
 #   include <private/qt_cocoa_helpers_mac_p.h>
 #endif
 
+#include <private/qkeymapper_p.h>
 
 QT_BEGIN_NAMESPACE
 
@@ -2653,18 +2654,29 @@
                 int clashCount = 0;
                 QAction *first = 0, *currentSelected = 0, *firstAfterCurrent = 0;
                 QChar c = e->text().at(0).toUpper();
+
+                QList<int> possibleKeys = qt_keymapper_private()->possibleKeys(e);
+                if(!possibleKeys.contains(c.unicode()))
+                    possibleKeys += c.unicode(); 
+
                 for(int i = 0; i < d->actionList.size(); ++i) {
                     register QAction *act = d->actionList.at(i);
                     QKeySequence sequence = QKeySequence::mnemonic(act->text());
                     int key = sequence[0] & 0xffff;
-                    if (key == c.unicode()) {
-                        clashCount++;
-                        if (!first)
-                            first = act;
-                        if (act == d->currentAction)
-                            currentSelected = act;
-                        else if (!firstAfterCurrent && currentSelected)
-                            firstAfterCurrent = act;
+
+                    QListIterator<int> k(possibleKeys);
+                    while (k.hasNext()) {
+                        int key_e = k.next();
+                        if (key == key_e) {
+                            clashCount++;
+                            if (!first)
+                                first = act;
+                            if (act == d->currentAction)
+                                currentSelected = act;
+                            else if (!firstAfterCurrent && currentSelected)
+                                firstAfterCurrent = act;
+                            break;
+                        }
                     }
                 }
                 if (clashCount == 1)
