From: Dana Jansens Date: Fri, 8 Jan 2010 15:22:30 +0000 (-0500) Subject: Merge branch 'backport' into work X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=73575c10ce3ede1637e4f959b56e1f7d5f110b91;p=chaz%2Fopenbox Merge branch 'backport' into work Conflicts: Makefile.am openbox/actions/focus.c openbox/config.c openbox/event.c openbox/menuframe.c --- 73575c10ce3ede1637e4f959b56e1f7d5f110b91 diff --cc Makefile.am index 45a3bd2f,14786f57..9617a1ca --- a/Makefile.am +++ b/Makefile.am @@@ -501,10 -493,10 +501,12 @@@ dist_noinst_DATA = doc/openbox-gnome-session.1.in \ doc/openbox-kde-session.1.sgml \ doc/openbox-kde-session.1.in \ + doc/obxprop.1.sgml \ + doc/obxprop.1.in \ - render/obrender-3.0.pc.in \ - parser/obparser-3.0.pc.in \ + obrender/version.h.in \ + obrender/obrender-3.5.pc.in \ + obt/obt-3.5.pc.in \ + obt/version.h.in \ tools/themeupdate/themeupdate.py \ tests/hideshow.py \ tests/Makefile \ diff --cc openbox/actions/focus.c index 40c2c80d,1b544910..8bae49c7 --- a/openbox/actions/focus.c +++ b/openbox/actions/focus.c @@@ -6,9 -6,11 +6,10 @@@ typedef struct { gboolean here; + gboolean stop_int; } Options; -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node); -static void free_func(gpointer options); +static gpointer setup_func(xmlNodePtr node); static gboolean run_func(ObActionsData *data, gpointer options); void action_focus_startup(void) @@@ -22,9 -28,12 +23,12 @@@ static gpointer setup_func(xmlNodePtr n Options *o; o = g_new0(Options, 1); + o->stop_int = TRUE; - if ((n = parse_find_node("here", node))) - o->here = parse_bool(doc, n); - if ((n = parse_find_node("stopInteractive", node))) - o->stop_int = parse_bool(doc, n); + if ((n = obt_xml_find_node(node, "here"))) + o->here = obt_xml_node_bool(n); ++ if ((n = obt_xml_find_node(node, "stopInteractive"))) ++ o->stop_int = obt_xml_node_bool(n); return o; } diff --cc openbox/config.c index 92445517,240606a4..0241e3f4 --- a/openbox/config.c +++ b/openbox/config.c @@@ -807,21 -807,23 +808,23 @@@ static void parse_menu(xmlNodePtr node xmlNodePtr n; node = node->children; - if ((n = parse_find_node("hideDelay", node))) - config_menu_hide_delay = parse_int(doc, n); - if ((n = parse_find_node("middle", node))) - config_menu_middle = parse_bool(doc, n); - if ((n = parse_find_node("submenuShowDelay", node))) - config_submenu_show_delay = parse_int(doc, n); - if ((n = parse_find_node("submenuHideDelay", node))) - config_submenu_hide_delay = parse_int(doc, n); - if ((n = parse_find_node("applicationIcons", node))) - config_menu_client_list_icons = parse_bool(doc, n); - if ((n = parse_find_node("manageDesktops", node))) - config_menu_manage_desktops = parse_bool(doc, n); - - while ((node = parse_find_node("file", node))) { - gchar *c = parse_string(doc, node); + if ((n = obt_xml_find_node(node, "hideDelay"))) + config_menu_hide_delay = obt_xml_node_int(n); + if ((n = obt_xml_find_node(node, "middle"))) + config_menu_middle = obt_xml_node_bool(n); + if ((n = obt_xml_find_node(node, "submenuShowDelay"))) + config_submenu_show_delay = obt_xml_node_int(n); ++ if ((n = obt_xml_find_node(node, "submenuHideDelay"))) ++ config_submenu_hide_delay = obt_xml_node_int(n); + if ((n = obt_xml_find_node(node, "applicationIcons"))) + config_menu_client_list_icons = obt_xml_node_bool(n); + if ((n = obt_xml_find_node(node, "manageDesktops"))) + config_menu_manage_desktops = obt_xml_node_bool(n); + + while ((node = obt_xml_find_node(node, "file"))) { + gchar *c = obt_xml_node_string(node); config_menu_files = g_slist_append(config_menu_files, - parse_expand_tilde(c)); + obt_paths_expand_tilde(c)); g_free(c); node = node->next; } diff --cc openbox/event.c index 2f853fbb,ad9dade6..5127c28f --- a/openbox/event.c +++ b/openbox/event.c @@@ -1742,160 -1674,130 +1742,165 @@@ static gboolean event_handle_prompt(ObP return FALSE; } -static gboolean event_handle_menu_keyboard(XEvent *ev) +static gboolean event_handle_menu_input(XEvent *ev) { - guint keycode, state; - gunichar unikey; - ObMenuFrame *frame; gboolean ret = FALSE; - keycode = ev->xkey.keycode; - state = ev->xkey.state; - unikey = translate_unichar(keycode); + if (ev->type == ButtonRelease || ev->type == ButtonPress) { + ObMenuEntryFrame *e; - frame = find_active_or_last_menu(); - if (frame == NULL) - g_assert_not_reached(); /* there is no active menu */ + if (menu_hide_delay_reached() && + (ev->xbutton.button < 4 || ev->xbutton.button > 5)) + { + if ((e = menu_entry_frame_under(ev->xbutton.x_root, + ev->xbutton.y_root))) + { + if (ev->type == ButtonPress && e->frame->child) + menu_frame_select(e->frame->child, NULL, TRUE); + menu_frame_select(e->frame, e, TRUE); + if (ev->type == ButtonRelease) + menu_entry_frame_execute(e, ev->xbutton.state); + } + else if (ev->type == ButtonRelease) + menu_frame_hide_all(); + } + ret = TRUE; + } + else if (ev->type == MotionNotify) { + ObMenuFrame *f; + ObMenuEntryFrame *e; - /* Allow control while going thru the menu */ - else if (ev->type == KeyPress && (state & ~ControlMask) == 0) { - frame->got_press = TRUE; + if ((e = menu_entry_frame_under(ev->xmotion.x_root, + ev->xmotion.y_root))) + if (!(f = find_active_menu()) || + f == e->frame || + f->parent == e->frame || + f->child == e->frame) + menu_frame_select(e->frame, e, FALSE); + } + else if (ev->type == KeyPress || ev->type == KeyRelease) { + guint keycode, state; + gunichar unikey; + ObMenuFrame *frame; - if (ob_keycode_match(keycode, OB_KEY_ESCAPE)) { - menu_frame_hide_all(); - ret = TRUE; - } + keycode = ev->xkey.keycode; + state = ev->xkey.state; + unikey = obt_keyboard_keycode_to_unichar(keycode); + + frame = find_active_or_last_menu(); + if (frame == NULL) + g_assert_not_reached(); /* there is no active menu */ - else if (ob_keycode_match(keycode, OB_KEY_LEFT)) { - /* Left goes to the parent menu */ - if (frame->parent) { - /* remove focus from the child */ - menu_frame_select(frame, NULL, TRUE); - /* and put it in the parent */ - menu_frame_select(frame->parent, frame->parent->selected, - TRUE); + /* Allow control while going thru the menu */ + else if (ev->type == KeyPress && (state & ~ControlMask) == 0) { + frame->got_press = TRUE; + + if (ob_keycode_match(keycode, OB_KEY_ESCAPE)) { + menu_frame_hide_all(); + ret = TRUE; } - ret = TRUE; - } - else if (ob_keycode_match(keycode, OB_KEY_RIGHT)) { - /* Right goes to the selected submenu */ - if (frame->child) menu_frame_select_next(frame->child); - ret = TRUE; - } + else if (ob_keycode_match(keycode, OB_KEY_LEFT)) { + /* Left goes to the parent menu */ - if (frame->parent) ++ if (frame->parent) { ++ /* remove focus from the child */ + menu_frame_select(frame, NULL, TRUE); ++ /* and put it in the parent */ ++ menu_frame_select(frame->parent, frame->parent->selected, ++ TRUE); ++ } + ret = TRUE; + } - else if (ob_keycode_match(keycode, OB_KEY_UP)) { - menu_frame_select_previous(frame); - ret = TRUE; - } + else if (ob_keycode_match(keycode, OB_KEY_RIGHT)) { + /* Right goes to the selected submenu */ + if (frame->child) menu_frame_select_next(frame->child); + ret = TRUE; + } + + else if (ob_keycode_match(keycode, OB_KEY_UP)) { + menu_frame_select_previous(frame); + ret = TRUE; + } - else if (ob_keycode_match(keycode, OB_KEY_DOWN)) { - menu_frame_select_next(frame); - ret = TRUE; + else if (ob_keycode_match(keycode, OB_KEY_DOWN)) { + menu_frame_select_next(frame); + ret = TRUE; + } } - } - /* Use KeyRelease events for running things so that the key release doesn't - get sent to the focused application. + /* Use KeyRelease events for running things so that the key release + doesn't get sent to the focused application. - Allow ControlMask only, and don't bother if the menu is empty */ - else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 && - frame->entries && frame->got_press) - { - if (ob_keycode_match(keycode, OB_KEY_RETURN)) { - /* Enter runs the active item or goes into the submenu. - Control-Enter runs it without closing the menu. */ - if (frame->child) - menu_frame_select_next(frame->child); - else if (frame->selected) - menu_entry_frame_execute(frame->selected, state); - - ret = TRUE; - } + Allow ControlMask only, and don't bother if the menu is empty */ + else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 && + frame->entries && frame->got_press) + { + if (ob_keycode_match(keycode, OB_KEY_RETURN)) { + /* Enter runs the active item or goes into the submenu. + Control-Enter runs it without closing the menu. */ + if (frame->child) + menu_frame_select_next(frame->child); + else if (frame->selected) + menu_entry_frame_execute(frame->selected, state); - /* keyboard accelerator shortcuts. (if it was a valid key) */ - else if (unikey != 0) { - GList *start; - GList *it; - ObMenuEntryFrame *found = NULL; - guint num_found = 0; - - /* 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; + ret = TRUE; } - it = start; - do { - ObMenuEntryFrame *e = it->data; - gunichar entrykey = 0; + /* keyboard accelerator shortcuts. (if it was a valid key) */ + else if (unikey != 0) { + GList *start; + GList *it; + ObMenuEntryFrame *found = NULL; + guint num_found = 0; + + /* 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 (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; - } + 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); + /* 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); /* highlight the item for a short bit so the - user can see what happened */ - menu_entry_frame_execute(found, state); - } else { - menu_frame_select(frame, found, TRUE); - if (num_found == 1) - menu_frame_select_next(frame->child); - } + if (found) { + if (found->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && + num_found == 1) + { + menu_frame_select(frame, found, TRUE); + usleep(50000); /* highlight the item for a short bit so + the user can see what happened */ + menu_entry_frame_execute(found, state); + } else { + menu_frame_select(frame, found, TRUE); + if (num_found == 1) + menu_frame_select_next(frame->child); + } - ret = TRUE; + ret = TRUE; + } } } } @@@ -1903,7 -1805,16 +1908,16 @@@ return ret; } + static Bool event_look_for_menu_enter(Display *d, XEvent *ev, XPointer arg) + { + ObMenuFrame *f = (ObMenuFrame*)arg; + ObMenuEntryFrame *e; + return ev->type == EnterNotify && + (e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window)) && + !e->ignore_enters && e->frame == f; + } + -static gboolean event_handle_menu(XEvent *ev) +static void event_handle_menu(ObMenuFrame *frame, XEvent *ev) { ObMenuFrame *f; ObMenuEntryFrame *e; @@@ -1925,14 -1851,16 +1939,16 @@@ if (ev->xcrossing.detail == NotifyInferior) break; - if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window)) && - (f = find_active_menu()) && f->selected == e) + if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window))) { - ObMenuEntryFrame *u = menu_entry_frame_under(ev->xcrossing.x_root, - ev->xcrossing.y_root); - /* if we're just going from one entry in the menu to the next, - don't unselect stuff first */ - if (!u || e->frame != u->frame) + XEvent ce; + + /* check if an EnterNotify event is coming, and if not, then select + nothing in the menu */ - if (XCheckIfEvent(ob_display, &ce, event_look_for_menu_enter, ++ if (XCheckIfEvent(obt_display, &ce, event_look_for_menu_enter, + (XPointer)e->frame)) - XPutBackEvent(ob_display, &ce); ++ XPutBackEvent(obt_display, &ce); + else menu_frame_select(e->frame, NULL, FALSE); } break; diff --cc openbox/menuframe.c index ee374de5,076fe6ef..57f29438 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@@ -92,10 -94,9 +93,9 @@@ ObMenuFrame* menu_frame_new(ObMenu *men XSetWindowAttributes attr; self = g_new0(ObMenuFrame, 1); - self->type = Window_Menu; + self->obwin.type = OB_WINDOW_CLASS_MENUFRAME; self->menu = menu; self->selected = NULL; - self->open_submenu = NULL; self->client = client; self->direction_right = TRUE; self->show_from = show_from; @@@ -985,6 -974,15 +985,15 @@@ gboolean menu_frame_show_topmenu(ObMenu return TRUE; } + /*! Stop hiding an open submenu. + @child The OnMenuFrame of the submenu to be hidden + */ + static void remove_submenu_hide_timeout(ObMenuFrame *child) + { - ob_main_loop_timeout_remove_data(ob_main_loop, submenu_hide_timeout, - child, FALSE); ++ obt_main_loop_timeout_remove_data(ob_main_loop, submenu_hide_timeout, ++ child, FALSE); + } + gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent, ObMenuEntryFrame *parent_entry) { @@@ -1071,11 -1073,7 +1084,7 @@@ void menu_frame_hide_all(void if (config_submenu_show_delay) { /* remove any submenu open requests */ - obt_main_loop_timeout_remove(ob_main_loop, - menu_entry_frame_submenu_show_timeout); - /* remove any submenu close delays */ - obt_main_loop_timeout_remove(ob_main_loop, - menu_entry_frame_submenu_hide_timeout); - ob_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout); ++ obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout); } if ((it = g_list_last(menu_frame_visible))) menu_frame_hide(it->data); @@@ -1089,13 -1087,8 +1098,8 @@@ void menu_frame_hide_all_client(ObClien if (f->client == client) { if (config_submenu_show_delay) { /* remove any submenu open requests */ - obt_main_loop_timeout_remove - (ob_main_loop, - menu_entry_frame_submenu_show_timeout); - /* remove any submenu close delays */ - obt_main_loop_timeout_remove - (ob_main_loop, - menu_entry_frame_submenu_hide_timeout); - ob_main_loop_timeout_remove(ob_main_loop, - submenu_show_timeout); ++ obt_main_loop_timeout_remove(ob_main_loop, ++ submenu_show_timeout); } menu_frame_hide(f); } @@@ -1167,19 -1170,7 +1181,7 @@@ void menu_frame_select(ObMenuFrame *sel if (config_submenu_show_delay) { /* remove any submenu open requests */ - obt_main_loop_timeout_remove(ob_main_loop, - menu_entry_frame_submenu_show_timeout); - } - - if (!entry && self->open_submenu) { - /* we moved out of the menu, so move the selection back to the open - submenu */ - entry = self->open_submenu; - oldchild = NULL; - - /* remove any submenu close delays */ - obt_main_loop_timeout_remove(ob_main_loop, - menu_entry_frame_submenu_hide_timeout); - ob_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout); ++ obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout); } self->selected = entry; @@@ -1187,50 -1178,47 +1189,47 @@@ if (old) menu_entry_frame_render(old); - if (oldchild) { - /* there is an open submenu */ - - if (config_submenu_show_delay && !immediate) { - if (entry == self->open_submenu) { - /* we moved onto the entry that has an open submenu, so stop - trying to close the submenu */ - obt_main_loop_timeout_remove - (ob_main_loop, - menu_entry_frame_submenu_hide_timeout); - } - else if (old == self->open_submenu) { - /* we just moved off the entry with an open submenu, so - close the open submenu after a delay */ - obt_main_loop_timeout_add - (ob_main_loop, - config_submenu_show_delay * 1000, - menu_entry_frame_submenu_hide_timeout, - self->child, g_direct_equal, - NULL); - } + if (oldchild_entry) { + /* There is an open submenu */ + if (oldchild_entry == self->selected) { + /* The open submenu has been reselected, so stop hiding the + submenu */ + remove_submenu_hide_timeout(oldchild); + } + else if (oldchild_entry == old) { + /* The open submenu was selected and is no longer, so hide the + submenu */ + if (immediate || config_submenu_hide_delay == 0) + menu_frame_hide(oldchild); + else if (config_submenu_hide_delay > 0) - ob_main_loop_timeout_add(ob_main_loop, - config_submenu_hide_delay * 1000, - submenu_hide_timeout, - oldchild, g_direct_equal, - NULL); ++ obt_main_loop_timeout_add(ob_main_loop, ++ config_submenu_hide_delay * 1000, ++ submenu_hide_timeout, ++ oldchild, g_direct_equal, ++ NULL); } - else - menu_frame_hide(oldchild); } if (self->selected) { menu_entry_frame_render(self->selected); - /* if we've selected a submenu and it wasn't already open, then - show it */ - if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU && - self->selected != self->open_submenu) - { - if (config_submenu_show_delay && !immediate) { - /* initiate a new submenu open request */ - obt_main_loop_timeout_add - (ob_main_loop, - config_submenu_show_delay * 1000, - menu_entry_frame_submenu_show_timeout, - self->selected, g_direct_equal, - NULL); - } else { - menu_entry_frame_show_submenu(self->selected); + if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) { + /* only show if the submenu isn't already showing */ + if (oldchild_entry != self->selected) { + if (immediate || config_submenu_hide_delay == 0) + menu_entry_frame_show_submenu(self->selected); + else if (config_submenu_hide_delay > 0) - ob_main_loop_timeout_add(ob_main_loop, - config_submenu_show_delay * 1000, - submenu_show_timeout, - self->selected, g_direct_equal, - NULL); ++ obt_main_loop_timeout_add(ob_main_loop, ++ config_submenu_show_delay * 1000, ++ submenu_show_timeout, ++ self->selected, g_direct_equal, ++ NULL); + } + /* hide the grandchildren of this menu. and move the cursor to + the current menu */ + else if (immediate && self->child && self->child->child) { + menu_frame_hide(self->child->child); + menu_frame_select(self->child, NULL, TRUE); } } }