aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Djärv2004-11-13 20:18:21 +0000
committerJan Djärv2004-11-13 20:18:21 +0000
commitaf89e8710242b29ea53a150143df30207382891f (patch)
tree16436b4ad25d09f4801636e921654652b6800b23
parent3b8370e18bc4b13ec80f9a8c196381aa0a8383ff (diff)
downloademacs-af89e8710242b29ea53a150143df30207382891f.tar.gz
emacs-af89e8710242b29ea53a150143df30207382891f.zip
* xmenu.c (unuse_menu_items, pop_down_menu): Arg is of type
Lisp_Object. (popup_get_selection): Move unwind protect ... (create_and_show_popup_menu, create_and_show_dialog): ... to here. Move destroy of widget to pop_down_menu. (popup_widget_loop): Move unwind protect ... (create_and_show_popup_menu, create_and_show_dialog): ... to here. Move destroy of widget to pop_down_menu. (pop_down_menu): BLOCK_INPUT and destroy widget/window. (xmenu_show): record unwind pop_down_menu. Move XMenuDestroy, x_mouse_leave and grabbed = 0 to pop_down_menu.
-rw-r--r--src/ChangeLog14
-rw-r--r--src/xmenu.c185
2 files changed, 119 insertions, 80 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 65505cb7c6c..390ade23e10 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12004-11-13 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2
3 * xmenu.c (unuse_menu_items, pop_down_menu): Arg is of type
4 Lisp_Object.
5 (popup_get_selection): Move unwind protect ...
6 (create_and_show_popup_menu, create_and_show_dialog): ... to here.
7 Move destroy of widget to pop_down_menu.
8 (popup_widget_loop): Move unwind protect ...
9 (create_and_show_popup_menu, create_and_show_dialog): ... to here.
10 Move destroy of widget to pop_down_menu.
11 (pop_down_menu): BLOCK_INPUT and destroy widget/window.
12 (xmenu_show): record unwind pop_down_menu. Move XMenuDestroy,
13 x_mouse_leave and grabbed = 0 to pop_down_menu.
14
12004-11-13 Kim F. Storm <storm@cua.dk> 152004-11-13 Kim F. Storm <storm@cua.dk>
2 16
3 * xdisp.c (make_cursor_line_fully_visible_p): New variable. 17 * xdisp.c (make_cursor_line_fully_visible_p): New variable.
diff --git a/src/xmenu.c b/src/xmenu.c
index 3b813927281..c8c40a47256 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -288,7 +288,7 @@ finish_menu_items ()
288 288
289static Lisp_Object 289static Lisp_Object
290unuse_menu_items (dummy) 290unuse_menu_items (dummy)
291 int dummy; 291 Lisp_Object dummy;
292{ 292{
293 return menu_items_inuse = Qnil; 293 return menu_items_inuse = Qnil;
294} 294}
@@ -1173,14 +1173,6 @@ x_menu_wait_for_event (void *data)
1173 1173
1174#ifdef USE_X_TOOLKIT 1174#ifdef USE_X_TOOLKIT
1175 1175
1176static Lisp_Object
1177pop_down_menu (dummy)
1178 int dummy;
1179{
1180 popup_activated_flag = 0;
1181 return Qnil;
1182}
1183
1184/* Loop in Xt until the menu pulldown or dialog popup has been 1176/* Loop in Xt until the menu pulldown or dialog popup has been
1185 popped down (deactivated). This is used for x-popup-menu 1177 popped down (deactivated). This is used for x-popup-menu
1186 and x-popup-dialog; it is not used for the menu bar. 1178 and x-popup-dialog; it is not used for the menu bar.
@@ -1200,9 +1192,6 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1200{ 1192{
1201 XEvent event; 1193 XEvent event;
1202 1194
1203 int specpdl_count = SPECPDL_INDEX ();
1204 record_unwind_protect (pop_down_menu, Qnil);
1205
1206 while (popup_activated_flag) 1195 while (popup_activated_flag)
1207 { 1196 {
1208 if (initial_event) 1197 if (initial_event)
@@ -1252,8 +1241,6 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1252 1241
1253 x_dispatch_event (&event, event.xany.display); 1242 x_dispatch_event (&event, event.xany.display);
1254 } 1243 }
1255
1256 unbind_to (specpdl_count, Qnil);
1257} 1244}
1258 1245
1259#endif /* USE_X_TOOLKIT */ 1246#endif /* USE_X_TOOLKIT */
@@ -1261,30 +1248,12 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1261#ifdef USE_GTK 1248#ifdef USE_GTK
1262/* Loop util popup_activated_flag is set to zero in a callback. 1249/* Loop util popup_activated_flag is set to zero in a callback.
1263 Used for popup menus and dialogs. */ 1250 Used for popup menus and dialogs. */
1264static GtkWidget *current_menu;
1265
1266static Lisp_Object
1267pop_down_menu (dummy)
1268 int dummy;
1269{
1270 if (current_menu)
1271 {
1272 gtk_widget_unmap (current_menu);
1273 current_menu = 0;
1274 popup_activated_flag = 0;
1275 }
1276 return Qnil;
1277}
1278 1251
1279static void 1252static void
1280popup_widget_loop (do_timers, widget) 1253popup_widget_loop (do_timers, widget)
1281 int do_timers; 1254 int do_timers;
1282 GtkWidget *widget; 1255 GtkWidget *widget;
1283{ 1256{
1284 int specpdl_count = SPECPDL_INDEX ();
1285 current_menu = widget;
1286 record_unwind_protect (pop_down_menu, Qnil);
1287
1288 ++popup_activated_flag; 1257 ++popup_activated_flag;
1289 1258
1290 /* Process events in the Gtk event loop until done. */ 1259 /* Process events in the Gtk event loop until done. */
@@ -1293,8 +1262,6 @@ popup_widget_loop (do_timers, widget)
1293 if (do_timers) x_menu_wait_for_event (0); 1262 if (do_timers) x_menu_wait_for_event (0);
1294 gtk_main_iteration (); 1263 gtk_main_iteration ();
1295 } 1264 }
1296
1297 unbind_to (specpdl_count, Qnil);
1298} 1265}
1299#endif 1266#endif
1300 1267
@@ -2443,6 +2410,23 @@ popup_selection_callback (widget, client_data)
2443 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; 2410 if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
2444} 2411}
2445 2412
2413static GtkWidget *current_menu;
2414
2415static Lisp_Object
2416pop_down_menu (dummy)
2417 Lisp_Object dummy;
2418{
2419 popup_activated_flag = 0;
2420 if (current_menu)
2421 {
2422 BLOCK_INPUT;
2423 gtk_widget_destroy (current_menu);
2424 UNBLOCK_INPUT;
2425 current_menu = 0;
2426 }
2427 return Qnil;
2428}
2429
2446/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the 2430/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
2447 menu pops down. 2431 menu pops down.
2448 menu_item_selection will be set to the selection. */ 2432 menu_item_selection will be set to the selection. */
@@ -2458,6 +2442,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2458 GtkWidget *menu; 2442 GtkWidget *menu;
2459 GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */ 2443 GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */
2460 struct next_popup_x_y popup_x_y; 2444 struct next_popup_x_y popup_x_y;
2445 int specpdl_count = SPECPDL_INDEX ();
2461 2446
2462 xg_crazy_callback_abort = 1; 2447 xg_crazy_callback_abort = 1;
2463 menu = xg_create_widget ("popup", first_wv->name, f, first_wv, 2448 menu = xg_create_widget ("popup", first_wv->name, f, first_wv,
@@ -2488,13 +2473,16 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2488 gtk_widget_show_all (menu); 2473 gtk_widget_show_all (menu);
2489 gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0); 2474 gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0);
2490 2475
2476 current_menu = menu;
2477 record_unwind_protect (pop_down_menu, Qnil);
2478
2491 /* Set this to one. popup_widget_loop increases it by one, so it becomes 2479 /* Set this to one. popup_widget_loop increases it by one, so it becomes
2492 two. show_help_echo uses this to detect popup menus. */ 2480 two. show_help_echo uses this to detect popup menus. */
2493 popup_activated_flag = 1; 2481 popup_activated_flag = 1;
2494 /* Process events that apply to the menu. */ 2482 /* Process events that apply to the menu. */
2495 popup_widget_loop (1, 0); 2483 popup_widget_loop (1, menu);
2496 2484
2497 gtk_widget_destroy (menu); 2485 unbind_to (specpdl_count, Qnil);
2498 2486
2499 /* Must reset this manually because the button release event is not passed 2487 /* Must reset this manually because the button release event is not passed
2500 to Emacs event loop. */ 2488 to Emacs event loop. */
@@ -2522,6 +2510,24 @@ popup_selection_callback (widget, id, client_data)
2522 menu_item_selection = (Lisp_Object *) client_data; 2510 menu_item_selection = (Lisp_Object *) client_data;
2523} 2511}
2524 2512
2513/* ARG is the LWLIB ID of the dialog box, represented
2514 as a Lisp object as (HIGHPART . LOWPART). */
2515
2516static Lisp_Object
2517pop_down_menu (arg)
2518 Lisp_Object arg;
2519{
2520 LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
2521 | XINT (XCDR (arg)));
2522
2523 BLOCK_INPUT;
2524 lw_destroy_all_widgets (id);
2525 UNBLOCK_INPUT;
2526 popup_activated_flag = 0;
2527
2528 return Qnil;
2529}
2530
2525/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the 2531/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
2526 menu pops down. 2532 menu pops down.
2527 menu_item_selection will be set to the selection. */ 2533 menu_item_selection will be set to the selection. */
@@ -2578,15 +2584,19 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2578 /* Display the menu. */ 2584 /* Display the menu. */
2579 lw_popup_menu (menu, (XEvent *) &dummy); 2585 lw_popup_menu (menu, (XEvent *) &dummy);
2580 popup_activated_flag = 1; 2586 popup_activated_flag = 1;
2587
2588 {
2589 int fact = 4 * sizeof (LWLIB_ID);
2590 int specpdl_count = SPECPDL_INDEX ();
2591 record_unwind_protect (pop_down_menu,
2592 Fcons (make_number (menu_id >> (fact)),
2593 make_number (menu_id & ~(-1 << (fact)))));
2581 2594
2582 /* Process events that apply to the menu. */ 2595 /* Process events that apply to the menu. */
2583 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0); 2596 popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0);
2584 2597
2585 /* fp turned off the following statement and wrote a comment 2598 unbind_to (specpdl_count, Qnil);
2586 that it is unnecessary--that the menu has already disappeared. 2599 }
2587 Nowadays the menu disappears ok, all right, but
2588 we need to delete the widgets or multiple ones will pile up. */
2589 lw_destroy_all_widgets (menu_id);
2590} 2600}
2591 2601
2592#endif /* not USE_GTK */ 2602#endif /* not USE_GTK */
@@ -2897,13 +2907,17 @@ create_and_show_dialog (f, first_wv)
2897 2907
2898 if (menu) 2908 if (menu)
2899 { 2909 {
2910 int specpdl_count = SPECPDL_INDEX ();
2911 current_menu = menu;
2912 record_unwind_protect (pop_down_menu, Qnil);
2913
2900 /* Display the menu. */ 2914 /* Display the menu. */
2901 gtk_widget_show_all (menu); 2915 gtk_widget_show_all (menu);
2902 2916
2903 /* Process events that apply to the menu. */ 2917 /* Process events that apply to the menu. */
2904 popup_widget_loop (1, menu); 2918 popup_widget_loop (1, menu);
2905 2919
2906 gtk_widget_destroy (menu); 2920 unbind_to (specpdl_count, Qnil);
2907 } 2921 }
2908} 2922}
2909 2923
@@ -2926,23 +2940,6 @@ dialog_selection_callback (widget, id, client_data)
2926} 2940}
2927 2941
2928 2942
2929/* ARG is the LWLIB ID of the dialog box, represented
2930 as a Lisp object as (HIGHPART . LOWPART). */
2931
2932Lisp_Object
2933xdialog_show_unwind (arg)
2934 Lisp_Object arg;
2935{
2936 LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
2937 | XINT (XCDR (arg)));
2938 BLOCK_INPUT;
2939 lw_destroy_all_widgets (id);
2940 UNBLOCK_INPUT;
2941 popup_activated_flag = 0;
2942 return Qnil;
2943}
2944
2945
2946/* Pop up the dialog for frame F defined by FIRST_WV and loop until the 2943/* Pop up the dialog for frame F defined by FIRST_WV and loop until the
2947 dialog pops down. 2944 dialog pops down.
2948 menu_item_selection will be set to the selection. */ 2945 menu_item_selection will be set to the selection. */
@@ -2970,7 +2967,7 @@ create_and_show_dialog (f, first_wv)
2970 int fact = 4 * sizeof (LWLIB_ID); 2967 int fact = 4 * sizeof (LWLIB_ID);
2971 2968
2972 /* xdialog_show_unwind is responsible for popping the dialog box down. */ 2969 /* xdialog_show_unwind is responsible for popping the dialog box down. */
2973 record_unwind_protect (xdialog_show_unwind, 2970 record_unwind_protect (pop_down_menu,
2974 Fcons (make_number (dialog_id >> (fact)), 2971 Fcons (make_number (dialog_id >> (fact)),
2975 make_number (dialog_id & ~(-1 << (fact))))); 2972 make_number (dialog_id & ~(-1 << (fact)))));
2976 2973
@@ -3203,6 +3200,43 @@ menu_help_callback (help_string, pane, item)
3203 Qnil, menu_object, make_number (item), 1); 3200 Qnil, menu_object, make_number (item), 1);
3204} 3201}
3205 3202
3203static XMenu *current_menu;
3204
3205static Lisp_Object
3206pop_down_menu (frame)
3207 Lisp_Object frame;
3208{
3209 struct frame *f = XFRAME (frame);
3210
3211 BLOCK_INPUT;
3212 if (current_menu)
3213 {
3214#ifndef MSDOS
3215 XUngrabPointer (FRAME_X_DISPLAY (f), CurrentTime);
3216 XUngrabKeyboard (FRAME_X_DISPLAY (f), CurrentTime);
3217#endif
3218 XMenuDestroy (FRAME_X_DISPLAY (f), current_menu);
3219 current_menu = 0;
3220 }
3221
3222#ifdef HAVE_X_WINDOWS
3223 /* Assume the mouse has moved out of the X window.
3224 If it has actually moved in, we will get an EnterNotify. */
3225 x_mouse_leave (FRAME_X_DISPLAY_INFO (f));
3226
3227 /* State that no mouse buttons are now held.
3228 (The oldXMenu code doesn't track this info for us.)
3229 That is not necessarily true, but the fiction leads to reasonable
3230 results, and it is a pain to ask which are actually held now. */
3231 FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
3232
3233#endif /* HAVE_X_WINDOWS */
3234
3235 UNBLOCK_INPUT;
3236
3237 return Qnil;
3238}
3239
3206 3240
3207static Lisp_Object 3241static Lisp_Object
3208xmenu_show (f, x, y, for_click, keymaps, title, error) 3242xmenu_show (f, x, y, for_click, keymaps, title, error)
@@ -3216,7 +3250,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3216 Window root; 3250 Window root;
3217 XMenu *menu; 3251 XMenu *menu;
3218 int pane, selidx, lpane, status; 3252 int pane, selidx, lpane, status;
3219 Lisp_Object entry, pane_prefix; 3253 Lisp_Object entry, pane_prefix, frame;
3220 char *datap; 3254 char *datap;
3221 int ulx, uly, width, height; 3255 int ulx, uly, width, height;
3222 int dispwidth, dispheight; 3256 int dispwidth, dispheight;
@@ -3224,6 +3258,7 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3224 int maxwidth; 3258 int maxwidth;
3225 int dummy_int; 3259 int dummy_int;
3226 unsigned int dummy_uint; 3260 unsigned int dummy_uint;
3261 int specpdl_count = SPECPDL_INDEX ();
3227 3262
3228 *error = 0; 3263 *error = 0;
3229 if (menu_items_n_panes == 0) 3264 if (menu_items_n_panes == 0)
@@ -3416,20 +3451,17 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3416#ifndef MSDOS 3451#ifndef MSDOS
3417 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f)); 3452 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
3418#endif 3453#endif
3454
3455 XSETFRAME (frame, f);
3456 record_unwind_protect (pop_down_menu, frame);
3419 3457
3420 /* Help display under X won't work because XMenuActivate contains 3458 /* Help display under X won't work because XMenuActivate contains
3421 a loop that doesn't give Emacs a chance to process it. */ 3459 a loop that doesn't give Emacs a chance to process it. */
3422 menu_help_frame = f; 3460 menu_help_frame = f;
3461 current_menu = menu;
3423 status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx, 3462 status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx,
3424 x, y, ButtonReleaseMask, &datap, 3463 x, y, ButtonReleaseMask, &datap,
3425 menu_help_callback); 3464 menu_help_callback);
3426
3427
3428#ifdef HAVE_X_WINDOWS
3429 /* Assume the mouse has moved out of the X window.
3430 If it has actually moved in, we will get an EnterNotify. */
3431 x_mouse_leave (FRAME_X_DISPLAY_INFO (f));
3432#endif
3433 3465
3434 switch (status) 3466 switch (status)
3435 { 3467 {
@@ -3480,15 +3512,8 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3480 entry = Qnil; 3512 entry = Qnil;
3481 break; 3513 break;
3482 } 3514 }
3483 XMenuDestroy (FRAME_X_DISPLAY (f), menu);
3484 3515
3485#ifdef HAVE_X_WINDOWS 3516 unbind_to (specpdl_count, Qnil);
3486 /* State that no mouse buttons are now held.
3487 (The oldXMenu code doesn't track this info for us.)
3488 That is not necessarily true, but the fiction leads to reasonable
3489 results, and it is a pain to ask which are actually held now. */
3490 FRAME_X_DISPLAY_INFO (f)->grabbed = 0;
3491#endif
3492 3517
3493 return entry; 3518 return entry;
3494} 3519}