]> code.delx.au - gnu-emacs/blobdiff - src/nsterm.m
Avoid crashing due to closing of font whose driver pointer is NULL.
[gnu-emacs] / src / nsterm.m
index 6c5f5f54cb93f07a49ff7e0d4d2e9220cbb608ce..733c05ae53a7cf5cdb5c1c156de9a3adc8d1c467 100644 (file)
@@ -1,7 +1,7 @@
 /* NeXT/Open/GNUstep / MacOSX communication module.
 
-Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013 Free Software
-Foundation, Inc.
+Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013
+  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -173,29 +173,21 @@ Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper;
 extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft;
 
 static Lisp_Object QUTF8_STRING;
+static Lisp_Object Qcocoa, Qgnustep;
 
 /* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold,
    the maximum font size to NOT antialias.  On GNUstep there is currently
    no way to control this behavior. */
 float ns_antialias_threshold;
 
-/* Used to pick up AppleHighlightColor on OS X */
-NSString *ns_selection_color;
-
 NSArray *ns_send_types =0, *ns_return_types =0, *ns_drag_types =0;
 NSString *ns_app_name = @"Emacs";  /* default changed later */
 
 /* Display variables */
 struct ns_display_info *x_display_list; /* Chain of existing displays */
-Lisp_Object ns_display_name_list;
 long context_menu_value = 0;
 
 /* display update */
-NSPoint last_mouse_motion_position;
-static NSRect last_mouse_glyph;
-static Time last_mouse_movement_time = 0;
-static Lisp_Object last_mouse_motion_frame;
-static EmacsScroller *last_mouse_scroll_bar = nil;
 static struct frame *ns_updating_frame;
 static NSView *focus_view = NULL;
 static int ns_window_num = 0;
@@ -453,8 +445,8 @@ ns_exec_path (void)
 const char *
 ns_load_path (void)
 /* If running as a self-contained app bundle, return as a path string
-   the filenames of the site-lisp, lisp and leim directories.
-   Ie, site-lisp:lisp:leim.  Otherwise, return nil.  */
+   the filenames of the site-lisp and lisp directories.
+   Ie, site-lisp:lisp.  Otherwise, return nil.  */
 {
   NSBundle *bundle = [NSBundle mainBundle];
   NSString *resourceDir = [bundle resourcePath];
@@ -464,7 +456,7 @@ ns_load_path (void)
   BOOL isDir;
   NSArray *paths = [resourceDir stringsByAppendingPaths:
                               [NSArray arrayWithObjects:
-                                         @"site-lisp", @"lisp", @"leim", nil]];
+                                         @"site-lisp", @"lisp", nil]];
   NSEnumerator *pathEnum = [paths objectEnumerator];
   resourcePaths = @"";
 
@@ -641,9 +633,7 @@ ns_update_auto_hide_menu_bar (void)
 
   NSTRACE (ns_update_auto_hide_menu_bar);
 
