diff options
Diffstat (limited to 'src/xmenu.c')
-rw-r--r-- | src/xmenu.c | 309 |
1 files changed, 97 insertions, 212 deletions
diff --git a/src/xmenu.c b/src/xmenu.c index 9b1ac540c21..0f69ee28e84 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -110,11 +110,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ static Lisp_Object Qdebug_on_next_call; -#if defined (USE_X_TOOLKIT) || defined (USE_GTK) -static Lisp_Object xdialog_show (struct frame *, bool, Lisp_Object, Lisp_Object, - const char **); -#endif - /* Flag which when set indicates a dialog or menu has been posted by Xt on behalf of one of the widget sets. */ static int popup_activated_flag; @@ -122,7 +117,7 @@ static int popup_activated_flag; #ifdef USE_X_TOOLKIT -static int next_menubar_widget_id; +static LWLIB_ID next_menubar_widget_id; /* Return the frame whose ->output_data.x->id equals ID, or 0 if none. */ @@ -144,53 +139,6 @@ menubar_id_to_frame (LWLIB_ID id) } #endif - -#ifdef HAVE_X_WINDOWS -/* Return the mouse position in *X and *Y. The coordinates are window - relative for the edit window in frame F. - This is for Fx_popup_menu. The mouse_position_hook can not - be used for X, as it returns window relative coordinates - for the window where the mouse is in. This could be the menu bar, - the scroll bar or the edit window. Fx_popup_menu needs to be - sure it is the edit window. */ -void -mouse_position_for_popup (struct frame *f, int *x, int *y) -{ - Window root, dummy_window; - int dummy; - - eassert (FRAME_X_P (f)); - - block_input (); - - XQueryPointer (FRAME_X_DISPLAY (f), - DefaultRootWindow (FRAME_X_DISPLAY (f)), - - /* The root window which contains the pointer. */ - &root, - - /* Window pointer is on, not used */ - &dummy_window, - - /* The position on that root window. */ - x, y, - - /* x/y in dummy_window coordinates, not used. */ - &dummy, &dummy, - - /* Modifier keys and pointer buttons, about which - we don't care. */ - (unsigned int *) &dummy); - - unblock_input (); - - /* xmenu_show expects window coordinates, not root window - coordinates. Translate. */ - *x -= f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f); - *y -= f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f); -} - -#endif /* HAVE_X_WINDOWS */ #ifndef MSDOS @@ -213,9 +161,6 @@ x_menu_set_in_use (int in_use) /* Wait for an X event to arrive or for a timer to expire. */ -#ifndef USE_MOTIF -static -#endif void x_menu_wait_for_event (void *data) { @@ -682,7 +627,6 @@ update_frame_menubar (struct frame *f) xg_update_frame_menubar (f); #else struct x_output *x; - int columns, rows; eassert (FRAME_X_P (f)); @@ -692,10 +636,6 @@ update_frame_menubar (struct frame *f) return; block_input (); - /* Save the size of the frame because the pane widget doesn't accept - to resize itself. So force it. */ - columns = FRAME_COLS (f); - rows = FRAME_LINES (f); /* Do the voodoo which means "I'm changing lots of things, don't try to refigure sizes until I'm done." */ @@ -716,10 +656,16 @@ update_frame_menubar (struct frame *f) XtManageChild (x->edit_widget); lw_refigure_widget (x->column_widget, True); - /* Force the pane widget to resize itself with the right values. */ - EmacsFrameSetCharSize (x->edit_widget, columns, rows); + /* Force the pane widget to resize itself. */ +#ifdef USE_LUCID + /* For reasons I don't know Lucid wants to add one pixel to the frame + height when adding the menu bar. Compensate that here. */ + adjust_frame_size (f, -1, FRAME_TEXT_HEIGHT (f) - 1, 2, 0, Qmenu_bar_lines); +#else + adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines); +#endif /* USE_LUCID */ unblock_input (); -#endif +#endif /* USE_GTK */ } #ifdef USE_LUCID @@ -760,7 +706,7 @@ apply_systemfont_to_menu (struct frame *f, Widget w) void set_frame_menubar (struct frame *f, bool first_time, bool deep_p) { - xt_or_gtk_widget menubar_widget; + xt_or_gtk_widget menubar_widget, old_widget; #ifdef USE_X_TOOLKIT LWLIB_ID id; #endif @@ -773,7 +719,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) eassert (FRAME_X_P (f)); - menubar_widget = f->output_data.x->menubar_widget; + menubar_widget = old_widget = f->output_data.x->menubar_widget; XSETFRAME (Vmenu_updating_frame, f); @@ -793,12 +739,6 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) f->output_data.x->saved_menu_event->type = 0; } -#ifdef USE_GTK - /* If we have detached menus, we must update deep so detached menus - also gets updated. */ - deep_p = deep_p || xg_have_tear_offs (f); -#endif - if (deep_p) { /* Make a widget-value tree representing the entire menu trees. */ @@ -887,12 +827,8 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) /* Convert menu_items into widget_value trees to display the menu. This cannot evaluate Lisp code. */ - wv = xmalloc_widget_value (); - wv->name = "menubar"; - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value ("menubar", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; first_wv = wv; for (i = 0; submenu_start[i] >= 0; i++) @@ -957,12 +893,8 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) /* Make a widget-value tree containing just the top level menu bar strings. */ - wv = xmalloc_widget_value (); - wv->name = "menubar"; - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value ("menubar", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; first_wv = wv; items = FRAME_MENU_BAR_ITEMS (f); @@ -974,12 +906,8 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) if (NILP (string)) break; - wv = xmalloc_widget_value (); - wv->name = SSDATA (string); - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value (SSDATA (string), NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; /* This prevents lwlib from assuming this menu item is really supposed to be empty. */ /* The intptr_t cast avoids a warning. @@ -1090,7 +1018,7 @@ set_frame_menubar (struct frame *f, bool first_time, bool deep_p) #endif /* USE_LUCID */ #endif /* 1 */ - f->output_data.x->menubar_height = menubar_size; + FRAME_MENUBAR_HEIGHT (f) = menubar_size; } #endif /* not USE_GTK */ @@ -1128,12 +1056,18 @@ void free_frame_menubar (struct frame *f) { Widget menubar_widget; +#ifdef USE_MOTIF + /* Motif automatically shrinks the frame in lw_destroy_all_widgets. + If we want to preserve the old height, calculate it now so we can + restore it below. */ + int old_height = FRAME_TEXT_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f); +#endif eassert (FRAME_X_P (f)); menubar_widget = f->output_data.x->menubar_widget; - f->output_data.x->menubar_height = 0; + FRAME_MENUBAR_HEIGHT (f) = 0; if (menubar_widget) { @@ -1165,9 +1099,20 @@ free_frame_menubar (struct frame *f) XtVaGetValues (f->output_data.x->widget, XtNx, &x1, XtNy, &y1, NULL); if (x1 == 0 && y1 == 0) XtVaSetValues (f->output_data.x->widget, XtNx, x0, XtNy, y0, NULL); + if (frame_inhibit_resize (f, 0, Qmenu_bar_lines)) + adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines); + else +#endif /* USE_MOTIF */ + adjust_frame_size (f, -1, -1, 2, 0, Qmenu_bar_lines); + } + else + { +#ifdef USE_MOTIF + if (frame_inhibit_resize (f, 0, Qmenu_bar_lines)) + adjust_frame_size (f, -1, old_height, 1, 0, Qmenu_bar_lines); #endif - x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1); } + unblock_input (); } } @@ -1175,16 +1120,17 @@ free_frame_menubar (struct frame *f) #endif /* USE_X_TOOLKIT || USE_GTK */ -/* xmenu_show actually displays a menu using the panes and items in menu_items +/* x_menu_show actually displays a menu using the panes and items in menu_items and returns the value selected from it. - There are two versions of xmenu_show, one for Xt and one for Xlib. + There are two versions of x_menu_show, one for Xt and one for Xlib. Both assume input is blocked by the caller. */ /* F is the frame the menu is for. X and Y are the frame-relative specified position, relative to the inside upper left corner of the frame F. - FOR_CLICK is true if this menu was invoked for a mouse click. - KEYMAPS is true if this menu was specified with keymaps; + Bitfield MENUFLAGS bits are: + MENU_FOR_CLICK is set if this menu was invoked for a mouse click. + MENU_KEYMAPS is set if this menu was specified with keymaps; in that case, we return a list containing the chosen item's value and perhaps also the pane's prefix. TITLE is the specified menu title. @@ -1339,8 +1285,8 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, /* We need a unique id for each widget handled by the Lucid Widget library. - For the main windows, and popup menus, we use this counter, - which we increment each time after use. This starts from 1<<16. + For the main windows, and popup menus, we use this counter, which we + increment each time after use. This starts from WIDGET_ID_TICK_START. For menu bars, we use numbers starting at 0, counted in next_menubar_widget_id. */ @@ -1352,17 +1298,13 @@ popup_selection_callback (Widget widget, LWLIB_ID id, XtPointer client_data) menu_item_selection = client_data; } -/* ARG is the LWLIB ID of the dialog box, represented - as a Lisp object as (HIGHPART . LOWPART). */ +/* ID is the LWLIB ID of the dialog box. */ static void -pop_down_menu (Lisp_Object arg) +pop_down_menu (int id) { - LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID) - | XINT (XCDR (arg))); - block_input (); - lw_destroy_all_widgets (id); + lw_destroy_all_widgets ((LWLIB_ID) id); unblock_input (); popup_activated_flag = 0; } @@ -1428,11 +1370,9 @@ create_and_show_popup_menu (struct frame *f, widget_value *first_wv, x_activate_timeout_atimer (); { - int fact = 4 * sizeof (LWLIB_ID); ptrdiff_t specpdl_count = SPECPDL_INDEX (); - record_unwind_protect (pop_down_menu, - Fcons (make_number (menu_id >> (fact)), - make_number (menu_id & ~(-1 << (fact))))); + + record_unwind_protect_int (pop_down_menu, (int) menu_id); /* Process events that apply to the menu. */ popup_get_selection (0, FRAME_DISPLAY_INFO (f), menu_id, 1); @@ -1450,8 +1390,8 @@ cleanup_widget_value_tree (void *arg) } Lisp_Object -xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, - Lisp_Object title, const char **error_name) +x_menu_show (struct frame *f, int x, int y, int menuflags, + Lisp_Object title, const char **error_name) { int i; widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; @@ -1479,12 +1419,8 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, /* Create a tree of widget_value objects representing the panes and their items. */ - wv = xmalloc_widget_value (); - wv->name = "menu"; - wv->value = 0; - wv->enabled = 1; + wv = make_widget_value ("menu", NULL, true, Qnil); wv->button_type = BUTTON_TYPE_NONE; - wv->help =Qnil; first_wv = wv; first_pane = 1; @@ -1540,20 +1476,16 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, /* If the pane has a meaningful name, make the pane a top-level menu item with its items as a submenu beneath it. */ - if (!keymaps && strcmp (pane_string, "")) + if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, "")) { - wv = xmalloc_widget_value (); + wv = make_widget_value (pane_string, NULL, true, Qnil); if (save_wv) save_wv->next = wv; else first_wv->contents = wv; - wv->name = (char *) pane_string; - if (keymaps && !NILP (prefix)) + if ((menuflags & MENU_KEYMAPS) && !NILP (prefix)) wv->name++; - wv->value = 0; - wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; - wv->help = Qnil; save_wv = wv; prev_wv = 0; } @@ -1591,20 +1523,18 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, } #endif /* not HAVE_MULTILINGUAL_MENU */ - wv = xmalloc_widget_value (); + wv = make_widget_value (SSDATA (item_name), NULL, !NILP (enable), + STRINGP (help) ? help : Qnil); if (prev_wv) prev_wv->next = wv; else save_wv->contents = wv; - wv->name = SSDATA (item_name); if (!NILP (descrip)) wv->key = SSDATA (descrip); - wv->value = 0; /* If this item has a null value, make the call_data null so that it won't display a box when the mouse is on it. */ wv->call_data = !NILP (def) ? aref_addr (menu_items, i) : 0; - wv->enabled = !NILP (enable); if (NILP (type)) wv->button_type = BUTTON_TYPE_NONE; @@ -1617,11 +1547,6 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, wv->selected = !NILP (selected); - if (! STRINGP (help)) - help = Qnil; - - wv->help = help; - prev_wv = wv; i += MENU_ITEMS_ITEM_LENGTH; @@ -1631,27 +1556,20 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, /* Deal with the title, if it is non-nil. */ if (!NILP (title)) { - widget_value *wv_title = xmalloc_widget_value (); - widget_value *wv_sep1 = xmalloc_widget_value (); - widget_value *wv_sep2 = xmalloc_widget_value (); + widget_value *wv_title; + widget_value *wv_sep1 = make_widget_value ("--", NULL, false, Qnil); + widget_value *wv_sep2 = make_widget_value ("--", NULL, false, Qnil); - wv_sep2->name = "--"; wv_sep2->next = first_wv->contents; - wv_sep2->help = Qnil; - - wv_sep1->name = "--"; wv_sep1->next = wv_sep2; - wv_sep1->help = Qnil; #ifndef HAVE_MULTILINGUAL_MENU if (STRING_MULTIBYTE (title)) title = ENCODE_MENU_STRING (title); #endif - wv_title->name = SSDATA (title); - wv_title->enabled = true; + wv_title = make_widget_value (SSDATA (title), NULL, true, Qnil); wv_title->button_type = BUTTON_TYPE_NONE; - wv_title->help = Qnil; wv_title->next = wv_sep1; first_wv->contents = wv_title; } @@ -1664,7 +1582,8 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv); /* Actually create and show the menu until popped down. */ - create_and_show_popup_menu (f, first_wv, x, y, for_click); + create_and_show_popup_menu (f, first_wv, x, y, + menuflags & MENU_FOR_CLICK); unbind_to (specpdl_count, Qnil); @@ -1705,7 +1624,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); if (menu_item_selection == aref_addr (menu_items, i)) { - if (keymaps) + if (menuflags & MENU_KEYMAPS) { int j; @@ -1723,7 +1642,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, } } } - else if (!for_click) + else if (!(menuflags & MENU_FOR_CLICK)) { unblock_input (); /* Make "Cancel" equivalent to C-g. */ @@ -1819,12 +1738,10 @@ create_and_show_dialog (struct frame *f, widget_value *first_wv) Also handle timers. */ { ptrdiff_t count = SPECPDL_INDEX (); - int fact = 4 * sizeof (LWLIB_ID); /* xdialog_show_unwind is responsible for popping the dialog box down. */ - record_unwind_protect (pop_down_menu, - Fcons (make_number (dialog_id >> (fact)), - make_number (dialog_id & ~(-1 << (fact))))); + + record_unwind_protect_int (pop_down_menu, (int) dialog_id); popup_get_selection (0, FRAME_DISPLAY_INFO (f), dialog_id, 1); @@ -1839,11 +1756,8 @@ static const char * button_names [] = { "button6", "button7", "button8", "button9", "button10" }; static Lisp_Object -xdialog_show (struct frame *f, - bool keymaps, - Lisp_Object title, - Lisp_Object header, - const char **error_name) +x_dialog_show (struct frame *f, Lisp_Object title, + Lisp_Object header, const char **error_name) { int i, nb_buttons=0; char dialog_name[6]; @@ -1870,19 +1784,12 @@ xdialog_show (struct frame *f, /* Create a tree of widget_value objects representing the text label and buttons. */ { - Lisp_Object pane_name, prefix; + Lisp_Object pane_name; const char *pane_string; pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME); - prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX); pane_string = (NILP (pane_name) ? "" : SSDATA (pane_name)); - prev_wv = xmalloc_widget_value (); - prev_wv->value = (char *) pane_string; - if (keymaps && !NILP (prefix)) - prev_wv->name++; - prev_wv->enabled = 1; - prev_wv->name = "message"; - prev_wv->help = Qnil; + prev_wv = make_widget_value ("message", (char *) pane_string, true, Qnil); first_wv = prev_wv; /* Loop over all panes and items, filling in the tree. */ @@ -1918,15 +1825,13 @@ xdialog_show (struct frame *f, return Qnil; } - wv = xmalloc_widget_value (); + wv = make_widget_value (button_names[nb_buttons], + SSDATA (item_name), + !NILP (enable), Qnil); prev_wv->next = wv; - wv->name = (char *) button_names[nb_buttons]; if (!NILP (descrip)) wv->key = SSDATA (descrip); - wv->value = SSDATA (item_name); wv->call_data = aref_addr (menu_items, i); - wv->enabled = !NILP (enable); - wv->help = Qnil; prev_wv = wv; if (! boundary_seen) @@ -1941,9 +1846,7 @@ xdialog_show (struct frame *f, if (! boundary_seen) left_count = nb_buttons - nb_buttons / 2; - wv = xmalloc_widget_value (); - wv->name = dialog_name; - wv->help = Qnil; + wv = make_widget_value (dialog_name, NULL, false, Qnil); /* Frame title: 'Q' = Question, 'I' = Information. Can also have 'E' = Error if, one day, we want @@ -1982,20 +1885,13 @@ xdialog_show (struct frame *f, the proper value. */ if (menu_item_selection != 0) { - Lisp_Object prefix; - - prefix = Qnil; i = 0; while (i < menu_items_used) { Lisp_Object entry; if (EQ (AREF (menu_items, i), Qt)) - { - prefix - = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); - i += MENU_ITEMS_PANE_LENGTH; - } + i += MENU_ITEMS_PANE_LENGTH; else if (EQ (AREF (menu_items, i), Qquote)) { /* This is the boundary between left-side elts and @@ -2007,15 +1903,7 @@ xdialog_show (struct frame *f, entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); if (menu_item_selection == aref_addr (menu_items, i)) - { - if (keymaps != 0) - { - entry = list1 (entry); - if (!NILP (prefix)) - entry = Fcons (prefix, entry); - } - return entry; - } + return entry; i += MENU_ITEMS_ITEM_LENGTH; } } @@ -2052,7 +1940,7 @@ xw_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents) /* Display them in a dialog box. */ block_input (); - selection = xdialog_show (f, 0, title, header, &error_name); + selection = x_dialog_show (f, title, header, &error_name); unblock_input (); unbind_to (specpdl_count, Qnil); @@ -2090,7 +1978,7 @@ menu_help_callback (char const *help_string, int pane, int item) if (EQ (first_item[0], Qt)) pane_name = first_item[MENU_ITEMS_PANE_NAME]; else if (EQ (first_item[0], Qquote)) - /* This shouldn't happen, see xmenu_show. */ + /* This shouldn't happen, see x_menu_show. */ pane_name = empty_unibyte_string; else pane_name = first_item[MENU_ITEMS_ITEM_NAME]; @@ -2132,13 +2020,14 @@ pop_down_menu (Lisp_Object arg) Lisp_Object -xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, - Lisp_Object title, const char **error_name) +x_menu_show (struct frame *f, int x, int y, int menuflags, + Lisp_Object title, const char **error_name) { Window root; XMenu *menu; int pane, selidx, lpane, status; - Lisp_Object entry, pane_prefix; + Lisp_Object entry = Qnil; + Lisp_Object pane_prefix; char *datap; int ulx, uly, width, height; int dispwidth, dispheight; @@ -2160,6 +2049,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, return Qnil; } + USE_SAFE_ALLOCA; block_input (); /* Figure out which root window F is on. */ @@ -2172,8 +2062,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, if (menu == NULL) { *error_name = "Can't create menu"; - unblock_input (); - return Qnil; + goto return_entry; } /* Don't GC while we prepare and show the menu, @@ -2208,7 +2097,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); pane_string = (NILP (pane_name) ? "" : SSDATA (pane_name)); - if (keymaps && !NILP (prefix)) + if ((menuflags & MENU_KEYMAPS) && !NILP (prefix)) pane_string++; lpane = XMenuAddPane (FRAME_X_DISPLAY (f), menu, pane_string, TRUE); @@ -2216,8 +2105,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, { XMenuDestroy (FRAME_X_DISPLAY (f), menu); *error_name = "Can't create pane"; - unblock_input (); - return Qnil; + goto return_entry; } i += MENU_ITEMS_PANE_LENGTH; @@ -2261,9 +2149,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, if (!NILP (descrip)) { - /* if alloca is fast, use that to make the space, - to reduce gc needs. */ - item_data = alloca (maxwidth + SBYTES (descrip) + 1); + item_data = SAFE_ALLOCA (maxwidth + SBYTES (descrip) + 1); memcpy (item_data, SSDATA (item_name), SBYTES (item_name)); for (j = SCHARS (item_name); j < maxwidth; j++) item_data[j] = ' '; @@ -2281,8 +2167,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, { XMenuDestroy (FRAME_X_DISPLAY (f), menu); *error_name = "Can't add selection to menu"; - unblock_input (); - return Qnil; + goto return_entry; } i += MENU_ITEMS_ITEM_LENGTH; lines++; @@ -2331,7 +2216,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, if (ulx < 0) x -= ulx; if (uly < 0) y -= uly; - if (! for_click) + if (!(menuflags & MENU_FOR_CLICK)) { /* If position was not given by a mouse click, adjust so upper left corner of the menu as a whole ends up at given coordinates. This @@ -2356,7 +2241,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx, x, y, ButtonReleaseMask, &datap, menu_help_callback); - entry = pane_prefix = Qnil; + pane_prefix = Qnil; switch (status) { @@ -2385,7 +2270,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, { entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); - if (keymaps) + if (menuflags & MENU_KEYMAPS) { entry = list1 (entry); if (!NILP (pane_prefix)) @@ -2407,7 +2292,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, case XM_NO_SELECT: /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means the menu was invoked with a mouse event as POSITION). */ - if (! for_click) + if (!(menuflags & MENU_FOR_CLICK)) { unblock_input (); Fsignal (Qquit, Qnil); @@ -2415,10 +2300,10 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, break; } + return_entry: unblock_input (); - unbind_to (specpdl_count, Qnil); - - return entry; + SAFE_FREE (); + return unbind_to (specpdl_count, entry); } #endif /* not USE_X_TOOLKIT */ @@ -2446,13 +2331,13 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_ void syms_of_xmenu (void) { - DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); - #ifdef USE_X_TOOLKIT - widget_id_tick = (1<<16); + enum { WIDGET_ID_TICK_START = 1 << 16 }; + widget_id_tick = WIDGET_ID_TICK_START; next_menubar_widget_id = 1; #endif + DEFSYM (Qdebug_on_next_call, "debug-on-next-call"); defsubr (&Smenu_or_popup_active_p); #if defined (USE_GTK) || defined (USE_X_TOOLKIT) |