X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=6f819cc1f4c0838524d03fdd590d416e95fb3e23;hb=7c1fb96bd33a97c9be55e5fcfae6cf7d625acbb6;hp=8329f0287b3c35c94b49e52f84c32ae88b3daacf;hpb=5009498d5934944c70b6c520ca45a727800e9528;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 8329f028..6f819cc1 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -79,7 +79,8 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e); static void event_handle_client(ObClient *c, XEvent *e); static void event_handle_group(ObGroup *g, XEvent *e); -static void focus_delay_destroy(gpointer data); +static void focus_delay_dest(gpointer data); +static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2); static gboolean focus_delay_func(gpointer data); static void focus_delay_client_dest(ObClient *client, gpointer data); @@ -105,11 +106,6 @@ static guint ignore_enter_focus = 0; static gboolean menu_can_hide; -static ObFocusDelayData focus_delay_data = { .client = NULL, - .time = CurrentTime }; - - - #ifdef USE_SM static void ice_handler(gint fd, gpointer conn) { @@ -397,17 +393,13 @@ static Bool look_for_focusin(Display *d, XEvent *e, XPointer arg) static gboolean event_ignore(XEvent *e, ObClient *client) { switch(e->type) { - case EnterNotify: - case LeaveNotify: - return keyboard_interactively_grabbed(); case FocusIn: case FocusOut: - /* I don't think this should ever happen with our event masks, but - if it does, we don't want it. */ - if (client == NULL) - return TRUE; - if (!wanted_focusevent(e)) + if (!wanted_focusevent(e)) { + ob_debug_type(OB_DEBUG_FOCUS, "focus event ignored\n"); return TRUE; + } + ob_debug_type(OB_DEBUG_FOCUS, "focus event used;\n"); break; } return FALSE; @@ -489,6 +481,58 @@ static void event_process(const XEvent *ec, gpointer data) { /* crossing events for menu */ event_handle_menu(e); + } else if (e->type == FocusIn) { + if (e->xfocus.detail == NotifyPointerRoot || + e->xfocus.detail == NotifyDetailNone) { + ob_debug_type(OB_DEBUG_FOCUS, "Focus went to root\n"); + /* Focus has been reverted to the root window or nothing, so fall + back to something other than the window which just had it. */ + focus_fallback(FALSE); + } else if (e->xfocus.detail == NotifyInferior) { + ob_debug_type(OB_DEBUG_FOCUS, "Focus went to parent\n"); + /* Focus has been reverted to parent, which is our frame window, + or the root window, so fall back to something other than the + window which had it. */ + focus_fallback(FALSE); + } else if (client && client != focus_client) { + focus_set_client(client); + frame_adjust_focus(client->frame, TRUE); + client_calc_layer(client); + } + } else if (e->type == FocusOut) { + gboolean nomove = FALSE; + XEvent ce; + + ob_debug_type(OB_DEBUG_FOCUS, "FocusOut Event\n"); + + /* Look for the followup FocusIn */ + if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) { + /* There is no FocusIn, this means focus went to a window that + is not being managed, or a window on another screen. */ + ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n"); + } else if (ce.xany.window == e->xany.window) { + /* If focus didn't actually move anywhere, there is nothing to do*/ + nomove = TRUE; + } else { + /* Focus did move, so process the FocusIn event */ + ObEventData ed = { .ignored = FALSE }; + event_process(&ce, &ed); + if (ed.ignored) { + /* 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", + ce.xfocus.window); + focus_fallback(TRUE); + } + } + + if (client && !nomove) { + /* This client is no longer focused, so show that */ + focus_hilite = NULL; + frame_adjust_focus(client->frame, FALSE); + client_calc_layer(client); + } } else if (group) event_handle_group(group, e); else if (client) @@ -543,12 +587,12 @@ static void event_process(const XEvent *ec, gpointer data) ob_main_loop_timeout_add(ob_main_loop, config_menu_hide_delay * 1000, menu_hide_delay_func, - NULL, NULL); + NULL, g_direct_equal, NULL); if (e->type == ButtonPress || e->type == ButtonRelease || - e->type == MotionNotify) + e->type == MotionNotify) { mouse_event(client, e); - else if (e->type == KeyPress) { + } else if (e->type == KeyPress) { keyboard_event((focus_cycle_target ? focus_cycle_target : (focus_hilite ? focus_hilite : client)), e); @@ -628,17 +672,24 @@ void event_enter_client(ObClient *client) if (client_normal(client) && client_can_focus(client)) { if (config_focus_delay) { + ObFocusDelayData *data; + ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func); - focus_delay_data.client = client; - focus_delay_data.time = event_curtime; + data = g_new(ObFocusDelayData, 1); + data->client = client; + data->time = event_curtime; ob_main_loop_timeout_add(ob_main_loop, config_focus_delay, focus_delay_func, - NULL, focus_delay_destroy); - } else - focus_delay_func(NULL); + data, focus_delay_cmp, focus_delay_dest); + } else { + ObFocusDelayData data; + data.client = client; + data.time = event_curtime; + focus_delay_func(&data); + } } } @@ -687,53 +738,6 @@ static void event_handle_client(ObClient *client, XEvent *e) } } break; - case FocusIn: - if (client != focus_client) { - focus_set_client(client); - frame_adjust_focus(client->frame, TRUE); - client_calc_layer(client); - } - break; - case FocusOut: - /* Look for the followup FocusIn */ - if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) { - /* There is no FocusIn, this means focus went to a window that - is not being managed, or a window on another screen. */ - ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n"); - } else if (ce.xany.window == e->xany.window) { - /* If focus didn't actually move anywhere, there is nothing to do*/ - break; - } else if (ce.xfocus.detail == NotifyPointerRoot || - ce.xfocus.detail == NotifyDetailNone) { - ob_debug_type(OB_DEBUG_FOCUS, "Focus went to root\n"); - /* Focus has been reverted to the root window or nothing, so fall - back to something other than the window which just had it. */ - focus_fallback(FALSE); - } else if (ce.xfocus.detail == NotifyInferior) { - ob_debug_type(OB_DEBUG_FOCUS, "Focus went to parent\n"); - /* Focus has been reverted to parent, which is our frame window, - or the root window, so fall back to something other than the - window which had it. */ - focus_fallback(FALSE); - } else { - /* Focus did move, so process the FocusIn event */ - ObEventData ed = { .ignored = FALSE }; - event_process(&ce, &ed); - if (ed.ignored) { - /* 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", - ce.xfocus.window); - focus_fallback(TRUE); - } - } - - /* This client is no longer focused, so show that */ - focus_hilite = NULL; - frame_adjust_focus(client->frame, FALSE); - client_calc_layer(client); - break; case LeaveNotify: con = frame_context(client, e->xcrossing.window); switch (con) { @@ -758,10 +762,12 @@ static void event_handle_client(ObClient *client, XEvent *e) frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: + if (keyboard_interactively_grabbed()) + break; if (config_focus_follow && config_focus_delay) ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func, - client, TRUE); + client, FALSE); break; default: break; @@ -799,6 +805,8 @@ static void event_handle_client(ObClient *client, XEvent *e) frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: + if (keyboard_interactively_grabbed()) + break; if (e->xcrossing.mode == NotifyGrab || e->xcrossing.mode == NotifyUngrab) { @@ -1297,6 +1305,11 @@ static void event_handle_menu(XEvent *ev) { menu_frame_select(e->frame, NULL); } + case MotionNotify: + if ((e = menu_entry_frame_under(ev->xmotion.x_root, + ev->xmotion.y_root))) + menu_frame_select(e->frame, e); + break; case KeyPress: if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) menu_frame_hide_all(); @@ -1332,19 +1345,26 @@ static gboolean menu_hide_delay_func(gpointer data) return FALSE; /* no repeat */ } -static void focus_delay_destroy(gpointer data) +static void focus_delay_dest(gpointer data) +{ + g_free(data); +} + +static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2) { - focus_delay_data.client = NULL; - focus_delay_data.time = CurrentTime; + const ObFocusDelayData *f1 = d1; + return f1->client == d2; } static gboolean focus_delay_func(gpointer data) { + ObFocusDelayData *d = data; Time old = event_curtime; - event_curtime = focus_delay_data.time; - if (focus_client != focus_delay_data.client) { - if (client_focus(focus_delay_data.client) && config_focus_raise) - client_raise(focus_delay_data.client); + + 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 */ @@ -1353,7 +1373,7 @@ static gboolean focus_delay_func(gpointer data) static void focus_delay_client_dest(ObClient *client, gpointer data) { ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func, - client, TRUE); + client, FALSE); } static void event_client_dest(ObClient *client, gpointer data)