X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=2d47fd328a09c55ec9f2a3f01a5e398cd8fba2ee;hb=3fcba81510c98ac517afbab0ba60ced3d30f202f;hp=cf057fc88d0c49be1082c24ea2746e9b7e2ddd4e;hpb=6de84db80daaef511a1b22be0179dcbf1a55fe07;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index cf057fc8..2d47fd32 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -24,10 +24,6 @@ #include #include -#ifdef USE_LIBSN -# include -#endif - #ifdef HAVE_SYS_SELECT_H # include #endif @@ -46,6 +42,9 @@ 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 gboolean focus_delay_func(gpointer data); +static void focus_delay_client_dest(gpointer data); + #define INVALID_FOCUSIN(e) ((e)->xfocus.detail == NotifyInferior || \ (e)->xfocus.detail == NotifyAncestor || \ (e)->xfocus.detail > NotifyNonlinearVirtual) @@ -69,6 +68,8 @@ static const int mask_table[] = { }; static int mask_table_size; +static ObClient *focus_delay_client; + #ifdef USE_SM static void ice_handler(int fd, gpointer conn) { @@ -91,18 +92,10 @@ static void ice_watch(IceConn conn, IcePointer data, Bool opening, } #endif -#ifdef USE_LIBSN -static void sn_handler(const XEvent *e, gpointer display) +void event_startup(gboolean reconfig) { - XEvent ec; - ec = *e; - sn_display_process_event(display, &ec); -} -#endif + if (reconfig) return; - -void event_startup() -{ mask_table_size = sizeof(mask_table) / sizeof(mask_table[0]); /* get lock masks that are defined by the display (not constant) */ @@ -134,13 +127,14 @@ void event_startup() IceAddConnectionWatch(ice_watch, NULL); #endif -#ifdef USE_LIBSN - ob_main_loop_x_add(ob_main_loop, sn_handler, ob_sn_display, NULL); -#endif + client_add_destructor(focus_delay_client_dest); } -void event_shutdown() +void event_shutdown(gboolean reconfig) { + if (reconfig) return; + + client_remove_destructor(focus_delay_client_dest); XFreeModifiermap(modmap); } @@ -319,13 +313,13 @@ static gboolean event_ignore(XEvent *e, ObClient *client) gboolean fallback = TRUE; while (TRUE) { - if (!XCheckTypedWindowEvent(ob_display, FocusOut, - e->xfocus.window,&fe)) + if (!XCheckTypedWindowEvent(ob_display, e->xfocus.window, + FocusOut, &fe)) if (!XCheckTypedEvent(ob_display, FocusIn, &fe)) break; if (fe.type == FocusOut) { #ifdef DEBUG_FOCUS - ob_debug("found pending FocusOut"); + ob_debug("found pending FocusOut\n"); #endif if (!INVALID_FOCUSOUT(&fe)) { /* if there is a VALID FocusOut still coming, don't @@ -336,7 +330,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client) } } else { #ifdef DEBUG_FOCUS - ob_debug("found pending FocusIn"); + ob_debug("found pending FocusIn\n"); #endif /* is the focused window getting a FocusOut/In back to itself? @@ -354,7 +348,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client) if (focus_client) { #ifdef DEBUG_FOCUS ob_debug("focused window got an Out/In back to " - "itself IGNORED both"); + "itself IGNORED both\n"); #endif return TRUE; } else { @@ -362,7 +356,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client) #ifdef DEBUG_FOCUS ob_debug("focused window got an Out/In back to " "itself but focus_client was null " - "IGNORED just the Out"); + "IGNORED just the Out\n"); #endif return TRUE; } @@ -382,7 +376,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client) if (fallback) { #ifdef DEBUG_FOCUS ob_debug("no valid FocusIn and no FocusOut events found, " - "falling back"); + "falling back\n"); #endif focus_fallback(OB_FOCUS_FALLBACK_NOFOCUS); } @@ -398,7 +392,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client) (e->xcrossing.mode == NotifyUngrab && e->xcrossing.detail == NotifyVirtual)) { #ifdef DEBUG_FOCUS - ob_debug("%sNotify mode %d detail %d on %lx IGNORED", + ob_debug("%sNotify mode %d detail %d on %lx IGNORED\n", (e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, e->xcrossing.detail, client?client->window:0); @@ -406,7 +400,7 @@ static gboolean event_ignore(XEvent *e, ObClient *client) return TRUE; } #ifdef DEBUG_FOCUS - ob_debug("%sNotify mode %d detail %d on %lx", + ob_debug("%sNotify mode %d detail %d on %lx\n", (e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, e->xcrossing.detail, client?client->window:0); @@ -493,19 +487,20 @@ static void event_process(const XEvent *ec, gpointer data) { if (menu_frame_visible) event_handle_menu(e); - else if (moveresize_in_progress) - moveresize_event(e); else { - ObFrameContext context; + if (!keyboard_process_interactive_grab(e, &client)) { + if (moveresize_in_progress) + moveresize_event(e); - context = frame_context(client, e->xany.window); - - if (!keyboard_process_interactive_grab(e, &client, &context)) { if (e->type == ButtonPress || e->type == ButtonRelease || e->type == MotionNotify) - mouse_event(client, context, e); + mouse_event(client, e); else if (e->type == KeyPress) - keyboard_event(client, e); + /* when in the middle of a focus cycling action, this + causes the window which appears to be focused to be + the one on which the actions will be executed */ + keyboard_event((focus_cycle_target ? + focus_cycle_target : client), e); } } } @@ -648,6 +643,15 @@ static void event_handle_client(ObClient *client, XEvent *e) client->frame->close_hover = FALSE; frame_adjust_state(client->frame); break; + case OB_FRAME_CONTEXT_FRAME: + /* XXX if doing a 'reconfigure' make sure you kill this timer, + maybe all timers.. */ + if (config_focus_delay && client == focus_delay_client) { + ob_main_loop_timeout_remove_data(ob_main_loop, + focus_delay_func, + focus_delay_client); + focus_delay_client = NULL; + } default: break; } @@ -690,7 +694,14 @@ static void event_handle_client(ObClient *client, XEvent *e) ob_debug("EnterNotify on %lx, focusing window\n", client->window); #endif - client_focus(client); + if (config_focus_delay) { + ob_main_loop_timeout_add(ob_main_loop, + config_focus_delay, + focus_delay_func, + client, NULL); + focus_delay_client = client; + } else + client_focus(client); } } break; @@ -845,8 +856,8 @@ static void event_handle_client(ObClient *client, XEvent *e) msgtype = e->xclient.message_type; if (msgtype == prop_atoms.wm_change_state) { /* compress changes into a single change */ - while (XCheckTypedWindowEvent(ob_display, e->type, - client->window, &ce)) { + while (XCheckTypedWindowEvent(ob_display, client->window, + e->type, &ce)) { /* XXX: it would be nice to compress ALL messages of a type, not just messages in a row without other message types between. */ @@ -859,8 +870,8 @@ static void event_handle_client(ObClient *client, XEvent *e) client_set_wm_state(client, e->xclient.data.l[0]); } else if (msgtype == prop_atoms.net_wm_desktop) { /* compress changes into a single change */ - while (XCheckTypedWindowEvent(ob_display, e->type, - client->window, &ce)) { + while (XCheckTypedWindowEvent(ob_display, client->window, + e->type, &ce)) { /* XXX: it would be nice to compress ALL messages of a type, not just messages in a row without other message types between. */ @@ -974,14 +985,38 @@ static void event_handle_client(ObClient *client, XEvent *e) if (!client_validate(client)) break; /* compress changes to a single property into a single change */ - while (XCheckTypedWindowEvent(ob_display, e->type, - client->window, &ce)) { - /* XXX: it would be nice to compress ALL changes to a property, + while (XCheckTypedWindowEvent(ob_display, client->window, + e->type, &ce)) { + Atom a, b; + + /* XXX: it would be nice to compress ALL changes to a property, not just changes in a row without other props between. */ - if (ce.xproperty.atom != e->xproperty.atom) { - XPutBackEvent(ob_display, &ce); - break; - } + + a = ce.xproperty.atom; + b = e->xproperty.atom; + + if (a == b) + continue; + if ((a == prop_atoms.net_wm_name || + a == prop_atoms.wm_name || + a == prop_atoms.net_wm_icon_name || + a == prop_atoms.wm_icon_name) + && + (b == prop_atoms.net_wm_name || + b == prop_atoms.wm_name || + b == prop_atoms.net_wm_icon_name || + b == prop_atoms.wm_icon_name)) { + continue; + } + if ((a == prop_atoms.net_wm_icon || + a == prop_atoms.kwm_win_icon) + && + (b == prop_atoms.net_wm_icon || + b == prop_atoms.kwm_win_icon)) + continue; + + XPutBackEvent(ob_display, &ce); + break; } msgtype = e->xproperty.atom; @@ -989,24 +1024,22 @@ static void event_handle_client(ObClient *client, XEvent *e) client_update_normal_hints(client); /* normal hints can make a window non-resizable */ client_setup_decor_and_functions(client); - } - else if (msgtype == XA_WM_HINTS) + } else if (msgtype == XA_WM_HINTS) { client_update_wmhints(client); - else if (msgtype == XA_WM_TRANSIENT_FOR) { + } else if (msgtype == XA_WM_TRANSIENT_FOR) { client_update_transient_for(client); client_get_type(client); /* type may have changed, so update the layer */ client_calc_layer(client); client_setup_decor_and_functions(client); - } - else if (msgtype == prop_atoms.net_wm_name || - msgtype == prop_atoms.wm_name || - msgtype == prop_atoms.net_wm_icon_name || - msgtype == prop_atoms.wm_icon_name) + } else if (msgtype == prop_atoms.net_wm_name || + msgtype == prop_atoms.wm_name || + msgtype == prop_atoms.net_wm_icon_name || + msgtype == prop_atoms.wm_icon_name) { client_update_title(client); - else if (msgtype == prop_atoms.wm_class) + } else if (msgtype == prop_atoms.wm_class) { client_update_class(client); - else if (msgtype == prop_atoms.wm_protocols) { + } else if (msgtype == prop_atoms.wm_protocols) { client_update_protocols(client); client_setup_decor_and_functions(client); } @@ -1014,8 +1047,9 @@ static void event_handle_client(ObClient *client, XEvent *e) client_update_strut(client); } else if (msgtype == prop_atoms.net_wm_icon || - msgtype == prop_atoms.kwm_win_icon) + msgtype == prop_atoms.kwm_win_icon) { client_update_icons(client); + } default: ; #ifdef SHAPE @@ -1093,8 +1127,7 @@ static void event_handle_menu(XEvent *ev) else { if ((e = menu_entry_frame_under(ev->xbutton.x_root, ev->xbutton.y_root))) - menu_entry_frame_execute(e, - !(ev->xbutton.state & ControlMask)); + menu_entry_frame_execute(e, ev->xbutton.state); } break; case MotionNotify: @@ -1112,8 +1145,7 @@ static void event_handle_menu(XEvent *ev) else if (ev->xkey.keycode == ob_keycode(OB_KEY_RETURN)) { ObMenuFrame *f; if ((f = find_active_menu())) - menu_entry_frame_execute(f->selected, - !(ev->xkey.state & ControlMask)); + menu_entry_frame_execute(f->selected, ev->xkey.state); } else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) { ObMenuFrame *f; if ((f = find_active_menu()) && f->parent) @@ -1134,3 +1166,19 @@ static void event_handle_menu(XEvent *ev) break; } } + +static gboolean focus_delay_func(gpointer data) +{ + client_focus(focus_delay_client); + return FALSE; /* no repeat */ +} + +static void focus_delay_client_dest(gpointer data) +{ + ObClient *c = data; + if (c == focus_delay_client) { + ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func, + focus_delay_client); + focus_delay_client = NULL; + } +}