]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
use the timestamp from the original enter when delay-focusing a window
[chaz/openbox] / openbox / event.c
index b9f04e4d5c7ecd43d90bc47061386f3a87d942fa..8329f0287b3c35c94b49e52f84c32ae88b3daacf 100644 (file)
@@ -64,6 +64,12 @@ typedef struct
     gboolean ignored;
 } ObEventData;
 
+typedef struct
+{
+    ObClient *client;
+    Time time;
+} ObFocusDelayData;
+
 static void event_process(const XEvent *e, gpointer data);
 static void event_client_dest(ObClient *client, gpointer data);
 static void event_handle_root(XEvent *e);
@@ -73,6 +79,7 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e);
 static void event_handle_client(ObClient *c, XEvent *e);
 static void event_handle_group(ObGroup *g, XEvent *e);
 
+static void focus_delay_destroy(gpointer data);
 static gboolean focus_delay_func(gpointer data);
 static void focus_delay_client_dest(ObClient *client, gpointer data);
 
@@ -98,6 +105,11 @@ static guint ignore_enter_focus = 0;
 
 static gboolean menu_can_hide;
 
+static ObFocusDelayData focus_delay_data = { .client = NULL,
+                                             .time = CurrentTime };
+
+
+
 #ifdef USE_SM
 static void ice_handler(gint fd, gpointer conn)
 {
@@ -387,9 +399,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client)
     switch(e->type) {
     case EnterNotify:
     case LeaveNotify:
-        if (e->xcrossing.detail == NotifyInferior)
-            return TRUE;
-        break;
+        return keyboard_interactively_grabbed();
     case FocusIn:
     case FocusOut:
         /* I don't think this should ever happen with our event masks, but
@@ -473,7 +483,13 @@ static void event_process(const XEvent *ec, gpointer data)
             ed->ignored = FALSE;
 
     /* deal with it in the kernel */
-    if (group)
+
+    if (menu_frame_visible &&
+        (e->type == EnterNotify || e->type == LeaveNotify))
+    {
+        /* crossing events for menu */
+        event_handle_menu(e);
+    } else if (group)
         event_handle_group(group, e);
     else if (client)
         event_handle_client(client, e);
@@ -613,12 +629,16 @@ void event_enter_client(ObClient *client)
     if (client_normal(client) && client_can_focus(client)) {
         if (config_focus_delay) {
             ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
+
+            focus_delay_data.client = client;
+            focus_delay_data.time = event_curtime;
+
             ob_main_loop_timeout_add(ob_main_loop,
                                      config_focus_delay,
                                      focus_delay_func,
-                                     client, NULL);
+                                     NULL, focus_delay_destroy);
         } else
-            focus_delay_func(client);
+            focus_delay_func(NULL);
     }
 }
 
@@ -1262,26 +1282,21 @@ static void event_handle_menu(XEvent *ev)
                 menu_frame_hide_all();
         }
         break;
-    case MotionNotify:
-        if ((f = menu_frame_under(ev->xmotion.x_root,
-                                  ev->xmotion.y_root))) {
-            if ((e = menu_entry_frame_under(ev->xmotion.x_root,
-                                            ev->xmotion.y_root))) {
-                /* XXX menu_frame_entry_move_on_screen(f); */
-                menu_frame_select(f, e);
-            }
+    case EnterNotify:
+        if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window))) {
+            if (e->ignore_enters)
+                --e->ignore_enters;
+            else
+                menu_frame_select(e->frame, e);
         }
+        break;
+    case LeaveNotify:
+        if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window)) &&
+            (f = find_active_menu()) && f->selected == e &&
+            e->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU)
         {
-            ObMenuFrame *a;
-
-            a = find_active_menu();
-            if (a && a != f &&
-                a->selected->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU)
-            {
-                menu_frame_select(a, NULL);
-            }
+            menu_frame_select(e->frame, NULL);
         }
-        break;
     case KeyPress:
         if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))
             menu_frame_hide_all();
@@ -1317,14 +1332,21 @@ static gboolean menu_hide_delay_func(gpointer data)
     return FALSE; /* no repeat */
 }
 
-static gboolean focus_delay_func(gpointer data)
+static void focus_delay_destroy(gpointer data)
 {
-    ObClient *c = data;
+    focus_delay_data.client = NULL;
+    focus_delay_data.time = CurrentTime;
+}
 
-    if (focus_client != c) {
-        if (client_focus(c) && config_focus_raise)
-            client_raise(c);
+static gboolean focus_delay_func(gpointer data)
+{
+    Time old = event_curtime;
+    event_curtime = focus_delay_data.time;
+    if (focus_client != focus_delay_data.client) {
+        if (client_focus(focus_delay_data.client) && config_focus_raise)
+            client_raise(focus_delay_data.client);
     }
+    event_curtime = old;
     return FALSE; /* no repeat */
 }
 
This page took 0.029043 seconds and 4 git commands to generate.