From bfb89e3efee60558a2de73fb71d054836e2c87cc Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Fri, 29 Nov 2013 14:54:15 -0600 Subject: [PATCH] Do not grab wrong key when AltGr sequence is required to access global accelerator sequence character This resolves Bug 1676 (cherry picked from commit 05e764aa4c991949a0249ffdaa203f7292c7b138) --- kdecore/kaccelbase.cpp | 18 +++++++++++------- kdecore/kglobalaccel_x11.cpp | 30 +++++++++++++++++++++--------- kdecore/kkeynative_x11.cpp | 6 ++++-- kdecore/kkeyserver_x11.cpp | 20 +++++++++++++------- kdecore/kshortcut.cpp | 7 +++++-- 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/kdecore/kaccelbase.cpp b/kdecore/kaccelbase.cpp index 4ba4c9c3b..92f61ee82 100644 --- a/kdecore/kaccelbase.cpp +++ b/kdecore/kaccelbase.cpp @@ -131,7 +131,8 @@ KAccelAction* KAccelBase::insert( const TQString& sAction, const TQString& sDesc const TQObject* pObjSlot, const char* psMethodSlot, bool bConfigurable, bool bEnabled ) { - //kdDebug(125) << "KAccelBase::insert() begin" << endl; + kdDebug(125) << "KAccelBase::insert() begin" << endl; + kdDebug(125) << "\t" << sAction << ": " << rgCutDefaults3.toString() << ": " << rgCutDefaults4.toString() << endl; KAccelAction* pAction = m_rgActions.insert( sAction, sDesc, sHelp, rgCutDefaults3, rgCutDefaults4, @@ -369,7 +370,7 @@ bool KAccelBase::updateConnections() info.pAction = 0; } - //kdDebug(125) << "mapKeyToAction[" << key.toStringInternal() << "] = " << info.pAction << endl; + kdDebug(125) << "mapKeyToAction[" << key.key().toStringInternal() << "] = " << info.pAction << endl; mapKeyToAction[key] = info; } @@ -421,9 +422,10 @@ bool KAccelBase::updateConnections() // Construct a list of keys to be connected, sorted highest priority first. void KAccelBase::createKeyList( TQValueVector& rgKeys ) { - //kdDebug(125) << "KAccelBase::createKeyList()" << endl; - if( !isEnabledInternal()) + kdDebug(125) << "KAccelBase::createKeyList()" << endl; + if( !isEnabledInternal()) { return; + } // create the list // For each action @@ -437,13 +439,15 @@ void KAccelBase::createKeyList( TQValueVector& rgKeys ) KKeyServer::Variations vars; vars.init( seq.key(0), !m_bNativeKeys ); for( uint iVari = 0; iVari < vars.count(); iVari++ ) { - if( vars.key(iVari).code() && vars.key(iVari).sym() ) + if( vars.key(iVari).code() && vars.key(iVari).sym() ) { rgKeys.push_back( X( iAction, iSeq, iVari, vars.key( iVari ) ) ); - //kdDebug(125) << "\t" << pAction->name() << ": " << vars.key(iVari).toStringInternal() << endl; + } + kdDebug(125) << "\t" << pAction->name() << ": " << vars.key(iVari).key().toStringInternal() << " [action specified: " << pAction->toStringInternal() << "]" << endl; } } - //else + //else { // kdDebug(125) << "\t*" << pAction->name() << ":" << endl; + // } } } } diff --git a/kdecore/kglobalaccel_x11.cpp b/kdecore/kglobalaccel_x11.cpp index ce248ae02..caa722bf5 100644 --- a/kdecore/kglobalaccel_x11.cpp +++ b/kdecore/kglobalaccel_x11.cpp @@ -68,8 +68,8 @@ static void calculateGrabMasks() g_keyModMaskXOnOrOff = KKeyServer::modXLock() | KKeyServer::modXNumLock() | - KKeyServer::modXScrollLock() | - KKeyServer::modXModeSwitch(); + KKeyServer::modXScrollLock() | + KKeyServer::modXModeSwitch(); //kdDebug() << "g_keyModMaskXAccel = " << g_keyModMaskXAccel // << "g_keyModMaskXOnOrOff = " << g_keyModMaskXOnOrOff << endl; } @@ -164,8 +164,9 @@ bool KGlobalAccelPrivate::grabKey( const KKeyServer::Key& key, bool bGrab, KAcce } // Make sure that grab masks have been initialized. - if( g_keyModMaskXOnOrOff == 0 ) + if( g_keyModMaskXOnOrOff == 0 ) { calculateGrabMasks(); + } uchar keyCodeX = key.code(); uint keyModX = key.mod() & g_keyModMaskXAccel; // Get rid of any non-relevant bits in mod @@ -176,6 +177,14 @@ bool KGlobalAccelPrivate::grabKey( const KKeyServer::Key& key, bool bGrab, KAcce keyModX |= KKeyServer::modXAlt(); keyCodeX = 111; } + // If the MODE_SWITCH modifier was set in the original key, and was truncated in g_keyModMaskXAccel, XGrabKey will grab the wrong key + // See Bug 1676 + if ((key.mod() & KKeyServer::MODE_SWITCH) && (!(g_keyModMaskXAccel & KKeyServer::MODE_SWITCH))) { + // FIXME + // Is there any way to make AltGr-based character sequences work with XGrabKey? + kdWarning(125) << "KGlobalAccelPrivate::grabKey( " << key.key().toStringInternal() << ", " << bGrab << ", \"" << (pAction ? pAction->name().latin1() : "(null)") << "\" ): Tried to grab key requiring ISO_Level3_Shift (AltGr) sequence." << endl; + return false; + } #ifndef __osf__ // this crashes under Tru64 so ..... @@ -183,8 +192,9 @@ bool KGlobalAccelPrivate::grabKey( const KKeyServer::Key& key, bool bGrab, KAcce .arg( key.key().toStringInternal() ).arg( bGrab ) .arg( keyCodeX, 0, 16 ).arg( keyModX, 0, 16 )); #endif - if( !keyCodeX ) + if( !keyCodeX ) { return false; + } #ifdef Q_WS_X11 KXErrorHandler handler( XGrabErrorHandler ); @@ -253,8 +263,9 @@ bool KGlobalAccelPrivate::x11Event( XEvent* pEvent ) x11MappingNotify(); return false; case XKeyPress: - if( x11KeyPress( pEvent ) ) + if( x11KeyPress( pEvent ) ) { return true; + } default: return TQWidget::x11Event( pEvent ); } @@ -275,7 +286,7 @@ void KGlobalAccelPrivate::fakeKeyPressed(unsigned int keyCode) { codemod.code = keyCode; codemod.mod = 0; - KKey key = (keyCode, 0); + KKey key(keyCode, 0); kdDebug(125) << "fakeKeyPressed: seek " << key.toStringInternal() << TQString(TQString( " keyCodeX: %1 keyCode: %2 keyModX: %3" ) @@ -293,7 +304,7 @@ void KGlobalAccelPrivate::fakeKeyPressed(unsigned int keyCode) { #endif return; } - + KAccelAction* pAction = m_rgCodeModToAction[codemod]; if( !pAction ) { @@ -321,8 +332,9 @@ bool KGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent ) XFlush( qt_xdisplay()); // avoid X(?) bug } - if( !isEnabledInternal() || m_suspended ) + if( !isEnabledInternal() || m_suspended ) { return false; + } CodeMod codemod; codemod.code = pEvent->xkey.keycode; @@ -371,7 +383,7 @@ bool KGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent ) #endif return false; } - + KAccelAction* pAction = m_rgCodeModToAction[codemod]; if( !pAction ) { diff --git a/kdecore/kkeynative_x11.cpp b/kdecore/kkeynative_x11.cpp index 8fed59deb..0b8cd122a 100644 --- a/kdecore/kkeynative_x11.cpp +++ b/kdecore/kkeynative_x11.cpp @@ -179,10 +179,12 @@ KKey KKeyNative::key() const int KKeyNative::keyCodeQt() const { - int keyQt = KKeyServer::Sym(m_sym).qt(), modQt; + int keyQt = KKeyServer::Sym(m_sym).qt(); + int modQt; - if( keyQt != TQt::Key_unknown && KKeyServer::modXToModQt( m_mod, modQt ) ) + if( (keyQt != TQt::Key_unknown) && (KKeyServer::modXToModQt( m_mod, modQt )) ) { return keyQt | modQt; + } return 0; } diff --git a/kdecore/kkeyserver_x11.cpp b/kdecore/kkeyserver_x11.cpp index d03fd6afe..1143b22e7 100644 --- a/kdecore/kkeyserver_x11.cpp +++ b/kdecore/kkeyserver_x11.cpp @@ -495,8 +495,9 @@ int Sym::qt() const TQString Sym::toString( bool bUserSpace ) const { - if( m_sym == 0 ) + if( m_sym == 0 ) { return TQString::null; + } // If it's a unicode character, #ifdef Q_WS_WIN @@ -508,14 +509,16 @@ TQString Sym::toString( bool bUserSpace ) const // Print all non-space characters directly when output is user-visible. // Otherwise only print alphanumeric latin1 characters directly (A,B,C,1,2,3). if( (c.latin1() && c.isLetterOrNumber()) - || (bUserSpace && !c.isSpace()) ) + || (bUserSpace && !c.isSpace()) ) { return c; + } } // Look up in special names list for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) { - if( m_sym == g_rgSymNames[i].sym ) + if( m_sym == g_rgSymNames[i].sym ) { return bUserSpace ? i18n(g_rgSymNames[i].psName) : TQString(g_rgSymNames[i].psName); + } } TQString s; @@ -995,8 +998,9 @@ void Variations::init( const KKey& key, bool bQt ) uint nVariations = 0; for( uint i = 0; i < m_nVariations; i++ ) { int keyQt = KKeyNative( m_rgkey[i].code(), m_rgkey[i].mod(), m_rgkey[i].sym() ).keyCodeQt(); - if( keyQt ) + if( keyQt ) { m_rgkey[nVariations++].setKeycodeQt( keyQt ); + } } m_nVariations = nVariations; @@ -1006,8 +1010,9 @@ void Variations::init( const KKey& key, bool bQt ) for( uint j = 0; j < i; j++ ) { // If key is already present in list, then remove it. if( m_rgkey[i].keyCodeQt() == m_rgkey[j].keyCodeQt() ) { - for( uint k = i; k < m_nVariations - 1; k++ ) + for( uint k = i; k < m_nVariations - 1; k++ ) { m_rgkey[k].setKeycodeQt( m_rgkey[k+1].keyCodeQt() ); + } m_nVariations--; i--; break; @@ -1019,7 +1024,7 @@ void Variations::init( const KKey& key, bool bQt ) } // end of namespace KKeyServer block -// FIXME: This needs to be moved to kshortcut.cpp, and create a +// FIXME: This needs to be moved to kshortcut.cpp, and create a // KKeyServer::method which it will call. // Alt+SysReq => Alt+Print // Ctrl+Shift+Plus => Ctrl+Plus (en) @@ -1040,8 +1045,9 @@ void KKey::simplify() } // If this is a letter, don't remove any modifiers. - if( m_sym < 0x3000 && TQChar(m_sym).isLetter() ) + if( m_sym < 0x3000 && TQChar(m_sym).isLetter() ) { m_sym = TQChar(m_sym).lower().unicode(); + } // Remove modifers from modifier list which are implicit in the symbol. // Ex. Shift+Plus => Plus (en) diff --git a/kdecore/kshortcut.cpp b/kdecore/kshortcut.cpp index 10c6c31fa..337a126f2 100644 --- a/kdecore/kshortcut.cpp +++ b/kdecore/kshortcut.cpp @@ -70,8 +70,9 @@ bool KKey::init( int keyQt ) //if( sym.initQt( keyQt ) if( KKeyServer::keyQtToSym( keyQt, m_sym ) - && KKeyServer::keyQtToMod( keyQt, m_mod ) ) + && KKeyServer::keyQtToMod( keyQt, m_mod ) ) { return true; + } else { m_sym = 0; m_mod = 0; @@ -422,8 +423,10 @@ bool KShortcut::init( int keyQt ) if( keyQt ) { m_nSeqs = 1; m_rgseq[0].init( TQKeySequence(keyQt) ); - } else + } + else { clear(); + } return true; }