]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
fix escape's behavior in menus. make static stuff that shouldnt be used by others
[chaz/openbox] / openbox / event.c
index 0add317a587c854aaa607dae2b4a74d5caff9c15..ace548a6498fbe3b877ed4469cf9740cb3dc9d44 100644 (file)
@@ -38,6 +38,7 @@
 #include "mainloop.h"
 #include "framerender.h"
 #include "focus.h"
+#include "focus_cycle.h"
 #include "moveresize.h"
 #include "group.h"
 #include "stacking.h"
@@ -884,7 +885,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
                corresponding enter events. Pretend like the animating window
                doesn't even exist..! */
             if (frame_iconify_animating(client->frame))
-                event_ignore_enters_leaving_window(client);
+                event_ignore_all_queued_enters();
 
             ob_debug_type(OB_DEBUG_FOCUS,
                           "%sNotify mode %d detail %d on %lx\n",
@@ -1079,7 +1080,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_configure(client, x, y, w, h, FALSE, TRUE);
 
             /* ignore enter events caused by these like ob actions do */
-            event_ignore_enters_leaving_window(client);
+            event_ignore_all_queued_enters();
         }
         break;
     }
@@ -1175,7 +1176,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
                              e->xclient.data.l[1], e->xclient.data.l[2]);
 
             /* ignore enter events caused by these like ob actions do */
-            event_ignore_enters_leaving_window(client);
+            event_ignore_all_queued_enters();
         } else if (msgtype == prop_atoms.net_close_window) {
             ob_debug("net_close_window for 0x%lx\n", client->window);
             client_close(client);
@@ -1263,7 +1264,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             client_configure(client, x, y, w, h, FALSE, TRUE);
 
             /* ignore enter events caused by these like ob actions do */
-            event_ignore_enters_leaving_window(client);
+            event_ignore_all_queued_enters();
         } else if (msgtype == prop_atoms.net_restack_window) {
             if (e->xclient.data.l[0] != 2) {
                 ob_debug_type(OB_DEBUG_APP_BUGS,
@@ -1273,8 +1274,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
             } else {
                 ObClient *sibling = NULL;
                 if (e->xclient.data.l[1]) {
-                    ObWindow *win = g_hash_table_lookup(window_map,
-                                                        &e->xclient.data.l[1]);
+                    ObWindow *win = g_hash_table_lookup
+                        (window_map, &e->xclient.data.l[1]);
                     if (WINDOW_IS_CLIENT(win) &&
                         WINDOW_AS_CLIENT(win) != client)
                     {
@@ -1481,8 +1482,11 @@ static gboolean event_handle_menu_keyboard(XEvent *ev)
         ret = FALSE;
 
     else if (keycode == ob_keycode(OB_KEY_ESCAPE) && state == 0) {
-        /* Escape closes the active menu */
-        menu_frame_hide(frame);
+        /* Escape goes to the parent menu or closes the last one */
+        if (frame->parent)
+            menu_frame_select(frame, NULL, TRUE);
+        else
+            menu_frame_hide_all();
     }
 
     else if (keycode == ob_keycode(OB_KEY_RETURN) && (state == 0 ||
@@ -1606,6 +1610,10 @@ static gboolean event_handle_menu(XEvent *ev)
         }
         break;
     case LeaveNotify:
+        /*ignore leaves when we're already in the window */
+        if (ev->xcrossing.detail == NotifyInferior)
+            break;
+
         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)
@@ -1716,10 +1724,9 @@ static Bool event_look_for_enters(Display *d, XEvent *e, XPointer arg)
 {
     if (e->type == EnterNotify &&
         /* these types aren't used for focusing */
-        (e->xcrossing.mode == NotifyGrab ||
-         e->xcrossing.mode == NotifyUngrab ||
-         /*ignore enters when we're already in the window */
-         e->xcrossing.detail == NotifyInferior))
+        !(e->xcrossing.mode == NotifyGrab ||
+          e->xcrossing.mode == NotifyUngrab ||
+          e->xcrossing.detail == NotifyInferior))
     {
         ObWindow *win;
 
@@ -1733,19 +1740,11 @@ static Bool event_look_for_enters(Display *d, XEvent *e, XPointer arg)
 }
 
 void event_ignore_all_queued_enters()
-{
-    event_ignore_enters_leaving_window(NULL);
-}
-
-void event_ignore_enters_leaving_window(ObClient *c)
 {
     XEvent e;
 
     XSync(ob_display, FALSE);
 
-    ob_debug_type(OB_DEBUG_FOCUS, "want to ignore enters leaving window "
-                  "%s\n", c?c->title:"(all)");
-
     /* count the events without disrupting them */
     ignore_enter_focus = 0;
     XCheckIfEvent(ob_display, &e, event_look_for_enters, NULL);
@@ -1753,7 +1752,10 @@ void event_ignore_enters_leaving_window(ObClient *c)
 
 static gboolean is_enter_focus_event_ignored(XEvent *e)
 {
-    g_assert(e->type == EnterNotify);
+    g_assert(e->type == EnterNotify &&
+             !(e->xcrossing.mode == NotifyGrab ||
+               e->xcrossing.mode == NotifyUngrab ||
+               e->xcrossing.detail == NotifyInferior));
 
     ob_debug_type(OB_DEBUG_FOCUS, "# enters ignored: %d\n",
                   ignore_enter_focus);
This page took 0.024448 seconds and 4 git commands to generate.