Do not grab wrong key when AltGr sequence is required to access global accelerator sequence character

This resolves Bug 1676
pull/16/head
Timothy Pearson 11 years ago
parent 72849e2a6f
commit 05e764aa4c

@ -69,8 +69,8 @@ static void calculateGrabMasks()
g_keyModMaskXOnOrOff = g_keyModMaskXOnOrOff =
KKeyServer::modXLock() | KKeyServer::modXLock() |
KKeyServer::modXNumLock() | KKeyServer::modXNumLock() |
KKeyServer::modXScrollLock() | KKeyServer::modXScrollLock() |
KKeyServer::modXModeSwitch(); KKeyServer::modXModeSwitch();
//kdDebug() << "g_keyModMaskXAccel = " << g_keyModMaskXAccel //kdDebug() << "g_keyModMaskXAccel = " << g_keyModMaskXAccel
// << "g_keyModMaskXOnOrOff = " << g_keyModMaskXOnOrOff << endl; // << "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. // Make sure that grab masks have been initialized.
if( g_keyModMaskXOnOrOff == 0 ) if( g_keyModMaskXOnOrOff == 0 ) {
calculateGrabMasks(); calculateGrabMasks();
}
uchar keyCodeX = key.code(); uchar keyCodeX = key.code();
uint keyModX = key.mod() & g_keyModMaskXAccel; // Get rid of any non-relevant bits in mod 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(); keyModX |= KKeyServer::modXAlt();
keyCodeX = 111; 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__ #ifndef __osf__
// this crashes under Tru64 so ..... // 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( key.key().toStringInternal() ).arg( bGrab )
.arg( keyCodeX, 0, 16 ).arg( keyModX, 0, 16 )); .arg( keyCodeX, 0, 16 ).arg( keyModX, 0, 16 ));
#endif #endif
if( !keyCodeX ) if( !keyCodeX ) {
return false; return false;
}
#ifdef Q_WS_X11 #ifdef Q_WS_X11
KXErrorHandler handler( XGrabErrorHandler ); KXErrorHandler handler( XGrabErrorHandler );
@ -254,8 +264,9 @@ bool TDEGlobalAccelPrivate::x11Event( XEvent* pEvent )
x11MappingNotify(); x11MappingNotify();
return false; return false;
case XKeyPress: case XKeyPress:
if( x11KeyPress( pEvent ) ) if( x11KeyPress( pEvent ) ) {
return true; return true;
}
default: default:
return TQWidget::x11Event( pEvent ); return TQWidget::x11Event( pEvent );
} }
@ -276,7 +287,7 @@ void TDEGlobalAccelPrivate::fakeKeyPressed(unsigned int keyCode) {
codemod.code = keyCode; codemod.code = keyCode;
codemod.mod = 0; codemod.mod = 0;
KKey key = (keyCode, 0); KKey key(keyCode, 0);
kdDebug(125) << "fakeKeyPressed: seek " << key.toStringInternal() kdDebug(125) << "fakeKeyPressed: seek " << key.toStringInternal()
<< TQString(TQString( " keyCodeX: %1 keyCode: %2 keyModX: %3" ) << TQString(TQString( " keyCodeX: %1 keyCode: %2 keyModX: %3" )
@ -294,7 +305,7 @@ void TDEGlobalAccelPrivate::fakeKeyPressed(unsigned int keyCode) {
#endif #endif
return; return;
} }
TDEAccelAction* pAction = m_rgCodeModToAction[codemod]; TDEAccelAction* pAction = m_rgCodeModToAction[codemod];
if( !pAction ) { if( !pAction ) {
@ -322,8 +333,9 @@ bool TDEGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent )
XFlush( tqt_xdisplay()); // avoid X(?) bug XFlush( tqt_xdisplay()); // avoid X(?) bug
} }
if( !isEnabledInternal() || m_suspended ) if( !isEnabledInternal() || m_suspended ) {
return false; return false;
}
CodeMod codemod; CodeMod codemod;
codemod.code = pEvent->xkey.keycode; codemod.code = pEvent->xkey.keycode;
@ -372,7 +384,7 @@ bool TDEGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent )
#endif #endif
return false; return false;
} }
TDEAccelAction* pAction = m_rgCodeModToAction[codemod]; TDEAccelAction* pAction = m_rgCodeModToAction[codemod];
if( !pAction ) { if( !pAction ) {

@ -180,10 +180,12 @@ KKey KKeyNative::key() const
int KKeyNative::keyCodeQt() 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 keyQt | modQt;
}
return 0; return 0;
} }

