Bug 763 - Adds timeout for focus follow and warps pointer to titlebar on alt-tab
Status: CLOSED FIXED
Alias: None
Product: Openbox
Classification: Unclassified
Component: general
Version: 3.0-alpha5
Hardware: PC Linux
: P5 enhancement
Assignee: Dana Jansens
QA Contact:
URL: http://mikachu.ath.cx/openbox3-focust...
Depends on:
Blocks: 767
 
Reported: 2003-08-20 09:02 EDT by Mikachu
Modified: 2007-05-16 15:51:48 EDT
0 users

See Also:



Description Mikachu 2003-08-20 09:02:40 EDT
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)
Comment 1 Mikachu 2003-08-20 12:40:42 EDT
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)
Comment 2 Dana Jansens 2003-09-03 18:34:09 EDT
The focusDelay option has been added to CVS. The warp has not. I don't think I
will add that though.