# HG changeset patch # User Gerd Moellmann # Date 932593432 0 # Node ID 825f11b1c34d93c64fd7d98bbc8455344a1b9a35 # Parent f1632be03391788d8cac037d29ba158e3b0e997f Ditto. (xmenu_show) [LESSTIF_VERSION]: Add workaround for remaining button grab under LessTif (HAVE_BOXES): Define if USE_X_TOOLKIT. (HAVE_BOXES): Define if using Lucid menus. (single_submenu): Set button_type of menu to BUTTON_TYPE_NONE. (single_submenu): Likewise for panes and menu items. (set_frame_menubar): Set button_type of menu bar to none. (xmenu_show): Likewise. (single_submenu): Set widget values selected slot. (xmenu_show): Likewise. (push_menu_item): Add parameters `type' and `selected'. Store it in menu_items. (MENU_ITEMS_ITEM_TYPE): New. (MENU_ITEMS_ITEM_SELECTED): New. (MENU_ITEMS_ITEM_LENGTH): Increase by two. (popup_get_selection): Use xmalloc/xfree instead of malloc/free. diff -r f1632be03391 -r 825f11b1c34d src/xmenu.c --- a/src/xmenu.c Wed Jul 21 21:43:52 1999 +0000 +++ b/src/xmenu.c Wed Jul 21 21:43:52 1999 +0000 @@ -78,6 +78,10 @@ #endif /* not USE_X_TOOLKIT */ #endif /* HAVE_X_WINDOWS */ +#ifdef USE_MOTIF +#include /* for LESSTIF_VERSION */ +#endif + #define min(x,y) (((x) < (y)) ? (x) : (y)) #define max(x,y) (((x) > (y)) ? (x) : (y)) @@ -111,6 +115,16 @@ void popup_get_selection (); #endif +#ifdef USE_X_TOOLKIT + +/* Define HAVE_BOXES if meus can handle radio and toggle buttons. */ + +#define HAVE_BOXES 1 +#endif + +static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object)); static Lisp_Object xmenu_show (); static void keymap_panes (); static void single_keymap_panes (); @@ -149,7 +163,9 @@ #define MENU_ITEMS_ITEM_VALUE 2 #define MENU_ITEMS_ITEM_EQUIV_KEY 3 #define MENU_ITEMS_ITEM_DEFINITION 4 -#define MENU_ITEMS_ITEM_LENGTH 5 +#define MENU_ITEMS_ITEM_TYPE 5 +#define MENU_ITEMS_ITEM_SELECTED 6 +#define MENU_ITEMS_ITEM_LENGTH 7 static Lisp_Object menu_items; @@ -315,17 +331,17 @@ XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec; } -/* Push one menu item into the current pane. - NAME is the string to display. ENABLE if non-nil means - this item can be selected. KEY is the key generated by - choosing this item, or nil if this item doesn't really have a definition. - DEF is the definition of this item. - EQUIV is the textual description of the keyboard equivalent for - this item (or nil if none). */ +/* Push one menu item into the current pane. NAME is the string to + display. ENABLE if non-nil means this item can be selected. KEY + is the key generated by choosing this item, or nil if this item + doesn't really have a definition. DEF is the definition of this + item. EQUIV is the textual description of the keyboard equivalent + for this item (or nil if none). TYPE is the type of this menu + item, one of nil, `toggle' or `radio'. */ static void -push_menu_item (name, enable, key, def, equiv) - Lisp_Object name, enable, key, def, equiv; +push_menu_item (name, enable, key, def, equiv, type, selected) + Lisp_Object name, enable, key, def, equiv, type, selected; { if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) grow_menu_items (); @@ -335,6 +351,8 @@ XVECTOR (menu_items)->contents[menu_items_used++] = key; XVECTOR (menu_items)->contents[menu_items_used++] = equiv; XVECTOR (menu_items)->contents[menu_items_used++] = def; + XVECTOR (menu_items)->contents[menu_items_used++] = type; + XVECTOR (menu_items)->contents[menu_items_used++] = selected; } /* Look through KEYMAPS, a vector of keymaps that is NMAPS long, @@ -561,7 +579,9 @@ push_menu_item (item_string, enabled, key, XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], - XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]); + XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], + XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], + XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]); #ifdef USE_X_TOOLKIT /* Display a submenu using the toolkit. */ @@ -613,7 +633,7 @@ { item = Fcar (tail); if (STRINGP (item)) - push_menu_item (item, Qnil, Qnil, Qt, Qnil); + push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil); else if (NILP (item)) push_left_right_boundary (); else @@ -621,7 +641,7 @@ CHECK_CONS (item, 0); item1 = Fcar (item); CHECK_STRING (item1, 1); - push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil); + push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil); } } } @@ -1319,7 +1339,7 @@ as opposed to a submenu. */ top_level_items = 1; push_menu_pane (Qnil, Qnil); - push_menu_item (item_name, Qt, item_key, mapvec[i], Qnil); + push_menu_item (item_name, Qt, item_key, mapvec[i], Qnil, Qnil, Qnil); } else single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); @@ -1334,6 +1354,7 @@ wv->name = "menu"; wv->value = 0; wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; first_wv = wv; save_wv = 0; prev_wv = 0; @@ -1400,6 +1421,7 @@ wv->name++; wv->value = 0; wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; } save_wv = wv; prev_wv = 0; @@ -1408,18 +1430,22 @@ else { /* Create a new item within current pane. */ - Lisp_Object item_name, enable, descrip, def; + Lisp_Object item_name, enable, descrip, def, type, selected; item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; descrip = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION]; + type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE]; + selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED]; + #ifndef HAVE_MULTILINGUAL_MENU - if (STRING_MULTIBYTE (item_name)) - item_name = string_make_unibyte (item_name); - if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) - descrip = string_make_unibyte (descrip); + if (STRING_MULTIBYTE (item_name)) + item_name = string_make_unibyte (item_name); + if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) + descrip = string_make_unibyte (descrip); #endif + wv = xmalloc_widget_value (); if (prev_wv) prev_wv->next = wv; @@ -1434,6 +1460,18 @@ as long as pointers have enough bits to hold small integers. */ wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0); wv->enabled = !NILP (enable); + + if (NILP (type)) + wv->button_type = BUTTON_TYPE_NONE; + else if (EQ (type, QCradio)) + wv->button_type = BUTTON_TYPE_RADIO; + else if (EQ (type, QCtoggle)) + wv->button_type = BUTTON_TYPE_TOGGLE; + else + abort (); + + wv->selected = !NILP (selected); + prev_wv = wv; i += MENU_ITEMS_ITEM_LENGTH; @@ -1551,6 +1589,7 @@ wv->name = "menubar"; wv->value = 0; wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; first_wv = wv; if (deep_p) @@ -1623,6 +1662,7 @@ first_wv->contents = wv; /* Don't set wv->name here; GC during the loop might relocate it. */ wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; prev_wv = wv; } @@ -1681,6 +1721,7 @@ wv->name = (char *) XSTRING (string)->data; wv->value = 0; wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; /* This prevents lwlib from assuming this menu item is really supposed to be empty. */ /* The EMACS_INT cast avoids a warning. @@ -1879,6 +1920,7 @@ wv->name = "menu"; wv->value = 0; wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; first_wv = wv; first_pane = 1; @@ -1941,6 +1983,7 @@ wv->name++; wv->value = 0; wv->enabled = 1; + wv->button_type = BUTTON_TYPE_NONE; save_wv = wv; prev_wv = 0; } @@ -1955,19 +1998,22 @@ else { /* Create a new item within current pane. */ - Lisp_Object item_name, enable, descrip, def; + Lisp_Object item_name, enable, descrip, def, type, selected; item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; descrip = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION]; + type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE]; + selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED]; + #ifndef HAVE_MULTILINGUAL_MENU - if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) - item_name = string_make_unibyte (item_name); - if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) - item_name = string_make_unibyte (descrip); + if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) + item_name = string_make_unibyte (item_name); + if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) + item_name = string_make_unibyte (descrip); #endif - + wv = xmalloc_widget_value (); if (prev_wv) prev_wv->next = wv; @@ -1983,6 +2029,18 @@ wv->call_data = (!NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0); wv->enabled = !NILP (enable); + + if (NILP (type)) + wv->button_type = BUTTON_TYPE_NONE; + else if (EQ (type, QCtoggle)) + wv->button_type = BUTTON_TYPE_TOGGLE; + else if (EQ (type, QCradio)) + wv->button_type = BUTTON_TYPE_RADIO; + else + abort (); + + wv->selected = !NILP (selected); + prev_wv = wv; i += MENU_ITEMS_ITEM_LENGTH; @@ -2008,6 +2066,7 @@ #endif wv_title->name = (char *) XSTRING (title)->data; wv_title->enabled = True; + wv_title->button_type = BUTTON_TYPE_NONE; wv_title->next = wv_sep1; first_wv->contents = wv_title; } @@ -2085,6 +2144,17 @@ /* Process events that apply to the menu. */ popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id); +#ifdef LESSTIF_VERSION + /* Nov 1998: For an unknown reason a button grab remains active + after the popup menu has gone. */ + XUngrabButton (XtDisplay (f->output_data.x->widget), + AnyButton, AnyModifier, + XtWindow (f->output_data.x->widget)); + XUngrabButton (XtDisplay (f->output_data.x->edit_widget), + AnyButton, AnyModifier, + XtWindow (f->output_data.x->edit_widget)); +#endif /* LESSTIF_VERSION */ + /* fp turned off the following statement and wrote a comment that it is unnecessary--that the menu has already disappeared. Nowadays the menu disappears ok, all right, but