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 =
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 ) {

@ -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;
}

@ -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)

@ -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<struct X>& 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<struct X>& 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;
// }
}
}
}

@ -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;
}

Loading…
Cancel
Save