-  if (NSApp != nil
-      && [NSApp isActive]
-      && [NSApp respondsToSelector:@selector(setPresentationOptions:)])
+  if (NSApp != nil && [NSApp isActive])
     {
       // Note, "setPresentationOptions" triggers an error unless the
       // application is active.
@@ -652,10 +642,11 @@ ns_update_auto_hide_menu_bar (void)
       if (menu_bar_should_be_hidden != ns_menu_bar_is_hidden)
         {
           NSApplicationPresentationOptions options
-            = NSApplicationPresentationAutoHideDock;
+            = NSApplicationPresentationDefault;
 
           if (menu_bar_should_be_hidden)
-            options |= NSApplicationPresentationAutoHideMenuBar;
+            options |= NSApplicationPresentationAutoHideMenuBar
+              | NSApplicationPresentationAutoHideDock;
 
           [NSApp setPresentationOptions: options];
 
@@ -681,11 +672,22 @@ ns_update_begin (struct frame *f)
    external (RIF) call; whole frame, called before update_window_begin
    -------------------------------------------------------------------------- */
 {
-  NSView *view = FRAME_NS_VIEW (f);
+  EmacsView *view = FRAME_NS_VIEW (f);
   NSTRACE (ns_update_begin);
 
   ns_update_auto_hide_menu_bar ();
 
+#ifdef NS_IMPL_COCOA
+  if ([view isFullscreen] && [view fsIsNative])
+  {
+    // Fix reappearing tool bar in fullscreen for OSX 10.7
+    BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (f) ? YES : NO;
+    NSToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar];
+    if (! tbar_visible != ! [toolbar isVisible])
+      [toolbar setVisible: tbar_visible];
+  }
+#endif
+
   ns_updating_frame = f;
   [view lockFocus];
 
@@ -769,7 +771,12 @@ ns_update_window_end (struct window *w, bool cursor_on_p,
                                w->output_cursor.x, w->output_cursor.y);
 
       if (draw_window_fringes (w, 1))
-       x_draw_vertical_border (w);
+       {
+         if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+           x_draw_right_divider (w);
+         else
+           x_draw_vertical_border (w);
+       }
 
       unblock_input ();
     }
@@ -1148,9 +1155,7 @@ x_free_frame_resources (struct frame *f)
   block_input ();
 
   free_frame_menubar (f);
-
-  if (FRAME_FACE_CACHE (f))
-    free_frame_faces (f);
+  free_frame_faces (f);
 
   if (f == dpyinfo->x_focus_frame)
     dpyinfo->x_focus_frame = 0;
@@ -1233,7 +1238,11 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav)
 
 
 void
-x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
+x_set_window_size (struct frame *f,
+                   int change_grav,
+                   int width,
+                   int height,
+                   bool pixelwise)
 /* --------------------------------------------------------------------------
      Adjust window pixel size based on given character grid size
      Impl is a bit more complex than other terms, need to do some
@@ -1245,23 +1254,36 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
   NSRect wr = [window frame];
   int tb = FRAME_EXTERNAL_TOOL_BAR (f);
   int pixelwidth, pixelheight;
+  int rows, cols;
 
   NSTRACE (x_set_window_size);
 
   if (view == nil)
     return;
 
-/*fprintf (stderr, "\tsetWindowSize: %d x %d, font size %d x %d\n", cols, rows, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f)); */
+/*fprintf (stderr, "\tsetWindowSize: %d x %d, pixelwise %d, font size %d x %d\n", width, height, pixelwise, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f));*/
 
   block_input ();
 
-  check_frame_size (f, &rows, &cols);
+  check_frame_size (f, &width, &height, pixelwise);
 
   f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f);
   compute_fringe_widths (f, 0);
 
-  pixelwidth =  FRAME_TEXT_COLS_TO_PIXEL_WIDTH   (f, cols);
-  pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows);
+  if (pixelwise)
+    {
+      pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width);
+      pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height);
+      cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth);
+      rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight);
+    }
+  else
+    {
+      pixelwidth =  FRAME_TEXT_COLS_TO_PIXEL_WIDTH   (f, width);
+      pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
+      cols = width;
+      rows = height;
+    }
 
   /* If we have a toolbar, take its height into account. */
   if (tb && ! [view isFullscreen])
@@ -1296,8 +1318,6 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
   [view setRows: rows andColumns: cols];
   [window setFrame: wr display: YES];
 
-/*fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight); */
-
   /* This is a trick to compensate for Emacs' managing the scrollbar area
      as a fixed number of standard character columns.  Instead of leaving
      blank space for the extra, we chopped it off above.  Now for
@@ -1314,9 +1334,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows)
     [view setBoundsOrigin: origin];
   }
 
-  change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */
-  FRAME_PIXEL_WIDTH (f) = pixelwidth;
-  FRAME_PIXEL_HEIGHT (f) = pixelheight;
+  change_frame_size (f, width, height, 0, 1, 0, pixelwise);
 /*  SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */
 
   mark_window_cursors_off (XWINDOW (f->root_window));
