diff options
| author | Adrian Robert | 2009-02-07 11:04:22 +0000 |
|---|---|---|
| committer | Adrian Robert | 2009-02-07 11:04:22 +0000 |
| commit | 3175b12ae7dc142799e993a3bc5e076d47e20bd4 (patch) | |
| tree | 2a0cd5461010b7f3fdd1da04e63f4abad2d6d448 /src | |
| parent | 8434d0b8c0fe9870c4cf97079c69e29995e8f1e7 (diff) | |
| download | emacs-3175b12ae7dc142799e993a3bc5e076d47e20bd4.tar.gz emacs-3175b12ae7dc142799e993a3bc5e076d47e20bd4.zip | |
* nsterm.m (EmacsApp-sendEvent:): Defer NSApplicationDefined event
when modal window is active. (Bug #2152)
(applicationShouldTerminate:): Remove now-unneeded while loop
around NSRunAlertPanel.
* nsmenu.m (popupSession): New file-global variable.
(pop_down_menu): End the popupSession before closing dialog.
(ns_popup_dialog): BLOCK_INPUT around dialog presentation.
(EmacsDialogPanel-runDialogAt:): Don't place window (superfluous),
don't query NSApp for events (just sleep instead).
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/nsmenu.m | 29 | ||||
| -rw-r--r-- | src/nsterm.m | 33 |
3 files changed, 43 insertions, 32 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 67ef7ad46a5..280af6c8b42 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2009-02-07 Adrian Robert <Adrian.B.Robert@gmail.com> | ||
| 2 | |||
| 3 | * nsterm.m (EmacsApp-sendEvent:): Defer NSApplicationDefined event | ||
| 4 | when modal window is active. (Bug #2152) | ||
| 5 | (applicationShouldTerminate:): Remove now-unneeded while loop | ||
| 6 | around NSRunAlertPanel. | ||
| 7 | |||
| 8 | * nsmenu.m (popupSession): New file-global variable. | ||
| 9 | (pop_down_menu): End the popupSession before closing dialog. | ||
| 10 | (ns_popup_dialog): BLOCK_INPUT around dialog presentation. | ||
| 11 | (EmacsDialogPanel-runDialogAt:): Don't place window (superfluous), | ||
| 12 | don't query NSApp for events (just sleep instead). | ||
| 13 | |||
| 1 | 2009-02-07 Eli Zaretskii <eliz@gnu.org> | 14 | 2009-02-07 Eli Zaretskii <eliz@gnu.org> |
| 2 | 15 | ||
| 3 | * coding.c (syms_of_coding) <translation-table-for-input>: Modify | 16 | * coding.c (syms_of_coding) <translation-table-for-input>: Modify |
diff --git a/src/nsmenu.m b/src/nsmenu.m index c6d4c21a179..f6b2075a841 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -73,6 +73,7 @@ EmacsMenu *mainMenu, *svcsMenu, *dockMenu; | |||
| 73 | 73 | ||
| 74 | /* Nonzero means a menu is currently active. */ | 74 | /* Nonzero means a menu is currently active. */ |
| 75 | static int popup_activated_flag; | 75 | static int popup_activated_flag; |
| 76 | static NSModalSession popupSession; | ||
| 76 | 77 | ||
| 77 | /* NOTE: toolbar implementation is at end, | 78 | /* NOTE: toolbar implementation is at end, |
| 78 | following complete menu implementation. */ | 79 | following complete menu implementation. */ |
| @@ -1495,6 +1496,7 @@ pop_down_menu (Lisp_Object arg) | |||
| 1495 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 1496 | struct Lisp_Save_Value *p = XSAVE_VALUE (arg); |
| 1496 | popup_activated_flag = 0; | 1497 | popup_activated_flag = 0; |
| 1497 | BLOCK_INPUT; | 1498 | BLOCK_INPUT; |
| 1499 | [NSApp endModalSession: popupSession]; | ||
| 1498 | [((EmacsDialogPanel *) (p->pointer)) close]; | 1500 | [((EmacsDialogPanel *) (p->pointer)) close]; |
| 1499 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; | 1501 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; |
| 1500 | UNBLOCK_INPUT; | 1502 | UNBLOCK_INPUT; |
| @@ -1554,6 +1556,8 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | |||
| 1554 | 1556 | ||
| 1555 | p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2; | 1557 | p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2; |
| 1556 | p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2; | 1558 | p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2; |
| 1559 | |||
| 1560 | BLOCK_INPUT; | ||
| 1557 | dialog = [[EmacsDialogPanel alloc] initFromContents: contents | 1561 | dialog = [[EmacsDialogPanel alloc] initFromContents: contents |
| 1558 | isQuestion: isQ]; | 1562 | isQuestion: isQ]; |
| 1559 | { | 1563 | { |
| @@ -1567,6 +1571,7 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) | |||
| 1567 | 1571 | ||
| 1568 | [dialog close]; | 1572 | [dialog close]; |
| 1569 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; | 1573 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; |
| 1574 | UNBLOCK_INPUT; | ||
| 1570 | 1575 | ||
| 1571 | return tem; | 1576 | return tem; |
| 1572 | } | 1577 | } |
| @@ -1872,27 +1877,21 @@ void process_dialog (id window, Lisp_Object list) | |||
| 1872 | 1877 | ||
| 1873 | - (Lisp_Object)runDialogAt: (NSPoint)p | 1878 | - (Lisp_Object)runDialogAt: (NSPoint)p |
| 1874 | { | 1879 | { |
| 1875 | NSEvent *e; | ||
| 1876 | NSModalSession session; | ||
| 1877 | int ret; | 1880 | int ret; |
| 1878 | 1881 | ||
| 1879 | [self center]; /*XXX p ignored? */ | 1882 | popupSession = [NSApp beginModalSessionForWindow: self]; |
| 1880 | [self orderFront: NSApp]; | ||
| 1881 | |||
| 1882 | session = [NSApp beginModalSessionForWindow: self]; | ||
| 1883 | while (popup_activated_flag | 1883 | while (popup_activated_flag |
| 1884 | && (ret = [NSApp runModalSession: session]) == NSRunContinuesResponse) | 1884 | && (ret = [NSApp runModalSession: popupSession]) |
| 1885 | == NSRunContinuesResponse) | ||
| 1885 | { | 1886 | { |
| 1886 | timer_check (1); // for timers.el, indep of atimers; might not return | 1887 | /* Run this for timers.el, indep of atimers; might not return. |
| 1887 | e = [NSApp nextEventMatchingMask: NSAnyEventMask | 1888 | TODO: use return value to avoid calling every iteration. */ |
| 1888 | untilDate: [NSDate dateWithTimeIntervalSinceNow: 1] | 1889 | timer_check (1); |
| 1889 | inMode: NSModalPanelRunLoopMode | 1890 | [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]]; |
| 1890 | dequeue: NO]; | ||
| 1891 | /*fprintf (stderr, "ret = %d\te = %p\n", ret, e);*/ | ||
| 1892 | } | 1891 | } |
| 1893 | [NSApp endModalSession: session]; | 1892 | [NSApp endModalSession: popupSession]; |
| 1894 | 1893 | ||
| 1895 | { // FIXME: BIG UGLY HACK!!! | 1894 | { /* FIXME: BIG UGLY HACK!!! */ |
| 1896 | Lisp_Object tmp; | 1895 | Lisp_Object tmp; |
| 1897 | *(EMACS_INT*)(&tmp) = ret; | 1896 | *(EMACS_INT*)(&tmp) = ret; |
| 1898 | return tmp; | 1897 | return tmp; |
diff --git a/src/nsterm.m b/src/nsterm.m index 2ef3a3ec906..b674edae580 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -4037,7 +4037,8 @@ ns_term_shutdown (int sig) | |||
| 4037 | 4037 | ||
| 4038 | - (void)sendEvent: (NSEvent *)theEvent | 4038 | - (void)sendEvent: (NSEvent *)theEvent |
| 4039 | /* -------------------------------------------------------------------------- | 4039 | /* -------------------------------------------------------------------------- |
| 4040 | Events posted by ns_send_appdefined interrupt the run loop here | 4040 | Called when NSApp is running for each event received. Used to stop |
| 4041 | the loop when we choose, since there's no way to just run one iteration. | ||
| 4041 | -------------------------------------------------------------------------- */ | 4042 | -------------------------------------------------------------------------- */ |
| 4042 | { | 4043 | { |
| 4043 | int type = [theEvent type]; | 4044 | int type = [theEvent type]; |
| @@ -4081,8 +4082,19 @@ ns_term_shutdown (int sig) | |||
| 4081 | 4082 | ||
| 4082 | if (type == NSApplicationDefined) | 4083 | if (type == NSApplicationDefined) |
| 4083 | { | 4084 | { |
| 4084 | last_appdefined_event = theEvent; | 4085 | /* Events posted by ns_send_appdefined interrupt the run loop here. |
| 4085 | [self stop: self]; | 4086 | But, if a modal window is up, an appdefined can still come through, |
| 4087 | (e.g., from a makeKeyWindow event) but stopping self also stops the | ||
| 4088 | modal loop. Just defer it until later. */ | ||
| 4089 | if ([NSApp modalWindow] == nil) | ||
| 4090 | { | ||
| 4091 | last_appdefined_event = theEvent; | ||
| 4092 | [self stop: self]; | ||
| 4093 | } | ||
| 4094 | else | ||
| 4095 | { | ||
| 4096 | send_appdefined = YES; | ||
| 4097 | } | ||
| 4086 | } | 4098 | } |
| 4087 | 4099 | ||
| 4088 | [super sendEvent: theEvent]; | 4100 | [super sendEvent: theEvent]; |
| @@ -4199,28 +4211,15 @@ ns_term_shutdown (int sig) | |||
| 4199 | if (ns_shutdown_properly || NILP (ns_confirm_quit)) | 4211 | if (ns_shutdown_properly || NILP (ns_confirm_quit)) |
| 4200 | return NSTerminateNow; | 4212 | return NSTerminateNow; |
| 4201 | 4213 | ||
| 4202 | /* XXX: This while() loop is needed because if the user switches to another | ||
| 4203 | application while the panel is up, it is taken down w/a return value | ||
| 4204 | of NSRunStoppedResponse, and the event queue gets messed up. | ||
| 4205 | In this case resend the appdefined and put up the window again. */ | ||
| 4206 | while (1) { | ||
| 4207 | ret = NSRunAlertPanel([[NSProcessInfo processInfo] processName], | 4214 | ret = NSRunAlertPanel([[NSProcessInfo processInfo] processName], |
| 4208 | [NSString stringWithUTF8String:"Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?"], | 4215 | [NSString stringWithUTF8String:"Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?"], |
| 4209 | @"Save Buffers and Exit", @"Cancel", nil); | 4216 | @"Save Buffers and Exit", @"Cancel", nil); |
| 4210 | 4217 | ||
| 4211 | if (ret == NSAlertDefaultReturn) | 4218 | if (ret == NSAlertDefaultReturn) |
| 4212 | { | ||
| 4213 | send_appdefined = YES; | ||
| 4214 | ns_send_appdefined(-1); | ||
| 4215 | return NSTerminateNow; | 4219 | return NSTerminateNow; |
| 4216 | } | ||
| 4217 | else if (ret == NSAlertAlternateReturn) | 4220 | else if (ret == NSAlertAlternateReturn) |
| 4218 | { | ||
| 4219 | send_appdefined = YES; | ||
| 4220 | ns_send_appdefined(-1); | ||
| 4221 | return NSTerminateCancel; | 4221 | return NSTerminateCancel; |
| 4222 | } | 4222 | return NSTerminateNow; /* just in case */ |
| 4223 | } | ||
| 4224 | } | 4223 | } |
| 4225 | 4224 | ||
| 4226 | 4225 | ||