Changes to remove Feval calls from GUI under NS.
authorAdrian Robert <Adrian.B.Robert@gmail.com>
Sun, 25 Jan 2009 19:43:31 +0000 (19:43 +0000)
committerAdrian Robert <Adrian.B.Robert@gmail.com>
Sun, 25 Jan 2009 19:43:31 +0000 (19:43 +0000)
* 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
src/keyboard.c
src/nsmenu.m
src/nsterm.h
src/nsterm.m
src/termhooks.h

index c3867a8..f5b481d 100644 (file)
@@ -1,3 +1,30 @@
+2009-01-25  Adrian Robert  <Adrian.B.Robert@gmail.com>
+
+       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  <cyd@stupidchicken.com>
 
        * dispnew.c (buffer_posn_from_coords): Use Fset_buffer instead of
index a6be5b1..cae40ff 100644 (file)
@@ -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.
index 94e8cb7..b3c5680 100644 (file)
@@ -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];
 
index 781d312..b1bff2e 100644 (file)
@@ -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
index 46bb50a..91dd37e 100644 (file)
@@ -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);
 /* <NSTextInput> implementation (called through super interpretKeyEvents:]). */
 
 
-/* <NSTextInput>: called through when done composing */
+/* <NSTextInput>: 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);
 }
 
 
index ed15b0f..5dedd48 100644 (file)
@@ -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