@@ -1383,7 +1401,7 @@ ns_index_color (NSColor *color, struct frame *f)
       color_table->empty_indices = [[NSMutableSet alloc] init];
     }
 
-  /* do we already have this color ? */
+  /* Do we already have this color?  */
   for (i = 1; i < color_table->avail; i++)
     if (color_table->colors[i] && [color_table->colors[i] isEqual: color])
       return i;
@@ -1459,10 +1477,40 @@ ns_get_color (const char *name, NSColor **col)
 /*fprintf (stderr, "ns_get_color: '%s'\n", name); */
   block_input ();
 
-  if ([nsname isEqualToString: @"ns_selection_color"])
+  if ([nsname isEqualToString: @"ns_selection_bg_color"])
     {
-      nsname = ns_selection_color;
-      name = [ns_selection_color UTF8String];
+#ifdef NS_IMPL_COCOA
+      NSString *defname = [[NSUserDefaults standardUserDefaults]
+                            stringForKey: @"AppleHighlightColor"];
+      if (defname != nil)
+        nsname = defname;
+      else
+#endif
+      if ((new = [NSColor selectedTextBackgroundColor]) != nil)
+        {
+          *col = [new colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+          unblock_input ();
+          return 0;
+        }
+      else
+        nsname = NS_SELECTION_BG_COLOR_DEFAULT;
+
+      name = [nsname UTF8String];
+    }
+  else if ([nsname isEqualToString: @"ns_selection_fg_color"])
+    {
+      /* NOTE: OSX applications normally don't set foreground selection, but
+         text may be unreadable if we don't.
+      */
+      if ((new = [NSColor selectedTextColor]) != nil)
+        {
+          *col = [new colorUsingColorSpaceName: NSCalibratedRGBColorSpace];
+          unblock_input ();
+          return 0;
+        }
+
+      nsname = NS_SELECTION_FG_COLOR_DEFAULT;
+      name = [nsname UTF8String];
     }
 
   /* First, check for some sort of numeric specification. */
@@ -1740,24 +1788,26 @@ note_mouse_movement (struct frame *frame, CGFloat x, CGFloat y)
      known as last_mouse_glyph.
      ------------------------------------------------------------------------ */
 {
+  struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
+  NSRect *r;
+
 //  NSTRACE (note_mouse_movement);
 
-  XSETFRAME (last_mouse_motion_frame, frame);
+  dpyinfo->last_mouse_motion_frame = frame;
+  r = &dpyinfo->last_mouse_glyph;
 
   /* Note, this doesn't get called for enter/leave, since we don't have a
      position.  Those are taken care of in the corresponding NSView methods. */
 
   /* has movement gone beyond last rect we were tracking? */
-  if (x < last_mouse_glyph.origin.x ||
-      x >= (last_mouse_glyph.origin.x + last_mouse_glyph.size.width) ||
-      y < last_mouse_glyph.origin.y ||
-      y >= (last_mouse_glyph.origin.y + last_mouse_glyph.size.height))
+  if (x < r->origin.x || x >= r->origin.x + r->size.width
+      || y < r->origin.y || y >= r->origin.y + r->size.height)
     {
-      ns_update_begin(frame);
+      ns_update_begin (frame);
       frame->mouse_moved = 1;
       note_mouse_highlight (frame, x, y);
-      remember_mouse_glyph (frame, x, y, &last_mouse_glyph);
-      ns_update_end(frame);
+      remember_mouse_glyph (frame, x, y, r);
+      ns_update_end (frame);
       return 1;
     }
 
@@ -1794,14 +1844,15 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
   block_input ();
 
-  if (last_mouse_scroll_bar != nil && insist == 0)
+  if (dpyinfo->last_mouse_scroll_bar != nil && insist == 0)
     {
       /* TODO: we do not use this path at the moment because drag events will
            go directly to the EmacsScroller.  Leaving code in for now. */
-      [last_mouse_scroll_bar getMouseMotionPart: (int *)part window: bar_window
-                                              x: x y: y];
-      if (time) *time = last_mouse_movement_time;
-      last_mouse_scroll_bar = nil;
+      [dpyinfo->last_mouse_scroll_bar
+         getMouseMotionPart: (int *)part window: bar_window x: x y: y];
+      if (time)
+       *time = dpyinfo->last_mouse_movement_time;
+      dpyinfo->last_mouse_scroll_bar = nil;
     }
   else
     {
@@ -1811,9 +1862,10 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
             && FRAME_NS_DISPLAY (XFRAME (frame)) == FRAME_NS_DISPLAY (*fp))
           XFRAME (frame)->mouse_moved = 0;
 
-      last_mouse_scroll_bar = nil;
-      if (last_mouse_frame && FRAME_LIVE_P (last_mouse_frame))
-        f = last_mouse_frame;
+      dpyinfo->last_mouse_scroll_bar = nil;
+      if (dpyinfo->last_mouse_frame
+         && FRAME_LIVE_P (dpyinfo->last_mouse_frame))
+        f = dpyinfo->last_mouse_frame;
       else
         f = dpyinfo->x_focus_frame ? dpyinfo->x_focus_frame
                                     : SELECTED_FRAME ();
@@ -1824,7 +1876,8 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
           position = [[view window] mouseLocationOutsideOfEventStream];
           position = [view convertPoint: position fromView: nil];
-          remember_mouse_glyph (f, position.x, position.y, &last_mouse_glyph);
+          remember_mouse_glyph (f, position.x, position.y,
+                               &dpyinfo->last_mouse_glyph);
 /*fprintf (stderr, "ns_mouse_position: %.0f, %.0f\n", position.x, position.y); */
 
           if (bar_window) *bar_window = Qnil;
@@ -1832,7 +1885,8 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 
           if (x) XSETINT (*x, lrint (position.x));
           if (y) XSETINT (*y, lrint (position.y));
-          if (time) *time = last_mouse_movement_time;
+          if (time)
+           *time = dpyinfo->last_mouse_movement_time;
           *fp = f;
         }
     }
