/* X Communication module for terminals which understand the X protocol.
Copyright (C) 1986, 1988, 1993, 1994, 1996, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006 Free Software Foundation, Inc.
+ 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#ifdef USE_LUCID
+#ifdef HAVE_XAW3D
+#include <X11/Xaw3d/Paned.h>
+#else /* !HAVE_XAW3D */
#include <X11/Xaw/Paned.h>
+#endif /* HAVE_XAW3D */
#endif /* USE_LUCID */
#include "../lwlib/lwlib.h"
#else /* not USE_X_TOOLKIT */
#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;
menu_items_used = XINT (XCAR (saved));
saved = XCDR (saved);
menu_items_n_panes = XINT (XCAR (saved));
- saved = XCDR (saved);
+ saved = XCDR (saved);
menu_items_submenu_depth = XINT (XCAR (saved));
return Qnil;
}
int xpos = 0, ypos = 0;
Lisp_Object title;
char *error_name = NULL;
- Lisp_Object selection;
+ Lisp_Object selection = Qnil;
FRAME_PTR f = NULL;
Lisp_Object x, y, window;
int keymaps = 0;
{
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. */
}
}
+DEFUN ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_internal, 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 ("x-menu-bar-open-internal", Fx_menu_bar_open_internal, Sx_menu_bar_open_internal, 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. */
f->output_data.x->saved_menu_event->type = 0;
}
-/* Detect if a dialog or menu has been posted. */
-
-int
-popup_activated ()
-{
- return popup_activated_flag;
-}
-
/* This callback is invoked when the user selects a menubar cascade
pushbutton, but before the pulldown menu is posted. */
XtPointer client_data;
{
popup_activated_flag = 1;
+#ifdef USE_X_TOOLKIT
+ x_activate_timeout_atimer ();
+#endif
}
#endif
/* Display the menu. */
lw_popup_menu (menu, (XEvent *) &dummy);
popup_activated_flag = 1;
+ x_activate_timeout_atimer ();
{
int fact = 4 * sizeof (LWLIB_ID);
/* 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. */
/* No selection has been chosen yet. */
menu_item_selection = 0;
+ /* Force a redisplay before showing the dialog. If a frame is created
+ just before showing the dialog, its contents may not have been fully
+ drawn, as this depends on timing of events from the X server. Redisplay
+ is not done when a dialog is shown. If redisplay could be done in the
+ X event loop (i.e. the X event loop does not run in a signal handler)
+ this would not be needed. */
+ Fredisplay (Qt);
+
/* Actually create and show the dialog. */
create_and_show_dialog (f, first_wv);
pane_name = first_item[MENU_ITEMS_PANE_NAME];
else if (EQ (first_item[0], Qquote))
/* This shouldn't happen, see xmenu_show. */
- pane_name = empty_string;
+ pane_name = empty_unibyte_string;
else
pane_name = first_item[MENU_ITEMS_ITEM_NAME];
#endif /* not USE_X_TOOLKIT */
#endif /* HAVE_MENUS */
+
+/* Detect if a dialog or menu has been posted. */
+
+int
+popup_activated ()
+{
+ return popup_activated_flag;
+}
+
+/* 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 ()
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 (&Sx_menu_bar_open_internal);
+ Ffset (intern ("accelerate-menu"),
+ intern (Sx_menu_bar_open_internal.symbol_name));
+#endif
+
#ifdef HAVE_MENUS
defsubr (&Sx_popup_dialog);
#endif