aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2004-11-12 08:33:51 +0000
committerJan Djärv2004-11-12 08:33:51 +0000
commitc3438661cbfac6a4622ea16c25c237a4ecd43009 (patch)
tree519d4ab8c8df884d27accc24cf301db6128255bc /src
parent141dbd2b161fb6aa97b935799cfd7edb7105f980 (diff)
downloademacs-c3438661cbfac6a4622ea16c25c237a4ecd43009.tar.gz
emacs-c3438661cbfac6a4622ea16c25c237a4ecd43009.zip
* xmenu.c (x_menu_wait_for_event): New function.
(popup_get_selection, popup_widget_loop): Call x_menu_wait_for_event to handle timers. (xmenu_show): Call XMenuActivateSetWaitFunction so that x_menu_wait_for_event is called by XMenuActivate.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/xmenu.c78
2 files changed, 76 insertions, 10 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e7d9d37aa3a..7f66e82bfc6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12004-11-12 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
2
3 * xmenu.c (x_menu_wait_for_event): New function.
4 (popup_get_selection, popup_widget_loop): Call x_menu_wait_for_event
5 to handle timers.
6 (xmenu_show): Call XMenuActivateSetWaitFunction so that
7 x_menu_wait_for_event is called by XMenuActivate.
8
12004-11-10 Stefan Monnier <monnier@iro.umontreal.ca> 92004-11-10 Stefan Monnier <monnier@iro.umontreal.ca>
2 10
3 * keymap.c (Fkeymap_prompt): Accept symbol keymaps. 11 * keymap.c (Fkeymap_prompt): Accept symbol keymaps.
diff --git a/src/xmenu.c b/src/xmenu.c
index 9868902f3f3..9b9de8aa16d 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */
48#include "buffer.h" 48#include "buffer.h"
49#include "charset.h" 49#include "charset.h"
50#include "coding.h" 50#include "coding.h"
51#include "sysselect.h"
51 52
52#ifdef MSDOS 53#ifdef MSDOS
53#include "msdos.h" 54#include "msdos.h"
@@ -157,8 +158,6 @@ static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
157static void list_of_panes P_ ((Lisp_Object)); 158static void list_of_panes P_ ((Lisp_Object));
158static void list_of_items P_ ((Lisp_Object)); 159static void list_of_items P_ ((Lisp_Object));
159 160
160extern EMACS_TIME timer_check P_ ((int));
161
162 161
163/* This holds a Lisp vector that holds the results of decoding 162/* This holds a Lisp vector that holds the results of decoding
164 the keymaps or alist-of-alists that specify a menu. 163 the keymaps or alist-of-alists that specify a menu.
@@ -1115,6 +1114,60 @@ on the left of the dialog box and all following items on the right.
1115 } 1114 }
1116#endif 1115#endif
1117} 1116}
1117
1118
1119#ifndef MSDOS
1120
1121/* Wait for an X event to arrive or for a timer to expire. */
1122
1123static void
1124x_menu_wait_for_event (void *data)
1125{
1126 extern EMACS_TIME timer_check P_ ((int));
1127
1128 /* Another way to do this is to register a timer callback, that can be
1129 done in GTK and Xt. But we have to do it like this when using only X
1130 anyway, and with callbacks we would have three variants for timer handling
1131 instead of the small ifdefs below. */
1132
1133 while (
1134#ifdef USE_X_TOOLKIT
1135 XtAppPending (Xt_app_con)
1136#elif defined USE_GTK
1137 ! gtk_events_pending ()
1138#else
1139 ! XPending ((Display*) data)
1140#endif
1141 )
1142 {
1143 EMACS_TIME next_time = timer_check (1);
1144 long secs = EMACS_SECS (next_time);
1145 long usecs = EMACS_USECS (next_time);
1146 SELECT_TYPE read_fds;
1147 struct x_display_info *dpyinfo;
1148 int n = 0;
1149
1150 FD_ZERO (&read_fds);
1151 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
1152 {
1153 int fd = ConnectionNumber (dpyinfo->display);
1154 FD_SET (fd, &read_fds);
1155 if (fd > n) n = fd;
1156 }
1157
1158 if (secs < 0 || (secs == 0 && usecs == 0))
1159 {
1160 /* Sometimes timer_check returns -1 (no timers) even if there are
1161 timers. So do a timeout anyway. */
1162 EMACS_SET_SECS (next_time, 1);
1163 EMACS_SET_USECS (next_time, 0);
1164 }
1165
1166 select (n + 1, &read_fds, (SELECT_TYPE *)0, (SELECT_TYPE *)0, &next_time);
1167 }
1168}
1169#endif /* ! MSDOS */
1170
1118 1171
1119#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 1172#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
1120 1173
@@ -1140,17 +1193,16 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1140 1193
1141 while (popup_activated_flag) 1194 while (popup_activated_flag)
1142 { 1195 {
1143 /* If we have no events to run, consider timers. */
1144 if (do_timers && !XtAppPending (Xt_app_con))
1145 timer_check (1);
1146
1147 if (initial_event) 1196 if (initial_event)
1148 { 1197 {
1149 event = *initial_event; 1198 event = *initial_event;
1150 initial_event = 0; 1199 initial_event = 0;
1151 } 1200 }
1152 else 1201 else
1153 XtAppNextEvent (Xt_app_con, &event); 1202 {
1203 if (do_timers) x_menu_wait_for_event (0);
1204 XtAppNextEvent (Xt_app_con, &event);
1205 }
1154 1206
1155 /* Make sure we don't consider buttons grabbed after menu goes. 1207 /* Make sure we don't consider buttons grabbed after menu goes.
1156 And make sure to deactivate for any ButtonRelease, 1208 And make sure to deactivate for any ButtonRelease,
@@ -1196,13 +1248,15 @@ popup_get_selection (initial_event, dpyinfo, id, do_timers, down_on_keypress)
1196/* Loop util popup_activated_flag is set to zero in a callback. 1248/* Loop util popup_activated_flag is set to zero in a callback.
1197 Used for popup menus and dialogs. */ 1249 Used for popup menus and dialogs. */
1198static void 1250static void
1199popup_widget_loop () 1251popup_widget_loop (do_timers)
1252 int do_timers;
1200{ 1253{
1201 ++popup_activated_flag; 1254 ++popup_activated_flag;
1202 1255
1203 /* Process events in the Gtk event loop until done. */ 1256 /* Process events in the Gtk event loop until done. */
1204 while (popup_activated_flag) 1257 while (popup_activated_flag)
1205 { 1258 {
1259 if (do_timers) x_menu_wait_for_event (0);
1206 gtk_main_iteration (); 1260 gtk_main_iteration ();
1207 } 1261 }
1208} 1262}
@@ -2402,7 +2456,7 @@ create_and_show_popup_menu (f, first_wv, x, y, for_click)
2402 two. show_help_echo uses this to detect popup menus. */ 2456 two. show_help_echo uses this to detect popup menus. */
2403 popup_activated_flag = 1; 2457 popup_activated_flag = 1;
2404 /* Process events that apply to the menu. */ 2458 /* Process events that apply to the menu. */
2405 popup_widget_loop (); 2459 popup_widget_loop (0);
2406 2460
2407 gtk_widget_destroy (menu); 2461 gtk_widget_destroy (menu);
2408 2462
@@ -2811,7 +2865,7 @@ create_and_show_dialog (f, first_wv)
2811 gtk_widget_show_all (menu); 2865 gtk_widget_show_all (menu);
2812 2866
2813 /* Process events that apply to the menu. */ 2867 /* Process events that apply to the menu. */
2814 popup_widget_loop (); 2868 popup_widget_loop (1);
2815 2869
2816 gtk_widget_destroy (menu); 2870 gtk_widget_destroy (menu);
2817 } 2871 }
@@ -3323,6 +3377,10 @@ xmenu_show (f, x, y, for_click, keymaps, title, error)
3323 XMenuSetFreeze (menu, TRUE); 3377 XMenuSetFreeze (menu, TRUE);
3324 pane = selidx = 0; 3378 pane = selidx = 0;
3325 3379
3380#ifndef MSDOS
3381 XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
3382#endif
3383
3326 /* Help display under X won't work because XMenuActivate contains 3384 /* Help display under X won't work because XMenuActivate contains
3327 a loop that doesn't give Emacs a chance to process it. */ 3385 a loop that doesn't give Emacs a chance to process it. */
3328 menu_help_frame = f; 3386 menu_help_frame = f;