@@ -2466,6 +2520,28 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
 }
 
 
+static void
+ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
+/* --------------------------------------------------------------------------
+     External (RIF): Draw a window divider.
+   -------------------------------------------------------------------------- */
+{
+  struct frame *f = XFRAME (WINDOW_FRAME (w));
+  struct face *face;
+  NSRect r = NSMakeRect (x0, y0, x1-x0, y1-y0);
+
+  NSTRACE (ns_draw_window_divider);
+
+  face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+  if (face)
+      [ns_lookup_indexed_color(face->foreground, f) set];
+
+  ns_focus (f, &r, 1);
+  NSRectFill(r);
+  ns_unfocus (f);
+}
+
+
 void
 show_hourglass (struct atimer *timer)
 {
@@ -3357,7 +3433,6 @@ check_native_fs ()
 
   ns_last_use_native_fullscreen = ns_use_native_fullscreen;
 
-  /* Clear the mouse-moved flag for every frame on this display.  */
   FOR_EACH_FRAME (tail, frame)
     {
       struct frame *f = XFRAME (frame);
@@ -3938,7 +4013,6 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo)
                 && ![NSCalibratedWhiteColorSpace isEqualToString:
                                                  NSColorSpaceFromDepth (depth)];
     dpyinfo->n_planes = NSBitsPerPixelFromDepth (depth);
-    dpyinfo->image_cache = make_image_cache ();
     dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table);
     dpyinfo->color_table->colors = NULL;
     dpyinfo->root_window = 42; /* a placeholder.. */
@@ -3981,6 +4055,7 @@ static struct redisplay_interface ns_redisplay_interface =
   ns_clear_frame_area,
   ns_draw_window_cursor,
   ns_draw_vertical_window_border,
+  ns_draw_window_divider,
   ns_shift_glyphs_for_insert
 };
 
