Configurable focus stealing prevention aggressivity.

svn path=/trunk/kdebase/kwin/; revision=254817
This commit is contained in:
Luboš Luňák 2003-09-29 11:23:14 +00:00
parent 81e475c523
commit 720b988790
5 changed files with 79 additions and 4 deletions

View file

@ -411,8 +411,19 @@ void Workspace::gotFocusIn( const Client* c )
// session_active -> the window was active when saving session // session_active -> the window was active when saving session
bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in, bool session_active ) bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in, bool session_active )
{ {
if( session_saving ) // options->focusStealingPreventionLevel :
// 0 - none - old KWin behaviour, new windows always get focus
// 1 - low - focus stealing prevention is applied normally, when unsure, activation is allowed
// 2 - normal - focus stealing prevention is applied normally, when unsure, activation is not allowed,
// this is the default
// 3 - high - new window gets focus only if it belongs to the active application,
// or when no window is currently active
// 4 - extreme - no window gets focus without user intervention
if( session_saving
&& options->focusStealingPreventionLevel <= 3 ) // <= normal
{
return true; return true;
}
Client* ac = activeClient(); Client* ac = activeClient();
if( focus_in ) if( focus_in )
{ {
@ -422,6 +433,10 @@ bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in
// got FocusOut, and therefore got deactivated. // got FocusOut, and therefore got deactivated.
ac = last_active_client; ac = last_active_client;
} }
if( options->focusStealingPreventionLevel == 0 ) // none
return true;
if( options->focusStealingPreventionLevel == 5 ) // extreme
return false;
if( ac == NULL || ac->isDesktop()) if( ac == NULL || ac->isDesktop())
{ {
kdDebug( 1212 ) << "Activation: No client active, allowing" << endl; kdDebug( 1212 ) << "Activation: No client active, allowing" << endl;
@ -435,17 +450,22 @@ bool Workspace::allowClientActivation( const Client* c, Time time, bool focus_in
kdDebug( 1212 ) << "Activation: Belongs to active application" << endl; kdDebug( 1212 ) << "Activation: Belongs to active application" << endl;
return true; return true;
} }
if( options->focusStealingPreventionLevel == 4 ) // high
return false;
if( time == -1U ) // no time known if( time == -1U ) // no time known
if( session_active ) if( session_active )
return !was_user_interaction; // see Client::readUserTimeMapTimestamp() return !was_user_interaction; // see Client::readUserTimeMapTimestamp()
else else
{ {
kdDebug() << "Activation: No timestamp at all" << endl; kdDebug() << "Activation: No timestamp at all" << endl;
if( options->focusStealingPreventionLevel == 1 ) // low
return true;
// no timestamp at all, don't activate - because there's also creation timestamp // no timestamp at all, don't activate - because there's also creation timestamp
// done on CreateNotify, this case should happen only in case application // done on CreateNotify, this case should happen only in case application
// maps again already used window, i.e. this won't happen after app startup // maps again already used window, i.e. this won't happen after app startup
return false; return false;
} }
// options->focusStealingPreventionLevel == 2 // normal
Time user_time = ac->userTime(); Time user_time = ac->userTime();
kdDebug( 1212 ) << "Activation, compared:" << time << ":" << user_time kdDebug( 1212 ) << "Activation, compared:" << time << ":" << user_time
<< ":" << ( timestampCompare( time, user_time ) >= 0 ) << endl; << ":" << ( timestampCompare( time, user_time ) >= 0 ) << endl;

View file

@ -39,6 +39,7 @@
#include <kapplication.h> #include <kapplication.h>
#include <kdialog.h> #include <kdialog.h>
#include <dcopclient.h> #include <dcopclient.h>
#include <kglobal.h>
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -66,6 +67,7 @@
#define KWIN_ROLL_OVER_DESKTOPS "RollOverDesktops" #define KWIN_ROLL_OVER_DESKTOPS "RollOverDesktops"
#define KWIN_SHADEHOVER "ShadeHover" #define KWIN_SHADEHOVER "ShadeHover"
#define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval" #define KWIN_SHADEHOVER_INTERVAL "ShadeHoverInterval"
#define KWIN_FOCUS_STEALING "FocusStealingPreventionLevel"
// kwm config keywords // kwm config keywords
#define KWM_ELECTRIC_BORDER "ElectricBorders" #define KWM_ELECTRIC_BORDER "ElectricBorders"
@ -511,6 +513,38 @@ KAdvancedConfig::KAdvancedConfig (bool _standAlone, KConfig *_config, QWidget *p
lay->addWidget(electricBox); lay->addWidget(electricBox);
QHBoxLayout* focusStealingLayout = new QHBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint());
QLabel* focusStealingLabel = new QLabel( i18n( "Focus Stealing Prevention Level:" ), this );
focusStealing = new QComboBox( this );
focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "None" ));
focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "Low" ));
focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "Normal" ));
focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "High" ));
focusStealing->insertItem( i18n( "Focus Stealing Prevention Level", "Extreme" ));
focusStealingLabel->setBuddy( focusStealing );
focusStealingLayout->addWidget( focusStealingLabel );
focusStealingLayout->addWidget( focusStealing, AlignLeft );
wtstr = i18n( "This option specifies how much will KWin try to prevent unwanted focus stealing "
"caused by unexpected activation of new windows.<ul>"
"<li><em>None:</em> The standard old behaviour - prevention is turned off "
"and new windows get always activated.</li>"
"<li><em>Low:</em> Prevention is enabled; when some window doesn't have support "
"for the underlying mechanism and KWin cannot reliably decide whether to "
"activate the window or not, it will be activated. This setting may have both"
"worse and better results than normal level depending on the applications.</li>"
"<li><em>Normal:</em> Prevention is enabled; the default setting.</li>"
"<li><em>High:</em> New windows get activated only if no window is currently active "
"or if they belong to the currently active application. This setting is probably "
"not really usable when noting using mouse focus policy.</li>"
"<li><em>Extreme:</em> All windows must be explicitly activated by the user.</li>"
"</ul>" );
QWhatsThis::add( focusStealing, wtstr );
QWhatsThis::add( focusStealingLabel, wtstr );
connect(focusStealing, SIGNAL(activated(int)), SLOT(changed()));
lay->addLayout( focusStealingLayout );
lay->addStretch(); lay->addStretch();
load(); load();
@ -538,6 +572,11 @@ void KAdvancedConfig::setAnimateShade(bool a) {
animateShade->setChecked(a); animateShade->setChecked(a);
} }
void KAdvancedConfig::setFocusStealing(int l) {
l = KMAX( 0, KMIN( 4, l ));
focusStealing->setCurrentItem(l);
}
void KAdvancedConfig::load( void ) void KAdvancedConfig::load( void )
{ {
config->setGroup( "Windows" ); config->setGroup( "Windows" );
@ -548,6 +587,9 @@ void KAdvancedConfig::load( void )
setElectricBorders(config->readNumEntry(KWM_ELECTRIC_BORDER, false)); setElectricBorders(config->readNumEntry(KWM_ELECTRIC_BORDER, false));
setElectricBorderDelay(config->readNumEntry(KWM_ELECTRIC_BORDER_DELAY, 150)); setElectricBorderDelay(config->readNumEntry(KWM_ELECTRIC_BORDER_DELAY, 150));
setFocusStealing( config->readNumEntry(KWIN_FOCUS_STEALING, 2 ));
setChanged(false); setChanged(false);
} }
@ -569,6 +611,8 @@ void KAdvancedConfig::save( void )
config->writeEntry(KWM_ELECTRIC_BORDER, getElectricBorders()); config->writeEntry(KWM_ELECTRIC_BORDER, getElectricBorders());
config->writeEntry(KWM_ELECTRIC_BORDER_DELAY,getElectricBorderDelay()); config->writeEntry(KWM_ELECTRIC_BORDER_DELAY,getElectricBorderDelay());
config->writeEntry(KWIN_FOCUS_STEALING, focusStealing->currentItem());
if (standAlone) if (standAlone)
{ {
config->sync(); config->sync();
@ -586,6 +630,7 @@ void KAdvancedConfig::defaults()
setShadeHoverInterval(250); setShadeHoverInterval(250);
setElectricBorders(0); setElectricBorders(0);
setElectricBorderDelay(150); setElectricBorderDelay(150);
setFocusStealing(2);
setChanged(true); setChanged(true);
} }