@ -496,8 +496,9 @@ int Sym::qt() const
TQString Sym::toString( bool bUserSpace ) const TQString Sym::toString( bool bUserSpace ) const
{ {
if( m_sym == 0 ) if( m_sym == 0 ) {
return TQString::null; return TQString::null;
}
// If it's a unicode character, // If it's a unicode character,
#ifdef Q_WS_WIN #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. // Print all non-space characters directly when output is user-visible.
// Otherwise only print alphanumeric latin1 characters directly (A,B,C,1,2,3). // Otherwise only print alphanumeric latin1 characters directly (A,B,C,1,2,3).
if( (c.latin1() && c.isLetterOrNumber()) if( (c.latin1() && c.isLetterOrNumber())
|| (bUserSpace && !c.isSpace()) ) || (bUserSpace && !c.isSpace()) ) {
return c; return c;
}
} }
// Look up in special names list // Look up in special names list
for( int i = 0; g_rgSymNames[i].sym != 0; i++ ) { 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); return bUserSpace ? i18n(g_rgSymNames[i].psName) : TQString(g_rgSymNames[i].psName);
}
} }
TQString s; TQString s;
@ -996,8 +999,9 @@ void Variations::init( const KKey& key, bool bQt )
uint nVariations = 0; uint nVariations = 0;
for( uint i = 0; i < m_nVariations; i++ ) { for( uint i = 0; i < m_nVariations; i++ ) {
int keyQt = KKeyNative( m_rgkey[i].code(), m_rgkey[i].mod(), m_rgkey[i].sym() ).keyCodeQt(); 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_rgkey[nVariations++].setKeycodeQt( keyQt );
}
} }
m_nVariations = nVariations; m_nVariations = nVariations;
@ -1007,8 +1011,9 @@ void Variations::init( const KKey& key, bool bQt )
for( uint j = 0; j < i; j++ ) { for( uint j = 0; j < i; j++ ) {
// If key is already present in list, then remove it. // If key is already present in list, then remove it.
if( m_rgkey[i].keyCodeQt() == m_rgkey[j].keyCodeQt() ) { 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_rgkey[k].setKeycodeQt( m_rgkey[k+1].keyCodeQt() );
}
m_nVariations--; m_nVariations--;
i--; i--;
break; break;
@ -1020,7 +1025,7 @@ void Variations::init( const KKey& key, bool bQt )
} // end of namespace KKeyServer block } // 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. // KKeyServer::method which it will call.
// Alt+SysReq => Alt+Print // Alt+SysReq => Alt+Print
// Ctrl+Shift+Plus => Ctrl+Plus (en) // Ctrl+Shift+Plus => Ctrl+Plus (en)
@ -1041,8 +1046,9 @@ void KKey::simplify()
} }
// If this is a letter, don't remove any modifiers. // 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(); m_sym = TQChar(m_sym).lower().unicode();
}
// Remove modifers from modifier list which are implicit in the symbol. // Remove modifers from modifier list which are implicit in the symbol.
// Ex. Shift+Plus => Plus (en) // Ex. Shift+Plus => Plus (en)

@ -131,7 +131,8 @@ TDEAccelAction* TDEAccelBase::insert( const TQString& sAction, const TQString& s
const TQObject* pObjSlot, const char* psMethodSlot, const TQObject* pObjSlot, const char* psMethodSlot,
bool bConfigurable, bool bEnabled ) 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( TDEAccelAction* pAction = m_rgActions.insert(
sAction, sDesc, sHelp, sAction, sDesc, sHelp,
rgCutDefaults3, rgCutDefaults4, rgCutDefaults3, rgCutDefaults4,
@ -369,7 +370,7 @@ bool TDEAccelBase::updateConnections()
info.pAction = 0; info.pAction = 0;
} }
//kdDebug(125) << "mapKeyToAction[" << key.toStringInternal() << "] = " << info.pAction << endl; kdDebug(125) << "mapKeyToAction[" << key.key().toStringInternal() << "] = " << info.pAction << endl;
mapKeyToAction[key] = info; mapKeyToAction[key] = info;
} }
@ -421,9 +422,10 @@ bool TDEAccelBase::updateConnections()
// Construct a list of keys to be connected, sorted highest priority first. // Construct a list of keys to be connected, sorted highest priority first.
void TDEAccelBase::createKeyList( TQValueVector<struct X>& rgKeys ) void TDEAccelBase::createKeyList( TQValueVector<struct X>& rgKeys )
{ {
//kdDebug(125) << "TDEAccelBase::createKeyList()" << endl; kdDebug(125) << "TDEAccelBase::createKeyList()" << endl;
if( !isEnabledInternal()) if( !isEnabledInternal()) {
return; return;
}
// create the list // create the list
// For each action // For each action
@ -437,13 +439,15 @@ void TDEAccelBase::createKeyList( TQValueVector<struct X>& rgKeys )
KKeyServer::Variations vars; KKeyServer::Variations vars;
vars.init( seq.key(0), !m_bNativeKeys ); vars.init( seq.key(0), !m_bNativeKeys );
for( uint iVari = 0; iVari < vars.count(); iVari++ ) { 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 ) ) ); 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; // kdDebug(125) << "\t*" << pAction->name() << ":" << endl;
// }
} }
} }
} }

@ -70,8 +70,9 @@ bool KKey::init( int keyQt )
//if( sym.initQt( keyQt ) //if( sym.initQt( keyQt )
if( KKeyServer::keyQtToSym( keyQt, m_sym ) if( KKeyServer::keyQtToSym( keyQt, m_sym )
&& KKeyServer::keyQtToMod( keyQt, m_mod ) ) && KKeyServer::keyQtToMod( keyQt, m_mod ) ) {
return true; return true;
}
else { else {
m_sym = 0; m_sym = 0;
m_mod = 0; m_mod = 0;
@ -422,8 +423,10 @@ bool TDEShortcut::init( int keyQt )
if( keyQt ) { if( keyQt ) {
m_nSeqs = 1; m_nSeqs = 1;
m_rgseq[0].init( TQKeySequence(keyQt) ); m_rgseq[0].init( TQKeySequence(keyQt) );
} else }
else {
clear(); clear();
}
return true; return true;
} }

Loading…
Cancel
Save