@@ -4054,12 +4129,6 @@ ns_create_terminal (struct ns_display_info *dpyinfo)
   terminal->delete_frame_hook = x_destroy_window;
   terminal->delete_terminal_hook = ns_delete_terminal;
 
-  terminal->scroll_region_ok = 1;
-  terminal->char_ins_del_ok = 1;
-  terminal->line_ins_del_ok = 1;
-  terminal->fast_clear_end_of_line = 1;
-  terminal->memory_below_frame = 0;
-
   return terminal;
 }
 
@@ -4132,11 +4201,7 @@ ns_term_init (Lisp_Object display_name)
   ns_initialize_display_info (dpyinfo);
   terminal = ns_create_terminal (dpyinfo);
 
-  terminal->kboard = xmalloc (sizeof *terminal->kboard);
-  init_kboard (terminal->kboard);
-  kset_window_system (terminal->kboard, Qns);
-  terminal->kboard->next_kboard = all_kboards;
-  all_kboards = terminal->kboard;
+  terminal->kboard = allocate_kboard (Qns);
   /* Don't let the initial kboard remain current longer than necessary.
      That would cause problems if a file loaded on startup tries to
      prompt in the mini-buffer.  */
@@ -4147,10 +4212,7 @@ ns_term_init (Lisp_Object display_name)
   dpyinfo->next = x_display_list;
   x_display_list = dpyinfo;
 
-  /* Put it on ns_display_name_list */
-  ns_display_name_list = Fcons (Fcons (display_name, Qnil),
-                                ns_display_name_list);
-  dpyinfo->name_list_element = XCAR (ns_display_name_list);
+  dpyinfo->name_list_element = Fcons (display_name, Qnil);
 
   terminal->name = xstrdup (SSDATA (display_name));
 
@@ -4167,11 +4229,6 @@ ns_term_init (Lisp_Object display_name)
       ns_antialias_threshold = NILP (tmp) ? 10.0 : XFLOATINT (tmp);
     }
 
