/* display update */
static int ns_window_num = 0;
+static BOOL gsaved = NO;
static BOOL ns_fake_keydown = NO;
#ifdef NS_IMPL_COCOA
static BOOL ns_menu_bar_is_hidden = NO;
NSRectClipList (r, 2);
else
NSRectClip (*r);
+ gsaved = YES;
return YES;
}
{
NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping");
- [[NSGraphicsContext currentContext] restoreGraphicsState];
+ if (gsaved)
+ {
+ [[NSGraphicsContext currentContext] restoreGraphicsState];
+ gsaved = NO;
+ }
+}
+
+
+static BOOL
+ns_clip_to_row (struct window *w, struct glyph_row *row,
+ enum glyph_row_area area, BOOL gc)
+/* --------------------------------------------------------------------------
+ Internal (but parallels other terms): Focus drawing on given row
+ -------------------------------------------------------------------------- */
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+ NSRect clip_rect;
+ int window_x, window_y, window_width;
+
+ window_box (w, area, &window_x, &window_y, &window_width, 0);
+
+ clip_rect.origin.x = window_x;
+ clip_rect.origin.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
+ clip_rect.origin.y = max (clip_rect.origin.y, window_y);
+ clip_rect.size.width = window_width;
+ clip_rect.size.height = row->visible_height;
+
+ return ns_clip_to_rect (f, &clip_rect, 1);
+}
+
+
+static void
+ns_flush_display (struct frame *f)
+/* Force the frame to redisplay. If areas have previously been marked
+ dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call
+ draw_rect: which will "expose" those areas. */
+{
+ block_input ();
+ [FRAME_NS_VIEW (f) displayIfNeeded];
+ unblock_input ();
}
static void
ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
{
- NSSize delta = NSMakeSize (dest.origin.x - src.origin.x,
- dest.origin.y - src.origin.y);
NSTRACE ("ns_copy_bits");
if (FRAME_NS_VIEW (f))
/* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is
no obvious replacement so we may have to come up with our own. */
- [FRAME_NS_VIEW (f) scrollRect: src by: delta];
-
-#ifdef NS_IMPL_COCOA
- /* As far as I can tell from the documentation, scrollRect:by:,
- above, should copy the dirty rectangles from our source
- rectangle to our destination, however it appears it clips the
- operation to src. As a result we need to use
- translateRectsNeedingDisplayInRect:by: below, and we have to
- union src and dest so it can pick up the dirty rectangles,
- and place them, as it also clips to the rectangle.
-
- FIXME: We need a GNUstep equivalent. */
- [FRAME_NS_VIEW (f) translateRectsNeedingDisplayInRect:NSUnionRect (src, dest)
- by:delta];
-#endif
+ [FRAME_NS_VIEW (f) scrollRect: src
+ by: NSMakeSize (dest.origin.x - src.origin.x,
+ dest.origin.y - src.origin.y)];
+ [FRAME_NS_VIEW (f) setNeedsDisplay:YES];
}
}
else
[FRAME_CURSOR_COLOR (f) set];
+#ifdef NS_IMPL_COCOA
+ /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
+ atomic. Cleaner ways of doing this should be investigated.
+ One way would be to set a global variable DRAWING_CURSOR
+ when making the call to draw_phys..(), don't focus in that
+ case, then move the ns_reset_clipping() here after that call. */
+ NSDisableScreenUpdates ();
+#endif
+
switch (cursor_type)
{
case DEFAULT_CURSOR:
if (cursor_type == FILLED_BOX_CURSOR || cursor_type == HOLLOW_BOX_CURSOR)
draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
- ns_reset_clipping (f);
- }
- else if (! redisplaying_p)
- {
- /* If this function is called outside redisplay, it probably
- means we need an immediate update. */
- [FRAME_NS_VIEW (f) display];
+#ifdef NS_IMPL_COCOA
+ NSEnableScreenUpdates ();
+#endif
}
}
size_title = xmalloc (strlen (old_title) + 40);
esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows);
[window setTitle: [NSString stringWithUTF8String: size_title]];
+ [window display];
xfree (size_title);
}
}
- (void)drawRect: (NSRect)rect
{
- const NSRect *rectList;
- NSInteger numRects;
+ int x = NSMinX (rect), y = NSMinY (rect);
+ int width = NSWidth (rect), height = NSHeight (rect);
NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]",
NSTRACE_ARG_RECT(rect));
if (!emacsframe || !emacsframe->output_data.ns)
return;
+ ns_clear_frame_area (emacsframe, x, y, width, height);
block_input ();
-
- /* Get only the precise dirty rectangles to avoid redrawing
- potentially large areas of the frame that haven't changed.
-
- I'm not sure this actually provides much of a performance benefit
- as it's hard to benchmark, but it certainly doesn't seem to
- hurt. */
- [self getRectsBeingDrawn:&rectList count:&numRects];
- for (int i = 0 ; i < numRects ; i++)
- {
- NSRect r = rectList[i];
-
- NSTRACE_RECT ("r", r);
-
- expose_frame (emacsframe,
- NSMinX (r), NSMinY (r),
- NSWidth (r), NSHeight (r));
- }
-
+ expose_frame (emacsframe, x, y, width, height);
unblock_input ();
/*