From 05e764aa4c991949a0249ffdaa203f7292c7b138 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 --- tdecore/kglobalaccel_x11.cpp | 30 +++++++++++++++++++++--------- tdecore/kkeynative_x11.cpp | 6 ++++-- tdecore/kkeyserver_x11.cpp | 20 +++++++++++++------- tdecore/tdeaccelbase.cpp | 18 +++++++++++------- tdecore/tdeshortcut.cpp | 7 +++++-- 5 files changed, 54 insertions(+), 27 deletions(-) diff --git a/tdecore/kglobalaccel_x11.cpp b/tdecore/kglobalaccel_x11.cpp index 2a67c73b5..4ee2770ba 100644 --- a/tdecore/kglobalaccel_x11.cpp +++ b/tdecore/kglobalaccel_x11.cpp @@ -69,8 +69,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; } @@ -165,8 +165,9 @@ bool TDEGlobalAccelPrivate::grabKey( const KKeyServer::Key& key, bool bGrab, TDE } // 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 @@ -177,6 +178,14 @@ bool TDEGlobalAccelPrivate::grabKey( const KKeyServer::Key& key, bool bGrab, TDE 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) << "TDEGlobalAccelPrivate::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 ..... @@ -184,8 +193,9 @@ bool TDEGlobalAccelPrivate::grabKey( const KKeyServer::Key& key, bool bGrab, TDE .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 ); @@ -254,8 +264,9 @@ bool TDEGlobalAccelPrivate::x11Event( XEvent* pEvent ) x11MappingNotify(); return false; case XKeyPress: - if( x11KeyPress( pEvent ) ) + if( x11KeyPress( pEvent ) ) { return true; + } default: return TQWidget::x11Event( pEvent ); } @@ -276,7 +287,7 @@ void TDEGlobalAccelPrivate::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" ) @@ -294,7 +305,7 @@ void TDEGlobalAccelPrivate::fakeKeyPressed(unsigned int keyCode) { #endif return; } - + TDEAccelAction* pAction = m_rgCodeModToAction[codemod]; if( !pAction ) { @@ -322,8 +333,9 @@ bool TDEGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent ) XFlush( tqt_xdisplay()); // avoid X(?) bug } - if( !isEnabledInternal() || m_suspended ) + if( !isEnabledInternal() || m_suspended ) { return false; + } CodeMod codemod; codemod.code = pEvent->xkey.keycode; @@ -372,7 +384,7 @@ bool TDEGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent ) #endif return false; } - + TDEAccelAction* pAction = m_rgCodeModToAction[codemod]; if( !pAction ) { diff --git a/tdecore/kkeynative_x11.cpp b/tdecore/kkeynative_x11.cpp index a44305dad..d5ecb24da 100644 --- a/tdecore/kkeynative_x11.cpp +++ b/tdecore/kkeynative_x11.cpp @@ -180,10 +180,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/tdecore/kkeyserver_x11.cpp b/tdecore/kkeyserver_x11.cpp index 64bfe383d..283c87ce6 100644 --- a/tdecore/kkeyserver_x11.cpp +++ b/tdecore/kkeyserver_x11.cpp @@ -496,8 +496,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 @@ -509,14 +510,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; @@ -996,8 +999,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; @@ -1007,8 +1011,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; @@ -1020,7 +1025,7 @@ void Variations::init( const KKey& key, bool bQt ) } // end of namespace KKeyServer block -// FIXME: This needs to be moved to tdeshortcut.cpp, and create a +// FIXME: This needs to be moved to tdeshortcut.cpp, and create a // KKeyServer::method which it will call. // Alt+SysReq => Alt+Print // Ctrl+Shift+Plus => Ctrl+Plus (en) @@ -1041,8 +1046,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/tdecore/tdeaccelbase.cpp b/tdecore/tdeaccelbase.cpp index 6673cabb4..41864d47c 100644 --- a/tdecore/tdeaccelbase.cpp +++ b/tdecore/tdeaccelbase.cpp @@ -131,7 +131,8 @@ TDEAccelAction* TDEAccelBase::insert( const TQString& sAction, const TQString& s const TQObject* pObjSlot, const char* psMethodSlot, bool bConfigurable, bool bEnabled ) { - //kdDebug(125) << "TDEAccelBase::insert() begin" << endl; + kdDebug(125) << "TDEAccelBase::insert() begin" << endl; + kdDebug(125) << "\t" << sAction << ": " << rgCutDefaults3.toString() << ": " << rgCutDefaults4.toString() << endl; TDEAccelAction* pAction = m_rgActions.insert( sAction, sDesc, sHelp, rgCutDefaults3, rgCutDefaults4, @@ -369,7 +370,7 @@ bool TDEAccelBase::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 TDEAccelBase::updateConnections() // Construct a list of keys to be connected, sorted highest priority first. void TDEAccelBase::createKeyList( TQValueVector& rgKeys ) { - //kdDebug(125) << "TDEAccelBase::createKeyList()" << endl; - if( !isEnabledInternal()) + kdDebug(125) << "TDEAccelBase::createKeyList()" << endl; + if( !isEnabledInternal()) { return; + } // create the list // For each action @@ -437,13 +439,15 @@ void TDEAccelBase::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/tdecore/tdeshortcut.cpp b/tdecore/tdeshortcut.cpp index bae897e98..86b532f9c 100644 --- a/tdecore/tdeshortcut.cpp +++ b/tdecore/tdeshortcut.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 TDEShortcut::init( int keyQt ) if( keyQt ) { m_nSeqs = 1; m_rgseq[0].init( TQKeySequence(keyQt) ); - } else + } + else { clear(); + } return true; }