+ 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)
+ {
+ menu_frame_select(e->frame, NULL, FALSE);
+ }
+ case MotionNotify:
+ if ((e = menu_entry_frame_under(ev->xmotion.x_root,
+ ev->xmotion.y_root)))
+ menu_frame_select(e->frame, e, FALSE);
+ break;
+ case KeyPress:
+ if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))
+ if ((f = find_active_or_last_menu()) && f->parent)
+ menu_frame_select(f, NULL, TRUE);
+ else
+ menu_frame_hide_all();
+ else if (ev->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
+ ObMenuFrame *f;
+ if ((f = find_active_menu())) {
+ if (f->child)
+ menu_frame_select_next(f->child);
+ else
+ menu_entry_frame_execute(f->selected, ev->xkey.state,
+ ev->xkey.time);
+ }
+ } else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) {
+ ObMenuFrame *f;
+ if ((f = find_active_or_last_menu()))
+ menu_frame_select(f, NULL, TRUE);
+ } else if (ev->xkey.keycode == ob_keycode(OB_KEY_RIGHT)) {
+ ObMenuFrame *f;
+ if ((f = find_active_menu()) && f->child)
+ menu_frame_select_next(f->child);
+ } else if (ev->xkey.keycode == ob_keycode(OB_KEY_UP)) {
+ ObMenuFrame *f;
+ if ((f = find_active_or_last_menu()))
+ menu_frame_select_previous(f);
+ } else if (ev->xkey.keycode == ob_keycode(OB_KEY_DOWN)) {
+ ObMenuFrame *f;
+ if ((f = find_active_or_last_menu()))
+ menu_frame_select_next(f);
+ } else
+ event_handle_menu_shortcut(ev);
+ break;
+ }
+}
+
+static gboolean menu_hide_delay_func(gpointer data)
+{
+ menu_can_hide = TRUE;
+ return FALSE; /* no repeat */
+}
+
+static void focus_delay_dest(gpointer data)
+{
+ g_free(data);
+}
+
+static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2)
+{
+ const ObFocusDelayData *f1 = d1;
+ return f1->client == d2;
+}
+
+static gboolean focus_delay_func(gpointer data)
+{
+ ObFocusDelayData *d = data;
+ Time old = event_curtime;
+
+ event_curtime = d->time;
+ if (focus_client != d->client) {
+ if (client_focus(d->client) && config_focus_raise)
+ client_raise(d->client);
+ }
+ event_curtime = old;
+ return FALSE; /* no repeat */
+}
+
+static void focus_delay_client_dest(ObClient *client, gpointer data)
+{
+ ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func,
+ client, FALSE);
+}
+
+void event_halt_focus_delay()
+{
+ ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
+}
+
+void event_ignore_queued_enters()
+{
+ GSList *saved = NULL, *it;
+ XEvent *e;
+
+ XSync(ob_display, FALSE);
+
+ /* count the events */
+ while (TRUE) {
+ e = g_new(XEvent, 1);
+ if (XCheckTypedEvent(ob_display, EnterNotify, e)) {
+ ObWindow *win;
+
+ win = g_hash_table_lookup(window_map, &e->xany.window);
+ if (win && WINDOW_IS_CLIENT(win))
+ ++ignore_enter_focus;
+
+ saved = g_slist_append(saved, e);
+ } else {
+ g_free(e);
+ break;
+ }
+ }
+ /* put the events back */
+ for (it = saved; it; it = g_slist_next(it)) {
+ XPutBackEvent(ob_display, it->data);
+ g_free(it->data);