X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=535e9f14d3ad98cf1ba5ecec88750ca506197f5f;hb=dd740b5562806a6b4692c938ad0e903ad89b6193;hp=cd5625990e9fa31ea1cac9f4863a6fb97bfe8f64;hpb=2b80e4e8ef56bb4fba614139601e750344418e5b;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index cd562599..535e9f14 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -43,6 +43,7 @@ #include "stacking.h" #include "extensions.h" #include "translate.h" +#include "ping.h" #include #include @@ -74,6 +75,7 @@ typedef struct { ObClient *client; Time time; + gulong serial; } ObFocusDelayData; typedef struct @@ -101,8 +103,8 @@ static void focus_delay_client_dest(ObClient *client, gpointer data); Time event_curtime = CurrentTime; Time event_last_user_time = CurrentTime; /*! The serial of the current X event */ -gulong event_curserial; +static gulong event_curserial; static gboolean focus_left_screen = FALSE; /*! A list of ObSerialRanges which are to be ignored for mouse enter events */ static GSList *ignore_serials = NULL; @@ -246,7 +248,6 @@ static void event_set_curtime(XEvent *e) event_last_user_time = CurrentTime; event_curtime = t; - event_curserial = 0; } static void event_hack_mods(XEvent *e) @@ -269,7 +270,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(ob_display, XkbUseCoreKbd, &xkb_state) == Success) - e->xkey.state = xkb_state.compat_state; + e->xkey.state = + modkeys_only_modifier_masks(xkb_state.compat_state); else #endif { @@ -475,10 +477,12 @@ static void event_process(const XEvent *ec, gpointer data) client = WINDOW_AS_CLIENT(obwin); break; case Window_Menu: - case Window_Internal: /* not to be used for events */ g_assert_not_reached(); break; + case Window_Internal: + /* we don't do anything with events directly on these windows */ + break; } } @@ -639,9 +643,12 @@ static void event_process(const XEvent *ec, gpointer data) else if (e->type == MapRequest) client_manage(window); else if (e->type == MappingNotify) { - /* keyboard layout changes, reconfigure openbox. need to restart the - modkeys system, but also to reload the key bindings. */ - ob_reconfigure(); + /* 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"); + modkeys_shutdown(TRUE); + modkeys_startup(TRUE); + keyboard_rebind(); } else if (e->type == ClientMessage) { /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for @@ -705,30 +712,9 @@ static void event_process(const XEvent *ec, gpointer data) /* Otherwise only process it if it was physically on an openbox internal window */ else { - Window target, parent, root, *children; - unsigned int nchildren; ObWindow *w; - /* Find the top level ancestor of the subwindow, besides the - root */ - target = e->xbutton.subwindow; - ob_debug("subwindow 0x%x\n", target); - while (XQueryTree(ob_display, target, &root, &parent, &children, - &nchildren) != 0) - { - XFree(children); - if (parent == root) { - ob_debug("parent is root\n"); - break; - } - target = parent; - } - ob_debug("toplevel 0x%x\n", target); - - w = g_hash_table_lookup(window_map, &target); - ob_debug("w 0x%x\n", w); - - if ((w = g_hash_table_lookup(window_map, &target)) && + if ((w = g_hash_table_lookup(window_map, &e->xbutton.subwindow)) && WINDOW_IS_INTERNAL(w)) { event_handle_user_input(client, e); @@ -742,6 +728,7 @@ static void event_process(const XEvent *ec, gpointer data) /* if something happens and it's not from an XEvent, then we don't know the time */ event_curtime = CurrentTime; + event_curserial = 0; } static void event_handle_root(XEvent *e) @@ -782,6 +769,9 @@ static void event_handle_root(XEvent *e) ob_restart(); else if (e->xclient.data.l[0] == 3) ob_exit(0); + } else if (msgtype == prop_atoms.wm_protocols) { + if ((Atom)e->xclient.data.l[0] == prop_atoms.net_wm_ping) + ping_got_pong(e->xclient.data.l[1]); } break; case PropertyNotify: @@ -816,6 +806,7 @@ void event_enter_client(ObClient *client) data = g_new(ObFocusDelayData, 1); data->client = client; data->time = event_curtime; + data->serial = event_curserial; ob_main_loop_timeout_add(ob_main_loop, config_focus_delay * 1000, @@ -825,6 +816,7 @@ void event_enter_client(ObClient *client) ObFocusDelayData data; data.client = client; data.time = event_curtime; + data.serial = event_curserial; focus_delay_func(&data); } } @@ -1689,6 +1681,8 @@ static gboolean event_handle_menu_keyboard(XEvent *ev) /* Allow control while going thru the menu */ else if (ev->type == KeyPress && (state & ~ControlMask) == 0) { + frame->got_press = TRUE; + if (keycode == ob_keycode(OB_KEY_ESCAPE)) { menu_frame_hide_all(); ret = TRUE; @@ -1722,7 +1716,7 @@ static gboolean event_handle_menu_keyboard(XEvent *ev) Allow ControlMask only, and don't bother if the menu is empty */ else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 && - frame->entries) + frame->entries && frame->got_press) { if (keycode == ob_keycode(OB_KEY_RETURN)) { /* Enter runs the active item or goes into the submenu. @@ -1912,6 +1906,7 @@ static gboolean focus_delay_func(gpointer data) if (menu_frame_visible || moveresize_in_progress) return FALSE; event_curtime = d->time; + event_curserial = d->serial; if (client_focus(d->client) && config_focus_raise) stacking_raise(CLIENT_AS_WINDOW(d->client)); event_curtime = old; @@ -1924,7 +1919,7 @@ static void focus_delay_client_dest(ObClient *client, gpointer data) client, FALSE); } -void event_halt_focus_delay(gulong serial) +void event_halt_focus_delay(void) { /* ignore all enter events up till the event which caused this to occur */ if (event_curserial) event_ignore_enter_range(1, event_curserial); @@ -1933,9 +1928,7 @@ void event_halt_focus_delay(gulong serial) gulong event_start_ignore_all_enters(void) { - /* increment the serial so we don't ignore events we weren't meant to */ - XSync(ob_display, FALSE); - return LastKnownRequestProcessed(ob_display); + return NextRequest(ob_display); } static void event_ignore_enter_range(gulong start, gulong end) @@ -1954,12 +1947,18 @@ 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) { - 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) @@ -2007,6 +2006,8 @@ void event_cancel_all_key_grabs(void) } else ungrab_passive_key(); + + XSync(ob_display, FALSE); } gboolean event_time_after(Time t1, Time t2)