22 #include <tqwindowdefs.h> 25 #include "kglobalaccel_x11.h" 26 #include "kglobalaccel.h" 27 #include "kkeyserver_x11.h" 29 #include <tqpopupmenu.h> 32 #include <tqmetaobject.h> 33 #include <tqucomextra_p.h> 34 #include <kapplication.h> 36 #include <kkeynative.h> 39 #include <kxerrorhandler.h> 44 #include <X11/keysym.h> 48 static int XGrabErrorHandler( Display *, XErrorEvent *e ) {
49 if ( e->error_code != BadAccess ) {
50 kdWarning() <<
"grabKey: got X error " << e->type <<
" instead of BadAccess\n";
62 static uint g_keyModMaskXAccel = 0;
63 static uint g_keyModMaskXOnOrOff = 0;
65 static void calculateGrabMasks()
68 g_keyModMaskXOnOrOff =
79 static TQValueList< KGlobalAccelPrivate* >* all_accels = 0;
81 KGlobalAccelPrivate::KGlobalAccelPrivate()
82 : KAccelBase( KAccelBase::NATIVE_KEYS )
84 , m_blockingDisabled( false )
85 , m_suspended( false )
87 if( all_accels == NULL )
88 all_accels =
new TQValueList< KGlobalAccelPrivate* >;
89 all_accels->append(
this );
90 m_sConfigGroup =
"Global Shortcuts";
91 kapp->installX11EventFilter(
this );
92 connect(kapp, TQT_SIGNAL(coreFakeKeyPress(
unsigned int)),
this, TQT_SLOT(fakeKeyPressed(
unsigned int)));
95 KGlobalAccelPrivate::~KGlobalAccelPrivate()
101 all_accels->remove(
this );
102 if( all_accels->count() == 0 ) {
108 void KGlobalAccelPrivate::setEnabled(
bool bEnable )
110 m_bEnabled = bEnable;
114 void KGlobalAccelPrivate::blockShortcuts(
bool block )
116 if( all_accels == NULL )
118 for( TQValueList< KGlobalAccelPrivate* >::ConstIterator it = all_accels->begin();
119 it != all_accels->end();
121 if( (*it)->m_blockingDisabled )
123 (*it)->m_blocked = block;
124 (*it)->updateConnections();
128 void KGlobalAccelPrivate::disableBlocking(
bool block )
130 m_blockingDisabled = block;
133 bool KGlobalAccelPrivate::isEnabledInternal()
const 135 return KAccelBase::isEnabled() && !m_blocked;
140 void KGlobalAccelPrivate::suspend(
bool s )
145 bool KGlobalAccelPrivate::emitSignal( Signal )
150 bool KGlobalAccelPrivate::connectKey( KAccelAction& action,
const KKeyServer::Key& key )
151 {
return grabKey( key,
true, &action ); }
153 {
return grabKey( key,
true, 0 ); }
154 bool KGlobalAccelPrivate::disconnectKey( KAccelAction& action,
const KKeyServer::Key& key )
155 {
return grabKey( key,
false, &action ); }
157 {
return grabKey( key,
false, 0 ); }
159 bool KGlobalAccelPrivate::grabKey(
const KKeyServer::Key& key,
bool bGrab, KAccelAction* pAction )
162 kdWarning(125) <<
"KGlobalAccelPrivate::grabKey( " << key.
key().
toStringInternal() <<
", " << bGrab <<
", \"" << (pAction ? pAction->name().latin1() :
"(null)") <<
"\" ): Tried to grab key with null code." <<
endl;
167 if( g_keyModMaskXOnOrOff == 0 ) {
168 calculateGrabMasks();
171 uchar keyCodeX = key.
code();
172 uint keyModX = key.
mod() & g_keyModMaskXAccel;
176 if( key.
sym() == XK_Sys_Req && XKeycodeToKeysym( qt_xdisplay(), 111, 0 ) == XK_Print ) {
182 if ((key.
mod() & KKeyServer::MODE_SWITCH) && (!(g_keyModMaskXAccel & KKeyServer::MODE_SWITCH))) {
185 kdWarning(125) <<
"KGlobalAccelPrivate::grabKey( " << key.
key().
toStringInternal() <<
", " << bGrab <<
", \"" << (pAction ? pAction->name().latin1() :
"(null)") <<
"\" ): Tried to grab key requiring ISO_Level3_Shift (AltGr) sequence." <<
endl;
191 kdDebug(125) << TQString(TQString(
"grabKey( key: '%1', bGrab: %2 ): keyCodeX: %3 keyModX: %4\n" )
193 .arg( keyCodeX, 0, 16 ).arg( keyModX, 0, 16 ));
208 TQString sDebug = TQString(
"\tcode: 0x%1 state: 0x%2 | ").arg(keyCodeX,0,16).arg(keyModX,0,16);
210 uint keyModMaskX = ~g_keyModMaskXOnOrOff;
211 for( uint irrelevantBitsMask = 0; irrelevantBitsMask <= 0xff; irrelevantBitsMask++ ) {
212 if( (irrelevantBitsMask & keyModMaskX) == 0 ) {
214 sDebug += TQString(
"0x%3, ").arg(irrelevantBitsMask, 0, 16);
217 XGrabKey( qt_xdisplay(), keyCodeX, keyModX | irrelevantBitsMask,
218 qt_xrootwin(), True, GrabModeAsync, GrabModeSync );
220 XUngrabKey( qt_xdisplay(), keyCodeX, keyModX | irrelevantBitsMask, qt_xrootwin() );
224 kdDebug(125) << sDebug <<
endl;
230 failed = handler.error(
true );
234 kdDebug(125) <<
"grab failed!\n";
235 for( uint m = 0; m <= 0xff; m++ ) {
236 if(( m & keyModMaskX ) == 0 )
237 XUngrabKey( qt_xdisplay(), keyCodeX, keyModX | m, qt_xrootwin() );
244 codemod.code = keyCodeX;
245 codemod.mod = keyModX;
246 if( key.
mod() & KKeyServer::MODE_SWITCH )
247 codemod.mod |= KKeyServer::MODE_SWITCH;
250 m_rgCodeModToAction.insert( codemod, pAction );
252 m_rgCodeModToAction.remove( codemod );
257 bool KGlobalAccelPrivate::x11Event( XEvent* pEvent )
260 switch( pEvent->type ) {
262 XRefreshKeyboardMapping( &pEvent->xmapping );
266 if( x11KeyPress( pEvent ) ) {
270 return TQWidget::x11Event( pEvent );
274 void KGlobalAccelPrivate::x11MappingNotify()
276 kdDebug(125) <<
"KGlobalAccelPrivate::x11MappingNotify()" <<
endl;
279 calculateGrabMasks();
284 void KGlobalAccelPrivate::fakeKeyPressed(
unsigned int keyCode) {
286 codemod.code = keyCode;
289 KKey key(keyCode, 0);
291 kdDebug(125) <<
"fakeKeyPressed: seek " << key.toStringInternal()
292 << TQString(TQString(
" keyCodeX: %1 keyCode: %2 keyModX: %3" )
293 .arg( codemod.code, 0, 16 ).arg( keyCode, 0, 16 ).arg( codemod.mod, 0, 16 )) << endl;
296 if( !m_rgCodeModToAction.contains( codemod ) ) {
298 for( CodeModMap::ConstIterator it = m_rgCodeModToAction.begin(); it != m_rgCodeModToAction.end(); ++it ) {
299 KAccelAction* pAction = *it;
300 kdDebug(125) <<
"\tcode: " << TQString::number(it.key().code, 16) <<
" mod: " << TQString::number(it.key().mod, 16)
301 << (pAction ? TQString(
" name: \"%1\" shortcut: %2").arg(pAction->name()).arg(pAction->shortcut().toStringInternal()) : TQString())
308 KAccelAction* pAction = m_rgCodeModToAction[codemod];
311 static bool recursion_block =
false;
312 if( !recursion_block ) {
313 recursion_block =
true;
314 TQPopupMenu* pMenu = createPopupMenu( 0,
KKeySequence(key) );
315 connect( pMenu, TQT_SIGNAL(activated(
int)),
this, TQT_SLOT(slotActivated(
int)) );
316 pMenu->exec( TQPoint( 0, 0 ) );
317 disconnect( pMenu, TQT_SIGNAL(activated(
int)),
this, TQT_SLOT(slotActivated(
int)));
319 recursion_block =
false;
321 }
else if( !pAction->objSlotPtr() || !pAction->isEnabled() )
327 bool KGlobalAccelPrivate::x11KeyPress(
const XEvent *pEvent )
330 if ( !TQWidget::keyboardGrabber() && !TQApplication::activePopupWidget() ) {
331 XUngrabKeyboard( qt_xdisplay(), pEvent->xkey.time );
332 XFlush( qt_xdisplay());
335 if( !isEnabledInternal() || m_suspended ) {
340 codemod.code = pEvent->xkey.keycode;
341 codemod.mod = pEvent->xkey.state & (g_keyModMaskXAccel | KKeyServer::MODE_SWITCH);
347 uint sym = XKeycodeToKeysym( qt_xdisplay(), codemod.code, 0 );
349 if( sym >= XK_KP_Space && sym <= XK_KP_9 ) {
368 KKey key = keyNative;
371 << TQString(TQString(
" keyCodeX: %1 state: %2 keyModX: %3" )
372 .arg( codemod.code, 0, 16 ).arg( pEvent->xkey.state, 0, 16 ).arg( codemod.mod, 0, 16 )) << endl;
375 if( !m_rgCodeModToAction.contains( codemod ) ) {
377 for( CodeModMap::ConstIterator it = m_rgCodeModToAction.begin(); it != m_rgCodeModToAction.end(); ++it ) {
378 KAccelAction* pAction = *it;
379 kdDebug(125) <<
"\tcode: " << TQString::number(it.key().code, 16) <<
" mod: " << TQString::number(it.key().mod, 16)
380 << (pAction ? TQString(
" name: \"%1\" shortcut: %2").arg(pAction->name()).arg(pAction->shortcut().toStringInternal()) : TQString())
387 KAccelAction* pAction = m_rgCodeModToAction[codemod];
390 static bool recursion_block =
false;
391 if( !recursion_block ) {
392 recursion_block =
true;
393 TQPopupMenu* pMenu = createPopupMenu( 0,
KKeySequence(key) );
394 connect( pMenu, TQT_SIGNAL(activated(
int)),
this, TQT_SLOT(slotActivated(
int)) );
395 pMenu->exec( TQPoint( 0, 0 ) );
396 disconnect( pMenu, TQT_SIGNAL(activated(
int)),
this, TQT_SLOT(slotActivated(
int)));
398 recursion_block =
false;
400 }
else if( !pAction->objSlotPtr() || !pAction->isEnabled() )
408 void KGlobalAccelPrivate::activate( KAccelAction* pAction,
const KKeySequence& seq )
410 kdDebug(125) <<
"KGlobalAccelPrivate::activate( \"" << pAction->name() <<
"\" ) " <<
endl;
412 TQRegExp rexPassIndex(
"([ ]*int[ ]*)" );
413 TQRegExp rexPassInfo(
" TQString" );
414 TQRegExp rexIndex(
" ([0-9]+)$" );
419 if( rexPassIndex.search( pAction->methodSlotPtr() ) >= 0 && rexIndex.search( pAction->name() ) >= 0 ) {
420 int n = rexIndex.cap(1).toInt();
421 kdDebug(125) <<
"Calling " << pAction->methodSlotPtr() <<
" int = " << n <<
endl;
422 int slot_id = pAction->objSlotPtr()->metaObject()->findSlot( normalizeSignalSlot( pAction->methodSlotPtr() ).data() + 1, true );
425 static_TQUType_int.set(o+1,n);
426 const_cast< TQObject*
>( pAction->objSlotPtr())->qt_invoke( slot_id, o );
428 }
else if( rexPassInfo.search( pAction->methodSlotPtr() ) ) {
429 int slot_id = pAction->objSlotPtr()->metaObject()->findSlot( normalizeSignalSlot( pAction->methodSlotPtr() ).data() + 1, true );
432 static_TQUType_TQString.set(o+1,pAction->name());
433 static_TQUType_TQString.set(o+2,pAction->label());
434 static_TQUType_ptr.set(o+3,&seq);
435 const_cast< TQObject*
>( pAction->objSlotPtr())->qt_invoke( slot_id, o );
438 int slot_id = pAction->objSlotPtr()->metaObject()->findSlot( normalizeSignalSlot( pAction->methodSlotPtr() ).data() + 1, true );
440 const_cast< TQObject*
>( pAction->objSlotPtr())->qt_invoke( slot_id, 0 );
444 void KGlobalAccelPrivate::slotActivated(
int iAction )
446 KAccelAction* pAction = KAccelBase::actions().actionPtr( iAction );
451 #include "kglobalaccel_x11.moc" A collection of functions for the conversion of key presses and their modifiers from the window syste...
uint modXNumLock()
Returns the X11 NumLock modifier mask/flag.
uint modXScrollLock()
Returns the X11 ScrollLock modifier mask/flag.
uint modXAlt()
Returns the X11 Alt (Mod1) modifier mask/flag.
uint modXModeSwitch()
Returns the X11 Mode_switch modifier mask/flag.
uint modXShift()
Returns the X11 Shift modifier mask/flag.
A KKeySequence object holds a sequence of up to 4 keys.
uint mod() const
Returns the modifiers of the key.
KKey key() const
Converts this Key to a KKey.
kdbgstream kdWarning(int area=0)
TQString toStringInternal() const
Returns an untranslated text representation of the key in the form "modifier+key", suitable e.g.
This class simplifies handling of X errors.
bool initializeMods()
TODO: please document.
uint modXLock()
Returns the X11 Lock modifier mask/flag.
Representation of a key in the format native of the windowing system (eg.
uint code() const
Returns the code of the key.
A KKey object represents a single key with possible modifiers (Shift, Ctrl, Alt, Win).
kndbgstream & endl(kndbgstream &s)
Does nothing.
uint accelModMaskX()
Returns bitwise OR'ed mask containing Shift, Ctrl, Alt, and Win (if available).
uint sym() const
Returns the symbol of the key.
bool updateConnections()
Updates the connections of the accelerations after changing them.