X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=12c0edcfc6325d1a3c5a9203dd374204acdeeb4d;hb=3263845459d15da683b7cab92fb856acbdf2800e;hp=2e3a44c56a63f64a7c301c7b0de2e8a977ce7eef;hpb=52369e319f11e1189e8980f64974236eeb4de96e;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 2e3a44c5..12c0edcf 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -29,6 +29,7 @@ #include "frame.h" #include "grab.h" #include "menu.h" +#include "prompt.h" #include "menuframe.h" #include "keyboard.h" #include "mouse.h" @@ -85,11 +86,12 @@ static void event_process(const XEvent *e, gpointer data); static void event_handle_root(XEvent *e); static gboolean event_handle_menu_input(XEvent *e); static void event_handle_menu(ObMenuFrame *frame, XEvent *e); +static gboolean event_handle_prompt(ObPrompt *p, XEvent *e); 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 event_handle_user_input(ObClient *client, XEvent *e); -static gboolean is_enter_focus_event_ignored(XEvent *e); +static gboolean is_enter_focus_event_ignored(gulong serial); static void event_ignore_enter_range(gulong start, gulong end); static void focus_delay_dest(gpointer data); @@ -161,7 +163,13 @@ static Window event_get_window(XEvent *e) case SelectionClear: window = obt_root(ob_screen); break; + case CreateNotify: + window = e->xcreatewindow.window; + break; case MapRequest: + window = e->xmaprequest.window; + break; + case MapNotify: window = e->xmap.window; break; case UnmapNotify: @@ -269,7 +277,8 @@ static void event_hack_mods(XEvent *e) magic. Our X core protocol stuff won't work, so we use this to find what the modifier state is instead. */ if (XkbGetState(obt_display, XkbUseCoreKbd, &xkb_state) == Success) - e->xkey.state = xkb_state.compat_state; + e->xkey.state = + obt_keyboard_only_modmasks(xkb_state.compat_state); else #endif { @@ -424,7 +433,7 @@ static void print_focusevent(XEvent *e) g_assert(modestr); g_assert(detailstr); - ob_debug_type(OB_DEBUG_FOCUS, "Focus%s 0x%x mode=%s detail=%s\n", + ob_debug_type(OB_DEBUG_FOCUS, "Focus%s 0x%x mode=%s detail=%s", (e->xfocus.type == FocusIn ? "In" : "Out"), win, modestr, detailstr); @@ -459,19 +468,24 @@ static void event_process(const XEvent *ec, gpointer data) ObDockApp *dockapp = NULL; ObWindow *obwin = NULL; ObMenuFrame *menu = NULL; + ObPrompt *prompt = NULL; /* make a copy we can mangle */ ee = *ec; e = ⅇ window = event_get_window(e); - if ((obwin = window_find(window))) { + if (window == obt_root(ob_screen)) + /* don't do any lookups, waste of cpu */; + else if ((obwin = window_find(window))) { switch (obwin->type) { case OB_WINDOW_CLASS_DOCK: dock = WINDOW_AS_DOCK(obwin); break; case OB_WINDOW_CLASS_CLIENT: client = WINDOW_AS_CLIENT(obwin); + /* events on clients can be events on prompt windows too */ + prompt = client->prompt; break; case OB_WINDOW_CLASS_MENUFRAME: menu = WINDOW_AS_MENUFRAME(obwin); @@ -479,6 +493,9 @@ static void event_process(const XEvent *ec, gpointer data) case OB_WINDOW_CLASS_INTERNAL: /* we don't do anything with events directly on these windows */ break; + case OB_WINDOW_CLASS_PROMPT: + prompt = WINDOW_AS_PROMPT(obwin); + break; } } else @@ -512,7 +529,6 @@ static void event_process(const XEvent *ec, gpointer data) window with RevertToParent focus */ frame_adjust_focus(client->frame, FALSE); /* focus_set_client(NULL) has already been called */ - client_calc_layer(client); } else if (e->xfocus.detail == NotifyPointerRoot || e->xfocus.detail == NotifyDetailNone || @@ -522,7 +538,7 @@ static void event_process(const XEvent *ec, gpointer data) XEvent ce; ob_debug_type(OB_DEBUG_FOCUS, - "Focus went to root or pointer root/none\n"); + "Focus went to root or pointer root/none"); if (e->xfocus.detail == NotifyInferior || e->xfocus.detail == NotifyNonlinear) @@ -548,7 +564,7 @@ static void event_process(const XEvent *ec, gpointer data) { XPutBackEvent(obt_display, &ce); ob_debug_type(OB_DEBUG_FOCUS, - " but another FocusIn is coming\n"); + " but another FocusIn is coming"); } else { /* Focus has been reverted. @@ -564,7 +580,7 @@ static void event_process(const XEvent *ec, gpointer data) else if (!client) { ob_debug_type(OB_DEBUG_FOCUS, - "Focus went to a window that is already gone\n"); + "Focus went to a window that is already gone"); /* If you send focus to a window and then it disappears, you can get the FocusIn for it, after it is unmanaged. @@ -595,12 +611,12 @@ static void event_process(const XEvent *ec, gpointer data) root != obt_root(ob_screen)) { ob_debug_type(OB_DEBUG_FOCUS, - "Focus went to another screen !\n"); + "Focus went to another screen !"); focus_left_screen = TRUE; } else ob_debug_type(OB_DEBUG_FOCUS, - "Focus went to a black hole !\n"); + "Focus went to a black hole !"); obt_display_ignore_errors(FALSE); /* nothing is focused */ focus_set_client(NULL); @@ -612,7 +628,7 @@ static void event_process(const XEvent *ec, gpointer data) /* The FocusIn was ignored, this means it was on a window that isn't a client. */ ob_debug_type(OB_DEBUG_FOCUS, - "Focus went to an unmanaged window 0x%x !\n", + "Focus went to an unmanaged window 0x%x !", ce.xfocus.window); focus_fallback(TRUE, config_focus_under_mouse, TRUE, TRUE); } @@ -622,7 +638,6 @@ static void event_process(const XEvent *ec, gpointer data) frame_adjust_focus(client->frame, FALSE); /* focus_set_client(NULL) has already been called in this section or by focus_fallback */ - client_calc_layer(client); } } else if (client) @@ -636,11 +651,11 @@ static void event_process(const XEvent *ec, gpointer data) else if (window == obt_root(ob_screen)) event_handle_root(e); else if (e->type == MapRequest) - client_manage(window); + window_manage(window); 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("Kepboard map changed. Reloading keyboard bindings.\n"); + ob_debug("Kepboard map changed. Reloading keyboard bindings."); obt_keyboard_reload(); keyboard_rebind(); } @@ -697,9 +712,11 @@ static void event_process(const XEvent *ec, gpointer data) } #endif - if (e->type == ButtonPress || e->type == ButtonRelease) { + if (prompt && event_handle_prompt(prompt, e)) + ; + else if (e->type == ButtonPress || e->type == ButtonRelease) { /* If the button press was on some non-root window, or was physically - on the root window, the process it */ + on the root window, then process it */ if (window != obt_root(ob_screen) || e->xbutton.subwindow == None) { @@ -733,7 +750,7 @@ static void event_handle_root(XEvent *e) switch(e->type) { case SelectionClear: - ob_debug("Another WM has requested to replace us. Exiting.\n"); + ob_debug("Another WM has requested to replace us. Exiting."); ob_exit_replace(); break; @@ -748,7 +765,7 @@ static void event_handle_root(XEvent *e) if (event_curtime == 0) ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_CURRENT_DESKTOP message is missing " - "a timestamp\n"); + "a timestamp"); screen_set_desktop(d, TRUE); } } else if (msgtype == OBT_PROP_ATOM(NET_NUMBER_OF_DESKTOPS)) { @@ -758,7 +775,7 @@ static void event_handle_root(XEvent *e) } else if (msgtype == OBT_PROP_ATOM(NET_SHOWING_DESKTOP)) { screen_show_desktop(e->xclient.data.l[0] != 0, NULL); } else if (msgtype == OBT_PROP_ATOM(OB_CONTROL)) { - ob_debug("OB_CONTROL: %d\n", e->xclient.data.l[0]); + ob_debug("OB_CONTROL: %d", e->xclient.data.l[0]); if (e->xclient.data.l[0] == 1) ob_reconfigure(); else if (e->xclient.data.l[0] == 2) @@ -772,7 +789,7 @@ static void event_handle_root(XEvent *e) break; case PropertyNotify: if (e->xproperty.atom == OBT_PROP_ATOM(NET_DESKTOP_NAMES)) { - ob_debug("UPDATE DESKTOP NAMES\n"); + ob_debug("UPDATE DESKTOP NAMES"); screen_update_desktop_names(); } else if (e->xproperty.atom == OBT_PROP_ATOM(NET_DESKTOP_LAYOUT)) @@ -793,6 +810,12 @@ 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" + "on client 0x%x", event_curserial, client->window); + return; + } + if (client_enter_focusable(client) && client_can_focus(client)) { if (config_focus_delay) { ObFocusDelayData *data; @@ -825,6 +848,7 @@ static void event_handle_client(ObClient *client, XEvent *e) ObFrameContext con; static gint px = -1, py = -1; static guint pb = 0; + static ObFrameContext pcon = OB_FRAME_CONTEXT_NONE; switch (e->type) { case ButtonPress: @@ -833,11 +857,15 @@ static void event_handle_client(ObClient *client, XEvent *e) pb = e->xbutton.button; px = e->xbutton.x; py = e->xbutton.y; + + pcon = frame_context(client, e->xbutton.window, px, py); + pcon = mouse_button_frame_context(pcon, e->xbutton.button, + e->xbutton.state); } case ButtonRelease: /* Wheel buttons don't draw because they are an instant click, so it is a waste of resources to go drawing it. - if the user is doing an intereactive thing, or has a menu open then + if the user is doing an interactive thing, or has a menu open then the mouse is grabbed (possibly) and if we get these events we don't want to deal with them */ @@ -850,7 +878,7 @@ static void event_handle_client(ObClient *client, XEvent *e) e->xbutton.state); if (e->type == ButtonRelease && e->xbutton.button == pb) - pb = 0, px = py = -1; + pb = 0, px = py = -1, pcon = OB_FRAME_CONTEXT_NONE; switch (con) { case OB_FRAME_CONTEXT_MAXIMIZE: @@ -904,31 +932,31 @@ static void event_handle_client(ObClient *client, XEvent *e) } break; case OB_FRAME_CONTEXT_MAXIMIZE: - if (!client->frame->max_hover) { + if (!client->frame->max_hover && !pb) { client->frame->max_hover = TRUE; frame_adjust_state(client->frame); } break; case OB_FRAME_CONTEXT_ALLDESKTOPS: - if (!client->frame->desk_hover) { + if (!client->frame->desk_hover && !pb) { client->frame->desk_hover = TRUE; frame_adjust_state(client->frame); } break; case OB_FRAME_CONTEXT_SHADE: - if (!client->frame->shade_hover) { + if (!client->frame->shade_hover && !pb) { client->frame->shade_hover = TRUE; frame_adjust_state(client->frame); } break; case OB_FRAME_CONTEXT_ICONIFY: - if (!client->frame->iconify_hover) { + if (!client->frame->iconify_hover && !pb) { client->frame->iconify_hover = TRUE; frame_adjust_state(client->frame); } break; case OB_FRAME_CONTEXT_CLOSE: - if (!client->frame->close_hover) { + if (!client->frame->close_hover && !pb) { client->frame->close_hover = TRUE; frame_adjust_state(client->frame); } @@ -959,22 +987,27 @@ static void event_handle_client(ObClient *client, XEvent *e) break; case OB_FRAME_CONTEXT_MAXIMIZE: client->frame->max_hover = FALSE; + client->frame->max_press = FALSE; frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_ALLDESKTOPS: client->frame->desk_hover = FALSE; + client->frame->desk_press = FALSE; frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_SHADE: client->frame->shade_hover = FALSE; + client->frame->shade_press = FALSE; frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_ICONIFY: client->frame->iconify_hover = FALSE; + client->frame->iconify_press = FALSE; frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_CLOSE: client->frame->close_hover = FALSE; + client->frame->close_press = FALSE; frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: @@ -985,7 +1018,7 @@ static void event_handle_client(ObClient *client, XEvent *e) event_end_ignore_all_enters(event_start_ignore_all_enters()); ob_debug_type(OB_DEBUG_FOCUS, - "%sNotify mode %d detail %d on %lx\n", + "%sNotify mode %d detail %d on %lx", (e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, e->xcrossing.detail, (client?client->window:0)); @@ -1013,22 +1046,27 @@ static void event_handle_client(ObClient *client, XEvent *e) switch (con) { case OB_FRAME_CONTEXT_MAXIMIZE: client->frame->max_hover = TRUE; + client->frame->max_press = (con == pcon); frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_ALLDESKTOPS: client->frame->desk_hover = TRUE; + client->frame->desk_press = (con == pcon); frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_SHADE: client->frame->shade_hover = TRUE; + client->frame->shade_press = (con == pcon); frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_ICONIFY: client->frame->iconify_hover = TRUE; + client->frame->iconify_press = (con == pcon); frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_CLOSE: client->frame->close_hover = TRUE; + client->frame->close_press = (con == pcon); frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: @@ -1037,12 +1075,11 @@ static void event_handle_client(ObClient *client, XEvent *e) if (e->xcrossing.mode == NotifyGrab || e->xcrossing.mode == NotifyUngrab || /*ignore enters when we're already in the window */ - e->xcrossing.detail == NotifyInferior || - is_enter_focus_event_ignored(e)) + e->xcrossing.detail == NotifyInferior) { ob_debug_type(OB_DEBUG_FOCUS, "%sNotify mode %d detail %d serial %lu on %lx " - "IGNORED\n", + "IGNORED", (e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, e->xcrossing.detail, @@ -1052,7 +1089,7 @@ static void event_handle_client(ObClient *client, XEvent *e) else { ob_debug_type(OB_DEBUG_FOCUS, "%sNotify mode %d detail %d serial %lu on %lx, " - "focusing window\n", + "focusing window", (e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, e->xcrossing.detail, @@ -1083,10 +1120,10 @@ static void event_handle_client(ObClient *client, XEvent *e) RECT_TO_DIMS(client->area, x, y, w, h); ob_debug("ConfigureRequest for \"%s\" desktop %d wmstate %d " - "visibile %d\n" - " x %d y %d w %d h %d b %d\n", + "visibile %d", client->title, - screen_desktop, client->wmstate, client->frame->visible, + screen_desktop, client->wmstate, client->frame->visible); + ob_debug(" x %d y %d w %d h %d b %d", x, y, w, h, client->border_width); if (e->xconfigurerequest.value_mask & CWBorderWidth) @@ -1166,7 +1203,7 @@ static void event_handle_client(ObClient *client, XEvent *e) } ob_debug("ConfigureRequest x(%d) %d y(%d) %d w(%d) %d h(%d) %d " - "move %d resize %d\n", + "move %d resize %d", e->xconfigurerequest.value_mask & CWX, x, e->xconfigurerequest.value_mask & CWY, y, e->xconfigurerequest.value_mask & CWWidth, w, @@ -1192,7 +1229,7 @@ static void event_handle_client(ObClient *client, XEvent *e) ob_debug_type(OB_DEBUG_APP_BUGS, "Application %s is trying to move via " "ConfigureRequest to it's root window position " - "but it is not using StaticGravity\n", + "but it is not using StaticGravity", client->title); /* don't move it */ x = client->area.x; @@ -1220,25 +1257,25 @@ static void event_handle_client(ObClient *client, XEvent *e) client_find_onscreen(client, &x, &y, w, h, FALSE); - ob_debug("Granting ConfigureRequest x %d y %d w %d h %d\n", + ob_debug("Granting ConfigureRequest x %d y %d w %d h %d", x, y, w, h); client_configure(client, x, y, w, h, FALSE, TRUE, TRUE); } break; } case UnmapNotify: + ob_debug("UnmapNotify for window 0x%x eventwin 0x%x sendevent %d " + "ignores left %d", + client->window, e->xunmap.event, e->xunmap.from_configure, + client->ignore_unmaps); if (client->ignore_unmaps) { client->ignore_unmaps--; break; } - ob_debug("UnmapNotify for window 0x%x eventwin 0x%x sendevent %d " - "ignores left %d\n", - client->window, e->xunmap.event, e->xunmap.from_configure, - client->ignore_unmaps); client_unmanage(client); break; case DestroyNotify: - ob_debug("DestroyNotify for window 0x%x\n", client->window); + ob_debug("DestroyNotify for window 0x%x", client->window); client_unmanage(client); break; case ReparentNotify: @@ -1256,11 +1293,11 @@ static void event_handle_client(ObClient *client, XEvent *e) X server to deal with after we unmanage the window */ XPutBackEvent(obt_display, e); - ob_debug("ReparentNotify for window 0x%x\n", client->window); + ob_debug("ReparentNotify for window 0x%x", client->window); client_unmanage(client); break; case MapRequest: - ob_debug("MapRequest for 0x%lx\n", client->window); + ob_debug("MapRequest for 0x%lx", client->window); if (!client->iconic) break; /* this normally doesn't happen, but if it does, we don't want it! it can happen now when the window is on @@ -1310,7 +1347,7 @@ static void event_handle_client(ObClient *client, XEvent *e) gulong ignore_start; /* can't compress these */ - ob_debug("net_wm_state %s %ld %ld for 0x%lx\n", + ob_debug("net_wm_state %s %ld %ld for 0x%lx", (e->xclient.data.l[0] == 0 ? "Remove" : e->xclient.data.l[0] == 1 ? "Add" : e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"), @@ -1325,10 +1362,10 @@ static void event_handle_client(ObClient *client, XEvent *e) if (!config_focus_under_mouse) event_end_ignore_all_enters(ignore_start); } else if (msgtype == OBT_PROP_ATOM(NET_CLOSE_WINDOW)) { - ob_debug("net_close_window for 0x%lx\n", client->window); + ob_debug("net_close_window for 0x%lx", client->window); client_close(client); } else if (msgtype == OBT_PROP_ATOM(NET_ACTIVE_WINDOW)) { - ob_debug("net_active_window for 0x%lx source=%s\n", + ob_debug("net_active_window for 0x%lx source=%s", client->window, (e->xclient.data.l[0] == 0 ? "unknown" : (e->xclient.data.l[0] == 1 ? "application" : @@ -1342,16 +1379,16 @@ static void event_handle_client(ObClient *client, XEvent *e) if (e->xclient.data.l[1] == 0) ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_ACTIVE_WINDOW message for window %s is" - " missing a timestamp\n", client->title); + " missing a timestamp", client->title); } else ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_ACTIVE_WINDOW message for window %s is " - "missing source indication\n"); - client_activate(client, FALSE, TRUE, TRUE, + "missing source indication"); + client_activate(client, TRUE, TRUE, TRUE, (e->xclient.data.l[0] == 0 || e->xclient.data.l[0] == 2)); } else if (msgtype == OBT_PROP_ATOM(NET_WM_MOVERESIZE)) { - ob_debug("net_wm_moveresize for 0x%lx direction %d\n", + ob_debug("net_wm_moveresize for 0x%lx direction %d", client->window, e->xclient.data.l[2]); if ((Atom)e->xclient.data.l[2] == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT) || @@ -1424,7 +1461,7 @@ static void event_handle_client(ObClient *client, XEvent *e) else h = client->area.height; - ob_debug("MOVERESIZE x %d %d y %d %d (gravity %d)\n", + ob_debug("MOVERESIZE x %d %d y %d %d (gravity %d)", e->xclient.data.l[0] & 1 << 8, x, e->xclient.data.l[0] & 1 << 9, y, client->gravity); @@ -1438,7 +1475,7 @@ static void event_handle_client(ObClient *client, XEvent *e) if (e->xclient.data.l[0] != 2) { ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_RESTACK_WINDOW sent for window %s with " - "invalid source indication %ld\n", + "invalid source indication %ld", client->title, e->xclient.data.l[0]); } else { ObClient *sibling = NULL; @@ -1452,7 +1489,7 @@ static void event_handle_client(ObClient *client, XEvent *e) if (sibling == NULL) ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_RESTACK_WINDOW sent for window %s " - "with invalid sibling 0x%x\n", + "with invalid sibling 0x%x", client->title, e->xclient.data.l[1]); } if (e->xclient.data.l[2] == Below || @@ -1477,7 +1514,7 @@ static void event_handle_client(ObClient *client, XEvent *e) } else ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_RESTACK_WINDOW sent for window %s " - "with invalid detail %d\n", + "with invalid detail %d", client->title, e->xclient.data.l[2]); } } @@ -1520,7 +1557,7 @@ static void event_handle_client(ObClient *client, XEvent *e) msgtype = e->xproperty.atom; if (msgtype == XA_WM_NORMAL_HINTS) { - ob_debug("Update NORMAL hints\n"); + ob_debug("Update NORMAL hints"); client_update_normal_hints(client); /* normal hints can make a window non-resizable */ client_setup_decor_and_functions(client, FALSE); @@ -1622,13 +1659,13 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e) app->ignore_unmaps--; break; } - dock_remove(app, TRUE); + dock_unmanage(app, TRUE); break; case DestroyNotify: - dock_remove(app, FALSE); + dock_unmanage(app, FALSE); break; case ReparentNotify: - dock_remove(app, FALSE); + dock_unmanage(app, FALSE); break; case ConfigureNotify: dock_app_configure(app, e->xconfigure.width, e->xconfigure.height); @@ -1660,11 +1697,26 @@ static ObMenuFrame* find_active_or_last_menu(void) return ret; } +static gboolean event_handle_prompt(ObPrompt *p, XEvent *e) +{ + switch (e->type) { + case ButtonPress: + case ButtonRelease: + case MotionNotify: + return prompt_mouse_event(p, e); + break; + case KeyPress: + return prompt_key_event(p, e); + break; + } + return FALSE; +} + static gboolean event_handle_menu_input(XEvent *ev) { gboolean ret = FALSE; - if (ev->type == ButtonRelease) { + if (ev->type == ButtonRelease || ev->type == ButtonPress) { ObMenuEntryFrame *e; if (menu_hide_delay_reached() && @@ -1673,10 +1725,13 @@ 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); menu_frame_select(e->frame, e, TRUE); - menu_entry_frame_execute(e, ev->xbutton.state); + if (ev->type == ButtonRelease) + menu_entry_frame_execute(e, ev->xbutton.state); } - else + else if (ev->type == ButtonRelease) menu_frame_hide_all(); } ret = TRUE; @@ -1927,8 +1982,7 @@ void event_halt_focus_delay(void) gulong event_start_ignore_all_enters(void) { - XSync(obt_display, FALSE); - return LastKnownRequestProcessed(obt_display); + return NextRequest(obt_display); } static void event_ignore_enter_range(gulong start, gulong end) @@ -1943,39 +1997,39 @@ static void event_ignore_enter_range(gulong start, gulong end) r->end = end; ignore_serials = g_slist_prepend(ignore_serials, r); - ob_debug_type(OB_DEBUG_FOCUS, "ignoring enters from %lu until %lu\n", + ob_debug_type(OB_DEBUG_FOCUS, "ignoring enters from %lu until %lu", r->start, r->end); /* increment the serial so we don't ignore events we weren't meant to */ - XSync(obt_display, FALSE); + OBT_PROP_ERASE(screen_support_win, MOTIF_WM_HINTS); } void event_end_ignore_all_enters(gulong start) { - XSync(obt_display, FALSE); - event_ignore_enter_range(start, LastKnownRequestProcessed(obt_display)); + /* Use (NextRequest-1) so that we ignore up to the current serial only. + Inside event_ignore_enter_range, we increment the serial by one, but if + we ignore that serial too, then any enter events generated by mouse + movement will be ignored until we create some further network traffic. + Instead ignore up to NextRequest-1, then when we increment the serial, + we will be *past* the range of ignored serials */ + event_ignore_enter_range(start, NextRequest(obt_display)-1); } -static gboolean is_enter_focus_event_ignored(XEvent *e) +static gboolean is_enter_focus_event_ignored(gulong serial) { GSList *it, *next; - g_assert(e->type == EnterNotify && - !(e->xcrossing.mode == NotifyGrab || - e->xcrossing.mode == NotifyUngrab || - e->xcrossing.detail == NotifyInferior)); - for (it = ignore_serials; it; it = next) { ObSerialRange *r = it->data; next = g_slist_next(it); - if ((glong)(e->xany.serial - r->end) > 0) { + if ((glong)(serial - r->end) > 0) { /* past the end */ ignore_serials = g_slist_delete_link(ignore_serials, it); g_free(r); } - else if ((glong)(e->xany.serial - r->start) >= 0) + else if ((glong)(serial - r->start) >= 0) return TRUE; } return FALSE; @@ -1985,19 +2039,19 @@ void event_cancel_all_key_grabs(void) { if (actions_interactive_act_running()) { actions_interactive_cancel_act(); - ob_debug("KILLED interactive action\n"); + ob_debug("KILLED interactive action"); } else if (menu_frame_visible) { menu_frame_hide_all(); - ob_debug("KILLED open menus\n"); + ob_debug("KILLED open menus"); } else if (moveresize_in_progress) { moveresize_end(TRUE); - ob_debug("KILLED interactive moveresize\n"); + ob_debug("KILLED interactive moveresize"); } else if (grab_on_keyboard()) { ungrab_keyboard(); - ob_debug("KILLED active grab on keyboard\n"); + ob_debug("KILLED active grab on keyboard"); } else ungrab_passive_key();