aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Third2018-10-14 19:12:00 +0100
committerAlan Third2018-10-24 11:32:23 +0100
commit7e8eee60a9dbb0c59cf26f237b21efe7fd1043c9 (patch)
treef30088bfeb0bd46f1f0ac420d88c54edc910b758 /src
parentd72975a654e5effe86625126ba7f2923c8e2f9d2 (diff)
downloademacs-7e8eee60a9dbb0c59cf26f237b21efe7fd1043c9.tar.gz
emacs-7e8eee60a9dbb0c59cf26f237b21efe7fd1043c9.zip
Fix some NS drawing issues (bug#32932)
* src/nsterm.m (ns_clip_to_rect): (ns_reset_clipping): Remove gsaved variable and associated code. (ns_flush_display): Remove function. (ns_copy_bits): use translateRectsNeedingDisplayInRect:by: to copy any pending drawing actions along with the image. ([EmacsView windowWillResize:toSize:]): Remove unneeded call. ([EmacsView drawRect:]): Remove redundant call to ns_clear_frame_area, and optimize the exposed rectangles. (ns_draw_window_cursor): Remove unneeded disabling of screen updates.
Diffstat (limited to 'src')
-rw-r--r--src/nsterm.m80
1 files changed, 37 insertions, 43 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index 8c355a89f8f..4b5d025ee3c 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -277,7 +277,6 @@ long context_menu_value = 0;
277 277
278/* display update */ 278/* display update */
279static int ns_window_num = 0; 279static int ns_window_num = 0;
280static BOOL gsaved = NO;
281static BOOL ns_fake_keydown = NO; 280static BOOL ns_fake_keydown = NO;
282#ifdef NS_IMPL_COCOA 281#ifdef NS_IMPL_COCOA
283static BOOL ns_menu_bar_is_hidden = NO; 282static BOOL ns_menu_bar_is_hidden = NO;
@@ -1180,7 +1179,6 @@ ns_clip_to_rect (struct frame *f, NSRect *r, int n)
1180 NSRectClipList (r, 2); 1179 NSRectClipList (r, 2);
1181 else 1180 else
1182 NSRectClip (*r); 1181 NSRectClip (*r);
1183 gsaved = YES;
1184 1182
1185 return YES; 1183 return YES;
1186 } 1184 }
@@ -1204,11 +1202,7 @@ ns_reset_clipping (struct frame *f)
1204{ 1202{
1205 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping"); 1203 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping");
1206 1204
1207 if (gsaved) 1205 [[NSGraphicsContext currentContext] restoreGraphicsState];
1208 {
1209 [[NSGraphicsContext currentContext] restoreGraphicsState];
1210 gsaved = NO;
1211 }
1212} 1206}
1213 1207
1214 1208
@@ -1234,19 +1228,6 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
1234 return ns_clip_to_rect (f, &clip_rect, 1); 1228 return ns_clip_to_rect (f, &clip_rect, 1);
1235} 1229}
1236 1230
1237
1238static void
1239ns_flush_display (struct frame *f)
1240/* Force the frame to redisplay. If areas have previously been marked
1241 dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call
1242 draw_rect: which will "expose" those areas. */
1243{
1244 block_input ();
1245 [FRAME_NS_VIEW (f) displayIfNeeded];
1246 unblock_input ();
1247}
1248
1249
1250/* ========================================================================== 1231/* ==========================================================================
1251 1232
1252 Visible bell and beep. 1233 Visible bell and beep.
@@ -2710,6 +2691,8 @@ ns_clear_frame_area (struct frame *f, int x, int y, int width, int height)
2710static void 2691static void
2711ns_copy_bits (struct frame *f, NSRect src, NSRect dest) 2692ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
2712{ 2693{
2694 NSSize delta = NSMakeSize (dest.origin.x - src.origin.x,
2695 dest.origin.y - src.origin.y)
2713 NSTRACE ("ns_copy_bits"); 2696 NSTRACE ("ns_copy_bits");
2714 2697
2715 if (FRAME_NS_VIEW (f)) 2698 if (FRAME_NS_VIEW (f))
@@ -2718,10 +2701,21 @@ ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
2718 2701
2719 /* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is 2702 /* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is
2720 no obvious replacement so we may have to come up with our own. */ 2703 no obvious replacement so we may have to come up with our own. */
2721 [FRAME_NS_VIEW (f) scrollRect: src 2704 [FRAME_NS_VIEW (f) scrollRect: src by: delta];
2722 by: NSMakeSize (dest.origin.x - src.origin.x, 2705
2723 dest.origin.y - src.origin.y)]; 2706#ifdef NS_IMPL_COCOA
2724 [FRAME_NS_VIEW (f) setNeedsDisplay:YES]; 2707 /* As far as I can tell from the documentation, scrollRect:by:,
2708 above, should copy the dirty rectangles from our source
2709 rectangle to our destination, however it appears it clips the
2710 operation to src. As a result we need to use
2711 translateRectsNeedingDisplayInRect:by: below, and we have to
2712 union src and dest so it can pick up the dirty rectangles,
2713 and place them, as it also clips to the rectangle.
2714
2715 FIXME: We need a GNUstep equivalent. */
2716 [FRAME_NS_VIEW (f) translateRectsNeedingDisplayInRect:NSUnionRect (src, dest)
2717 by:delta];
2718#endif
2725 } 2719 }
2726} 2720}
2727 2721
@@ -3106,15 +3100,6 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3106 else 3100 else
3107 [FRAME_CURSOR_COLOR (f) set]; 3101 [FRAME_CURSOR_COLOR (f) set];
3108 3102
3109#ifdef NS_IMPL_COCOA
3110 /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
3111 atomic. Cleaner ways of doing this should be investigated.
3112 One way would be to set a global variable DRAWING_CURSOR
3113 when making the call to draw_phys..(), don't focus in that
3114 case, then move the ns_reset_clipping() here after that call. */
3115 NSDisableScreenUpdates ();
3116#endif
3117
3118 switch (cursor_type) 3103 switch (cursor_type)
3119 { 3104 {
3120 case DEFAULT_CURSOR: 3105 case DEFAULT_CURSOR:
@@ -3148,10 +3133,6 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3148 /* draw the character under the cursor */ 3133 /* draw the character under the cursor */
3149 if (cursor_type != NO_CURSOR) 3134 if (cursor_type != NO_CURSOR)
3150 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 3135 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
3151
3152#ifdef NS_IMPL_COCOA
3153 NSEnableScreenUpdates ();
3154#endif
3155 } 3136 }
3156} 3137}
3157 3138
@@ -4977,7 +4958,7 @@ static struct redisplay_interface ns_redisplay_interface =
4977 ns_after_update_window_line, 4958 ns_after_update_window_line,
4978 ns_update_window_begin, 4959 ns_update_window_begin,
4979 ns_update_window_end, 4960 ns_update_window_end,
4980 ns_flush_display, /* flush_display */ 4961 0, /* flush_display */
4981 x_clear_window_mouse_face, 4962 x_clear_window_mouse_face,
4982 x_get_glyph_overhangs, 4963 x_get_glyph_overhangs,
4983 x_fix_overlapping_area, 4964 x_fix_overlapping_area,
@@ -7046,7 +7027,6 @@ not_in_argv (NSString *arg)
7046 size_title = xmalloc (strlen (old_title) + 40); 7027 size_title = xmalloc (strlen (old_title) + 40);
7047 esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows); 7028 esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows);
7048 [window setTitle: [NSString stringWithUTF8String: size_title]]; 7029 [window setTitle: [NSString stringWithUTF8String: size_title]];
7049 [window display];
7050 xfree (size_title); 7030 xfree (size_title);
7051 } 7031 }
7052 } 7032 }
@@ -8095,8 +8075,8 @@ not_in_argv (NSString *arg)
8095 8075
8096- (void)drawRect: (NSRect)rect 8076- (void)drawRect: (NSRect)rect
8097{ 8077{
8098 int x = NSMinX (rect), y = NSMinY (rect); 8078 const NSRect *rectList;
8099 int width = NSWidth (rect), height = NSHeight (rect); 8079 NSInteger numRects;
8100 8080
8101 NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]", 8081 NSTRACE ("[EmacsView drawRect:" NSTRACE_FMT_RECT "]",
8102 NSTRACE_ARG_RECT(rect)); 8082 NSTRACE_ARG_RECT(rect));
@@ -8104,9 +8084,23 @@ not_in_argv (NSString *arg)
8104 if (!emacsframe || !emacsframe->output_data.ns) 8084 if (!emacsframe || !emacsframe->output_data.ns)
8105 return; 8085 return;
8106 8086
8107 ns_clear_frame_area (emacsframe, x, y, width, height);
8108 block_input (); 8087 block_input ();
8109 expose_frame (emacsframe, x, y, width, height); 8088
8089 /* Get only the precise dirty rectangles to avoid redrawing
8090 potentially large areas of the frame that haven't changed.
8091
8092 I'm not sure this actually provides much of a performance benefit
8093 as it's hard to benchmark, but it certainly doesn't seem to
8094 hurt. */
8095 [self getRectsBeingDrawn:&rectList count:&numRects];
8096 for (int i = 0 ; i < numRects ; i++)
8097 {
8098 NSRect r = rectList[i];
8099 expose_frame (emacsframe,
8100 NSMinX (r), NSMinY (r),
8101 NSWidth (r), NSHeight (r));
8102 }
8103
8110 unblock_input (); 8104 unblock_input ();
8111 8105
8112 /* 8106 /*