From 8612b71a44b34519fe1b047a9f1d6f6b1431d411 Mon Sep 17 00:00:00 2001 From: Adrian Robert Date: Sun, 25 Jan 2009 19:43:31 +0000 Subject: [PATCH] Changes to remove Feval calls from GUI under NS. * nsterm.h: Move KEY_NS_... definitions here from nsterm.m. Add NS_TOGGLE_TOOLBAR, NS_PUT_WORKING_TEXT, NS_UNPUT_WORKING_TEXT. Remove NS_INSERT_WORKING_TEXT, NS_DELETE_WORKING_TEXT. * nsterm.m: Move KEY_NS_... definitions to nsterm.h. (EmacsView-toggleToolbar:): Use KEY_NS_TOGGLE_TOOLBAR. (EmacsView-setMarkedText:,-deleteWorkingText:): Use NS_TEXT_EVENT instead of NON_ASCII_KEYSTROKE_EVENT. (EmacsApp-terminate:): Use KEY_NS_POWER_OFF instead of Feval. (EmacsApp-applicationShouldTerminate:): Query user. (EmacsPreferencesController-runHelp:): Use KEY_NS_INFO_PREFS instead of Feval. * termhooks.h (NS_TEXT_EVENT): New event type under HAVE_NS. * keyboard.c (kbd_buffer_get_event): Check for it. (keys_of_keyboard): Define lispy keys for ns-put/unput-working-text. * nsmenu.m (ns_popup_dialog): Resync window setting with X and W32 versions. (EmacsDialog-runDialogAt:): Use NSModalPanelRunLoopMode. --- src/ChangeLog | 27 +++++++++ src/keyboard.c | 15 +++++ src/nsmenu.m | 22 ++++--- src/nsterm.h | 16 +++++ src/nsterm.m | 158 +++++++++++++++++++++++++++--------------------- src/termhooks.h | 7 +++ 6 files changed, 165 insertions(+), 80 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c3867a8de9b..f5b481d4f1e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,30 @@ +2009-01-25 Adrian Robert + + Changes to remove Feval calls from GUI under NS. + + * nsterm.h: Move KEY_NS_... definitions here from nsterm.m. Add + NS_TOGGLE_TOOLBAR, NS_PUT_WORKING_TEXT, NS_UNPUT_WORKING_TEXT. + Remove NS_INSERT_WORKING_TEXT, NS_DELETE_WORKING_TEXT. + + * nsterm.m: Move KEY_NS_... definitions to nsterm.h. + (EmacsView-toggleToolbar:): Use KEY_NS_TOGGLE_TOOLBAR. + (EmacsView-setMarkedText:,-deleteWorkingText:): Use NS_TEXT_EVENT + instead of NON_ASCII_KEYSTROKE_EVENT. + (EmacsApp-terminate:): Use KEY_NS_POWER_OFF instead of Feval. + (EmacsApp-applicationShouldTerminate:): Query user. + (EmacsPreferencesController-runHelp:): Use KEY_NS_INFO_PREFS + instead of Feval. + + * termhooks.h (NS_TEXT_EVENT): New event type under HAVE_NS. + + * keyboard.c (kbd_buffer_get_event): Check for it. + (keys_of_keyboard): Define lispy keys for + ns-put/unput-working-text. + + * nsmenu.m (ns_popup_dialog): Resync window setting with X and W32 + versions. + (EmacsDialog-runDialogAt:): Use NSModalPanelRunLoopMode. + 2009-01-25 Chong Yidong * dispnew.c (buffer_posn_from_coords): Use Fset_buffer instead of diff --git a/src/keyboard.c b/src/keyboard.c index a6be5b152db..cae40ffd85e 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -4113,6 +4113,17 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time) #endif } +#if defined (HAVE_NS) + else if (event->kind == NS_TEXT_EVENT) + { + if (event->code == KEY_NS_PUT_WORKING_TEXT) + obj = Fcons (intern ("ns-put-working-text"), Qnil); + else + obj = Fcons (intern ("ns-unput-working-text"), Qnil); + kbd_fetch_ptr = event + 1; + } +#endif + #if defined (HAVE_X11) || defined (HAVE_NTGUI) \ || defined (HAVE_NS) else if (event->kind == DELETE_WINDOW_EVENT) @@ -12382,6 +12393,10 @@ keys_of_keyboard () initial_define_lispy_key (Vspecial_event_map, "delete-frame", "handle-delete-frame"); + initial_define_lispy_key (Vspecial_event_map, "ns-put-working-text", + "ns-put-working-text"); + initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text", + "ns-unput-working-text"); /* Here we used to use `ignore-event' which would simple set prefix-arg to current-prefix-arg, as is done in `handle-switch-frame'. But `handle-switch-frame is not run from the special-map. diff --git a/src/nsmenu.m b/src/nsmenu.m index 94e8cb73fa8..b3c56809733 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -1500,7 +1500,9 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) isQ = NILP (header); - if (EQ (position, Qt)) + if (EQ (position, Qt) + || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) + || EQ (XCAR (position), Qtool_bar)))) { window = selected_window; } @@ -1516,23 +1518,23 @@ ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header) window = Fcar (tem); /* POSN_WINDOW (tem) */ } } - else if (FRAMEP (position)) + else if (WINDOWP (position) || FRAMEP (position)) { window = position; } else - { - CHECK_LIVE_WINDOW (position); - window = position; - } - + window = Qnil; + if (FRAMEP (window)) f = XFRAME (window); - else + else if (WINDOWP (window)) { CHECK_LIVE_WINDOW (window); f = XFRAME (WINDOW_FRAME (XWINDOW (window))); } + else + CHECK_WINDOW (window); + p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2; p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2; dialog = [[EmacsDialogPanel alloc] initFromContents: contents @@ -1860,9 +1862,9 @@ void process_dialog (id window, Lisp_Object list) { (e = [NSApp nextEventMatchingMask: NSAnyEventMask untilDate: [NSDate distantFuture] - inMode: NSEventTrackingRunLoopMode + inMode: NSModalPanelRunLoopMode dequeue: NO]); -/*fprintf (stderr, "ret = %d\te = %p\n", ret, e); */ +/*fprintf (stderr, "ret = %d\te = %p\n", ret, e);*/ } [NSApp endModalSession: session]; diff --git a/src/nsterm.h b/src/nsterm.h index 781d312bafc..b1bff2e916f 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -384,6 +384,22 @@ typedef unsigned long NSUInteger; ========================================================================== */ +/* Special keycodes that we pass down the event chain */ +#define KEY_NS_POWER_OFF ((1<<28)|(0<<16)|1) +#define KEY_NS_OPEN_FILE ((1<<28)|(0<<16)|2) +#define KEY_NS_OPEN_TEMP_FILE ((1<<28)|(0<<16)|3) +#define KEY_NS_DRAG_FILE ((1<<28)|(0<<16)|4) +#define KEY_NS_DRAG_COLOR ((1<<28)|(0<<16)|5) +#define KEY_NS_DRAG_TEXT ((1<<28)|(0<<16)|6) +#define KEY_NS_CHANGE_FONT ((1<<28)|(0<<16)|7) +#define KEY_NS_OPEN_FILE_LINE ((1<<28)|(0<<16)|8) +#define KEY_NS_PUT_WORKING_TEXT ((1<<28)|(0<<16)|9) +#define KEY_NS_UNPUT_WORKING_TEXT ((1<<28)|(0<<16)|10) +#define KEY_NS_SPI_SERVICE_CALL ((1<<28)|(0<<16)|11) +#define KEY_NS_NEW_FRAME ((1<<28)|(0<<16)|12) +#define KEY_NS_TOGGLE_TOOLBAR ((1<<28)|(0<<16)|13) +#define KEY_NS_INFO_PREFS ((1<<28)|(0<<16)|14) + /* could use list to store these, but rest of emacs has a big infrastructure for managing a table of bitmap "records" */ struct ns_bitmap_record diff --git a/src/nsterm.m b/src/nsterm.m index 46bb50a91b6..91dd37e3043 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -69,20 +69,6 @@ int term_trace_num = 0; ========================================================================== */ -/* Special keycodes that we pass down the event chain */ -#define KEY_NS_POWER_OFF ((1<<28)|(0<<16)|1) -#define KEY_NS_OPEN_FILE ((1<<28)|(0<<16)|2) -#define KEY_NS_OPEN_TEMP_FILE ((1<<28)|(0<<16)|3) -#define KEY_NS_DRAG_FILE ((1<<28)|(0<<16)|4) -#define KEY_NS_DRAG_COLOR ((1<<28)|(0<<16)|5) -#define KEY_NS_DRAG_TEXT ((1<<28)|(0<<16)|6) -#define KEY_NS_CHANGE_FONT ((1<<28)|(0<<16)|7) -#define KEY_NS_OPEN_FILE_LINE ((1<<28)|(0<<16)|8) -#define KEY_NS_INSERT_WORKING_TEXT ((1<<28)|(0<<16)|9) -#define KEY_NS_DELETE_WORKING_TEXT ((1<<28)|(0<<16)|10) -#define KEY_NS_SPI_SERVICE_CALL ((1<<28)|(0<<16)|11) -#define KEY_NS_NEW_FRAME ((1<<28)|(0<<16)|12) - /* Convert a symbol indexed with an NSxxx value to a value as defined in keyboard.c (lispy_function_key). I hope this is a correct way of doing things... */ @@ -4048,7 +4034,7 @@ ns_term_shutdown (int sig) int type = [theEvent type]; NSWindow *window = [theEvent window]; /* NSTRACE (sendEvent); */ -/*fprintf (stderr, "received event of type %d\n", [theEvent type]); */ +/*fprintf (stderr, "received event of type %d\t%d\n", type);*/ if (type == NSCursorUpdate && window == nil) { @@ -4153,37 +4139,79 @@ ns_term_shutdown (int sig) } +/* Termination sequences (ns_shutdown_properly): + C-x C-c: + Cmd-Q: + MenuBar | File | Exit: + ns_term_shutdown: 0 + received -terminate: 1 + received -appShouldTerminate: 1 + + Select Quit from App menubar: + received -terminate: 0 + ns_term_shutdown: 0 + received -terminate: 1 + received -appShouldTerminate: 1 + + Select Quit from Dock menu: + Logout attempt: + received -appShouldTerminate: 0 + Cancel -> Nothing else + Accept -> + received -terminate: 0 + ns_term_shutdown: 0 + received -terminate: 1 + received -appShouldTerminate: 1 +*/ + - (void) terminate: (id)sender { - BLOCK_INPUT; if (ns_shutdown_properly) [super terminate: sender]; else { -/* Fkill_emacs (Qnil); */ + struct frame *emacsframe = SELECTED_FRAME (); + + if (!emacs_event) + return; + ns_shutdown_properly = YES; - Feval (Fcons (intern ("save-buffers-kill-emacs"), Qnil)); + emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; + emacs_event->code = KEY_NS_POWER_OFF; + EV_TRAILER ((id)nil); } - UNBLOCK_INPUT; } - (NSApplicationTerminateReply)applicationShouldTerminate: (id)sender { + int ret; + if (ns_shutdown_properly) return NSTerminateNow; - Lisp_Object contents = list3 (build_string ("Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?"), - Fcons (build_string ("Cancel"), Qnil), - Fcons (build_string ("Save and Exit"), Qt)); - Lisp_Object res = ns_popup_dialog (Qt, contents, Qnil); -fprintf (stderr, "res = %d\n", EQ (res, Qt)); /* FIXME */ - if (EQ (res, Qt)) - { - Feval (Fcons (intern ("save-buffers-kill-emacs"), Qnil)); - return NSTerminateNow; - } - return NSTerminateCancel; + /* 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. */ + while (1) { + ret = NSRunAlertPanel([[NSProcessInfo processInfo] processName], + [NSString stringWithUTF8String:"Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?"], + @"Save Buffers and Exit", @"Cancel", nil); + + if (ret == NSAlertDefaultReturn) + { + send_appdefined = YES; + ns_send_appdefined(-1); + return NSTerminateNow; + } + else if (ret == NSAlertAlternateReturn) + { + send_appdefined = YES; + ns_send_appdefined(-1); + return NSTerminateCancel; + } + } } @@ -4612,7 +4640,9 @@ extern void update_window_cursor (struct window *w, int on); /* implementation (called through super interpretKeyEvents:]). */ -/* : called through when done composing */ +/* : called when done composing; + NOTE: also called when we delete over working text, followed immed. + by doCommandBySelector: deleteBackward: */ - (void)insertText: (id)aString { int code; @@ -4667,20 +4697,9 @@ extern void update_window_cursor (struct window *w, int on); workingText = [str copy]; ns_working_text = build_string ([workingText UTF8String]); - /* if in "echo area", not true minibuffer, can't show chars in interactive - mode, so call using eval; otherwise we send a key event, which was the - original way this was done */ - if (!EQ (Feval (Fcons (intern ("ns-in-echo-area"), Qnil)), Qnil)) - { - Feval (Fcons (intern ("ns-echo-working-text"), Qnil)); - ns_send_appdefined (-1); - } - else - { - emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; - emacs_event->code = KEY_NS_INSERT_WORKING_TEXT; - EV_TRAILER ((id)nil); - } + emacs_event->kind = NS_TEXT_EVENT; + emacs_event->code = KEY_NS_PUT_WORKING_TEXT; + EV_TRAILER ((id)nil); } @@ -4690,7 +4709,7 @@ extern void update_window_cursor (struct window *w, int on); if (workingText == nil) return; if (NS_KEYLOG) - fprintf (stderr, "deleteWorkingText len =%d\n", [workingText length]); + NSLog(@"deleteWorkingText len =%d\n", [workingText length]); [workingText release]; workingText = nil; processingCompose = NO; @@ -4698,18 +4717,10 @@ extern void update_window_cursor (struct window *w, int on); if (!emacs_event) return; - if (!EQ (Feval (Fcons (intern ("ns-in-echo-area"), Qnil)), Qnil)) - { - Feval (Fcons (intern ("ns-unecho-working-text"), Qnil)); - ns_send_appdefined (-1); - } - else - { - emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; - emacs_event->code = KEY_NS_DELETE_WORKING_TEXT; - EV_TRAILER ((id)nil); - } - } + emacs_event->kind = NS_TEXT_EVENT; + emacs_event->code = KEY_NS_UNPUT_WORKING_TEXT; + EV_TRAILER ((id)nil); +} - (BOOL)hasMarkedText @@ -4717,6 +4728,7 @@ extern void update_window_cursor (struct window *w, int on); return workingText != nil; } + - (NSRange)markedRange { NSRange rng = workingText != nil @@ -4726,6 +4738,7 @@ extern void update_window_cursor (struct window *w, int on); return rng; } + - (void)unmarkText { if (NS_KEYLOG) @@ -4734,6 +4747,7 @@ extern void update_window_cursor (struct window *w, int on); processingCompose = NO; } + /* used to position char selection windows, etc. */ - (NSRect)firstRectForCharacterRange: (NSRange)theRange { @@ -4755,12 +4769,12 @@ extern void update_window_cursor (struct window *w, int on); return rect; } + - (NSInteger)conversationIdentifier { return (NSInteger)self; } -/* TODO: below here not yet implemented correctly, but may not be needed */ - (void)doCommandBySelector: (SEL)aSelector { @@ -5398,7 +5412,7 @@ extern void update_window_cursor (struct window *w, int on); return self; /* send first event (for some reason two needed) */ - theEvent =[[self window] currentEvent]; + theEvent = [[self window] currentEvent]; emacs_event->kind = TOOL_BAR_EVENT; XSETFRAME (emacs_event->arg, emacsframe); EV_TRAILER (theEvent); @@ -5415,11 +5429,13 @@ extern void update_window_cursor (struct window *w, int on); - toggleToolbar: (id)sender { - Lisp_Object lispFrame; - XSETFRAME (lispFrame, emacsframe); - Feval (Fcons (intern ("ns-toggle-toolbar"), Fcons (lispFrame, Qnil))); - SET_FRAME_GARBAGED (emacsframe); - ns_send_appdefined (-1); + if (!emacs_event) + return self; + + emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; + emacs_event->code = KEY_NS_TOGGLE_TOOLBAR; + EV_TRAILER ((id)nil); + return self; } @@ -6266,11 +6282,13 @@ static void selectItemWithTag (NSPopUpButton *popup, int tag) - (IBAction)runHelp: (id)sender { - Feval (Fcons (intern ("info"), - Fcons (build_string ("(emacs)Mac / GNUstep Customization"), - Qnil))); - SET_FRAME_GARBAGED (frame); - ns_send_appdefined (-1); + struct frame *emacsframe = frame; + if (!emacs_event) + return; + ns_raise_frame(frame); + emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; + emacs_event->code = KEY_NS_INFO_PREFS; + EV_TRAILER ((id)nil); } diff --git a/src/termhooks.h b/src/termhooks.h index ed15b0f71cf..5dedd487a2a 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -198,6 +198,13 @@ enum event_kind first, so this is not a problem there. */ , MULTIMEDIA_KEY_EVENT #endif + +#ifdef HAVE_NS + /* Generated when native multi-keystroke input method is used to modify + tentative or indicative text display. */ + , NS_TEXT_EVENT +#endif + }; /* If a struct input_event has a kind which is SELECTION_REQUEST_EVENT -- 2.39.2