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