From ac6e620adc479a9e8c93c8ad787c3071aaefca23 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sun, 28 Jul 2019 15:10:29 +0100 Subject: [PATCH] Revert "Fix some NS drawing issues (bug#32932)" This reverts commit 7e8eee60a9dbb0c59cf26f237b21efe7fd1043c9. --- src/nsterm.m | 109 +++++++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index fd23bf6b2c9..c2b95ad3cc0 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -288,6 +288,7 @@ long context_menu_value = 0; /* 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; @@ -1150,6 +1151,7 @@ ns_clip_to_rect (struct frame *f, NSRect *r, int n) NSRectClipList (r, 2); else NSRectClip (*r); + gsaved = YES; return YES; } @@ -1173,7 +1175,46 @@ ns_reset_clipping (struct frame *f) { 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 (); } @@ -2813,8 +2854,6 @@ ns_clear_frame_area (struct frame *f, int x, int y, int width, int height) 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)) @@ -2823,21 +2862,10 @@ ns_copy_bits (struct frame *f, NSRect src, NSRect dest) /* 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]; } } @@ -3236,6 +3264,15 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, 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: @@ -3270,13 +3307,9 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, 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 } } @@ -7169,6 +7202,7 @@ not_in_argv (NSString *arg) 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); } } @@ -8218,8 +8252,8 @@ not_in_argv (NSString *arg) - (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)); @@ -8227,26 +8261,9 @@ not_in_argv (NSString *arg) 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 (); /* -- 2.39.2