-  ns_selection_color = [[NSUserDefaults standardUserDefaults]
-                        stringForKey: @"AppleHighlightColor"];
-  if (ns_selection_color == nil)
-    ns_selection_color = NS_SELECTION_COLOR_DEFAULT;
-
   {
     NSColorList *cl = [NSColorList colorListNamed: @"Emacs"];
 
@@ -4349,6 +4406,56 @@ ns_term_shutdown (int sig)
 
 @implementation EmacsApp
 
+- (id)init
+{
+  if (self = [super init])
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
+      self->isFirst = YES;
+#endif
+#ifdef NS_IMPL_GNUSTEP
+      self->applicationDidFinishLaunchingCalled = NO;
+#endif
+    }
+
+  return self;
+}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
+- (void)run
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    if (isFirst) [self finishLaunching];
+    isFirst = NO;
+
+    shouldKeepRunning = YES;
+    do
+      {
+        [pool release];
+        pool = [[NSAutoreleasePool alloc] init];
+
+        NSEvent *event =
+          [self nextEventMatchingMask:NSAnyEventMask
+                            untilDate:[NSDate distantFuture]
+                               inMode:NSDefaultRunLoopMode
+                              dequeue:YES];
+        [self sendEvent:event];
+        [self updateWindows];
+    } while (shouldKeepRunning);
+
+    [pool release];
+}
+
+- (void)stop: (id)sender
+{
+    shouldKeepRunning = NO;
+    // Stop possible dialog also.  Noop if no dialog present.
+    // The file dialog still leaks 7k - 10k on 10.9 though.
+    [super stop:sender];
+}
+#endif
+
 - (void)logNotification: (NSNotification *)notification
 {
   const char *name = [[notification name] UTF8String];
@@ -4501,6 +4608,9 @@ ns_term_shutdown (int sig)
    -------------------------------------------------------------------------- */
 {
   NSTRACE (applicationDidFinishLaunching);
+#ifdef NS_IMPL_GNUSTEP
+  ((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES;
+#endif
   [NSApp setServicesProvider: NSApp];
   ns_send_appdefined (-2);
 }
@@ -4628,6 +4738,10 @@ not_in_argv (NSString *arg)
 {
   NSTRACE (applicationDidBecomeActive);
 
+#ifdef NS_IMPL_GNUSTEP
+  if (! applicationDidFinishLaunchingCalled)
+    [self applicationDidFinishLaunching:notification];
+#endif
   //ns_app_active=YES;
 
   ns_update_auto_hide_menu_bar ();
@@ -5207,8 +5321,10 @@ not_in_argv (NSString *arg)
   NSString *str = [aString respondsToSelector: @selector (string)] ?
     [aString string] : aString;
   if (NS_KEYLOG)
-    NSLog (@"setMarkedText '%@' len =%d range %d from %d", str, [str length],
-           selRange.length, selRange.location);
+    NSLog (@"setMarkedText '%@' len =%lu range %lu from %lu",
+           str, (unsigned long)[str length],
+           (unsigned long)selRange.length,
+           (unsigned long)selRange.location);
 
   if (workingText != nil)
     [self deleteWorkingText];
@@ -5234,7 +5350,7 @@ not_in_argv (NSString *arg)
   if (workingText == nil)
     return;
   if (NS_KEYLOG)
-    NSLog(@"deleteWorkingText len =%d\n", [workingText length]);
+    NSLog(@"deleteWorkingText len =%lu\n", (unsigned long)[workingText length]);
   [workingText release];
   workingText = nil;
   processingCompose = NO;
@@ -5362,6 +5478,7 @@ not_in_argv (NSString *arg)
 /* This is what happens when the user presses a mouse button.  */
 - (void)mouseDown: (NSEvent *)theEvent
 {
+  struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe);
   NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
 
   NSTRACE (mouseDown);
@@ -5371,10 +5488,10 @@ not_in_argv (NSString *arg)
   if (!emacs_event)
     return;
 
-  last_mouse_frame = emacsframe;
+  dpyinfo->last_mouse_frame = emacsframe;
   /* appears to be needed to prevent spurious movement events generated on
      button clicks */
-  last_mouse_frame->mouse_moved = 0;
+  emacsframe->mouse_moved = 0;
 
   if ([theEvent type] == NSScrollWheel)
     {
@@ -5446,13 +5563,16 @@ not_in_argv (NSString *arg)
 - (void)mouseMoved: (NSEvent *)e
 {
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
+  struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe);
   Lisp_Object frame;
+  NSPoint pt;
 
 //  NSTRACE (mouseMoved);
 
-  last_mouse_movement_time = EV_TIMESTAMP (e);
-  last_mouse_motion_position
-    = [self convertPoint: [e locationInWindow] fromView: nil];
+  dpyinfo->last_mouse_movement_time = EV_TIMESTAMP (e);
+  pt = [self convertPoint: [e locationInWindow] fromView: nil];
+  dpyinfo->last_mouse_motion_x = pt.x;
+  dpyinfo->last_mouse_motion_y = pt.y;
 
   /* update any mouse face */
   if (hlinfo->mouse_face_hidden)
@@ -5469,9 +5589,8 @@ not_in_argv (NSString *arg)
     {
       NSTRACE (mouse_autoselect_window);
       static Lisp_Object last_mouse_window;
-      Lisp_Object window = window_from_coordinates
-       (emacsframe, last_mouse_motion_position.x,
-        last_mouse_motion_position.y, 0, 0);
+      Lisp_Object window
+       = window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0);
 
       if (WINDOWP (window)
           && !EQ (window, last_mouse_window)
@@ -5489,8 +5608,7 @@ not_in_argv (NSString *arg)
       last_mouse_window = window;
     }
 
-  if (!note_mouse_movement (emacsframe, last_mouse_motion_position.x,
-                            last_mouse_motion_position.y))
+  if (!note_mouse_movement (emacsframe, pt.x, pt.y))
     help_echo_string = previous_help_echo_string;
 
   XSETFRAME (frame, emacsframe);
@@ -5555,44 +5673,44 @@ not_in_argv (NSString *arg)
   NSWindow *window = [self window];
   NSRect wr = [window frame];
   int extra = 0;
-  int gsextra = 0;
-#ifdef NS_IMPL_GNUSTEP
-  gsextra = 3;
-#endif
-
   int oldc = cols, oldr = rows;
   int oldw = FRAME_PIXEL_WIDTH (emacsframe),
     oldh = FRAME_PIXEL_HEIGHT (emacsframe);
   int neww, newh;
 
-  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, wr.size.width + gsextra);
-
-  if (cols < MINWIDTH)
-    cols = MINWIDTH;
-
   if (! [self isFullscreen])
     {
+#ifdef NS_IMPL_GNUSTEP
+      // GNUStep does not always update the tool bar height.  Force it.
+      if (toolbar) update_frame_tool_bar (emacsframe);
+#endif
+
       extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
-        + FRAME_TOOLBAR_HEIGHT (emacsframe) - gsextra;
+        + FRAME_TOOLBAR_HEIGHT (emacsframe);
     }
 
-  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, wr.size.height - extra);
+  neww = (int)wr.size.width - emacsframe->border_width;
+  newh = (int)wr.size.height - extra;
+
+  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww);
+  rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh);
+
+  if (cols < MINWIDTH)
+    cols = MINWIDTH;
 
   if (rows < MINHEIGHT)
     rows = MINHEIGHT;
 
-  neww = (int)wr.size.width - emacsframe->border_width;
-  newh = (int)wr.size.height - extra;
-
   if (oldr != rows || oldc != cols || neww != oldw || newh != oldh)
     {
       NSView *view = FRAME_NS_VIEW (emacsframe);
       NSWindow *win = [view window];
       NSSize sz = [win resizeIncrements];
 
-      FRAME_PIXEL_WIDTH (emacsframe) = neww;
-      FRAME_PIXEL_HEIGHT (emacsframe) = newh;
-      change_frame_size (emacsframe, rows, cols, 0, delay, 0);
+      change_frame_size (emacsframe,
+                         FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww),
+                         FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh),
+                         0, delay, 0, 1);
       SET_FRAME_GARBAGED (emacsframe);
       cancel_mouse_face (emacsframe);
 