View file

@ -213,6 +213,10 @@ private:
QRadioButton *active_move; QRadioButton *active_move;
QRadioButton *active_always; QRadioButton *active_always;
KIntNumInput *delays; KIntNumInput *delays;
void setFocusStealing( int );
QComboBox* focusStealing;
}; };
#endif #endif

View file

@ -63,6 +63,9 @@ unsigned long Options::updateSettings()
rollOverDesktops = config->readBoolEntry("RollOverDesktops", TRUE); rollOverDesktops = config->readBoolEntry("RollOverDesktops", TRUE);
focusStealingPreventionLevel = config->readNumEntry( "FocusStealingPreventionLevel", 2 );
focusStealingPreventionLevel = KMAX( 0, KMIN( 4, focusStealingPreventionLevel ));
KConfig *gc = new KConfig("kdeglobals", false, false); KConfig *gc = new KConfig("kdeglobals", false, false);
bool isVirtual = KApplication::desktop()->isVirtualDesktop(); bool isVirtual = KApplication::desktop()->isVirtualDesktop();
gc->setGroup("Windows"); gc->setGroup("Windows");

View file

@ -180,6 +180,9 @@ class Options : public KDecorationOptions
*/ */
bool rollOverDesktops; bool rollOverDesktops;
// 0 - 4 , see Workspace::allowClientActivation()
int focusStealingPreventionLevel;
/** /**
* List of window classes to ignore PPosition size hint * List of window classes to ignore PPosition size hint
*/ */