aboutsummaryrefslogtreecommitdiffstats
path: root/src/xmenu.c
diff options
context:
space:
mode:
authorEli Zaretskii2013-09-29 21:38:56 +0300
committerEli Zaretskii2013-09-29 21:38:56 +0300
commit0afa0aabd833fff2e8da06e24da6c4bab7aadec3 (patch)
tree9420b06009efbb982e29d0fc2da77079d1cc5fd4 /src/xmenu.c
parent0fe3602a281b967ab1709da511c88f763a86e62a (diff)
downloademacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.tar.gz
emacs-0afa0aabd833fff2e8da06e24da6c4bab7aadec3.zip
x-popup-dialog fixed, almost.
Diffstat (limited to 'src/xmenu.c')
-rw-r--r--src/xmenu.c184
1 files changed, 35 insertions, 149 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index 054a52e7760..fe0e229ef20 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -192,149 +192,6 @@ mouse_position_for_popup (struct frame *f, int *x, int *y)
192 192
193#endif /* HAVE_X_WINDOWS */ 193#endif /* HAVE_X_WINDOWS */
194 194
195#ifdef HAVE_MENUS
196
197DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 3, 0,
198 doc: /* Pop up a dialog box and return user's selection.
199POSITION specifies which frame to use.
200This is normally a mouse button event or a window or frame.
201If POSITION is t, it means to use the frame the mouse is on.
202The dialog box appears in the middle of the specified frame.
203
204CONTENTS specifies the alternatives to display in the dialog box.
205It is a list of the form (DIALOG ITEM1 ITEM2...).
206Each ITEM is a cons cell (STRING . VALUE).
207The return value is VALUE from the chosen item.
208
209An ITEM may also be just a string--that makes a nonselectable item.
210An ITEM may also be nil--that means to put all preceding items
211on the left of the dialog box and all following items on the right.
212\(By default, approximately half appear on each side.)
213
214If HEADER is non-nil, the frame title for the box is "Information",
215otherwise it is "Question".
216
217If the user gets rid of the dialog box without making a valid choice,
218for instance using the window manager, then this produces a quit and
219`x-popup-dialog' does not return. */)
220 (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
221{
222 struct frame *f = NULL;
223 Lisp_Object window;
224
225 /* Decode the first argument: find the window or frame to use. */
226 if (EQ (position, Qt)
227 || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
228 || EQ (XCAR (position), Qtool_bar))))
229 {
230#if 0 /* Using the frame the mouse is on may not be right. */
231 /* Use the mouse's current position. */
232 struct frame *new_f = SELECTED_FRAME ();
233 Lisp_Object bar_window;
234 enum scroll_bar_part part;
235 Time time;
236 Lisp_Object x, y;
237
238 (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y, &time);
239
240 if (new_f != 0)
241 XSETFRAME (window, new_f);
242 else
243 window = selected_window;
244#endif
245 window = selected_window;
246 }
247 else if (CONSP (position))
248 {
249 Lisp_Object tem = XCAR (position);
250 if (CONSP (tem))
251 window = Fcar (XCDR (position));
252 else
253 {
254 tem = Fcar (XCDR (position)); /* EVENT_START (position) */
255 window = Fcar (tem); /* POSN_WINDOW (tem) */
256 }
257 }
258 else if (WINDOWP (position) || FRAMEP (position))
259 window = position;
260 else
261 window = Qnil;
262
263 /* Decode where to put the menu. */
264
265 if (FRAMEP (window))
266 f = XFRAME (window);
267 else if (WINDOWP (window))
268 {
269 CHECK_LIVE_WINDOW (window);
270 f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
271 }
272 else
273 /* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
274 but I don't want to make one now. */
275 CHECK_WINDOW (window);
276
277 check_window_system (f);
278
279 /* Force a redisplay before showing the dialog. If a frame is created
280 just before showing the dialog, its contents may not have been fully
281 drawn, as this depends on timing of events from the X server. Redisplay
282 is not done when a dialog is shown. If redisplay could be done in the
283 X event loop (i.e. the X event loop does not run in a signal handler)
284 this would not be needed.
285
286 Do this before creating the widget value that points to Lisp
287 string contents, because Fredisplay may GC and relocate them. */
288 Fredisplay (Qt);
289
290#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
291 /* Display a menu with these alternatives
292 in the middle of frame F. */
293 {
294 Lisp_Object x, y, frame, newpos;
295 XSETFRAME (frame, f);
296 XSETINT (x, FRAME_PIXEL_WIDTH (f) / 2);
297 XSETINT (y, FRAME_PIXEL_HEIGHT (f) / 2);
298 newpos = list2 (list2 (x, y), frame);
299
300 return Fx_popup_menu (newpos,
301 list2 (Fcar (contents), contents));
302 }
303#else
304 {
305 Lisp_Object title;
306 const char *error_name;
307 Lisp_Object selection;
308 ptrdiff_t specpdl_count = SPECPDL_INDEX ();
309
310 /* Decode the dialog items from what was specified. */
311 title = Fcar (contents);
312 CHECK_STRING (title);
313 record_unwind_protect_void (unuse_menu_items);
314
315 if (NILP (Fcar (Fcdr (contents))))
316 /* No buttons specified, add an "Ok" button so users can pop down
317 the dialog. Also, the lesstif/motif version crashes if there are
318 no buttons. */
319 contents = list2 (title, Fcons (build_string ("Ok"), Qt));
320
321 list_of_panes (list1 (contents));
322
323 /* Display them in a dialog box. */
324 block_input ();
325 selection = xdialog_show (f, 0, title, header, &error_name);
326 unblock_input ();
327
328 unbind_to (specpdl_count, Qnil);
329 discard_menu_items ();
330
331 if (error_name) error ("%s", error_name);
332 return selection;
333 }
334#endif
335}
336
337
338#ifndef MSDOS 195#ifndef MSDOS
339 196
340#if defined USE_GTK || defined USE_MOTIF 197#if defined USE_GTK || defined USE_MOTIF
@@ -2170,6 +2027,41 @@ xdialog_show (struct frame *f,
2170 return Qnil; 2027 return Qnil;
2171} 2028}
2172 2029
2030Lisp_Object
2031xw_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
2032{
2033 Lisp_Object title;
2034 const char *error_name;
2035 Lisp_Object selection;
2036 ptrdiff_t specpdl_count = SPECPDL_INDEX ();
2037
2038 check_window_system (f);
2039
2040 /* Decode the dialog items from what was specified. */
2041 title = Fcar (contents);
2042 CHECK_STRING (title);
2043 record_unwind_protect_void (unuse_menu_items);
2044
2045 if (NILP (Fcar (Fcdr (contents))))
2046 /* No buttons specified, add an "Ok" button so users can pop down
2047 the dialog. Also, the lesstif/motif version crashes if there are
2048 no buttons. */
2049 contents = list2 (title, Fcons (build_string ("Ok"), Qt));
2050
2051 list_of_panes (list1 (contents));
2052
2053 /* Display them in a dialog box. */
2054 block_input ();
2055 selection = xdialog_show (f, 0, title, header, &error_name);
2056 unblock_input ();
2057
2058 unbind_to (specpdl_count, Qnil);
2059 discard_menu_items ();
2060
2061 if (error_name) error ("%s", error_name);
2062 return selection;
2063}
2064
2173#else /* not USE_X_TOOLKIT && not USE_GTK */ 2065#else /* not USE_X_TOOLKIT && not USE_GTK */
2174 2066
2175/* The frame of the last activated non-toolkit menu bar. 2067/* The frame of the last activated non-toolkit menu bar.
@@ -2531,8 +2423,6 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps,
2531 2423
2532#endif /* not USE_X_TOOLKIT */ 2424#endif /* not USE_X_TOOLKIT */
2533 2425
2534#endif /* HAVE_MENUS */
2535
2536#ifndef MSDOS 2426#ifndef MSDOS
2537/* Detect if a dialog or menu has been posted. MSDOS has its own 2427/* Detect if a dialog or menu has been posted. MSDOS has its own
2538 implementation on msdos.c. */ 2428 implementation on msdos.c. */
@@ -2574,8 +2464,4 @@ syms_of_xmenu (void)
2574 Ffset (intern_c_string ("accelerate-menu"), 2464 Ffset (intern_c_string ("accelerate-menu"),
2575 intern_c_string (Sx_menu_bar_open_internal.symbol_name)); 2465 intern_c_string (Sx_menu_bar_open_internal.symbol_name));
2576#endif 2466#endif
2577
2578#ifdef HAVE_MENUS
2579 defsubr (&Sx_popup_dialog);
2580#endif
2581} 2467}