This patch adds an optional delay for when using sloppy focus, and an option to make the mouse pointer warp to titlebar on alt-tabbing or directional focus, setting names are focusDelay true or false to control if the timeout is used, focusTimeout for setting the timeout in milliseconds, and finally warpPointer true or false for warping the pointer or not. They all go in the <focus> section of the rc3 file. Index: kernel/client.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/client.c,v retrieving revision 1.215 diff -u -r1.215 client.c --- kernel/client.c 2003/08/14 05:57:20 1.215 +++ kernel/client.c 2003/08/20 12:55:57 @@ -2553,6 +2553,10 @@ client_shade(self, FALSE); client_focus(self); stacking_raise(CLIENT_AS_WINDOW(self)); + if (config_focus_warppointer) + XWarpPointer(ob_display, 0, RootWindow(ob_display, ob_screen), + 0, 0, 0, 0, self->area.x + self->area.width/2, + self->area.y + ob_rr_theme->title_height/2); } gboolean client_focused(ObClient *self) Index: kernel/config.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.c,v retrieving revision 1.34 diff -u -r1.34 config.c --- kernel/config.c 2003/08/12 19:57:04 1.34 +++ kernel/config.c 2003/08/20 12:55:58 @@ -7,6 +7,9 @@ gboolean config_focus_new; gboolean config_focus_follow; +guint config_focus_timeout; +gboolean config_focus_delay; +gboolean config_focus_warppointer; gboolean config_focus_last; gboolean config_focus_last_on_desktop; gboolean config_focus_popup; @@ -212,6 +215,12 @@ config_focus_new = parse_bool(doc, n); if ((n = parse_find_node("followMouse", node))) config_focus_follow = parse_bool(doc, n); + if ((n = parse_find_node("focusTimeout", node))) + config_focus_timeout = parse_int(doc, n); + if ((n = parse_find_node("focusDelay", node))) + config_focus_delay = parse_bool(doc, n); + if ((n = parse_find_node("warpPointer", node))) + config_focus_warppointer = parse_bool(doc, n); if ((n = parse_find_node("focusLast", node))) config_focus_last = parse_bool(doc, n); if ((n = parse_find_node("focusLastOnDesktop", node))) @@ -367,6 +376,9 @@ { config_focus_new = TRUE; config_focus_follow = FALSE; + config_focus_timeout = 100; + config_focus_delay = FALSE; + config_focus_warppointer = FALSE; config_focus_last = TRUE; config_focus_last_on_desktop = TRUE; config_focus_popup = TRUE; Index: kernel/config.h =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.h,v retrieving revision 1.23 diff -u -r1.23 config.h --- kernel/config.h 2003/08/12 19:57:04 1.23 +++ kernel/config.h 2003/08/20 12:55:58 @@ -12,6 +12,12 @@ extern gboolean config_focus_new; /*! Focus windows when the mouse enters them */ extern gboolean config_focus_follow; +/*! Timeout for focusing windows on focus follows mouse */ +extern guint config_focus_timeout; +/*! Whether to use the timeout or just focus right away */ +extern gboolean config_focus_delay; +/*! WarpPointer to titlebar on client_activate()? */ +extern gboolean config_focus_warppointer; /*! Focus the last focused window as a fallback */ extern gboolean config_focus_last; /*! Focus the last focused window as a fallback when switching desktops */ Index: kernel/event.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/event.c,v retrieving revision 1.147 diff -u -r1.147 event.c --- kernel/event.c 2003/08/14 05:57:36 1.147 +++ kernel/event.c 2003/08/20 12:56:00 @@ -44,6 +44,7 @@ static void event_handle_dock(ObDock *s, XEvent *e); static void event_handle_dockapp(ObDockApp *app, XEvent *e); static void event_handle_client(ObClient *c, XEvent *e); +static void focus_timeout(void *n); static void event_handle_menu(ObClient *c, XEvent *e); static void fd_event_handle(); #ifdef USE_SM @@ -61,6 +62,8 @@ (e)->xfocus.detail > NotifyNonlinearVirtual) Time event_lasttime = 0; +ObClient *TimeoutClient = NULL; +ObTimer *FocusTimer = NULL; /*! The value of the mask for the NumLock modifier */ unsigned int NumLockMask; @@ -699,6 +702,11 @@ client->frame->close_hover = FALSE; frame_adjust_state(client->frame); break; + case OB_FRAME_CONTEXT_FRAME: + if (config_focus_delay && FocusTimer) { + timer_stop(FocusTimer); + FocusTimer = NULL; + } default: break; } @@ -741,7 +749,17 @@ ob_debug("EnterNotify on %lx, focusing window\n", client->window); #endif - client_focus(client); + if (config_focus_delay) { + if (FocusTimer) { + timer_stop(FocusTimer); + FocusTimer = NULL; + } + TimeoutClient = client; + FocusTimer = timer_start(config_focus_timeout * 1000, + (ObTimeoutHandler)focus_timeout, NULL); + } else { + client_focus(client); + } } } break; @@ -1074,6 +1092,13 @@ } #endif } +} + +static void focus_timeout(void *n) +{ + timer_stop(FocusTimer); + FocusTimer = NULL; + client_focus(TimeoutClient); } static void event_handle_menu(ObClient *client, XEvent *e)
updated patch to fix a segfault pointed out by xor Index: kernel/client.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/client.c,v retrieving revision 1.215 diff -u -r1.215 client.c --- kernel/client.c 2003/08/14 05:57:20 1.215 +++ kernel/client.c 2003/08/20 16:39:13 @@ -20,6 +20,7 @@ #include "menu.h" #include "keyboard.h" #include "mouse.h" +#include "timer.h" #include "render/render.h" #include <glib.h> @@ -33,6 +34,8 @@ ButtonMotionMask) GList *client_list = NULL; +ObClient *client_timeout_client; +ObTimer *client_focus_timer; static void client_get_all(ObClient *self); static void client_toggle_border(ObClient *self, gboolean show); @@ -358,6 +361,14 @@ ob_debug("Unmanaging window: %lx (%s)\n", self->window, self->class); + if (client_timeout_client && client_timeout_client == self) { + if (client_focus_timer) { + timer_stop(client_focus_timer); + client_focus_timer = NULL; + } + client_timeout_client = NULL; + } + dispatch_client(Event_Client_Destroy, self, 0, 0); g_assert(self != NULL); @@ -2553,6 +2564,10 @@ client_shade(self, FALSE); client_focus(self); stacking_raise(CLIENT_AS_WINDOW(self)); + if (config_focus_warppointer) + XWarpPointer(ob_display, 0, RootWindow(ob_display, ob_screen), + 0, 0, 0, 0, self->area.x + self->area.width/2, + self->area.y + ob_rr_theme->title_height/2); } gboolean client_focused(ObClient *self) Index: kernel/client.h =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/client.h,v retrieving revision 1.60 diff -u -r1.60 client.h --- kernel/client.h 2003/08/14 05:57:20 1.60 +++ kernel/client.h 2003/08/20 16:39:13 @@ -5,6 +5,7 @@ #include "mwm.h" #include "geom.h" #include "stacking.h" +#include "timer.h" #include "render/color.h" #include <glib.h> @@ -234,6 +235,8 @@ }; extern GList *client_list; +extern ObClient *client_timeout_client; +extern ObTimer *client_focus_timer; void client_startup(); void client_shutdown(); Index: kernel/config.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.c,v retrieving revision 1.34 diff -u -r1.34 config.c --- kernel/config.c 2003/08/12 19:57:04 1.34 +++ kernel/config.c 2003/08/20 16:39:14 @@ -7,6 +7,9 @@ gboolean config_focus_new; gboolean config_focus_follow; +guint config_focus_timeout; +gboolean config_focus_delay; +gboolean config_focus_warppointer; gboolean config_focus_last; gboolean config_focus_last_on_desktop; gboolean config_focus_popup; @@ -212,6 +215,12 @@ config_focus_new = parse_bool(doc, n); if ((n = parse_find_node("followMouse", node))) config_focus_follow = parse_bool(doc, n); + if ((n = parse_find_node("focusTimeout", node))) + config_focus_timeout = parse_int(doc, n); + if ((n = parse_find_node("focusDelay", node))) + config_focus_delay = parse_bool(doc, n); + if ((n = parse_find_node("warpPointer", node))) + config_focus_warppointer = parse_bool(doc, n); if ((n = parse_find_node("focusLast", node))) config_focus_last = parse_bool(doc, n); if ((n = parse_find_node("focusLastOnDesktop", node))) @@ -367,6 +376,9 @@ { config_focus_new = TRUE; config_focus_follow = FALSE; + config_focus_timeout = 100; + config_focus_delay = FALSE; + config_focus_warppointer = FALSE; config_focus_last = TRUE; config_focus_last_on_desktop = TRUE; config_focus_popup = TRUE; Index: kernel/config.h =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.h,v retrieving revision 1.23 diff -u -r1.23 config.h --- kernel/config.h 2003/08/12 19:57:04 1.23 +++ kernel/config.h 2003/08/20 16:39:14 @@ -12,6 +12,12 @@ extern gboolean config_focus_new; /*! Focus windows when the mouse enters them */ extern gboolean config_focus_follow; +/*! Timeout for focusing windows on focus follows mouse */ +extern guint config_focus_timeout; +/*! Whether to use the timeout or just focus right away */ +extern gboolean config_focus_delay; +/*! WarpPointer to titlebar on client_activate()? */ +extern gboolean config_focus_warppointer; /*! Focus the last focused window as a fallback */ extern gboolean config_focus_last; /*! Focus the last focused window as a fallback when switching desktops */ Index: kernel/event.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/event.c,v retrieving revision 1.147 diff -u -r1.147 event.c --- kernel/event.c 2003/08/14 05:57:36 1.147 +++ kernel/event.c 2003/08/20 16:39:18 @@ -44,6 +44,7 @@ static void event_handle_dock(ObDock *s, XEvent *e); static void event_handle_dockapp(ObDockApp *app, XEvent *e); static void event_handle_client(ObClient *c, XEvent *e); +static void focus_timeout(void *n); static void event_handle_menu(ObClient *c, XEvent *e); static void fd_event_handle(); #ifdef USE_SM @@ -61,6 +62,8 @@ (e)->xfocus.detail > NotifyNonlinearVirtual) Time event_lasttime = 0; +ObClient *client_timeout_client; +ObTimer *client_focus_timer; /*! The value of the mask for the NumLock modifier */ unsigned int NumLockMask; @@ -138,6 +141,9 @@ #endif g_datalist_init(&fd_handler_list); + + client_timeout_client = NULL; + client_focus_timer = NULL; } void event_shutdown() @@ -699,6 +705,12 @@ client->frame->close_hover = FALSE; frame_adjust_state(client->frame); break; + case OB_FRAME_CONTEXT_FRAME: + if (config_focus_delay && client_focus_timer) { + timer_stop(client_focus_timer); + client_focus_timer = NULL; + client_timeout_client = NULL; + } default: break; } @@ -741,7 +753,17 @@ ob_debug("EnterNotify on %lx, focusing window\n", client->window); #endif - client_focus(client); + if (config_focus_delay) { + if (client_focus_timer) { + timer_stop(client_focus_timer); + client_focus_timer = NULL; + } + client_timeout_client = client; + client_focus_timer = timer_start(config_focus_timeout * 1000, + (ObTimeoutHandler)focus_timeout, NULL); + } else { + client_focus(client); + } } } break; @@ -1074,6 +1096,13 @@ } #endif } +} + +static void focus_timeout(void *n) +{ + timer_stop(client_focus_timer); + client_focus_timer = NULL; + client_focus(client_timeout_client); } static void event_handle_menu(ObClient *client, XEvent *e)
The focusDelay option has been added to CVS. The warp has not. I don't think I will add that though.
This patch adds an optional delay for when using sloppy focus, and an option to make the mouse pointer warp to titlebar on alt-tabbing or directional focus, setting names are focusDelay true or false to control if the timeout is used, focusTimeout for setting the timeout in milliseconds, and finally warpPointer true or false for warping the pointer or not. They all go in the <focus> section of the rc3 file. Index: kernel/client.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/client.c,v retrieving revision 1.215 diff -u -r1.215 client.c --- kernel/client.c 2003/08/14 05:57:20 1.215 +++ kernel/client.c 2003/08/20 12:55:57 @@ -2553,6 +2553,10 @@ client_shade(self, FALSE); client_focus(self); stacking_raise(CLIENT_AS_WINDOW(self)); + if (config_focus_warppointer) + XWarpPointer(ob_display, 0, RootWindow(ob_display, ob_screen), + 0, 0, 0, 0, self->area.x + self->area.width/2, + self->area.y + ob_rr_theme->title_height/2); } gboolean client_focused(ObClient *self) Index: kernel/config.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.c,v retrieving revision 1.34 diff -u -r1.34 config.c --- kernel/config.c 2003/08/12 19:57:04 1.34 +++ kernel/config.c 2003/08/20 12:55:58 @@ -7,6 +7,9 @@ gboolean config_focus_new; gboolean config_focus_follow; +guint config_focus_timeout; +gboolean config_focus_delay; +gboolean config_focus_warppointer; gboolean config_focus_last; gboolean config_focus_last_on_desktop; gboolean config_focus_popup; @@ -212,6 +215,12 @@ config_focus_new = parse_bool(doc, n); if ((n = parse_find_node("followMouse", node))) config_focus_follow = parse_bool(doc, n); + if ((n = parse_find_node("focusTimeout", node))) + config_focus_timeout = parse_int(doc, n); + if ((n = parse_find_node("focusDelay", node))) + config_focus_delay = parse_bool(doc, n); + if ((n = parse_find_node("warpPointer", node))) + config_focus_warppointer = parse_bool(doc, n); if ((n = parse_find_node("focusLast", node))) config_focus_last = parse_bool(doc, n); if ((n = parse_find_node("focusLastOnDesktop", node))) @@ -367,6 +376,9 @@ { config_focus_new = TRUE; config_focus_follow = FALSE; + config_focus_timeout = 100; + config_focus_delay = FALSE; + config_focus_warppointer = FALSE; config_focus_last = TRUE; config_focus_last_on_desktop = TRUE; config_focus_popup = TRUE; Index: kernel/config.h =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.h,v retrieving revision 1.23 diff -u -r1.23 config.h --- kernel/config.h 2003/08/12 19:57:04 1.23 +++ kernel/config.h 2003/08/20 12:55:58 @@ -12,6 +12,12 @@ extern gboolean config_focus_new; /*! Focus windows when the mouse enters them */ extern gboolean config_focus_follow; +/*! Timeout for focusing windows on focus follows mouse */ +extern guint config_focus_timeout; +/*! Whether to use the timeout or just focus right away */ +extern gboolean config_focus_delay; +/*! WarpPointer to titlebar on client_activate()? */ +extern gboolean config_focus_warppointer; /*! Focus the last focused window as a fallback */ extern gboolean config_focus_last; /*! Focus the last focused window as a fallback when switching desktops */ Index: kernel/event.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/event.c,v retrieving revision 1.147 diff -u -r1.147 event.c --- kernel/event.c 2003/08/14 05:57:36 1.147 +++ kernel/event.c 2003/08/20 12:56:00 @@ -44,6 +44,7 @@ static void event_handle_dock(ObDock *s, XEvent *e); static void event_handle_dockapp(ObDockApp *app, XEvent *e); static void event_handle_client(ObClient *c, XEvent *e); +static void focus_timeout(void *n); static void event_handle_menu(ObClient *c, XEvent *e); static void fd_event_handle(); #ifdef USE_SM @@ -61,6 +62,8 @@ (e)->xfocus.detail > NotifyNonlinearVirtual) Time event_lasttime = 0; +ObClient *TimeoutClient = NULL; +ObTimer *FocusTimer = NULL; /*! The value of the mask for the NumLock modifier */ unsigned int NumLockMask; @@ -699,6 +702,11 @@ client->frame->close_hover = FALSE; frame_adjust_state(client->frame); break; + case OB_FRAME_CONTEXT_FRAME: + if (config_focus_delay && FocusTimer) { + timer_stop(FocusTimer); + FocusTimer = NULL; + } default: break; } @@ -741,7 +749,17 @@ ob_debug("EnterNotify on %lx, focusing window\n", client->window); #endif - client_focus(client); + if (config_focus_delay) { + if (FocusTimer) { + timer_stop(FocusTimer); + FocusTimer = NULL; + } + TimeoutClient = client; + FocusTimer = timer_start(config_focus_timeout * 1000, + (ObTimeoutHandler)focus_timeout, NULL); + } else { + client_focus(client); + } } } break; @@ -1074,6 +1092,13 @@ } #endif } +} + +static void focus_timeout(void *n) +{ + timer_stop(FocusTimer); + FocusTimer = NULL; + client_focus(TimeoutClient); } static void event_handle_menu(ObClient *client, XEvent *e)updated patch to fix a segfault pointed out by xor Index: kernel/client.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/client.c,v retrieving revision 1.215 diff -u -r1.215 client.c --- kernel/client.c 2003/08/14 05:57:20 1.215 +++ kernel/client.c 2003/08/20 16:39:13 @@ -20,6 +20,7 @@ #include "menu.h" #include "keyboard.h" #include "mouse.h" +#include "timer.h" #include "render/render.h" #include <glib.h> @@ -33,6 +34,8 @@ ButtonMotionMask) GList *client_list = NULL; +ObClient *client_timeout_client; +ObTimer *client_focus_timer; static void client_get_all(ObClient *self); static void client_toggle_border(ObClient *self, gboolean show); @@ -358,6 +361,14 @@ ob_debug("Unmanaging window: %lx (%s)\n", self->window, self->class); + if (client_timeout_client && client_timeout_client == self) { + if (client_focus_timer) { + timer_stop(client_focus_timer); + client_focus_timer = NULL; + } + client_timeout_client = NULL; + } + dispatch_client(Event_Client_Destroy, self, 0, 0); g_assert(self != NULL); @@ -2553,6 +2564,10 @@ client_shade(self, FALSE); client_focus(self); stacking_raise(CLIENT_AS_WINDOW(self)); + if (config_focus_warppointer) + XWarpPointer(ob_display, 0, RootWindow(ob_display, ob_screen), + 0, 0, 0, 0, self->area.x + self->area.width/2, + self->area.y + ob_rr_theme->title_height/2); } gboolean client_focused(ObClient *self) Index: kernel/client.h =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/client.h,v retrieving revision 1.60 diff -u -r1.60 client.h --- kernel/client.h 2003/08/14 05:57:20 1.60 +++ kernel/client.h 2003/08/20 16:39:13 @@ -5,6 +5,7 @@ #include "mwm.h" #include "geom.h" #include "stacking.h" +#include "timer.h" #include "render/color.h" #include <glib.h> @@ -234,6 +235,8 @@ }; extern GList *client_list; +extern ObClient *client_timeout_client; +extern ObTimer *client_focus_timer; void client_startup(); void client_shutdown(); Index: kernel/config.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.c,v retrieving revision 1.34 diff -u -r1.34 config.c --- kernel/config.c 2003/08/12 19:57:04 1.34 +++ kernel/config.c 2003/08/20 16:39:14 @@ -7,6 +7,9 @@ gboolean config_focus_new; gboolean config_focus_follow; +guint config_focus_timeout; +gboolean config_focus_delay; +gboolean config_focus_warppointer; gboolean config_focus_last; gboolean config_focus_last_on_desktop; gboolean config_focus_popup; @@ -212,6 +215,12 @@ config_focus_new = parse_bool(doc, n); if ((n = parse_find_node("followMouse", node))) config_focus_follow = parse_bool(doc, n); + if ((n = parse_find_node("focusTimeout", node))) + config_focus_timeout = parse_int(doc, n); + if ((n = parse_find_node("focusDelay", node))) + config_focus_delay = parse_bool(doc, n); + if ((n = parse_find_node("warpPointer", node))) + config_focus_warppointer = parse_bool(doc, n); if ((n = parse_find_node("focusLast", node))) config_focus_last = parse_bool(doc, n); if ((n = parse_find_node("focusLastOnDesktop", node))) @@ -367,6 +376,9 @@ { config_focus_new = TRUE; config_focus_follow = FALSE; + config_focus_timeout = 100; + config_focus_delay = FALSE; + config_focus_warppointer = FALSE; config_focus_last = TRUE; config_focus_last_on_desktop = TRUE; config_focus_popup = TRUE; Index: kernel/config.h =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/config.h,v retrieving revision 1.23 diff -u -r1.23 config.h --- kernel/config.h 2003/08/12 19:57:04 1.23 +++ kernel/config.h 2003/08/20 16:39:14 @@ -12,6 +12,12 @@ extern gboolean config_focus_new; /*! Focus windows when the mouse enters them */ extern gboolean config_focus_follow; +/*! Timeout for focusing windows on focus follows mouse */ +extern guint config_focus_timeout; +/*! Whether to use the timeout or just focus right away */ +extern gboolean config_focus_delay; +/*! WarpPointer to titlebar on client_activate()? */ +extern gboolean config_focus_warppointer; /*! Focus the last focused window as a fallback */ extern gboolean config_focus_last; /*! Focus the last focused window as a fallback when switching desktops */ Index: kernel/event.c =================================================================== RCS file: /cvs/cvsroot/openbox/kernel/event.c,v retrieving revision 1.147 diff -u -r1.147 event.c --- kernel/event.c 2003/08/14 05:57:36 1.147 +++ kernel/event.c 2003/08/20 16:39:18 @@ -44,6 +44,7 @@ static void event_handle_dock(ObDock *s, XEvent *e); static void event_handle_dockapp(ObDockApp *app, XEvent *e); static void event_handle_client(ObClient *c, XEvent *e); +static void focus_timeout(void *n); static void event_handle_menu(ObClient *c, XEvent *e); static void fd_event_handle(); #ifdef USE_SM @@ -61,6 +62,8 @@ (e)->xfocus.detail > NotifyNonlinearVirtual) Time event_lasttime = 0; +ObClient *client_timeout_client; +ObTimer *client_focus_timer; /*! The value of the mask for the NumLock modifier */ unsigned int NumLockMask; @@ -138,6 +141,9 @@ #endif g_datalist_init(&fd_handler_list); + + client_timeout_client = NULL; + client_focus_timer = NULL; } void event_shutdown() @@ -699,6 +705,12 @@ client->frame->close_hover = FALSE; frame_adjust_state(client->frame); break; + case OB_FRAME_CONTEXT_FRAME: + if (config_focus_delay && client_focus_timer) { + timer_stop(client_focus_timer); + client_focus_timer = NULL; + client_timeout_client = NULL; + } default: break; } @@ -741,7 +753,17 @@ ob_debug("EnterNotify on %lx, focusing window\n", client->window); #endif - client_focus(client); + if (config_focus_delay) { + if (client_focus_timer) { + timer_stop(client_focus_timer); + client_focus_timer = NULL; + } + client_timeout_client = client; + client_focus_timer = timer_start(config_focus_timeout * 1000, + (ObTimeoutHandler)focus_timeout, NULL); + } else { + client_focus(client); + } } } break; @@ -1074,6 +1096,13 @@ } #endif } +} + +static void focus_timeout(void *n) +{ + timer_stop(client_focus_timer); + client_focus_timer = NULL; + client_focus(client_timeout_client); } static void event_handle_menu(ObClient *client, XEvent *e)