X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=e566f01f0c74d348936c70a99ffcd8fc5be6bcea;hb=dbd3e9b6b2b452e853a17352560b5a4b4c568e84;hp=409641df650b82107182476eef55e0064aaf3f2b;hpb=5e27544d073856731363c1be9b132074e13259f6;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 409641df..e566f01f 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -15,6 +15,7 @@ #include "framerender.h" #include "focus.h" #include "moveresize.h" +#include "group.h" #include "stacking.h" #include "extensions.h" #include "event.h" @@ -35,12 +36,18 @@ #include #endif +typedef struct +{ + gboolean ignored; +} ObEventData; + static void event_process(const XEvent *e, gpointer data); static void event_handle_root(XEvent *e); static void event_handle_menu(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_group(ObGroup *g, XEvent *e); static gboolean focus_delay_func(gpointer data); static void focus_delay_client_dest(gpointer data); @@ -287,8 +294,8 @@ static gboolean event_ignore(XEvent *e, ObClient *client) if (INVALID_FOCUSIN(e) || client == NULL) { #ifdef DEBUG_FOCUS - ob_debug("FocusIn on %lx mode %d detail %d IGNORED\n", - e->xfocus.window, e->xfocus.mode, e->xfocus.detail); + ob_debug("FocusIn on %lx mode %d detail %d IGNORED\n", + e->xfocus.window, e->xfocus.mode, e->xfocus.detail); #endif /* says a client was not found for the event (or a valid FocusIn event was not found. @@ -370,14 +377,20 @@ static gboolean event_ignore(XEvent *e, ObClient *client) } } - /* once all the FocusOut's have been dealt with, if there - is a FocusIn still left and it is valid, then use it */ - event_process(&fe, NULL); - /* secret magic way of event_process telling us that no - client was found for the FocusIn event. ^_^ */ - if (fe.xfocus.window != None) { - fallback = FALSE; - break; + { + ObEventData d; + + /* once all the FocusOut's have been dealt with, if + there is a FocusIn still left and it is valid, then + use it */ + event_process(&fe, &d); + if (!d.ignored) { +#ifdef DEBUG_FOCUS + ob_debug("FocusIn was OK, so don't fallback\n"); +#endif + fallback = FALSE; + break; + } } } } @@ -424,43 +437,53 @@ static gboolean event_ignore(XEvent *e, ObClient *client) static void event_process(const XEvent *ec, gpointer data) { Window window; + ObGroup *group = NULL; ObClient *client = NULL; ObDock *dock = NULL; ObDockApp *dockapp = NULL; ObWindow *obwin = NULL; XEvent ee, *e; + ObEventData *ed = data; /* make a copy we can mangle */ ee = *ec; e = ⅇ window = event_get_window(e); - if ((obwin = g_hash_table_lookup(window_map, &window))) { - switch (obwin->type) { - case Window_Dock: - dock = WINDOW_AS_DOCK(obwin); - break; - case Window_DockApp: - dockapp = WINDOW_AS_DOCKAPP(obwin); - break; - case Window_Client: - client = WINDOW_AS_CLIENT(obwin); - break; - case Window_Menu: - case Window_Internal: - /* not to be used for events */ - g_assert_not_reached(); - break; + if (!(e->type == PropertyNotify && + (group = g_hash_table_lookup(group_map, &window)))) + if ((obwin = g_hash_table_lookup(window_map, &window))) { + switch (obwin->type) { + case Window_Dock: + dock = WINDOW_AS_DOCK(obwin); + break; + case Window_DockApp: + dockapp = WINDOW_AS_DOCKAPP(obwin); + break; + case Window_Client: + client = WINDOW_AS_CLIENT(obwin); + break; + case Window_Menu: + case Window_Internal: + /* not to be used for events */ + g_assert_not_reached(); + break; + } } - } event_set_lasttime(e); event_hack_mods(e); - if (event_ignore(e, client)) + if (event_ignore(e, client)) { + if (ed) + ed->ignored = TRUE; return; + } else if (ed) + ed->ignored = FALSE; /* deal with it in the kernel */ - if (client) + if (group) + event_handle_group(group, e); + else if (client) event_handle_client(client, e); else if (dockapp) event_handle_dockapp(dockapp, e); @@ -572,6 +595,16 @@ static void event_handle_root(XEvent *e) } } +static void event_handle_group(ObGroup *group, XEvent *e) +{ + GSList *it; + + g_assert(e->type == PropertyNotify); + + for (it = group->members; it; it = g_slist_next(it)) + event_handle_client(it->data, e); +} + static void event_handle_client(ObClient *client, XEvent *e) { XEvent ce; @@ -1062,6 +1095,9 @@ static void event_handle_client(ObClient *client, XEvent *e) msgtype == prop_atoms.kwm_win_icon) { client_update_icons(client); } + else if (msgtype == prop_atoms.sm_client_id) { + client_update_sm_client_id(client); + } default: ; #ifdef SHAPE @@ -1147,6 +1183,16 @@ static void event_handle_menu(XEvent *ev) ev->xmotion.y_root))) menu_frame_select(f, e); } + { + ObMenuFrame *a; + + a = find_active_menu(); + if (a && a != f && + a->selected->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU) + { + menu_frame_select(a, NULL); + } + } break; case KeyPress: if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))