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
This commit is contained in:
Luboš Luňák 2005-01-17 15:53:14 +00:00
parent ded2f457b8
commit 07203ba5b6
12 changed files with 267 additions and 107 deletions

View file

@ -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_;

View file

@ -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 )
{

View file

@ -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:

View file

@ -12,6 +12,9 @@
<height>503</height>
</rect>
</property>
<property name="caption">
<string>Form2</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
@ -1205,31 +1208,6 @@
<string>&amp;Closeable</string>
</property>
</widget>
<spacer row="9" column="1">
<property name="name">
<cstring>spacer33</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>110</height>
</size>
</property>
</spacer>
<widget class="QCheckBox" row="8" column="0">
<property name="name">
<cstring>enable_opacityinactive</cstring>
</property>
<property name="text">
<string>I&amp;nactive opacity in %</string>
</property>
</widget>
<widget class="QCheckBox" row="7" column="0">
<property name="name">
<cstring>enable_opacityactive</cstring>
@ -1238,24 +1216,6 @@
<string>A&amp;ctive opacity in %</string>
</property>
</widget>
<widget class="KComboBox" row="8" column="1">
<item>
<property name="text">
<string>Do Not Affect</string>
</property>
</item>
<item>
<property name="text">
<string>Force</string>
</property>
</item>
<property name="name">
<cstring>rule_opacityinactive</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<widget class="KComboBox" row="7" column="1">
<item>
<property name="text">
@ -1274,17 +1234,6 @@
<bool>false</bool>
</property>
</widget>
<widget class="KRestrictedLine" row="8" column="2" rowspan="1" colspan="2">
<property name="name">
<cstring>opacityinactive</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="validChars">
<string>0123456789</string>
</property>
</widget>
<widget class="KRestrictedLine" row="7" column="2" rowspan="1" colspan="2">
<property name="name">
<cstring>opacityactive</cstring>
@ -1296,24 +1245,7 @@
<string>0123456789</string>
</property>
</widget>
<spacer row="8" column="4">
<property name="name">
<cstring>spacer25</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>181</width>
<height>20</height>
</size>
</property>
</spacer>
<spacer row="7" column="4">
<spacer row="7" column="4" rowspan="1" colspan="2">
<property name="name">
<cstring>spacer24</cstring>
</property>
@ -1330,7 +1262,7 @@
</size>
</property>
</spacer>
<spacer row="6" column="3" rowspan="1" colspan="2">
<spacer row="6" column="3" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer36_7</cstring>
</property>
@ -1347,7 +1279,7 @@
</size>
</property>
</spacer>
<spacer row="5" column="3" rowspan="1" colspan="2">
<spacer row="5" column="3" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer36_6</cstring>
</property>
@ -1364,7 +1296,7 @@
</size>
</property>
</spacer>
<spacer row="4" column="3" rowspan="1" colspan="2">
<spacer row="4" column="3" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer36_5</cstring>
</property>
@ -1381,7 +1313,7 @@
</size>
</property>
</spacer>
<spacer row="3" column="3" rowspan="1" colspan="2">
<spacer row="3" column="3" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer36_4</cstring>
</property>
@ -1398,7 +1330,7 @@
</size>
</property>
</spacer>
<spacer row="2" column="3" rowspan="1" colspan="2">
<spacer row="2" column="3" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer36_3</cstring>
</property>
@ -1415,7 +1347,7 @@
</size>
</property>
</spacer>
<spacer row="1" column="3" rowspan="1" colspan="2">
<spacer row="1" column="3" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer36_2</cstring>
</property>
@ -1432,7 +1364,7 @@
</size>
</property>
</spacer>
<spacer row="0" column="3" rowspan="1" colspan="2">
<spacer row="0" column="3" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer36</cstring>
</property>
@ -1702,6 +1634,132 @@
<bool>false</bool>
</property>
</widget>
<spacer row="10" column="1">
<property name="name">
<cstring>spacer33</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>80</height>
</size>
</property>
</spacer>
<widget class="KComboBox" row="8" column="1">
<item>
<property name="text">
<string>Do Not Affect</string>
</property>
</item>
<item>
<property name="text">
<string>Force</string>
</property>
</item>
<property name="name">
<cstring>rule_opacityinactive</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<widget class="KRestrictedLine" row="8" column="2" rowspan="1" colspan="2">
<property name="name">
<cstring>opacityinactive</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="validChars">
<string>0123456789</string>
</property>
</widget>
<spacer row="8" column="4" rowspan="1" colspan="2">
<property name="name">
<cstring>spacer25</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>181</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="QCheckBox" row="8" column="0">
<property name="name">
<cstring>enable_opacityinactive</cstring>
</property>
<property name="text">
<string>I&amp;nactive opacity in %</string>
</property>
</widget>
<widget class="QCheckBox" row="9" column="0">
<property name="name">
<cstring>enable_shortcut</cstring>
</property>
<property name="text">
<string>Shortcut</string>
</property>
<property name="accel">
<string></string>
</property>
</widget>
<widget class="KComboBox" row="9" column="1">
<item>
<property name="text">
<string>Do Not Affect</string>
</property>
</item>
<item>
<property name="text">
<string>Apply Initially</string>
</property>
</item>
<item>
<property name="text">
<string>Remember</string>
</property>
</item>
<item>
<property name="text">
<string>Force</string>
</property>
</item>
<property name="name">
<cstring>rule_shortcut</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<widget class="QPushButton" row="9" column="5">
<property name="name">
<cstring>shortcut_edit</cstring>
</property>
<property name="text">
<string>Edit</string>
</property>
</widget>
<widget class="KRestrictedLine" row="9" column="2" rowspan="1" colspan="3">
<property name="name">
<cstring>shortcut</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</grid>
</widget>
<widget class="QWidget">
@ -2075,6 +2133,8 @@
</widget>
</vbox>
</widget>
<customwidgets>
</customwidgets>
<connections>
<connection>
<sender>detect1</sender>
@ -2112,6 +2172,12 @@
<receiver>Form2</receiver>
<slot>machineMatchChanged()</slot>
</connection>
<connection>
<sender>shortcut_edit</sender>
<signal>clicked()</signal>
<receiver>Form2</receiver>
<slot>shortcutEditClicked()</slot>
</connection>
</connections>
<tabstops>
<tabstop>tabs</tabstop>
@ -2208,26 +2274,21 @@
<slot access="protected" specifier="pure virtual">titleMatchChanged()</slot>
<slot access="protected" specifier="pure virtual">extraMatchChanged()</slot>
<slot access="protected" specifier="pure virtual">machineMatchChanged()</slot>
<slot access="protected" specifier="pure virtual">shortcutEditClicked()</slot>
</slots>
<layoutdefaults spacing="6" margin="11"/>
<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
<includehints>
<includehint>klineedit.h</includehint>
<includehint>klineedit.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kpushbutton.h</includehint>
<includehint>klineedit.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kpushbutton.h</includehint>
<includehint>kpushbutton.h</includehint>
<includehint>klistbox.h</includehint>
<includehint>klineedit.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kpushbutton.h</includehint>
<includehint>klineedit.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kpushbutton.h</includehint>
<includehint>klineedit.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kpushbutton.h</includehint>
<includehint>kcombobox.h</includehint>
@ -2244,8 +2305,6 @@
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>krestrictedline.h</includehint>
<includehint>krestrictedline.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
@ -2255,6 +2314,10 @@
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>krestrictedline.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>krestrictedline.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>
<includehint>kcombobox.h</includehint>

View file

@ -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 ))

View file

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

View file

@ -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* );
};

2
sm.cpp
View file

@ -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 );
}
}

3
sm.h
View file

@ -15,7 +15,6 @@ License. See the file "COPYING" for the exact licensing terms.
#include <X11/SM/SMlib.h>
#include <kapplication.h>
#include <netwm_def.h>
#include <kshortcut.h>
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'
};

View file

@ -32,6 +32,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include <kconfig.h>
#include <kglobalaccel.h>
#include <kapplication.h>
#include <qregexp.h>
#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

View file

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

View file

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