(ns_popup_dialog): Call it on unwind.
(EmacsDialogPanel-runDialogAt:): Check popup_activated_flag and
call timer_check() (Bug#2154).
(EmacsMenu-menuNeedsUpdate:): Don't call ns_update_menu if
handling_signal is set.
(EmacsMenu-fillWithWidgetValue:): Set submenu title.
* s/darwin.h: Same and NO_SOCK_SIGIO as well.
* nsterm.m (ns_read_socket): Same and don't set handling_signal.
* keyboard.c (poll_for_input_1, handle_async_input): Set
handling_signal under HAVE_NS.
+2009-02-04 Adrian Robert <Adrian.B.Robert@gmail.com>
+
+ * nsmenu.m (pop_down_menu): New function.
+ (ns_popup_dialog): Call it on unwind.
+ (EmacsDialogPanel-runDialogAt:): Check popup_activated_flag and
+ call timer_check() (Bug#2154).
+ (EmacsMenu-menuNeedsUpdate:): Don't call ns_update_menu if
+ handling_signal is set.
+ (EmacsMenu-fillWithWidgetValue:): Set submenu title.
+
+ * config.in: Get rid of COCOA_EXPERIMENTAL_CTRL_G
+
+ * s/darwin.h: Same and NO_SOCK_SIGIO as well.
+
+ * nsterm.m (ns_read_socket): Same and don't set handling_signal.
+
+ * keyboard.c (poll_for_input_1, handle_async_input): Set
+ handling_signal under HAVE_NS.
+
2009-02-04 Glenn Morris <rgm@gnu.org>
* fileio.c (Fwrite_region): Doc fix (mention annotate-functions).
#ifdef POLL_FOR_INPUT
-/* Poll for input, so what we catch a C-g if it comes in. This
+/* Poll for input, so that we catch a C-g if it comes in. This
function is called from x_make_frame_visible, see comment
there. */
void
poll_for_input_1 ()
{
+/* Tell ns_read_socket() it is being called asynchronously so it can avoid
+ doing anything dangerous. */
+#ifdef HAVE_NS
+ ++handling_signal;
+#endif
if (interrupt_input_blocked == 0
&& !waiting_for_input)
read_avail_input (0);
+#ifdef HAVE_NS
+ --handling_signal;
+#endif
}
/* Timer callback function for poll_timer. TIMER is equal to
#ifdef SYNC_INPUT
pending_signals = pending_atimers;
#endif
-
+/* Tell ns_read_socket() it is being called asynchronously so it can avoid
+ doing anything dangerous. */
+#ifdef HAVE_NS
+ ++handling_signal;
+#endif
while (1)
{
int nread;
if (nread <= 0)
break;
}
+#ifdef HAVE_NS
+ --handling_signal;
+#endif
}
void
since key equivalents are handled through emacs.
On Leopard, even keystroke events generate SystemDefined events, but
their subtype is 8. */
- if ([event type] != NSSystemDefined || [event subtype] == 8)
+ if ([event type] != NSSystemDefined || [event subtype] == 8
+ /* Also, don't try this if from an event picked up asynchronously,
+ as lots of lisp evaluation happens in ns_update_menubar. */
+ || handling_signal != 0)
return;
/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
ns_update_menubar (frame, 1, self);
if (wv->contents)
{
- EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: @"Submenu"];
+ EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: [item title]];
[self setSubmenu: submenu forItem: item];
[submenu fillWithWidgetValue: wv->contents];
========================================================================== */
+
+static Lisp_Object
+pop_down_menu (Lisp_Object arg)
+{
+ struct Lisp_Save_Value *p = XSAVE_VALUE (arg);
+ popup_activated_flag = 0;
+ BLOCK_INPUT;
+ [((EmacsDialogPanel *) (p->pointer)) close];
+ [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+ UNBLOCK_INPUT;
+ return Qnil;
+}
+
+
Lisp_Object
ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
{
p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
dialog = [[EmacsDialogPanel alloc] initFromContents: contents
isQuestion: isQ];
- popup_activated_flag = 1;
- tem = [dialog runDialogAt: p];
- popup_activated_flag = 0;
+ {
+ int specpdl_count = SPECPDL_INDEX ();
+ record_unwind_protect (pop_down_menu, make_save_value (dialog, 0));
+ popup_activated_flag = 1;
+ tem = [dialog runDialogAt: p];
+ popup_activated_flag = 0;
+ unbind_to (specpdl_count, Qnil);
+ }
[dialog close];
-
[[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow];
+
return tem;
}
[self orderFront: NSApp];
session = [NSApp beginModalSessionForWindow: self];
- while ((ret = [NSApp runModalSession: session]) == NSRunContinuesResponse)
+ while (popup_activated_flag
+ && (ret = [NSApp runModalSession: session]) == NSRunContinuesResponse)
{
- (e = [NSApp nextEventMatchingMask: NSAnyEventMask
- untilDate: [NSDate distantFuture]
- inMode: NSModalPanelRunLoopMode
- dequeue: NO]);
+ timer_check (1); // for timers.el, indep of atimers; might not return
+ e = [NSApp nextEventMatchingMask: NSAnyEventMask
+ untilDate: [NSDate dateWithTimeIntervalSinceNow: 1]
+ inMode: NSModalPanelRunLoopMode
+ dequeue: NO];
/*fprintf (stderr, "ret = %d\te = %p\n", ret, e);*/
}
[NSApp endModalSession: session];
@end
-
/* ==========================================================================
Lisp definitions
int nevents;
static NSDate *lastCheck = nil;
-/* NSTRACE (ns_read_socket); */
+/* NSTRACE (ns_read_socket); */
if (interrupt_input_blocked)
{
#ifdef SYNC_INPUT
pending_signals = pending_atimers;
#endif
- BLOCK_INPUT;
-
-#ifdef COCOA_EXPERIMENTAL_CTRL_G
- /* causes Feval to abort; should probably set this in calling code when
- it IS actually called from signal handler, in which case we need to
- defer ns_update_menubar() calls */
- ++handling_signal;
-#endif
+ BLOCK_INPUT;
n_emacs_events_pending = 0;
EVENT_INIT (ev);
emacs_event = &ev;
nevents = n_emacs_events_pending;
n_emacs_events_pending = 0;
emacs_event = q_event_ptr = NULL;
-
-#ifdef COCOA_EXPERIMENTAL_CTRL_G
- --handling_signal;
-#endif
UNBLOCK_INPUT;
return nevents;
Cmd-Q:
MenuBar | File | Exit:
ns_term_shutdown: 0
- received -terminate: 1
- received -appShouldTerminate: 1
+ -terminate: 1
+ -appShouldTerminate: 1
Select Quit from App menubar:
received -terminate: 0
ns_term_shutdown: 0
- received -terminate: 1
- received -appShouldTerminate: 1
+ -terminate: 1
+ -appShouldTerminate: 1
Select Quit from Dock menu:
Logout attempt:
- received -appShouldTerminate: 0
+ -appShouldTerminate: 0
Cancel -> Nothing else
Accept ->
- received -terminate: 0
+ -terminate: 0
ns_term_shutdown: 0
- received -terminate: 1
- received -appShouldTerminate: 1
+ -terminate: 1
+ -appShouldTerminate: 1
*/
- (void) terminate: (id)sender
/* XXX: This while() loop is needed because if the user switches to another
application while the panel is up, it is taken down w/a return value
- of -1000, and the event queue gets messed up. In this case resend
- the appdefined and put up the window again. */
+ of NSRunStoppedResponse, and the event queue gets messed up.
+ In this case resend the appdefined and put up the window again. */
while (1) {
ret = NSRunAlertPanel([[NSProcessInfo processInfo] processName],
[NSString stringWithUTF8String:"Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?"],
x_set_window_size (emacsframe, 0, cols, rows);
ns_send_appdefined (-1);
-
- /* The following line causes a crash on GNUstep. Adrian Robert
- says he doesn't remember why he added this line, but removing it
- doesn't seem to cause problems on OSX, either. */
-#if 0
- [NSApp stopModal];
-#endif
}
/* Define HAVE_SOCKETS if system supports 4.2-compatible sockets. */
#define HAVE_SOCKETS
-/* This seems to help in Ctrl-G detection under Cocoa, however at the cost
- of some quirks that may or may not bother a given user.
- It was earlier commented that "In Carbon, asynchronous I/O (using SIGIO)
- can't be used for window events because they don't come from sockets,
- even though it works fine on tty's. Uncertain about situation in Cocoa. */
-#ifdef COCOA_EXPERIMENTAL_CTRL_G
-#define NO_SOCK_SIGIO
-#endif
-
/* Definitions for how to dump. Copied from nextstep.h. */
#define UNEXEC unexmacosx.o