diff --git a/activation.cpp b/activation.cpp
index cf327aa1f0..dbcf0a17a7 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -331,6 +331,7 @@ void Workspace::takeActivity( Client* c, int flags, bool handled )
c = modal;
handled = false;
}
+ cancelDelayFocus();
}
if ( !( flags & ActivityFocusForce ) && ( c->isTopMenu() || c->isDock() || c->isSplash()) )
flags &= ~ActivityFocus; // toplevel menus and dock windows don't take focus if not forced
diff --git a/events.cpp b/events.cpp
index 9978f9eb81..9bf1ed777f 100644
--- a/events.cpp
+++ b/events.cpp
@@ -890,8 +890,11 @@ void Client::enterNotifyEvent( XCrossingEvent* e )
if ( options->focusPolicy != Options::FocusStrictlyUnderMouse && ( isDesktop() || isDock() || isTopMenu() ) )
return;
+ if ( options->delayFocus )
+ workspace()->requestDelayFocus( this );
+ else
+ workspace()->requestFocus( this );
- workspace()->requestFocus( this );
return;
}
}
@@ -927,6 +930,7 @@ void Client::leaveNotifyEvent( XCrossingEvent* e )
if ( lostMouse )
{
cancelAutoRaise();
+ workspace()->cancelDelayFocus();
delete shadeHoverTimer;
shadeHoverTimer = 0;
if ( shade_mode == ShadeHover && !moveResizeMode && !buttonDown )
diff --git a/kcmkwin/kwinoptions/windows.cpp b/kcmkwin/kwinoptions/windows.cpp
index a137ac22f1..b44fbe8785 100644
--- a/kcmkwin/kwinoptions/windows.cpp
+++ b/kcmkwin/kwinoptions/windows.cpp
@@ -57,6 +57,8 @@
#define KWIN_GEOMETRY "GeometryTip"
#define KWIN_AUTORAISE_INTERVAL "AutoRaiseInterval"
#define KWIN_AUTORAISE "AutoRaise"
+#define KWIN_DELAYFOCUS_INTERVAL "DelayFocusInterval"
+#define KWIN_DELAYFOCUS "DelayFocus"
#define KWIN_CLICKRAISE "ClickRaise"
#define KWIN_ANIMSHADE "AnimateShade"
#define KWIN_MOVE_RESIZE_MAXIMIZED "MoveResizeMaximizedWindows"
@@ -164,6 +166,19 @@ KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent
autoRaise->setSuffix(i18n(" msec"));
fLay->addWidget(autoRaise);
+ connect(focusCombo, SIGNAL(activated(int)), this, SLOT(setDelayFocusEnabled()) );
+
+ delayFocusOn = new QCheckBox(i18n("Delay focus"), fcsBox);
+ fLay->addWidget(delayFocusOn);
+ connect(delayFocusOn,SIGNAL(toggled(bool)), this, SLOT(delayFocusOnTog(bool)));
+
+ delayFocus = new KIntNumInput(500, fcsBox);
+ delayFocus->setLabel(i18n("Dela&y:"), Qt::AlignVCenter|Qt::AlignLeft);
+ delayFocus->setRange(0, 3000, 100, true);
+ delayFocus->setSteps(100,100);
+ delayFocus->setSuffix(i18n(" msec"));
+ fLay->addWidget(delayFocus);
+
clickRaiseOn = new QCheckBox(i18n("C&lick raise active window"), fcsBox);
connect(clickRaiseOn,SIGNAL(toggled(bool)), this, SLOT(clickRaiseOnTog(bool)));
fLay->addWidget(clickRaiseOn);
@@ -182,6 +197,11 @@ KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent
" it for inactive windows, you need to change the settings"
" in the Actions tab.") );
+ QWhatsThis::add( delayFocusOn, i18n("When this option is enabled, there will be a delay after which the"
+ " window the mouse pointer is over will become active (receive focus).") );
+ QWhatsThis::add( delayFocus, i18n("This is the delay after which the window the mouse pointer is over"
+ " will automatically receive focus.") );
+
lay->addWidget(fcsBox);
kbdBox = new QButtonGroup(i18n("Navigation"), this);
@@ -235,6 +255,7 @@ KFocusConfig::KFocusConfig (bool _standAlone, KConfig *_config, QWidget * parent
connect(focusCombo, SIGNAL(activated(int)), SLOT(changed()));
connect(fcsBox, SIGNAL(clicked(int)), SLOT(changed()));
connect(autoRaise, SIGNAL(valueChanged(int)), SLOT(changed()));
+ connect(delayFocus, SIGNAL(valueChanged(int)), SLOT(changed()));
connect(kdeMode, SIGNAL(clicked()), SLOT(changed()));
connect(cdeMode, SIGNAL(clicked()), SLOT(changed()));
connect(traverseAll, SIGNAL(clicked()), SLOT(changed()));
@@ -263,16 +284,31 @@ void KFocusConfig::setAutoRaiseInterval(int tb)
autoRaise->setValue(tb);
}
+void KFocusConfig::setDelayFocusInterval(int tb)
+{
+ delayFocus->setValue(tb);
+}
+
int KFocusConfig::getAutoRaiseInterval()
{
return autoRaise->value();
}
+int KFocusConfig::getDelayFocusInterval()
+{
+ return delayFocus->value();
+}
+
void KFocusConfig::setAutoRaise(bool on)
{
autoRaiseOn->setChecked(on);
}
+void KFocusConfig::setDelayFocus(bool on)
+{
+ delayFocusOn->setChecked(on);
+}
+
void KFocusConfig::setClickRaise(bool on)
{
clickRaiseOn->setChecked(on);
@@ -293,12 +329,30 @@ void KFocusConfig::setAutoRaiseEnabled()
}
}
+void KFocusConfig::setDelayFocusEnabled()
+{
+ // the delayed focus related widgets are: delayFocus
+ if ( focusCombo->currentItem() != CLICK_TO_FOCUS )
+ {
+ delayFocusOn->setEnabled(true);
+ delayFocusOnTog(delayFocusOn->isChecked());
+ }
+ else
+ {
+ delayFocusOn->setEnabled(false);
+ delayFocusOnTog(false);
+ }
+}
void KFocusConfig::autoRaiseOnTog(bool a) {
autoRaise->setEnabled(a);
clickRaiseOn->setEnabled( !a );
}
+void KFocusConfig::delayFocusOnTog(bool a) {
+ delayFocus->setEnabled(a);
+}
+
void KFocusConfig::clickRaiseOnTog(bool ) {
}
@@ -338,11 +392,17 @@ void KFocusConfig::load( void )
int k = config->readNumEntry(KWIN_AUTORAISE_INTERVAL,750);
setAutoRaiseInterval(k);
+ k = config->readNumEntry(KWIN_DELAYFOCUS_INTERVAL,750);
+ setDelayFocusInterval(k);
+
key = config->readEntry(KWIN_AUTORAISE);
setAutoRaise(key == "on");
+ key = config->readEntry(KWIN_DELAYFOCUS);
+ setDelayFocus(key == "on");
key = config->readEntry(KWIN_CLICKRAISE);
setClickRaise(key != "off");
setAutoRaiseEnabled(); // this will disable/hide the auto raise delay widget if focus==click
+ setDelayFocusEnabled();
key = config->readEntry(KWIN_ALTTABMODE, "KDE");
setAltTabMode(key == "KDE");
@@ -379,11 +439,20 @@ void KFocusConfig::save( void )
if (v <0) v = 0;
config->writeEntry(KWIN_AUTORAISE_INTERVAL,v);
+ v = getDelayFocusInterval();
+ if (v <0) v = 0;
+ config->writeEntry(KWIN_DELAYFOCUS_INTERVAL,v);
+
if (autoRaiseOn->isChecked())
config->writeEntry(KWIN_AUTORAISE, "on");
else
config->writeEntry(KWIN_AUTORAISE, "off");
+ if (delayFocusOn->isChecked())
+ config->writeEntry(KWIN_DELAYFOCUS, "on");
+ else
+ config->writeEntry(KWIN_DELAYFOCUS, "off");
+
if (clickRaiseOn->isChecked())
config->writeEntry(KWIN_CLICKRAISE, "on");
else
@@ -417,8 +486,10 @@ void KFocusConfig::save( void )
void KFocusConfig::defaults()
{
setAutoRaiseInterval(0);
+ setDelayFocusInterval(0);
setFocus(CLICK_TO_FOCUS);
setAutoRaise(false);
+ setDelayFocus(false);
setClickRaise(true);
setAltTabMode(true);
setTraverseAll( false );
diff --git a/kcmkwin/kwinoptions/windows.h b/kcmkwin/kwinoptions/windows.h
index 56e4ce576d..f2a7c15413 100644
--- a/kcmkwin/kwinoptions/windows.h
+++ b/kcmkwin/kwinoptions/windows.h
@@ -77,8 +77,10 @@ public:
void defaults();
private slots:
+ void setDelayFocusEnabled();
void setAutoRaiseEnabled();
void autoRaiseOnTog(bool);//CT 23Oct1998
+ void delayFocusOnTog(bool);
void clickRaiseOnTog(bool);
void changed() { emit KCModule::changed(true); }
@@ -87,10 +89,13 @@ private:
int getFocus( void );
int getAutoRaiseInterval( void );
+ int getDelayFocusInterval( void );
void setFocus(int);
void setAutoRaiseInterval(int);
void setAutoRaise(bool);
+ void setDelayFocusInterval(int);
+ void setDelayFocus(bool);
void setClickRaise(bool);
void setAltTabMode(bool);
void setTraverseAll(bool);
@@ -100,8 +105,10 @@ private:
QButtonGroup *fcsBox;
QComboBox *focusCombo;
QCheckBox *autoRaiseOn;
+ QCheckBox *delayFocusOn;
QCheckBox *clickRaiseOn;
KIntNumInput *autoRaise;
+ KIntNumInput *delayFocus;
QButtonGroup *kbdBox;
QRadioButton *kdeMode;
diff --git a/kwin.kcfg b/kwin.kcfg
index d46c78d865..27fec89c23 100644
--- a/kwin.kcfg
+++ b/kwin.kcfg
@@ -45,6 +45,8 @@
+
+
diff --git a/options.cpp b/options.cpp
index effbfb8b8d..f16ccd7781 100644
--- a/options.cpp
+++ b/options.cpp
@@ -108,11 +108,15 @@ unsigned long Options::updateSettings()
{
autoRaise = false;
autoRaiseInterval = 0;
+ delayFocus = false;
+ delayFocusInterval = 0;
}
else
{
autoRaise = config->readBoolEntry("AutoRaise", FALSE );
autoRaiseInterval = config->readNumEntry("AutoRaiseInterval", 0 );
+ delayFocus = config->readBoolEntry("DelayFocus", FALSE );
+ delayFocusInterval = config->readNumEntry("DelayFocusInterval", 0 );
}
shadeHover = config->readBoolEntry("ShadeHover", FALSE );
diff --git a/options.h b/options.h
index 5c98c910cf..5b3bd2484c 100644
--- a/options.h
+++ b/options.h
@@ -83,6 +83,16 @@ class Options : public KDecorationOptions
*/
int autoRaiseInterval;
+ /**
+ whether delay focus is enabled or not.
+ */
+ bool delayFocus;
+
+ /**
+ delayed focus interval
+ */
+ int delayFocusInterval;
+
/**
Whether shade hover is enabled or not
*/
diff --git a/workspace.cpp b/workspace.cpp
index 8543b482ba..383d09f8a1 100644
--- a/workspace.cpp
+++ b/workspace.cpp
@@ -70,6 +70,7 @@ Workspace::Workspace( bool restore )
most_recently_raised (0),
movingClient(0),
pending_take_activity ( NULL ),
+ delayfocus_client (0),
was_user_interaction (false),
session_saving (false),
control_grab (false),
@@ -109,6 +110,8 @@ Workspace::Workspace( bool restore )
updateXTime(); // needed for proper initialization of user_time in Client ctor
+ delayFocusTimer = 0;
+
electric_time_first = qt_x_time;
electric_time_last = qt_x_time;
@@ -1641,7 +1644,27 @@ QWidget* Workspace::desktopWidget()
return desktop_widget;
}
-
+//Delayed focus functions
+void Workspace::delayFocus()
+ {
+ requestFocus( delayfocus_client );
+ cancelDelayFocus();
+ }
+
+void Workspace::requestDelayFocus( Client* c )
+ {
+ delayfocus_client = c;
+ delete delayFocusTimer;
+ delayFocusTimer = new QTimer( this );
+ connect( delayFocusTimer, SIGNAL( timeout() ), this, SLOT( delayFocus() ) );
+ delayFocusTimer->start( options->delayFocusInterval, TRUE );
+ }
+
+void Workspace::cancelDelayFocus()
+ {
+ delete delayFocusTimer;
+ delayFocusTimer = 0;
+ }
// Electric Borders
//========================================================================//
diff --git a/workspace.h b/workspace.h
index 06ce61b8ea..a74a23026c 100644
--- a/workspace.h
+++ b/workspace.h
@@ -244,6 +244,9 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
static QStringList configModules(bool controlCenter);
+ void cancelDelayFocus();
+ void requestDelayFocus( Client* );
+
public slots:
void refresh();
// keybindings
@@ -320,6 +323,7 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
void slotUpdateToolWindows();
void lostTopMenuSelection();
void lostTopMenuOwner();
+ void delayFocus();
protected:
bool keyPressMouseEmulation( XKeyEvent& ev );
@@ -431,6 +435,10 @@ class Workspace : public QObject, public KWinInterface, public KDecorationDefine
Client* movingClient;
Client* pending_take_activity;
+ // delay(ed) window focus timer and client
+ QTimer* delayFocusTimer;
+ Client* delayfocus_client;
+
ClientList clients;
ClientList desktops;