X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=9d6ff5fd86f09d8ee9ac24326d84411c10a98347;hb=5d5be2ba2a6e0b3886e0076475ed9d7a2d4ac9ab;hp=5bb0e2a09f4971d207bbde7e57a130e3a2da17b1;hpb=4543c1761a98f3feecf1630f5be78974753ee5f5;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 5bb0e2a0..9d6ff5fd 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -2,7 +2,7 @@ event.c for the Openbox window manager Copyright (c) 2006 Mikael Magnusson - Copyright (c) 2003 Ben Jansens + Copyright (c) 2003-2007 Dana Jansens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,6 +39,7 @@ #include "group.h" #include "stacking.h" #include "extensions.h" +#include "translate.h" #include #include @@ -72,6 +73,7 @@ typedef struct static void event_process(const XEvent *e, gpointer data); static void event_handle_root(XEvent *e); +static void event_handle_menu_shortcut(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); @@ -211,6 +213,13 @@ static Window event_get_window(XEvent *e) window = None; } } else +#endif +#ifdef SYNC + if (extensions_sync && + e->type == extensions_sync_event_basep + XSyncAlarmNotify) + { + window = None; + } else #endif window = e->xany.window; } @@ -244,6 +253,13 @@ static void event_set_curtime(XEvent *e) t = e->xcrossing.time; break; default: +#ifdef SYNC + if (extensions_sync && + e->type == extensions_sync_event_basep + XSyncAlarmNotify) + { + t = ((XSyncAlarmNotifyEvent*)e)->time; + } +#endif /* if more event types are anticipated, get their timestamp explicitly */ break; @@ -537,6 +553,15 @@ static void event_process(const XEvent *ec, gpointer data) e->xconfigurerequest.value_mask, &xwc); xerror_set_ignore(FALSE); } +#ifdef SYNC + else if (extensions_sync && + e->type == extensions_sync_event_basep + XSyncAlarmNotify) + { + XSyncAlarmNotifyEvent *se = (XSyncAlarmNotifyEvent*)e; + if (se->alarm == moveresize_alarm && moveresize_in_progress) + moveresize_event(e); + } +#endif /* user input (action-bound) events */ if (e->type == ButtonPress || e->type == ButtonRelease || @@ -566,7 +591,7 @@ static void event_process(const XEvent *ec, gpointer data) mouse_event(client, e); } else if (e->type == KeyPress) { keyboard_event((focus_cycle_target ? focus_cycle_target : - client), e); + (client ? client : focus_client)), e); } } } @@ -672,9 +697,6 @@ static void event_handle_client(ObClient *client, XEvent *e) ObFrameContext con; switch (e->type) { - case VisibilityNotify: - client->frame->obscured = e->xvisibility.state != VisibilityUnobscured; - break; case ButtonPress: case ButtonRelease: /* Wheel buttons don't draw because they are an instant click, so it @@ -733,12 +755,23 @@ static void event_handle_client(ObClient *client, XEvent *e) frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: + ob_debug_type(OB_DEBUG_FOCUS, + "%sNotify mode %d detail %d on %lx\n", + (e->type == EnterNotify ? "Enter" : "Leave"), + e->xcrossing.mode, + e->xcrossing.detail, (client?client->window:0)); if (keyboard_interactively_grabbed()) break; - if (config_focus_follow && config_focus_delay) + if (config_focus_follow && config_focus_delay && + /* leave inferior events can happen when the mouse goes onto + the window's border and then into the window before the + delay is up */ + e->xcrossing.detail != NotifyInferior) + { ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func, client, FALSE); + } break; default: break; @@ -779,7 +812,9 @@ static void event_handle_client(ObClient *client, XEvent *e) if (keyboard_interactively_grabbed()) break; if (e->xcrossing.mode == NotifyGrab || - e->xcrossing.mode == NotifyUngrab) + e->xcrossing.mode == NotifyUngrab || + /*ignore enters when we're already in the window */ + e->xcrossing.detail == NotifyInferior) { ob_debug_type(OB_DEBUG_FOCUS, "%sNotify mode %d detail %d on %lx IGNORED\n", @@ -1164,9 +1199,17 @@ static void event_handle_client(ObClient *client, XEvent *e) else if (msgtype == prop_atoms.net_wm_user_time) { client_update_user_time(client); } +#ifdef SYNC + else if (msgtype == prop_atoms.net_wm_sync_request_counter) { + client_update_sync_request_counter(client); + } +#endif else if (msgtype == prop_atoms.sm_client_id) { client_update_sm_client_id(client); } + case ColormapNotify: + client_update_colormap(client, e->xcolormap.colormap); + break; default: ; #ifdef SHAPE @@ -1221,7 +1264,7 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e) } } -ObMenuFrame* find_active_menu() +static ObMenuFrame* find_active_menu() { GList *it; ObMenuFrame *ret = NULL; @@ -1235,7 +1278,7 @@ ObMenuFrame* find_active_menu() return ret; } -ObMenuFrame* find_active_or_last_menu() +static ObMenuFrame* find_active_or_last_menu() { ObMenuFrame *ret = NULL; @@ -1245,6 +1288,77 @@ ObMenuFrame* find_active_or_last_menu() return ret; } +static void event_handle_menu_shortcut(XEvent *ev) +{ + gunichar unikey = 0; + ObMenuFrame *frame; + GList *start; + GList *it; + ObMenuEntryFrame *found = NULL; + guint num_found = 0; + + { + const char *key; + if ((key = translate_keycode(ev->xkey.keycode)) == NULL) + return; + unikey = g_utf8_get_char_validated(key, -1); + if (unikey == (gunichar)-1 || unikey == (gunichar)-2 || unikey == 0) + return; + } + + if ((frame = find_active_or_last_menu()) == NULL) + return; + + + if (!frame->entries) + return; /* nothing in the menu anyways */ + + /* start after the selected one */ + start = frame->entries; + if (frame->selected) { + for (it = start; frame->selected != it->data; it = g_list_next(it)) + g_assert(it != NULL); /* nothing was selected? */ + /* next with wraparound */ + start = g_list_next(it); + if (start == NULL) start = frame->entries; + } + + it = start; + do { + ObMenuEntryFrame *e = it->data; + gunichar entrykey = 0; + + if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) + entrykey = e->entry->data.normal.shortcut; + else if (e->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) + entrykey = e->entry->data.submenu.submenu->shortcut; + + if (unikey == entrykey) { + if (found == NULL) found = e; + ++num_found; + } + + /* next with wraparound */ + it = g_list_next(it); + if (it == NULL) it = frame->entries; + } while (it != start); + + if (found) { + if (found->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && + num_found == 1) + { + menu_frame_select(frame, found, TRUE); + usleep(50000); + menu_entry_frame_execute(found, ev->xkey.state, + ev->xkey.time); + } else { + menu_frame_select(frame, found, TRUE); + if (num_found == 1) + menu_frame_select_next(frame->child); + } + } +} + static void event_handle_menu(XEvent *ev) { ObMenuFrame *f; @@ -1266,7 +1380,7 @@ static void event_handle_menu(XEvent *ev) if (e->ignore_enters) --e->ignore_enters; else - menu_frame_select(e->frame, e); + menu_frame_select(e->frame, e, FALSE); } break; case LeaveNotify: @@ -1274,28 +1388,35 @@ static void event_handle_menu(XEvent *ev) (f = find_active_menu()) && f->selected == e && e->entry->type != OB_MENU_ENTRY_TYPE_SUBMENU) { - menu_frame_select(e->frame, NULL); + menu_frame_select(e->frame, NULL, FALSE); } case MotionNotify: if ((e = menu_entry_frame_under(ev->xmotion.x_root, ev->xmotion.y_root))) - menu_frame_select(e->frame, e); + menu_frame_select(e->frame, e, FALSE); break; case KeyPress: if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) - menu_frame_hide_all(); + if ((f = find_active_or_last_menu()) && f->parent) + menu_frame_select(f, NULL, TRUE); + else + menu_frame_hide_all(); 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, - ev->xkey.time); + if ((f = find_active_menu())) { + if (f->child) + menu_frame_select_next(f->child); + else + menu_entry_frame_execute(f->selected, ev->xkey.state, + ev->xkey.time); + } } else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) { ObMenuFrame *f; - if ((f = find_active_or_last_menu()) && f->parent) - menu_frame_select(f, NULL); + if ((f = find_active_or_last_menu())) + menu_frame_select(f, NULL, TRUE); } else if (ev->xkey.keycode == ob_keycode(OB_KEY_RIGHT)) { ObMenuFrame *f; - if ((f = find_active_or_last_menu()) && f->child) + if ((f = find_active_menu()) && f->child) menu_frame_select_next(f->child); } else if (ev->xkey.keycode == ob_keycode(OB_KEY_UP)) { ObMenuFrame *f; @@ -1305,7 +1426,8 @@ static void event_handle_menu(XEvent *ev) ObMenuFrame *f; if ((f = find_active_or_last_menu())) menu_frame_select_next(f); - } + } else + event_handle_menu_shortcut(ev); break; } }