From 07203ba5b68f866868058931a38b7b12813848f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Mon, 17 Jan 2005 15:53:14 +0000 Subject: [PATCH] Window-specific rules for dynamic windows shortcuts, so that it's possible to always have certain shortcuts assigned to their windows if such windows are open. Still few TODO items left, but let's consider it enough for #44268 to be marked as done. FEATURE: 44268 svn path=/trunk/kdebase/kwin/; revision=379444 --- client.h | 11 +- kcmkwin/kwinrules/ruleswidget.cpp | 14 ++ kcmkwin/kwinrules/ruleswidget.h | 2 + kcmkwin/kwinrules/ruleswidgetbase.ui | 237 +++++++++++++++++---------- manage.cpp | 6 +- rules.cpp | 11 +- rules.h | 4 + sm.cpp | 2 +- sm.h | 3 +- useractions.cpp | 81 ++++++++- workspace.cpp | 2 +- workspace.h | 1 + 12 files changed, 267 insertions(+), 107 deletions(-) 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();