diff --git a/client.h b/client.h
index 2e020a0fe5..8d0df5e2d4 100644
--- a/client.h
+++ b/client.h
@@ -212,7 +212,7 @@ class Client : public QObject, public KDecorationDefines
bool providesContextHelp() const;
KShortcut shortcut() const;
- void setShortcut( const KShortcut& cut );
+ void setShortcut( const QString& cut );
bool performMouseCommand( Options::MouseCommand, QPoint globalPos, bool handled = false );
@@ -365,6 +365,7 @@ class Client : public QObject, public KDecorationDefines
void setupWindowRules( bool ignore_temporary );
void updateWindowRules();
void finishWindowRules();
+ void setShortcutInternal( const KShortcut& cut );
void updateWorkareaDiffs();
void checkDirection( int new_diff, int old_diff, QRect& rect, const QRect& area );
@@ -872,14 +873,6 @@ inline KShortcut Client::shortcut() const
return _shortcut;
}
-inline void Client::setShortcut( const KShortcut& cut )
- {
- if( _shortcut == cut )
- return;
- _shortcut = cut;
- workspace()->clientShortcutUpdated( this );
- }
-
inline bool Client::isBMP()
{
return isBMP_;
diff --git a/kcmkwin/kwinrules/ruleswidget.cpp b/kcmkwin/kwinrules/ruleswidget.cpp
index e148fdba96..3b1f713b4d 100644
--- a/kcmkwin/kwinrules/ruleswidget.cpp
+++ b/kcmkwin/kwinrules/ruleswidget.cpp
@@ -89,6 +89,7 @@ RulesWidget::RulesWidget( QWidget* parent, const char* name )
SETUP( closeable, force );
SETUP( opacityactive, force );
SETUP( opacityinactive, force );
+ SETUP( shortcut, force );
// workarounds tab
SETUP( fsplevel, force );
SETUP( moveresizemode, force );
@@ -135,6 +136,11 @@ UPDATE_ENABLE_SLOT( acceptfocus )
UPDATE_ENABLE_SLOT( closeable )
UPDATE_ENABLE_SLOT( opacityactive )
UPDATE_ENABLE_SLOT( opacityinactive )
+void RulesWidget::updateEnableshortcut()
+ {
+ shortcut->setEnabled( enable_shortcut->isChecked() && rule_shortcut->currentItem() != 0 );
+ shortcut_edit->setEnabled( enable_shortcut->isChecked() && rule_shortcut->currentItem() != 0 );
+ }
// workarounds tab
UPDATE_ENABLE_SLOT( fsplevel )
UPDATE_ENABLE_SLOT( moveresizemode )
@@ -391,6 +397,7 @@ void RulesWidget::setRules( Rules* rules )
CHECKBOX_FORCE_RULE( closeable, );
LINEEDIT_FORCE_RULE( opacityactive, intToStr );
LINEEDIT_FORCE_RULE( opacityinactive, intToStr );
+ LINEEDIT_SET_RULE( shortcut, );
COMBOBOX_FORCE_RULE( fsplevel, );
COMBOBOX_FORCE_RULE( moveresizemode, moveresizeToCombo );
COMBOBOX_FORCE_RULE( type, typeToCombo );
@@ -479,6 +486,7 @@ Rules* RulesWidget::rules() const
CHECKBOX_FORCE_RULE( closeable, );
LINEEDIT_FORCE_RULE( opacityactive, strToInt );
LINEEDIT_FORCE_RULE( opacityinactive, strToInt );
+ LINEEDIT_SET_RULE( shortcut, );
COMBOBOX_FORCE_RULE( fsplevel, );
COMBOBOX_FORCE_RULE( moveresizemode, comboToMoveResize );
COMBOBOX_FORCE_RULE( type, comboToType );
@@ -594,6 +602,7 @@ void RulesWidget::prefillUnusedValues( const KWin::WindowInfo& info )
//CHECKBOX_PREFILL( closeable, );
LINEEDIT_PREFILL( opacityactive, intToStr, 100 /*get the actual opacity somehow*/);
LINEEDIT_PREFILL( opacityinactive, intToStr, 100 /*get the actual opacity somehow*/);
+ //LINEEDIT_PREFILL( shortcut, );
//COMBOBOX_PREFILL( fsplevel, );
//COMBOBOX_PREFILL( moveresizemode, moveresizeToCombo );
COMBOBOX_PREFILL( type, typeToCombo, info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) );
@@ -642,6 +651,11 @@ void RulesWidget::prepareWindowSpecific( WId window )
prefillUnusedValues( info );
}
+void RulesWidget::shortcutEditClicked()
+ {
+// TODO
+ }
+
RulesDialog::RulesDialog( QWidget* parent, const char* name )
: KDialogBase( parent, name, true, "", Ok | Cancel )
{
diff --git a/kcmkwin/kwinrules/ruleswidget.h b/kcmkwin/kwinrules/ruleswidget.h
index 00bc9d48bc..7ac952c5f6 100644
--- a/kcmkwin/kwinrules/ruleswidget.h
+++ b/kcmkwin/kwinrules/ruleswidget.h
@@ -50,6 +50,7 @@ class RulesWidget
virtual void titleMatchChanged();
virtual void extraMatchChanged();
virtual void machineMatchChanged();
+ virtual void shortcutEditClicked();
private slots:
// geometry tab
void updateEnableposition();
@@ -79,6 +80,7 @@ class RulesWidget
void updateEnableminsize();
void updateEnablemaxsize();
void updateEnablestrictgeometry();
+ void updateEnableshortcut();
// internal
void detected( bool );
private:
diff --git a/kcmkwin/kwinrules/ruleswidgetbase.ui b/kcmkwin/kwinrules/ruleswidgetbase.ui
index f5a92380a0..dc803f1c02 100644
--- a/kcmkwin/kwinrules/ruleswidgetbase.ui
+++ b/kcmkwin/kwinrules/ruleswidgetbase.ui
@@ -12,6 +12,9 @@
503
+
+ Form2
+
unnamed
@@ -1205,31 +1208,6 @@
&Closeable
-
-
- spacer33
-
-
- Vertical
-
-
- Expanding
-
-
-
- 20
- 110
-
-
-
-
-
- enable_opacityinactive
-
-
- I&nactive opacity in %
-
-
enable_opacityactive
@@ -1238,24 +1216,6 @@
A&ctive opacity in %
-
- -
-
- Do Not Affect
-
-
- -
-
- Force
-
-
-
- rule_opacityinactive
-
-
- false
-
-
-
@@ -1274,17 +1234,6 @@
false
-
-
- opacityinactive
-
-
- false
-
-
- 0123456789
-
-
opacityactive
@@ -1296,24 +1245,7 @@
0123456789
-
-
- spacer25
-
-
- Horizontal
-
-
- Expanding
-
-
-
- 181
- 20
-
-
-
-
+
spacer24
@@ -1330,7 +1262,7 @@
-
+
spacer36_7
@@ -1347,7 +1279,7 @@
-
+
spacer36_6
@@ -1364,7 +1296,7 @@
-
+
spacer36_5
@@ -1381,7 +1313,7 @@
-
+
spacer36_4
@@ -1398,7 +1330,7 @@
-
+
spacer36_3
@@ -1415,7 +1347,7 @@
-
+
spacer36_2
@@ -1432,7 +1364,7 @@
-
+
spacer36
@@ -1702,6 +1634,132 @@
false
+
+
+ spacer33
+
+
+ Vertical
+
+
+ Expanding
+
+
+
+ 20
+ 80
+
+
+
+
+ -
+
+ Do Not Affect
+
+
+ -
+
+ Force
+
+
+
+ rule_opacityinactive
+
+
+ false
+
+
+
+
+ opacityinactive
+
+
+ false
+
+
+ 0123456789
+
+
+
+
+ spacer25
+
+
+ Horizontal
+
+
+ Expanding
+
+
+
+ 181
+ 20
+
+
+
+
+
+ enable_opacityinactive
+
+
+ I&nactive opacity in %
+
+
+
+
+ enable_shortcut
+
+
+ Shortcut
+
+
+
+
+
+
+ -
+
+ Do Not Affect
+
+
+ -
+
+ Apply Initially
+
+
+ -
+
+ Remember
+
+
+ -
+
+ Force
+
+
+
+ rule_shortcut
+
+
+ false
+
+
+
+
+ shortcut_edit
+
+
+ Edit
+
+
+
+
+ shortcut
+
+
+ false
+
+
@@ -2075,6 +2133,8 @@
+
+
detect1
@@ -2112,6 +2172,12 @@
Form2
machineMatchChanged()
+
+ shortcut_edit
+ clicked()
+ Form2
+ shortcutEditClicked()
+
tabs
@@ -2208,26 +2274,21 @@
titleMatchChanged()
extraMatchChanged()
machineMatchChanged()
+ shortcutEditClicked()
- klineedit.h
- klineedit.h
kcombobox.h
kpushbutton.h
- klineedit.h
kcombobox.h
kpushbutton.h
kpushbutton.h
klistbox.h
- klineedit.h
kcombobox.h
kpushbutton.h
- klineedit.h
kcombobox.h
kpushbutton.h
- klineedit.h
kcombobox.h
kpushbutton.h
kcombobox.h
@@ -2244,8 +2305,6 @@
kcombobox.h
kcombobox.h
kcombobox.h
- kcombobox.h
- krestrictedline.h
krestrictedline.h
kcombobox.h
kcombobox.h
@@ -2255,6 +2314,10 @@
kcombobox.h
kcombobox.h
kcombobox.h
+ krestrictedline.h
+ kcombobox.h
+ krestrictedline.h
+ kcombobox.h
kcombobox.h
kcombobox.h
kcombobox.h
diff --git a/manage.cpp b/manage.cpp
index aebd0233ef..bbfaf69e98 100644
--- a/manage.cpp
+++ b/manage.cpp
@@ -131,10 +131,8 @@ bool Client::manage( Window w, bool isMapped )
if( session->userNoBorder )
setUserNoBorder( true );
}
-
- if( session && !session->shortcut.isNull())
- setShortcut( session->shortcut );
- // TODO use also rules for shortcut
+
+ setShortcut( rules()->checkShortcut( session ? session->shortcut : QString::null, true ));
init_minimize = rules()->checkMinimize( init_minimize, !isMapped );
if( rules()->checkNoBorder( false, !isMapped ))
diff --git a/rules.cpp b/rules.cpp
index 247b2803f0..5689653b0d 100644
--- a/rules.cpp
+++ b/rules.cpp
@@ -58,7 +58,8 @@ Rules::Rules()
, acceptfocusrule( UnusedForceRule )
, moveresizemoderule( UnusedForceRule )
, closeablerule( UnusedForceRule )
- , strictgeometry( UnusedForceRule )
+ , strictgeometryrule( UnusedForceRule )
+ , shortcutrule( UnusedSetRule )
{
}
@@ -159,6 +160,7 @@ void Rules::readFromCfg( KConfig& cfg )
READ_FORCE_RULE( moveresizemode, , Options::stringToMoveResizeMode );
READ_FORCE_RULE( closeable, Bool, );
READ_FORCE_RULE( strictgeometry, Bool, );
+ READ_SET_RULE( shortcut, , );
}
#undef READ_MATCH_STRING
@@ -246,6 +248,7 @@ void Rules::write( KConfig& cfg ) const
WRITE_FORCE_RULE( moveresizemode, Options::moveResizeModeToString );
WRITE_FORCE_RULE( closeable, );
WRITE_FORCE_RULE( strictgeometry, );
+ WRITE_SET_RULE( shortcut, );
}
#undef WRITE_MATCH_STRING
@@ -280,7 +283,8 @@ bool Rules::isEmpty() const
&& acceptfocusrule == UnusedForceRule
&& moveresizemoderule == UnusedForceRule
&& closeablerule == UnusedForceRule
- && strictgeometryrule == UnusedForceRule );
+ && strictgeometryrule == UnusedForceRule
+ && shortcutrule == UnusedSetRule );
}
Rules::SetRule Rules::readSetRule( KConfig& cfg, const QString& key )
@@ -598,6 +602,7 @@ APPLY_FORCE_RULE( acceptfocus, AcceptFocus, bool )
APPLY_FORCE_RULE( moveresizemode, MoveResizeMode, Options::MoveResizeMode )
APPLY_FORCE_RULE( closeable, Closeable, bool )
APPLY_FORCE_RULE( strictgeometry, StrictGeometry, bool )
+APPLY_RULE( shortcut, Shortcut, QString )
#undef APPLY_RULE
#undef APPLY_FORCE_RULE
@@ -728,6 +733,7 @@ CHECK_FORCE_RULE( AcceptFocus, bool )
CHECK_FORCE_RULE( MoveResizeMode, Options::MoveResizeMode )
CHECK_FORCE_RULE( Closeable, bool )
CHECK_FORCE_RULE( StrictGeometry, bool )
+CHECK_RULE( Shortcut, QString )
#undef CHECK_RULE
#undef CHECK_FORCE_RULE
@@ -782,6 +788,7 @@ void Client::setupWindowRules( bool ignore_temporary )
QSize s = adjustedSize( size());
if( s != size())
resizeWithChecks( s );
+ setShortcut( rules()->checkShortcut( shortcut().toString()));
}
}
diff --git a/rules.h b/rules.h
index e8f1e46f47..de4a960a98 100644
--- a/rules.h
+++ b/rules.h
@@ -66,6 +66,7 @@ class WindowRules
Options::MoveResizeMode checkMoveResizeMode( Options::MoveResizeMode mode ) const;
bool checkCloseable( bool closeable ) const;
bool checkStrictGeometry( bool strict ) const;
+ QString checkShortcut( QString s, bool init = false ) const;
private:
MaximizeMode checkMaximizeVert( MaximizeMode mode, bool init ) const;
MaximizeMode checkMaximizeHoriz( MaximizeMode mode, bool init ) const;
@@ -114,6 +115,7 @@ class Rules
bool applyMoveResizeMode( Options::MoveResizeMode& mode ) const;
bool applyCloseable( bool& closeable ) const;
bool applyStrictGeometry( bool& strict ) const;
+ bool applyShortcut( QString& shortcut, bool init ) const;
private:
#endif
bool matchType( NET::WindowType match_type ) const;
@@ -223,6 +225,8 @@ class Rules
ForceRule closeablerule;
bool strictgeometry;
ForceRule strictgeometryrule;
+ QString shortcut;
+ SetRule shortcutrule;
friend kdbgstream& operator<<( kdbgstream& stream, const Rules* );
};
diff --git a/sm.cpp b/sm.cpp
index 308be65d90..841aeb21e0 100644
--- a/sm.cpp
+++ b/sm.cpp
@@ -178,7 +178,7 @@ void Workspace::loadSessionInfo()
info->skipPager = config->readBoolEntry( QString("skipPager")+n, FALSE );
info->userNoBorder = config->readBoolEntry( QString("userNoBorder")+n, FALSE );
info->windowType = txtToWindowType( config->readEntry( QString("windowType")+n ).latin1());
- info->shortcut = KShortcut( config->readEntry( QString("shortcut")+n ));
+ info->shortcut = config->readEntry( QString("shortcut")+n );
info->active = ( active_client == i );
}
}
diff --git a/sm.h b/sm.h
index 58105b00c1..0a23b7badd 100644
--- a/sm.h
+++ b/sm.h
@@ -15,7 +15,6 @@ License. See the file "COPYING" for the exact licensing terms.
#include
#include
#include
-#include
class QSocketNotifier;
@@ -46,7 +45,7 @@ struct SessionInfo
bool skipPager;
bool userNoBorder;
NET::WindowType windowType;
- KShortcut shortcut;
+ QString shortcut;
bool active; // means 'was active in the saved session'
};
diff --git a/useractions.cpp b/useractions.cpp
index bd730f56a8..d9c53d51cf 100644
--- a/useractions.cpp
+++ b/useractions.cpp
@@ -32,6 +32,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include
#include
#include
+#include
#include "popupinfo.h"
#include "killwindow.h"
@@ -297,7 +298,7 @@ void Workspace::setupWindowShortcutDone( bool ok )
client_keys->setEnabled( true );
if( ok )
{
- client_keys_client->setShortcut( client_keys_dialog->shortcut());
+ client_keys_client->setShortcut( KShortcut( client_keys_dialog->shortcut()).toString());
}
closeActivePopup();
delete client_keys_dialog;
@@ -925,4 +926,82 @@ void Workspace::slotWindowResize()
performWindowOperation( active_client, Options::UnrestrictedResizeOp );
}
+void Client::setShortcut( const QString& _cut )
+ {
+ QString cut = rules()->checkShortcut( _cut );
+ if( cut.isEmpty())
+ return setShortcutInternal( KShortcut());
+// Format:
+// *base+[abcdef]|base+[abcdef]
+// E.g. Alt+Ctrl+[ABCDEF]|Win+X,Win+[ABCDEF]
+ if( cut[ 0 ] != '*' )
+ {
+ if( workspace()->shortcutAvailable( KShortcut( cut )))
+ setShortcutInternal( KShortcut( cut ));
+ else
+ setShortcutInternal( KShortcut());
+ return;
+ }
+ QValueList< KShortcut > keys;
+ QStringList groups = QStringList::split( '|', cut.mid( 1 ));
+ for( QStringList::ConstIterator it = groups.begin();
+ it != groups.end();
+ ++it )
+ {
+ QRegExp reg( "(.*\\+)\\[(.*)\\]" );
+ if( reg.search( *it ) > -1 )
+ {
+ QString base = reg.cap( 1 );
+ QString list = reg.cap( 2 );
+ for( unsigned int i = 0;
+ i < list.length();
+ ++i )
+ {
+ KShortcut c( base + list[ i ] );
+ if( !c.isNull())
+ keys.append( c );
+ }
+ }
+ }
+ for( QValueList< KShortcut >::ConstIterator it = keys.begin();
+ it != keys.end();
+ ++it )
+ {
+ if( _shortcut == *it ) // current one is in the list
+ return;
+ }
+ for( QValueList< KShortcut >::ConstIterator it = keys.begin();
+ it != keys.end();
+ ++it )
+ {
+ if( workspace()->shortcutAvailable( *it, this ))
+ {
+ setShortcutInternal( *it );
+ return;
+ }
+ }
+ setShortcutInternal( KShortcut());
+ }
+
+void Client::setShortcutInternal( const KShortcut& cut )
+ {
+ if( _shortcut == cut )
+ return;
+ _shortcut = cut;
+ workspace()->clientShortcutUpdated( this );
+ }
+
+bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
+ {
+ // TODO check global shortcuts etc.
+ for( ClientList::ConstIterator it = clients.begin();
+ it != clients.end();
+ ++it )
+ {
+ if( (*it) != ignore && (*it)->shortcut() == cut )
+ return false;
+ }
+ return true;
+ }
+
} // namespace
diff --git a/workspace.cpp b/workspace.cpp
index 4f818ee3a1..8330c995c2 100644
--- a/workspace.cpp
+++ b/workspace.cpp
@@ -540,7 +540,7 @@ void Workspace::removeClient( Client* c, allowed_t )
if( client_keys_client == c )
setupWindowShortcutDone( false );
if( !c->shortcut().isNull())
- c->setShortcut( KShortcut()); // remove from client_keys
+ c->setShortcut( QString::null ); // remove from client_keys
if( c->isDialog())
Notify::raise( Notify::TransDelete );
diff --git a/workspace.h b/workspace.h
index 4fdfd4b441..ec0d502f74 100644
--- a/workspace.h
+++ b/workspace.h
@@ -246,6 +246,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
bool forcedGlobalMouseGrab() const;
void clientShortcutUpdated( Client* c );
+ bool shortcutAvailable( const KShortcut& cut, Client* ignore = NULL ) const;
void sessionSaveStarted();
void sessionSaveDone();