]> code.delx.au - gnu-emacs/blobdiff - src/xmenu.c
(selection-coding-system): Fix docstring.
[gnu-emacs] / src / xmenu.c
index bb8cb19cbdfec588a57afa47cb885a07ec94e377..24be4fd5cb712ade0fc0cad574a98d542052f562 100644 (file)
@@ -97,10 +97,10 @@ Boston, MA 02110-1301, USA.  */
 #define FALSE 0
 #endif /* no TRUE */
 
-Lisp_Object Vmenu_updating_frame;
-
 Lisp_Object Qdebug_on_next_call;
 
+extern Lisp_Object Vmenu_updating_frame;
+
 extern Lisp_Object Qmenu_bar;
 
 extern Lisp_Object QCtoggle, QCradio;
@@ -327,6 +327,7 @@ restore_menu_items (saved)
   menu_items_n_panes = XINT (XCAR (saved));
   saved = XCDR (saved);  
   menu_items_submenu_depth = XINT (XCAR (saved));
+  return Qnil;
 }
 
 /* Push the whole state of menu_items processing onto the specpdl.
@@ -1181,6 +1182,10 @@ x_menu_set_in_use (in_use)
 {
   menu_items_inuse = in_use ? Qt : Qnil;
   popup_activated_flag = in_use;
+#ifdef USE_X_TOOLKIT
+  if (popup_activated_flag)
+    x_activate_timeout_atimer ();
+#endif
 }
 
 /* Wait for an X event to arrive or for a timer to expire.  */
@@ -1300,9 +1305,124 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers)
     }
 }
 
+DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+       doc: /* Start key navigation of the menu bar in FRAME.
+This initially opens the first menu bar item and you can then navigate with the
+arrow keys, select a menu entry with the return key or cancel with the
+escape key.  If FRAME has no menu bar this function does nothing.
+
+If FRAME is nil or not given, use the selected frame.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  XEvent ev;
+  FRAME_PTR f = check_x_frame (frame);
+  Widget menubar;
+  BLOCK_INPUT;
+
+  if (FRAME_EXTERNAL_MENU_BAR (f))
+    set_frame_menubar (f, 0, 1);
+
+  menubar = FRAME_X_OUTPUT (f)->menubar_widget;
+  if (menubar)
+    {
+      Window child;
+      int error_p = 0;
+
+      x_catch_errors (FRAME_X_DISPLAY (f));
+      memset (&ev, 0, sizeof ev);
+      ev.xbutton.display = FRAME_X_DISPLAY (f);
+      ev.xbutton.window = XtWindow (menubar);
+      ev.xbutton.root = FRAME_X_DISPLAY_INFO (f)->root_window;
+      ev.xbutton.time = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
+      ev.xbutton.button = Button1;
+      ev.xbutton.x = ev.xbutton.y = FRAME_MENUBAR_HEIGHT (f) / 2;
+      ev.xbutton.same_screen = True;
+
+#ifdef USE_MOTIF
+      {
+        Arg al[2];
+        WidgetList list;
+        Cardinal nr;
+        XtSetArg (al[0], XtNchildren, &list);
+        XtSetArg (al[1], XtNnumChildren, &nr);
+        XtGetValues (menubar, al, 2);
+        ev.xbutton.window = XtWindow (list[0]);
+      }
+#endif
+
+      XTranslateCoordinates (FRAME_X_DISPLAY (f),
+                             /* From-window, to-window.  */
+                             ev.xbutton.window, ev.xbutton.root,
+
+                             /* From-position, to-position.  */
+                             ev.xbutton.x, ev.xbutton.y,
+                             &ev.xbutton.x_root, &ev.xbutton.y_root,
+
+                             /* Child of win.  */
+                             &child);
+      error_p = x_had_errors_p (FRAME_X_DISPLAY (f));
+      x_uncatch_errors ();
+
+      if (! error_p)
+        {
+          ev.type = ButtonPress;
+          ev.xbutton.state = 0;
+
+          XtDispatchEvent (&ev);
+          ev.xbutton.type = ButtonRelease;
+          ev.xbutton.state = Button1Mask;
+          XtDispatchEvent (&ev);
+        }
+    }
+
+  UNBLOCK_INPUT;
+
+  return Qnil;
+}
 #endif /* USE_X_TOOLKIT */
 
