aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGlenn Morris2018-11-28 07:51:11 -0800
committerGlenn Morris2018-11-28 07:51:11 -0800
commitb58e8b82ededfb314e385d97df1efed2ce84f4db (patch)
tree2f8caac832104f1825349740693e1497e50b6a4e /src
parentfebdedfa8d43258edc4e0f2debd3910e073e9326 (diff)
parent094fcf62d289f19a4633275812e9e5e500463e91 (diff)
downloademacs-b58e8b82ededfb314e385d97df1efed2ce84f4db.tar.gz
emacs-b58e8b82ededfb314e385d97df1efed2ce84f4db.zip
Merge from origin/emacs-26
094fcf6 Fix more drawing bugs in NS port (bug#32932)
Diffstat (limited to 'src')
-rw-r--r--src/nsterm.m149
-rw-r--r--src/xdisp.c15
2 files changed, 91 insertions, 73 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index bcc23ffeaff..07978c0d3b8 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -850,6 +850,27 @@ ns_menu_bar_height (NSScreen *screen)
850} 850}
851 851
852 852
853static NSRect
854ns_row_rect (struct window *w, struct glyph_row *row,
855 enum glyph_row_area area)
856/* Get the row as an NSRect. */
857{
858 struct frame *f = XFRAME (WINDOW_FRAME (w));
859 NSRect rect;
860 int window_x, window_y, window_width;
861
862 window_box (w, area, &window_x, &window_y, &window_width, 0);
863
864 rect.origin.x = window_x;
865 rect.origin.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
866 rect.origin.y = max (rect.origin.y, window_y);
867 rect.size.width = window_width;
868 rect.size.height = row->visible_height;
869
870 return rect;
871}
872
873
853/* ========================================================================== 874/* ==========================================================================
854 875
855 Focus (clipping) and screen update 876 Focus (clipping) and screen update
@@ -1102,29 +1123,6 @@ ns_update_begin (struct frame *f)
1102 if (! tbar_visible != ! [toolbar isVisible]) 1123 if (! tbar_visible != ! [toolbar isVisible])
1103 [toolbar setVisible: tbar_visible]; 1124 [toolbar setVisible: tbar_visible];
1104 } 1125 }
1105
1106 /* drawRect may have been called for say the minibuffer, and then clip path
1107 is for the minibuffer. But the display engine may draw more because
1108 we have set the frame as garbaged. So reset clip path to the whole
1109 view. */
1110 /* FIXME: I don't think we need to do this. */
1111 if ([NSView focusView] == FRAME_NS_VIEW (f))
1112 {
1113 NSBezierPath *bp;
1114 NSRect r = [view frame];
1115 NSRect cr = [[view window] frame];
1116 /* If a large frame size is set, r may be larger than the window frame
1117 before constrained. In that case don't change the clip path, as we
1118 will clear in to the tool bar and title bar. */
1119 if (r.size.height
1120 + FRAME_NS_TITLEBAR_HEIGHT (f)
1121 + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height)
1122 {
1123 bp = [[NSBezierPath bezierPathWithRect: r] retain];
1124 [bp setClip];
1125 [bp release];
1126 }
1127 }
1128#endif 1126#endif
1129} 1127}
1130 1128
@@ -1260,28 +1258,6 @@ ns_reset_clipping (struct frame *f)
1260} 1258}
1261 1259
1262 1260
1263static BOOL
1264ns_clip_to_row (struct window *w, struct glyph_row *row,
1265 enum glyph_row_area area, BOOL gc)
1266/* --------------------------------------------------------------------------
1267 Internal (but parallels other terms): Focus drawing on given row
1268 -------------------------------------------------------------------------- */
1269{
1270 struct frame *f = XFRAME (WINDOW_FRAME (w));
1271 NSRect clip_rect;
1272 int window_x, window_y, window_width;
1273
1274 window_box (w, area, &window_x, &window_y, &window_width, 0);
1275
1276 clip_rect.origin.x = window_x;
1277 clip_rect.origin.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
1278 clip_rect.origin.y = max (clip_rect.origin.y, window_y);
1279 clip_rect.size.width = window_width;
1280 clip_rect.size.height = row->visible_height;
1281
1282 return ns_clip_to_rect (f, &clip_rect, 1);
1283}
1284
1285/* ========================================================================== 1261/* ==========================================================================
1286 1262
1287 Visible bell and beep. 1263 Visible bell and beep.
@@ -2819,7 +2795,7 @@ static void
2819ns_copy_bits (struct frame *f, NSRect src, NSRect dest) 2795ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
2820{ 2796{
2821 NSSize delta = NSMakeSize (dest.origin.x - src.origin.x, 2797 NSSize delta = NSMakeSize (dest.origin.x - src.origin.x,
2822 dest.origin.y - src.origin.y) 2798 dest.origin.y - src.origin.y);
2823 NSTRACE ("ns_copy_bits"); 2799 NSTRACE ("ns_copy_bits");
2824 2800
2825 if (FRAME_NS_VIEW (f)) 2801 if (FRAME_NS_VIEW (f))
@@ -2952,12 +2928,20 @@ ns_shift_glyphs_for_insert (struct frame *f,
2952 External (RIF): copy an area horizontally, don't worry about clearing src 2928 External (RIF): copy an area horizontally, don't worry about clearing src
2953 -------------------------------------------------------------------------- */ 2929 -------------------------------------------------------------------------- */
2954{ 2930{
2955 NSRect srcRect = NSMakeRect (x, y, width, height); 2931 //NSRect srcRect = NSMakeRect (x, y, width, height);
2956 NSRect dstRect = NSMakeRect (x+shift_by, y, width, height); 2932 NSRect dstRect = NSMakeRect (x+shift_by, y, width, height);
2957 2933
2958 NSTRACE ("ns_shift_glyphs_for_insert"); 2934 NSTRACE ("ns_shift_glyphs_for_insert");
2959 2935
2960 ns_copy_bits (f, srcRect, dstRect); 2936 /* This doesn't work now as we copy the "bits" before we've had a
2937 chance to actually draw any changes to the screen. This means in
2938 certain circumstances we end up with copies of the cursor all
2939 over the place. Just mark the area dirty so it is redrawn later.
2940
2941 FIXME: Work out how to do this properly. */
2942 // ns_copy_bits (f, srcRect, dstRect);
2943
2944 [FRAME_NS_VIEW (f) setNeedsDisplayInRect:dstRect];
2961} 2945}
2962 2946
2963 2947
@@ -3038,6 +3022,9 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3038 struct face *face = p->face; 3022 struct face *face = p->face;
3039 static EmacsImage **bimgs = NULL; 3023 static EmacsImage **bimgs = NULL;
3040 static int nBimgs = 0; 3024 static int nBimgs = 0;
3025 NSRect clearRect = NSZeroRect;
3026 NSRect imageRect = NSZeroRect;
3027 NSRect rowRect = ns_row_rect (w, row, ANY_AREA);
3041 3028
3042 NSTRACE_WHEN (NSTRACE_GROUP_FRINGE, "ns_draw_fringe_bitmap"); 3029 NSTRACE_WHEN (NSTRACE_GROUP_FRINGE, "ns_draw_fringe_bitmap");
3043 NSTRACE_MSG ("which:%d cursor:%d overlay:%d width:%d height:%d period:%d", 3030 NSTRACE_MSG ("which:%d cursor:%d overlay:%d width:%d height:%d period:%d",
@@ -3052,25 +3039,40 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3052 nBimgs = max_used_fringe_bitmap; 3039 nBimgs = max_used_fringe_bitmap;
3053 } 3040 }
3054 3041
3055 /* Must clip because of partially visible lines. */ 3042 /* Work out the rectangle we will composite into. */
3056 if (ns_clip_to_row (w, row, ANY_AREA, YES)) 3043 if (p->which)
3044 imageRect = NSMakeRect (p->x, p->y, p->wd, p->h);
3045
3046 /* Work out the rectangle we will need to clear. Because we're
3047 compositing rather than blitting, we need to clear the area under
3048 the image regardless of anything else. */
3049 if (!p->overlay_p)
3050 {
3051 clearRect = NSMakeRect (p->bx, p->by, p->nx, p->ny);
3052 clearRect = NSUnionRect (clearRect, imageRect);
3053 }
3054 else
3055 {
3056 clearRect = imageRect;
3057 }
3058
3059 /* Handle partially visible rows. */
3060 clearRect = NSIntersectionRect (clearRect, rowRect);
3061
3062 /* The visible portion of imageRect will always be contained within
3063 clearRect. */
3064 if (ns_clip_to_rect (f, &clearRect, 1))
3057 { 3065 {
3058 if (!p->overlay_p) 3066 if (! NSIsEmptyRect (clearRect))
3059 { 3067 {
3060 int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny; 3068 NSTRACE_RECT ("clearRect", clearRect);
3061 3069
3062 if (bx >= 0 && nx > 0) 3070 [ns_lookup_indexed_color(face->background, f) set];
3063 { 3071 NSRectFill (clearRect);
3064 NSRect r = NSMakeRect (bx, by, nx, ny);
3065 NSRectClip (r);
3066 [ns_lookup_indexed_color (face->background, f) set];
3067 NSRectFill (r);
3068 }
3069 } 3072 }
3070 3073
3071 if (p->which) 3074 if (p->which)
3072 { 3075 {
3073 NSRect r = NSMakeRect (p->x, p->y, p->wd, p->h);
3074 EmacsImage *img = bimgs[p->which - 1]; 3076 EmacsImage *img = bimgs[p->which - 1];
3075 3077
3076 if (!img) 3078 if (!img)
@@ -3091,13 +3093,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3091 xfree (cbits); 3093 xfree (cbits);
3092 } 3094 }
3093 3095
3094 NSTRACE_RECT ("r", r);
3095
3096 NSRectClip (r);
3097 /* Since we composite the bitmap instead of just blitting it, we need
3098 to erase the whole background. */
3099 [ns_lookup_indexed_color(face->background, f) set];
3100 NSRectFill (r);
3101 3096
3102 { 3097 {
3103 NSColor *bm_color; 3098 NSColor *bm_color;
@@ -3117,7 +3112,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3117 3112
3118 NSTRACE_RECT ("fromRect", fromRect); 3113 NSTRACE_RECT ("fromRect", fromRect);
3119 3114
3120 [img drawInRect: r 3115 [img drawInRect: imageRect
3121 fromRect: fromRect 3116 fromRect: fromRect
3122 operation: NSCompositingOperationSourceOver 3117 operation: NSCompositingOperationSourceOver
3123 fraction: 1.0 3118 fraction: 1.0
@@ -3125,7 +3120,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3125 hints: nil]; 3120 hints: nil];
3126#else 3121#else
3127 { 3122 {
3128 NSPoint pt = r.origin; 3123 NSPoint pt = imageRect.origin;
3129 pt.y += p->h; 3124 pt.y += p->h;
3130 [img compositeToPoint: pt operation: NSCompositingOperationSourceOver]; 3125 [img compositeToPoint: pt operation: NSCompositingOperationSourceOver];
3131 } 3126 }
@@ -3215,7 +3210,9 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3215 r.size.width = w->phys_cursor_width; 3210 r.size.width = w->phys_cursor_width;
3216 3211
3217 /* Prevent the cursor from being drawn outside the text area. */ 3212 /* Prevent the cursor from being drawn outside the text area. */
3218 if (ns_clip_to_row (w, glyph_row, TEXT_AREA, NO)) 3213 r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
3214
3215 if (ns_clip_to_rect (f, &r, 1))
3219 { 3216 {
3220 face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id); 3217 face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
3221 if (face && NS_FACE_BACKGROUND (face) 3218 if (face && NS_FACE_BACKGROUND (face)
@@ -3255,11 +3252,18 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3255 NSRectFill (s); 3252 NSRectFill (s);
3256 break; 3253 break;
3257 } 3254 }
3258 ns_reset_clipping (f);
3259 3255
3260 /* draw the character under the cursor */ 3256 /* draw the character under the cursor */
3261 if (cursor_type != NO_CURSOR) 3257 if (cursor_type != NO_CURSOR)
3262 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 3258 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
3259
3260 ns_reset_clipping (f);
3261 }
3262 else if (! redisplaying_p)
3263 {
3264 /* If this function is called outside redisplay, it probably
3265 means we need an immediate update. */
3266 [FRAME_NS_VIEW (f) display];
3263 } 3267 }
3264} 3268}
3265 3269
@@ -8165,6 +8169,9 @@ not_in_argv (NSString *arg)
8165 for (int i = 0 ; i < numRects ; i++) 8169 for (int i = 0 ; i < numRects ; i++)
8166 { 8170 {
8167 NSRect r = rectList[i]; 8171 NSRect r = rectList[i];
8172
8173 NSTRACE_RECT ("r", r);
8174
8168 expose_frame (emacsframe, 8175 expose_frame (emacsframe,
8169 NSMinX (r), NSMinY (r), 8176 NSMinX (r), NSMinY (r),
8170 NSWidth (r), NSHeight (r)); 8177 NSWidth (r), NSHeight (r));
diff --git a/src/xdisp.c b/src/xdisp.c
index fa7691cdd0f..a0113a05190 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -32360,7 +32360,14 @@ expose_window_tree (struct window *w, XRectangle *r)
32360 struct frame *f = XFRAME (w->frame); 32360 struct frame *f = XFRAME (w->frame);
32361 bool mouse_face_overwritten_p = false; 32361 bool mouse_face_overwritten_p = false;
32362 32362
32363 while (w && !FRAME_GARBAGED_P (f)) 32363 /* NS toolkits may have aleady modified the frame in expectation of
32364 a successful redraw, so don't bail out here if the frame is
32365 garbaged. */
32366 while (w
32367#if !defined (HAVE_NS)
32368 && !FRAME_GARBAGED_P (f)
32369#endif
32370 )
32364 { 32371 {
32365 mouse_face_overwritten_p 32372 mouse_face_overwritten_p
32366 |= (WINDOWP (w->contents) 32373 |= (WINDOWP (w->contents)
@@ -32388,12 +32395,16 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
32388 32395
32389 TRACE ((stderr, "expose_frame ")); 32396 TRACE ((stderr, "expose_frame "));
32390 32397
32391 /* No need to redraw if frame will be redrawn soon. */ 32398#if !defined (HAVE_NS)
32399 /* No need to redraw if frame will be redrawn soon except under NS
32400 where the toolkit may have already modified the frame in
32401 expectation of us redrawing it. */
32392 if (FRAME_GARBAGED_P (f)) 32402 if (FRAME_GARBAGED_P (f))
32393 { 32403 {
32394 TRACE ((stderr, " garbaged\n")); 32404 TRACE ((stderr, " garbaged\n"));
32395 return; 32405 return;
32396 } 32406 }
32407#endif
32397 32408
32398 /* If basic faces haven't been realized yet, there is no point in 32409 /* If basic faces haven't been realized yet, there is no point in
32399 trying to redraw anything. This can happen when we get an expose 32410 trying to redraw anything. This can happen when we get an expose