Bug 108961

Summary: "Disable shorcuts" window-specific setting
Product: [Plasma] kwin Reporter: Zachary Jensen <coolguyzak>
Component: generalAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: wishlist CC: contact, kjetil, thomas.bettler
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Gentoo Packages   
OS: Linux   
Latest Commit: Version Fixed In:

Description Zachary Jensen 2005-07-12 01:41:59 UTC
Version:            (using KDE KDE 3.4.1)
Installed from:    Gentoo Packages

Would it be possible to create a window-specific setting that forwards global keyboard shortcuts to the window?

Example: I am trying to use inkscape, and one of it's commands is alt+drag. But when I do that, kwin interprets it as "Zak is trying to move the window". Basically, kwin intercepts the signal before inkscape can act on it.

I don't want to ask you guys to change the default for the application's sake, but it would be nice if there was a way to disable it. (Maybe there is, using KHotKeys?)

I'll try the above solution, but it would be nice to have both options available.
Comment 1 Lubos Lunak 2005-07-19 15:08:03 UTC
*** Bug 94643 has been marked as a duplicate of this bug. ***
Comment 2 Lubos Lunak 2005-08-01 16:46:17 UTC
SVN commit 442075 by lunakl:

Implement #108961 - there's now a shortcut and window-specific setting
for 'Block global shortcuts', which allows applications like Xnest etc.
to get shortcuts like Alt+F4 etc. that'd be otherwise intercepted as
global shortcuts. A shortcut turn it on and off globally, window-specific
setting only for the given window, the shortcut can turn it temporarily
off even for window with a window-specific setting.
FEATURE: 108961



 M  +6 -1      kaccelbase.cpp  
 M  +1 -0      kaccelbase.h  
 M  +7 -1      kapplication.cpp  
 M  +6 -0      kglobalaccel.cpp  
 M  +9 -0      kglobalaccel.h  
 M  +42 -8     kglobalaccel_x11.cpp  
 M  +7 -0      kglobalaccel_x11.h  
 M  +1 -0      kipc.h  


--- branches/KDE/3.5/kdelibs/kdecore/kaccelbase.cpp #442074:442075
@@ -63,6 +63,11 @@
 uint KAccelBase::actionCount() const { return m_rgActions.count(); }
 KAccelActions& KAccelBase::actions() { return m_rgActions; }
 bool KAccelBase::isEnabled() const { return m_bEnabled; }
+// see KGlobalAccel::blockShortcuts() stuff - it's to temporarily block
+// all global shortcuts, so that the key grabs are released, but from the app's
+// point of view the KGlobalAccel is still enabled, so KGlobalAccel needs
+// to disable key grabbing even if enabled
+bool KAccelBase::isEnabledInternal() const { return isEnabled(); }
 
 KAccelAction* KAccelBase::actionPtr( const QString& sAction )
 	{ return m_rgActions.actionPtr( sAction ); }
@@ -417,7 +422,7 @@
 void KAccelBase::createKeyList( QValueVector<struct X>& rgKeys )
 {
 	//kdDebug(125) << "KAccelBase::createKeyList()" << endl;
-	if( !m_bEnabled )
+	if( !isEnabledInternal())
 		return;
 
 	// create the list
--- branches/KDE/3.5/kdelibs/kdecore/kaccelbase.h #442074:442075
@@ -198,6 +198,7 @@
 	virtual bool disconnectKey( const KKeyServer::Key& ) = 0;
 
  protected:
+        virtual bool isEnabledInternal() const;
 	struct ActionInfo
 	{
 		KAccelAction* pAction;
--- branches/KDE/3.5/kdelibs/kdecore/kapplication.cpp #442074:442075
@@ -73,6 +73,7 @@
 #include <kprotocolinfo.h>
 #include <kkeynative.h>
 #include <kmdcodec.h>
+#include <kglobalaccel.h>
 
 #if defined Q_WS_X11
 #include <kstartupinfo.h>
@@ -828,7 +829,7 @@
   kipcEventMask = (1 << KIPC::StyleChanged) | (1 << KIPC::PaletteChanged) |
                   (1 << KIPC::FontChanged) | (1 << KIPC::BackgroundChanged) |
                   (1 << KIPC::ToolbarStyleChanged) | (1 << KIPC::SettingsChanged) |
-                  (1 << KIPC::ClipboardConfigChanged);
+                  (1 << KIPC::ClipboardConfigChanged | (1 << KIPC::BlockShortcuts));
 #endif
 
   // Trigger creation of locale.
@@ -1779,6 +1780,11 @@
             case KIPC::ClipboardConfigChanged:
                 KClipboardSynchronizer::newConfiguration(arg);
                 break;
+                
+            case KIPC::BlockShortcuts:
+                KGlobalAccel::blockShortcuts(arg);
+                emit kipcMessage(id, arg); // some apps may do additional things
+                break;
             }
         }
         else if (id >= 32)
--- branches/KDE/3.5/kdelibs/kdecore/kglobalaccel.cpp #442074:442075
@@ -65,6 +65,12 @@
 void KGlobalAccel::setEnabled( bool bEnabled )
 	{ d->setEnabled( bEnabled ); }
 
