All pastes #899964 Raw Edit

Zeug

public text v1 · immutable
·published 2008-02-11 15:45 UTC
rendered paste body
diff --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;