Hi,

please find attached a patch that makes the behaviour of window
activation when a window is closed optional.
Currently, always the last active window is activated. Sometimes this
might not be the desired behaviour, but users (like me ;-) ) would like
the window under the pointer to be activated. This patch adds the latter
behaviour as an option while still keeping the former behaviour as
default.

Questions / concerns / objections / opinions anyone?

Regards,

Danny
diff --git a/include/compiz.h b/include/compiz.h
index 9d44fa4..8a04781 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -26,7 +26,7 @@
 #ifndef _COMPIZ_H
 #define _COMPIZ_H
 
-#define ABIVERSION 20070425
+#define ABIVERSION 20070430
 
 #include <stdio.h>
 #include <sys/time.h>
@@ -591,7 +591,8 @@ typedef int CompFileWatchHandle;
 #define COMP_DISPLAY_OPTION_TERMINAL			  56
 #define COMP_DISPLAY_OPTION_RUN_TERMINAL		  57
 #define COMP_DISPLAY_OPTION_PING_DELAY			  58
-#define COMP_DISPLAY_OPTION_NUM				  59
+#define COMP_DISPLAY_OPTION_FOCUS_ON_CLOSE_MODE           59
+#define COMP_DISPLAY_OPTION_NUM				  60
 
 typedef CompOption *(*GetDisplayOptionsProc) (CompDisplay *display,
 					      int	  *count);
@@ -730,6 +731,11 @@ typedef void (*MatchExpHandlerChangedProc) (CompDisplay *display);
 typedef void (*MatchPropertyChangedProc) (CompDisplay *display,
 					  CompWindow  *window);
 
+typedef enum {
+    CompFocusModeLastActive = 0,
+    CompFocusModeUnderPointer
+} CompFocusOnCloseMode;
+
 struct _CompDisplay {
     Display    *display;
     CompScreen *screens;
@@ -908,6 +914,8 @@ struct _CompDisplay {
 
     CompFileWatch *fileWatch;
 
+    CompFocusOnCloseMode focusOnCloseMode;
+
     SetDisplayOptionProc	  setDisplayOption;
     SetDisplayOptionForPluginProc setDisplayOptionForPlugin;
 
diff --git a/metadata/compiz.xml.in b/metadata/compiz.xml.in
index 623192b..e56d2d3 100644
--- a/metadata/compiz.xml.in
+++ b/metadata/compiz.xml.in
@@ -23,6 +23,15 @@
 		<_long>Click on window moves input focus to it</_long>
 		<default>true</default>
 	    </option>
+	    <option name="focus_on_close_mode" type="string">
+		<_short>Focus Window On Close</_short>
+		<_long>Defines the window to be focussed if 'Click To Focus' is disabled and the currently active window is closed.</_long>
+		<default>Last active window</default>
+		<allowed>
+		    <value>Last active window</value>
+		    <value>Window under pointer</value>
+		</allowed>
+	    </option>
 	    <option name="autoraise" type="bool">
 		<_short>Auto-Raise</_short>
 		<_long>Raise selected windows after interval</_long>
diff --git a/src/display.c b/src/display.c
index e97a567..44add7f 100644
--- a/src/display.c
+++ b/src/display.c
@@ -727,7 +727,8 @@ const CompMetadataOptionInfo coreDisplayOptionInfo[COMP_DISPLAY_OPTION_NUM] = {
     { "ignore_hints_when_maximized", "bool", 0, 0, 0 },
     { "command_terminal", "string", 0, 0, 0 },
     { "run_command_terminal", "action", 0, runCommandTerminal, 0 },
-    { "ping_delay", "int", "<min>1000</min>", 0, 0 }
+    { "ping_delay", "int", "<min>1000</min>", 0, 0 },
+    { "focus_on_close_mode", "string", 0, 0, 0}
 };
 
 CompOption *
@@ -857,6 +858,17 @@ setDisplayOption (CompDisplay     *display,
 	    return TRUE;
 	}
 	break;
+    case COMP_DISPLAY_OPTION_FOCUS_ON_CLOSE_MODE:
+	if (compSetStringOption (o, value))
+	{
+	    if (strcmp (o->value.s, "Window under pointer") == 0)
+		display->focusOnCloseMode = CompFocusModeUnderPointer;
+	    else
+		display->focusOnCloseMode = CompFocusModeLastActive;
+
+	    return TRUE;
+	}
+	break;
     case COMP_DISPLAY_OPTION_PING_DELAY:
 	if (compSetIntOption (o, value))
 	{
@@ -1941,6 +1953,8 @@ addDisplay (char *name)
     d->textureFilter = GL_LINEAR;
     d->below	     = None;
 
+    d->focusOnCloseMode = CompFocusModeLastActive;
+
     d->activeWindow = 0;
 
     d->autoRaiseHandle = 0;
@@ -2505,6 +2519,34 @@ getCurrentTimeFromDisplay (CompDisplay *d)
     return event.xproperty.time;
 }
 
+/* Attempts to focus a window located under the pointer. Returns TRUE if
+ * there is a window like that. FALSE otherwise.
+ */
+static Bool 
+focusMouseTarget (CompScreen *s)
+{
+    CompDisplay * d = s->display;
+    Window      tmpRoot, tmpChild;
+    CompWindow  * focus;
+    Bool        result;
+    int         x;
+
+    result = XQueryPointer (d->display, s->root, &tmpRoot, &tmpChild, 
+			    &x, &x, &x, &x, (unsigned int *)&x);
+
+    if (result && tmpChild)
+    {
+	focus = findWindowAtScreen (s, tmpChild);
+	if (focus && !(focus->wmType & 
+		       (CompWindowTypeDesktopMask | CompWindowTypeDockMask))) 
+	{
+	    moveInputFocusToWindow (focus);
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
 void
 focusDefaultWindow (CompDisplay *d)
 {
@@ -2512,6 +2554,13 @@ focusDefaultWindow (CompDisplay *d)
     CompWindow *w;
     CompWindow *focus = NULL;
 
+    if (d->focusOnCloseMode == CompFocusModeUnderPointer)
+    {
+	for (s = d->screens; s; s = s->next)
+	    if (focusMouseTarget (s))
+		return;
+    }
+
     for (s = d->screens; s; s = s->next)
     {
 	for (w = s->reverseWindows; w; w = w->prev)

_______________________________________________
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz

Reply via email to