X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=ea24971236da54a21eaa9e48ac86955399b4d01f;hb=6be85936aea651721419bb789677059ab3cffad8;hp=fba5e86d8e7491b98aea4fa3b80c3b62cc9a0abe;hpb=bed3cb7a30e5bc3e75bf624dafc2d7d94714ae2f;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index fba5e86d..ea249712 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -31,6 +31,7 @@ #include "frame.h" #include "grab.h" #include "menu.h" +#include "prompt.h" #include "menuframe.h" #include "keyboard.h" #include "modkeys.h" @@ -88,11 +89,12 @@ static void event_process(const XEvent *e, gpointer data); static void event_handle_root(XEvent *e); static gboolean event_handle_menu_keyboard(XEvent *e); static gboolean event_handle_menu(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); @@ -459,6 +461,7 @@ static void event_process(const XEvent *ec, gpointer data) ObWindow *obwin = NULL; XEvent ee, *e; ObEventData *ed = data; + ObPrompt *prompt = NULL; /* make a copy we can mangle */ ee = *ec; @@ -475,6 +478,8 @@ static void event_process(const XEvent *ec, gpointer data) break; case Window_Client: client = WINDOW_AS_CLIENT(obwin); + /* events on clients can be events on prompt windows too */ + prompt = client->prompt; break; case Window_Menu: /* not to be used for events */ @@ -483,6 +488,9 @@ static void event_process(const XEvent *ec, gpointer data) case Window_Internal: /* we don't do anything with events directly on these windows */ break; + case Window_Prompt: + prompt = WINDOW_AS_PROMPT(obwin); + break; } } @@ -519,7 +527,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 || @@ -629,7 +636,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) @@ -641,7 +647,7 @@ static void event_process(const XEvent *ec, gpointer data) else if (window == RootWindow(ob_display, ob_screen)) event_handle_root(e); else if (e->type == MapRequest) - client_manage(window); + client_manage(window, NULL); else if (e->type == MappingNotify) { /* keyboard layout changes for modifier mapping changes. reload the modifier map, and rebind all the key bindings as appropriate */ @@ -701,9 +707,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 != RootWindow(ob_display, ob_screen) || e->xbutton.subwindow == None) { @@ -797,6 +805,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; @@ -1041,8 +1055,7 @@ 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 " @@ -1352,7 +1365,7 @@ static void event_handle_client(ObClient *client, XEvent *e) 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, + client_activate(client, TRUE, TRUE, TRUE, (e->xclient.data.l[0] == 0 || e->xclient.data.l[0] == 2)); } else if (msgtype == prop_atoms.net_wm_moveresize) { @@ -1664,6 +1677,21 @@ 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_keyboard(XEvent *ev) { guint keycode, state; @@ -1928,8 +1956,7 @@ void event_halt_focus_delay(void) gulong event_start_ignore_all_enters(void) { - XSync(ob_display, FALSE); - return LastKnownRequestProcessed(ob_display); + return NextRequest(ob_display); } static void event_ignore_enter_range(gulong start, gulong end) @@ -1948,35 +1975,35 @@ static void event_ignore_enter_range(gulong start, gulong end) r->start, r->end); /* increment the serial so we don't ignore events we weren't meant to */ - XSync(ob_display, FALSE); + PROP_ERASE(screen_support_win, motif_wm_hints); } void event_end_ignore_all_enters(gulong start) { - XSync(ob_display, FALSE); - event_ignore_enter_range(start, LastKnownRequestProcessed(ob_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(ob_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;