Allow selecting menu entries during menuHideDelay if you click again, bug 5501
[mikachu/openbox.git] / openbox / event.c
index cf089b6..5774f67 100644 (file)
@@ -206,6 +206,7 @@ static Window event_get_window(XEvent *e)
             switch (((XkbAnyEvent*)e)->xkb_type) {
             case XkbBellNotify:
                 window = ((XkbBellNotifyEvent*)e)->window;
+                break;
             default:
                 window = None;
             }
@@ -636,11 +637,13 @@ static void event_process(const XEvent *ec, gpointer data)
     else if (e->type == MappingNotify) {
         /* keyboard layout changes for modifier mapping changes. reload the
            modifier map, and rebind all the key bindings as appropriate */
-        ob_debug("Keyboard map changed. Reloading keyboard bindings.");
-        ob_set_state(OB_STATE_RECONFIGURING);
-        obt_keyboard_reload();
-        keyboard_rebind();
-        ob_set_state(OB_STATE_RUNNING);
+        if (config_keyboard_rebind_on_mapping_notify) {
+            ob_debug("Keyboard map changed. Reloading keyboard bindings.");
+            ob_set_state(OB_STATE_RECONFIGURING);
+            obt_keyboard_reload();
+            keyboard_rebind();
+            ob_set_state(OB_STATE_RUNNING);
+        }
     }
     else if (e->type == ClientMessage) {
         /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for
@@ -698,7 +701,6 @@ static void event_process(const XEvent *ec, gpointer data)
     if (e->type == ButtonPress || e->type == ButtonRelease) {
         ObWindow *w;
         static guint pressed = 0;
-        static Window pressed_win = None;
 
         event_sourcetime = event_curtime;
 
@@ -719,10 +721,8 @@ static void event_process(const XEvent *ec, gpointer data)
             if (prompt && !used)
                 used = event_handle_prompt(prompt, e);
 
-            if (e->type == ButtonPress) {
+            if (e->type == ButtonPress)
                 pressed = e->xbutton.button;
-                pressed_win = e->xbutton.subwindow;
-            }
         }
     }
     else if (e->type == KeyPress || e->type == KeyRelease ||
@@ -775,7 +775,12 @@ static void event_handle_root(XEvent *e)
             if (d > 0 && d <= 1000)
                 screen_set_num_desktops(d);
         } else if (msgtype == OBT_PROP_ATOM(NET_SHOWING_DESKTOP)) {
-            screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
+            ObScreenShowDestopMode show_mode;
+            if (e->xclient.data.l[0] != 0)
+                show_mode = SCREEN_SHOW_DESKTOP_UNTIL_WINDOW;
+            else
+                show_mode = SCREEN_SHOW_DESKTOP_NO;
+            screen_show_desktop(show_mode, NULL);
         } else if (msgtype == OBT_PROP_ATOM(OB_CONTROL)) {
             ob_debug("OB_CONTROL: %d", e->xclient.data.l[0]);
             if (e->xclient.data.l[0] == 1)
@@ -813,11 +818,14 @@ void event_enter_client(ObClient *client)
     g_assert(config_focus_follow);
 
     if (is_enter_focus_event_ignored(event_curserial)) {
-        ob_debug_type(OB_DEBUG_FOCUS, "Ignoring enter event with serial %lu\n"
+        ob_debug_type(OB_DEBUG_FOCUS, "Ignoring enter event with serial %lu "
                       "on client 0x%x", event_curserial, client->window);
         return;
     }
 
+    ob_debug_type(OB_DEBUG_FOCUS, "using enter event with serial %lu "
+                  "on client 0x%x", event_curserial, client->window);
+
     if (client_enter_focusable(client) && client_can_focus(client)) {
         if (config_focus_delay) {
             ObFocusDelayData *data;
@@ -1190,7 +1198,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             }
 
         if (e->xconfigurerequest.value_mask & CWStackMode) {
-            ObClient *sibling = NULL;
+            ObWindow *sibling = NULL;
             gulong ignore_start;
             gboolean ok = TRUE;
 
@@ -1201,7 +1209,11 @@ static void event_handle_client(ObClient *client, XEvent *e)
                 if (win && WINDOW_IS_CLIENT(win) &&
                     WINDOW_AS_CLIENT(win) != client)
                 {
-                    sibling = WINDOW_AS_CLIENT(win);
+                    sibling = win;
+                }
+                else if (win && WINDOW_IS_DOCK(win))
+                {
+                    sibling = win;
                 }
                 else
                     /* an invalid sibling was specified so don't restack at
@@ -1495,7 +1507,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
             }
             else if ((Atom)e->xclient.data.l[2] ==
                      OBT_PROP_ATOM(NET_WM_MOVERESIZE_CANCEL))
-                moveresize_end(TRUE);
+                if (moveresize_client)
+                    moveresize_end(TRUE);
         } else if (msgtype == OBT_PROP_ATOM(NET_MOVERESIZE_WINDOW)) {
             gint ograv, x, y, w, h;
 
@@ -1551,13 +1564,17 @@ static void event_handle_client(ObClient *client, XEvent *e)
                               "invalid source indication %ld",
                               client->title, e->xclient.data.l[0]);
             } else {
-                ObClient *sibling = NULL;
+                ObWindow *sibling = NULL;
                 if (e->xclient.data.l[1]) {
                     ObWindow *win = window_find(e->xclient.data.l[1]);
                     if (WINDOW_IS_CLIENT(win) &&
                         WINDOW_AS_CLIENT(win) != client)
                     {
-                        sibling = WINDOW_AS_CLIENT(win);
+                        sibling = win;
+                    }
+                    if (WINDOW_IS_DOCK(win))
+                    {
+                        sibling = win;
                     }
                     if (sibling == NULL)
                         ob_debug_type(OB_DEBUG_APP_BUGS,
@@ -1819,8 +1836,14 @@ static gboolean event_handle_menu_input(XEvent *ev)
             if ((e = menu_entry_frame_under(ev->xbutton.x_root,
                                             ev->xbutton.y_root)))
             {
-                if (ev->type == ButtonPress && e->frame->child)
-                    menu_frame_select(e->frame->child, NULL, TRUE);
+                if (ev->type == ButtonPress) {
+                    /* We know this is a new press, so we don't have to
+                     * block release events anymore */
+                    menu_hide_delay_reset();
+
+                    if (e->frame->child)
+                        menu_frame_select(e->frame->child, NULL, TRUE);
+                }
                 menu_frame_select(e->frame, e, TRUE);
                 if (ev->type == ButtonRelease)
                     menu_entry_frame_execute(e, ev->xbutton.state);
@@ -2002,6 +2025,20 @@ static void event_handle_menu(ObMenuFrame *frame, XEvent *ev)
     ObMenuEntryFrame *e;
 
     switch (ev->type) {
+    case MotionNotify:
+        /* We need to catch MotionNotify in addition to EnterNotify because
+           it is possible for the menu to be opened under the mouse cursor, and
+           moving the mouse should select the item. */
+        if ((e = g_hash_table_lookup(menu_frame_map, &ev->xmotion.window))) {
+            if (e->ignore_enters)
+                --e->ignore_enters;
+            else if (!(f = find_active_menu()) ||
+                     f == e->frame ||
+                     f->parent == e->frame ||
+                     f->child == e->frame)
+                menu_frame_select(e->frame, e, FALSE);
+        }
+        break;
     case EnterNotify:
         if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window))) {
             if (e->ignore_enters)
@@ -2014,7 +2051,7 @@ static void event_handle_menu(ObMenuFrame *frame, XEvent *ev)
         }
         break;
     case LeaveNotify:
-        /*ignore leaves when we're already in the window */
+        /* ignore leaves when we're already in the window */
         if (ev->xcrossing.detail == NotifyInferior)
             break;
 
@@ -2091,6 +2128,7 @@ static gboolean focus_delay_func(gpointer data)
     if (client_focus(d->client) && config_focus_raise)
         stacking_raise(CLIENT_AS_WINDOW(d->client));
     event_curtime = old;
+
     return FALSE; /* no repeat */
 }
 
@@ -2103,6 +2141,7 @@ static gboolean unfocus_delay_func(gpointer data)
     event_curserial = d->serial;
     focus_nothing();
     event_curtime = old;
+
     return FALSE; /* no repeat */
 }