@@ -5614,10 +5732,6 @@ not_in_argv (NSString *arg)
 /* normalize frame to gridded text size */
 {
   int extra = 0;
-  int gsextra = 0;
-#ifdef NS_IMPL_GNUSTEP
-  gsextra = 3;
-#endif
 
   NSTRACE (windowWillResize);
 /*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */
@@ -5635,8 +5749,13 @@ not_in_argv (NSString *arg)
   if (fs_state == FULLSCREEN_NONE)
     maximized_width = maximized_height = -1;
 
-  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe,
-                                         frameSize.width + gsextra);
+  if (! [self isFullscreen])
+    {
+      extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe)
+        + FRAME_TOOLBAR_HEIGHT (emacsframe);
+    }
+
+  cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, frameSize.width);
   if (cols < MINWIDTH)
     cols = MINWIDTH;
 
@@ -6027,7 +6146,7 @@ if (cols > 0 && rows > 0)
 
   SET_FRAME_ICONIFIED (emacsframe, 0);
   SET_FRAME_VISIBLE (emacsframe, 1);
-  windows_or_buffers_changed++;
+  windows_or_buffers_changed = 63;
 
   if (emacs_event)
     {
@@ -6089,8 +6208,29 @@ if (cols > 0 && rows > 0)
       [self windowDidBecomeKey:notification];
       [nonfs_window orderOut:self];
     }
