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();