+void KGlobalAccel::blockShortcuts( bool block )
+        { KGlobalAccelPrivate::blockShortcuts( block ); }
+
+void KGlobalAccel::disableBlocking( bool disable )
+        { d->disableBlocking( disable ); }
+
 KAccelAction* KGlobalAccel::insert( const QString& sAction, const QString& sDesc, const QString& sHelp,
 		const KShortcut& cutDef3, const KShortcut& cutDef4,
 		const QObject* pObjSlot, const char* psMethodSlot,
--- branches/KDE/3.5/kdelibs/kdecore/kglobalaccel.h #442074:442075
@@ -206,6 +206,15 @@
 	 * KAccelActions::useFourModifierKeys().
 	 */
 	static bool useFourModifierKeys();
+        
+        /**
+         * @internal
+         */
+        static void blockShortcuts( bool block );
+        /**
+         * @internal
+         */
+        void disableBlocking( bool disable );
 
 private:
 
--- branches/KDE/3.5/kdelibs/kdecore/kglobalaccel_x11.cpp #442074:442075
@@ -76,9 +76,16 @@
 
 //----------------------------------------------------
 
+static QValueList< KGlobalAccelPrivate* >* all_accels;
+
 KGlobalAccelPrivate::KGlobalAccelPrivate()
 : KAccelBase( KAccelBase::NATIVE_KEYS )
+, m_blocked( false )
+, m_blockingDisabled( false )
 {
+        if( all_accels == NULL )
+            all_accels = new QValueList< KGlobalAccelPrivate* >;
+        all_accels->append( this );
 	m_sConfigGroup = "Global Shortcuts";
 	kapp->installX11EventFilter( this );
 }
@@ -89,6 +96,11 @@
 	//for( CodeModMap::ConstIterator it = m_rgCodeModToAction.begin(); it != m_rgCodeModToAction.end(); ++it ) {
 	//	const CodeMod& codemod = it.key();
 	//}
+        all_accels->remove( this );
+        if( all_accels->count() == 0 ) {
+            delete all_accels;
+            all_accels = NULL;
+        }
 }
 
 void KGlobalAccelPrivate::setEnabled( bool bEnable )
@@ -97,6 +109,30 @@
 	updateConnections();
 }
 
+void KGlobalAccelPrivate::blockShortcuts( bool block )
+{
+        if( all_accels == NULL )
+            return;
+        for( QValueList< KGlobalAccelPrivate* >::ConstIterator it = all_accels->begin();
+             it != all_accels->end();
+             ++it ) {
+            if( (*it)->m_blockingDisabled )
+                continue;
+            (*it)->m_blocked = block;
+            (*it)->updateConnections();
+        }
+}
+
+void KGlobalAccelPrivate::disableBlocking( bool block )
+{
+        m_blockingDisabled = block;
+}
+
+bool KGlobalAccelPrivate::isEnabledInternal() const
+{
+        return KAccelBase::isEnabled() && !m_blocked;
+}
+
 bool KGlobalAccelPrivate::emitSignal( Signal )
 {
 	return false;
@@ -216,13 +252,11 @@
 void KGlobalAccelPrivate::x11MappingNotify()
 {
 	kdDebug(125) << "KGlobalAccelPrivate::x11MappingNotify()" << endl;
-	if( m_bEnabled ) {
-		// Maybe the X modifier map has been changed.
-		KKeyServer::initializeMods();
-		calculateGrabMasks();
-		// Do new XGrabKey()s.
-		updateConnections();
-	}
+	// Maybe the X modifier map has been changed.
+	KKeyServer::initializeMods();
+	calculateGrabMasks();
+	// Do new XGrabKey()s.
+	updateConnections();
 }
 
 bool KGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent )
@@ -233,7 +267,7 @@
                 XFlush( qt_xdisplay()); // avoid X(?) bug
         }
 
-	if( !m_bEnabled )
+	if( !isEnabledInternal())
 		return false;
 
 	CodeMod codemod;
--- branches/KDE/3.5/kdelibs/kdecore/kglobalaccel_x11.h #442074:442075
@@ -93,9 +93,16 @@
 	void x11MappingNotify();
 	bool x11KeyPress( const XEvent *pEvent );
 	void activate( KAccelAction* pAction, const KKeySequence& seq );
+        virtual bool isEnabledInternal() const;
 
+        static void blockShortcuts( bool block );
+        void disableBlocking( bool disable );
+
  protected slots:
 	void slotActivated( int iAction );
+ private:
+        bool m_blocked;
+        bool m_blockingDisabled;
 };
 
 #endif // _KGLOBALACCEL_X11_H
--- branches/KDE/3.5/kdelibs/kdecore/kipc.h #442074:442075
@@ -56,6 +56,7 @@
     enum Message { PaletteChanged=0, FontChanged, StyleChanged,
                    BackgroundChanged, SettingsChanged, IconChanged, ToolbarStyleChanged,
                    ClipboardConfigChanged, /// @since 3.1
+                   BlockShortcuts, /// @since 3.5
                    UserMessage=32 };
 
     /**
Comment 3 Mircea Bardac 2005-08-06 23:43:23 UTC
Maybe this could somehow help: http://bugs.kde.org/show_bug.cgi?id=58672
Just a thought.
Comment 4 Mircea Bardac 2005-08-07 09:52:41 UTC
Rephrasing of my last comment:
Maybe this commit (or parts of it) could also (somehow) help: http://bugs.kde.org/show_bug.cgi?id=58672 
Comment 5 Lubos Lunak 2005-08-08 15:43:11 UTC
Not really, that's a different issue.
Comment 6 Lubos Lunak 2005-12-16 16:37:04 UTC
*** Bug 79966 has been marked as a duplicate of this bug. ***
Comment 7 Nicolas Goutte 2006-03-04 15:23:58 UTC
See bug #123058 which seems to be a consquence of this feature.