-  else if (! FRAME_EXTERNAL_TOOL_BAR (emacsframe))
-    [toolbar setVisible:NO];
+  else
+    {
+      BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (emacsframe) ? YES : NO;
+#ifdef NS_IMPL_COCOA
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+      unsigned val = (unsigned)[NSApp presentationOptions];
+
+      // OSX 10.7 bug fix, the menu won't appear without this.
+      // val is non-zero on other OSX versions.
+      if (val == 0)
+        {
+          NSApplicationPresentationOptions options
+            = NSApplicationPresentationAutoHideDock
+            | NSApplicationPresentationAutoHideMenuBar
+            | NSApplicationPresentationFullScreen
+            | NSApplicationPresentationAutoHideToolbar;
+
+          [NSApp setPresentationOptions: options];
+        }
+#endif
+#endif
+      [toolbar setVisible:tbar_visible];
+    }
 }
 
 - (void)windowWillExitFullScreen:(NSNotification *)notification
@@ -6103,7 +6243,7 @@ if (cols > 0 && rows > 0)
 {
   [self setFSValue: fs_before_fs];
   fs_before_fs = -1;
-#ifdef NS_IMPL_COCOA
+#ifdef HAVE_NATIVE_FS
   [self updateCollectionBehaviour];
 #endif
   if (FRAME_EXTERNAL_TOOL_BAR (emacsframe))
@@ -6164,7 +6304,7 @@ if (cols > 0 && rows > 0)
 
   if (fs_is_native)
     {
-#ifdef NS_IMPL_COCOA
+#ifdef HAVE_NATIVE_FS
       [[self window] toggleFullScreen:sender];
 #endif
       return;
@@ -6335,7 +6475,9 @@ if (cols > 0 && rows > 0)
 - (void)mouseEntered: (NSEvent *)theEvent
 {
   NSTRACE (mouseEntered);
-  last_mouse_movement_time = EV_TIMESTAMP (theEvent);
+  if (emacsframe)
+    FRAME_DISPLAY_INFO (emacsframe)->last_mouse_movement_time
+      = EV_TIMESTAMP (theEvent);
 }
 
 
@@ -6348,7 +6490,8 @@ if (cols > 0 && rows > 0)
   if (!hlinfo)
     return;
 
-  last_mouse_movement_time = EV_TIMESTAMP (theEvent);
+  FRAME_DISPLAY_INFO (emacsframe)->last_mouse_movement_time
+    = EV_TIMESTAMP (theEvent);
 
   if (emacsframe == hlinfo->mouse_face_mouse_frame)
     {
@@ -7208,6 +7351,7 @@ Lisp_Object
 x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
 {
   struct font *font = XFONT_OBJECT (font_object);
+  EmacsView *view = FRAME_NS_VIEW (f);
 
   if (fontset < 0)
     fontset = fontset_from_font (font_object);
@@ -7240,8 +7384,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
     }
 
   /* Now make the frame display the given font.  */
-  if (FRAME_NS_WINDOW (f) != 0)
-       x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+  if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen])
+    x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+                       FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1);
 
   return font_object;
 }
@@ -7411,12 +7556,6 @@ allowing it to be used at a lower level for accented character entry.");
                "Whether to confirm application quit using dialog.");
   ns_confirm_quit = Qnil;
 
-  staticpro (&ns_display_name_list);
-  ns_display_name_list = Qnil;
-
-  staticpro (&last_mouse_motion_frame);
-  last_mouse_motion_frame = Qnil;
-
   DEFVAR_LISP ("ns-auto-hide-menu-bar", ns_auto_hide_menu_bar,
                doc: /* Non-nil means that the menu bar is hidden, but appears when the mouse is near.
 Only works on OSX 10.6 or later.  */);
@@ -7462,11 +7601,17 @@ baseline level.  The default value is nil.  */);
   /* Tell Emacs about this window system.  */
   Fprovide (Qns, Qnil);
 
+  DEFSYM (Qcocoa, "cocoa");
+  DEFSYM (Qgnustep, "gnustep");
+
   syms_of_nsfont ();
 #ifdef NS_IMPL_COCOA
+  Fprovide (Qcocoa, Qnil);
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
   syms_of_macfont ();
 #endif
+#else
+  Fprovide (Qgnustep, Qnil);
 #endif
-  
+
 }