rendered paste bodydiff --git a/include/compiz-core.h b/include/compiz-core.h
index 9c8314c..88e947e 100644
--- a/include/compiz-core.h
+++ b/include/compiz-core.h
@@ -28,7 +28,7 @@
#include <compiz-plugin.h>
-#define CORE_ABIVERSION 20080130
+#define CORE_ABIVERSION 20080209
#include <stdio.h>
#include <sys/time.h>
@@ -1711,10 +1711,11 @@ disableTexture (CompScreen *screen,
#define COMP_SCREEN_OPTION_NUMBER_OF_DESKTOPS 9
#define COMP_SCREEN_OPTION_DETECT_OUTPUTS 10
#define COMP_SCREEN_OPTION_OUTPUTS 11
-#define COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH 12
-#define COMP_SCREEN_OPTION_OPACITY_MATCHES 13
-#define COMP_SCREEN_OPTION_OPACITY_VALUES 14
-#define COMP_SCREEN_OPTION_NUM 15
+#define COMP_SCREEN_OPTION_FOCUS_PREVENTION_LEVEL 12
+#define COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH 13
+#define COMP_SCREEN_OPTION_OPACITY_MATCHES 14
+#define COMP_SCREEN_OPTION_OPACITY_VALUES 15
+#define COMP_SCREEN_OPTION_NUM 16
#ifndef GLX_EXT_texture_from_pixmap
#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
@@ -1737,6 +1738,14 @@ disableTexture (CompScreen *screen,
#define GLX_FRONT_LEFT_EXT 0x20DE
#endif
+typedef enum
+{
+ FocusPreventionOff = 0,
+ FocusPreventionLow,
+ FocusPreventionHigh,
+ FocusPreventionVeryHigh
+} CompFSPLevel;
+
typedef void (*FuncPtr) (void);
typedef FuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName);
diff --git a/metadata/core.xml.in b/metadata/core.xml.in
index 0e46aa5..109a5e9 100644
--- a/metadata/core.xml.in
+++ b/metadata/core.xml.in
@@ -406,6 +406,29 @@
<value>640x480+0+0</value>
</default>
</option>
+ <option name="focus_prevention_level" type="int">
+ <_short>Focus Prevention Level</_short>
+ <_long>Level of focus stealing prevention</_long>
+ <min>0</min>
+ <max>3</max>
+ <default>1</default>
+ <desc>
+ <value>0</value>
+ <_name>Off</_name>
+ </desc>
+ <desc>
+ <value>1</value>
+ <_name>Low</_name>
+ </desc>
+ <desc>
+ <value>2</value>
+ <_name>High</_name>
+ </desc>
+ <desc>
+ <value>3</value>
+ <_name>Very High</_name>
+ </desc>
+ </option>
<option name="focus_prevention_match" type="match">
<_short>Focus Prevention Windows</_short>
<_long>Focus prevention windows</_long>
diff --git a/src/screen.c b/src/screen.c
index ca308df..fefc9ad 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -638,6 +638,7 @@ const CompMetadataOptionInfo coreScreenOptionInfo[COMP_SCREEN_OPTION_NUM] = {
{ "number_of_desktops", "int", "<min>1</min>", 0, 0 },
{ "detect_outputs", "bool", 0, 0, 0 },
{ "outputs", "list", "<type>string</type>", 0, 0 },
+ { "focus_prevention_level", "int", RESTOSTRING (0, 3), 0, 0 },
{ "focus_prevention_match", "match", 0, 0, 0 },
{ "opacity_matches", "list", "<type>match</type>", 0, 0 },
{ "opacity_values", "list", "<type>int</type>", 0, 0 }
diff --git a/src/window.c b/src/window.c
index 1b5a021..515ad95 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4694,14 +4694,18 @@ static Bool
isWindowFocusAllowed (CompWindow *w,
Time timestamp)
{
- CompDisplay *d = w->screen->display;
- CompScreen *s = w->screen;
- CompWindow *active;
- Time wUserTime, aUserTime;
- CompMatch *match;
- int vx, vy;
-
- if (w->id == d->activeWindow)
+ CompDisplay *d = w->screen->display;
+ CompScreen *s = w->screen;
+ CompWindow *active;
+ Time wUserTime, aUserTime;
+ Bool gotTimestamp = FALSE;
+ CompMatch *match;
+ int vx, vy;
+ CompFSPLevel level;
+
+ level = s->opt[COMP_SCREEN_OPTION_FOCUS_PREVENTION_LEVEL].value.i;
+
+ if (level == FocusPreventionOff)
return TRUE;
/* not in current viewport */
@@ -4714,37 +4718,54 @@ isWindowFocusAllowed (CompWindow *w,
/* the caller passed a timestamp, so use that
instead of the window's user time */
wUserTime = timestamp;
+ gotTimestamp = TRUE;
}
else
{
- if (!getWindowUserTime (w, &wUserTime))
+ if (getWindowUserTime (w, &wUserTime))
+ {
+ gotTimestamp = TRUE;
+ }
+ else if (w->initialTimestampSet)
{
- /* no user time or initial timestamp */
- if (!w->initialTimestampSet)
- return TRUE;
-
wUserTime = w->initialTimestamp;
+ gotTimestamp = TRUE;
}
+ }
+ if (gotTimestamp && !wUserTime)
+ {
/* window explicitly requested no focus */
- if (!wUserTime)
- return FALSE;
+ return FALSE;
}
- /* can't get user time for active window */
- active = findWindowAtDisplay (d, d->activeWindow);
- if (!active || !getWindowUserTime (active, &aUserTime))
+ /* allow focus for excluded windows */
+ match = &s->opt[COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH].value.match;
+ if (!matchEval (match, w))
return TRUE;
- match = &s->opt[COMP_SCREEN_OPTION_FOCUS_PREVENTION_MATCH].value.match;
+ if (level == FocusPreventionVeryHigh)
+ return FALSE;
- /* focus prevention */
- if (matchEval (match, w))
+ if (!gotTimestamp)
{
- if (XSERVER_TIME_IS_BEFORE (wUserTime, aUserTime))
+ /* unsure as we have nothing to compare - allow focus in low level,
+ don't allow in high level */
+ if (level == FocusPreventionLow)
+ return TRUE;
+
+ if (level == FocusPreventionHigh)
return FALSE;
}
+ /* can't get user time for active window */
+ active = findWindowAtDisplay (d, d->activeWindow);
+ if (!active || !getWindowUserTime (active, &aUserTime))
+ return TRUE;
+
+ if (XSERVER_TIME_IS_BEFORE (wUserTime, aUserTime))
+ return FALSE;
+
return TRUE;
}
@@ -4755,6 +4776,9 @@ allowWindowFocus (CompWindow *w,
{
Bool retval;
+ if (w->id == w->screen->display->activeWindow)
+ return TRUE;
+
/* do not focus windows of these types */
if (w->type & noFocusMask)
return FALSE;