+
 #ifdef USE_GTK
+DEFUN ("menu-bar-open", Fmenu_bar_open, Smenu_bar_open, 0, 1, "i",
+       doc: /* Start key navigation of the menu bar in FRAME.
+This initially opens the first menu bar item and you can then navigate with the
+arrow keys, select a menu entry with the return key or cancel with the
+escape key.  If FRAME has no menu bar this function does nothing.
+
+If FRAME is nil or not given, use the selected frame.  */)
+     (frame)
+     Lisp_Object frame;
+{
+  GtkWidget *menubar;
+  FRAME_PTR f;
+
+  /* gcc 2.95 doesn't accept the FRAME_PTR declaration after
+     BLOCK_INPUT.  */
+
+  BLOCK_INPUT;
+  f = check_x_frame (frame);
+
+  if (FRAME_EXTERNAL_MENU_BAR (f))
+    set_frame_menubar (f, 0, 1);
+
+  menubar = FRAME_X_OUTPUT (f)->menubar_widget;
+  if (menubar)
+    {
+      /* Activate the first menu.  */
+      GList *children = gtk_container_get_children (GTK_CONTAINER (menubar));
+
+      gtk_menu_shell_select_item (GTK_MENU_SHELL (menubar),
+                                  GTK_WIDGET (children->data));
+
+      popup_activated_flag = 1;
+      g_list_free (children);
+    }
+  UNBLOCK_INPUT;
+
+  return Qnil;
+}
+
 /* Loop util popup_activated_flag is set to zero in a callback.
    Used for popup menus and dialogs. */
 
@@ -1387,6 +1507,9 @@ popup_activate_callback (widget, id, client_data)
      XtPointer client_data;
 {
   popup_activated_flag = 1;
+#ifdef USE_X_TOOLKIT
+  x_activate_timeout_atimer ();
+#endif
 }
 #endif
 
@@ -2687,6 +2810,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
   /* Display the menu.  */
   lw_popup_menu (menu, (XEvent *) &dummy);
   popup_activated_flag = 1;
+  x_activate_timeout_atimer ();
 
   {
     int fact = 4 * sizeof (LWLIB_ID);
@@ -3064,6 +3188,7 @@ create_and_show_dialog (f, first_wv)
   /* Display the dialog box.  */
   lw_pop_up_all_widgets (dialog_id);
   popup_activated_flag = 1;
+  x_activate_timeout_atimer ();
 
   /* Process events that apply to the dialog box.
      Also handle timers.  */
@@ -3636,6 +3761,20 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
 #endif /* not USE_X_TOOLKIT */
 
 #endif /* HAVE_MENUS */
+
+
+/* The following is used by delayed window autoselection.  */
+
+DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
+       doc: /* Return t if a menu or popup dialog is active.  */)
+     ()
+{
+#ifdef HAVE_MENUS
+  return (popup_activated ()) ? Qt : Qnil;
+#else
+  return Qnil;
+#endif /* HAVE_MENUS */
+}
 \f
 void
 syms_of_xmenu ()
@@ -3647,17 +3786,19 @@ syms_of_xmenu ()
   Qdebug_on_next_call = intern ("debug-on-next-call");
   staticpro (&Qdebug_on_next_call);
 
-  DEFVAR_LISP ("menu-updating-frame", &Vmenu_updating_frame,
-              doc: /* Frame for which we are updating a menu.
-The enable predicate for a menu command should check this variable.  */);
-  Vmenu_updating_frame = Qnil;
-
 #ifdef USE_X_TOOLKIT
   widget_id_tick = (1<<16);
   next_menubar_widget_id = 1;
 #endif
 
   defsubr (&Sx_popup_menu);
+  defsubr (&Smenu_or_popup_active_p);
+
+#if defined (USE_GTK) || defined (USE_X_TOOLKIT)
+  defsubr (&Smenu_bar_open);
+  Ffset (intern ("accelerate-menu"), intern (Smenu_bar_open.symbol_name));
+#endif
+
 #ifdef HAVE_MENUS
   defsubr (&Sx_popup_dialog);
 #endif