From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alan Third Newsgroups: gmane.emacs.bugs Subject: bug#32932: [PATCH v2] Fix more drawing bugs in NS port (bug#32932) Date: Fri, 9 Nov 2018 09:08:55 +0000 Message-ID: <20181109090855.GA31723@breton.holly.idiocy.org> References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: blaine.gmane.org 1541754505 18676 195.159.176.226 (9 Nov 2018 09:08:25 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 9 Nov 2018 09:08:25 +0000 (UTC) User-Agent: Mutt/1.10.1 (2018-07-13) Cc: boris@d12frosted.io, 32932@debbugs.gnu.org To: Aaron Jensen Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Nov 09 10:08:20 2018 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gL2m3-0004gM-FX for geb-bug-gnu-emacs@m.gmane.org; Fri, 09 Nov 2018 10:08:19 +0100 Original-Received: from localhost ([::1]:32777 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL2o9-0000dM-RR for geb-bug-gnu-emacs@m.gmane.org; Fri, 09 Nov 2018 04:10:29 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:47984) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gL2nw-0000cS-Uo for bug-gnu-emacs@gnu.org; Fri, 09 Nov 2018 04:10:18 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gL2nr-00028U-P3 for bug-gnu-emacs@gnu.org; Fri, 09 Nov 2018 04:10:16 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:37941) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gL2ni-0001ul-LP for bug-gnu-emacs@gnu.org; Fri, 09 Nov 2018 04:10:06 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gL2ni-0002gb-Fa for bug-gnu-emacs@gnu.org; Fri, 09 Nov 2018 04:10:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Third Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 09 Nov 2018 09:10:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 32932 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 32932-submit@debbugs.gnu.org id=B32932.154175454710239 (code B ref 32932); Fri, 09 Nov 2018 09:10:02 +0000 Original-Received: (at 32932) by debbugs.gnu.org; 9 Nov 2018 09:09:07 +0000 Original-Received: from localhost ([127.0.0.1]:42195 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gL2mo-0002f5-Mj for submit@debbugs.gnu.org; Fri, 09 Nov 2018 04:09:07 -0500 Original-Received: from mail-wr1-f48.google.com ([209.85.221.48]:44715) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gL2mm-0002eZ-Qj for 32932@debbugs.gnu.org; Fri, 09 Nov 2018 04:09:05 -0500 Original-Received: by mail-wr1-f48.google.com with SMTP id j17-v6so1038234wrq.11 for <32932@debbugs.gnu.org>; Fri, 09 Nov 2018 01:09:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=MG7cJY6KACcEgOOEy7nYsb50x0fzR8+QdUoHuACEuoU=; b=qtppOQqtisQvh0+nYG3hw7LXbWbtCHJsny8WB65cCJDXEDQxQQnWaB+9nzLp5IPrxx 0N/ON4bVBBzARGqSedVGwtB7fITsCgz8Cp6R9DSn1gJvRkTbRCQpavkyS0cOanGwwKyZ YIolkXrzxu7vkM2O1MI46voDV6GnIehBX248eBwW6nMOgRgPNXepc0oHz5MueOYRBJfk c1cs7obBerYsK79Oyh++31Mq2j+AK3o/vhCgYex73lWIXLOlX11tzsL9j/Ci2wnz7bBU NVCh6x08O+COeSA7JUjfZ1gebIhdFoeZH2vbkNRf75EmlwAG4JanpDOMIpcMhmU9WAWG Tj6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition:in-reply-to:user-agent; bh=MG7cJY6KACcEgOOEy7nYsb50x0fzR8+QdUoHuACEuoU=; b=BYtDXJz/RhBLufojvp4KvZ2vKrGHusC6sP0Xp8OEukG161iED46vziz5Cqk9aqfaXB oAeYFxcNl9HLeeR15lwPONvw7T2pNzMf4MAQB6U5nAx1d/FBFWHATwI0n4WlMtkj5uy6 VVyNbHr1hPLtXIYzT/aC71hwWGClnMykL03X7S8rtFCU1amRiYKlCgkBesME654WozAd dMY6SZI9JSBX/oWUTnqSFa7QRFB+qJe7tR0BfS8L8b9nuG6wu7ABixXHqmEOE/+uA5tm mY0P9E1IfILZ/gZOLYXk46V2/E2SfvGncTcgUY0JguEQlHidoGWBPtjPCWbBctRg+C87 Fbvw== X-Gm-Message-State: AGRZ1gLTWZGpeEoH5mcjN5LAWyI1WOSdtoxDZnYlyGeu91PX5Hka7niO A0QAHcnRS0HW425LgTZFN1BWMhu8Q0k= X-Google-Smtp-Source: AJdET5eHVXUsM0r7jfbdM2YHCHi+jFVs+YfniciNsG3/g4fjl2/VWNIWOzSpulMUHvn8IYIMx8S9Ag== X-Received: by 2002:adf:97d3:: with SMTP id t19-v6mr7472961wrb.283.1541754539041; Fri, 09 Nov 2018 01:08:59 -0800 (PST) Original-Received: from breton.holly.idiocy.org (ip6-2001-08b0-03f8-8129-8cfe-35d9-62a3-d426.holly.idiocy.org. [2001:8b0:3f8:8129:8cfe:35d9:62a3:d426]) by smtp.gmail.com with ESMTPSA id z8sm6468161wrw.78.2018.11.09.01.08.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Nov 2018 01:08:58 -0800 (PST) Content-Disposition: inline In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:152201 Archived-At: * src/nsterm.m (ns_row_rect): New function. (ns_clip_to_row): Remove function. (ns_copy_bits): Fix mistake. (ns_draw_fringe_bitmap): Stop using ns_clip_to_row. (ns_draw_window_cursor): Stop using ns_clip_to_row and perform a display when not in redisplay. (ns_update_window_begin): Remove redundant code that never executes. ([EmacsView drawRect:]): Show the rectangle being exposed in NSTRACE. * src/xdisp.c (expose_window_tree) [HAVE_NS]: (expose_frame) [HAVE_NS]: Redraw even if the frame is garbaged. --- I realised about 4AM that I'd screwed this up. This one should replace the previous patch. Sorry for the hassle. src/nsterm.m | 137 +++++++++++++++++++++++++-------------------------- src/xdisp.c | 8 ++- 2 files changed, 75 insertions(+), 70 deletions(-) diff --git a/src/nsterm.m b/src/nsterm.m index 4b5d025ee3..9e6779d4a3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -796,6 +796,27 @@ Free a pool and temporary objects it refers to (callable from C) } +static NSRect +ns_row_rect (struct window *w, struct glyph_row *row, + enum glyph_row_area area) +/* Get the row as an NSRect. */ +{ + struct frame *f = XFRAME (WINDOW_FRAME (w)); + NSRect rect; + int window_x, window_y, window_width; + + window_box (w, area, &window_x, &window_y, &window_width, 0); + + rect.origin.x = window_x; + rect.origin.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y)); + rect.origin.y = max (rect.origin.y, window_y); + rect.size.width = window_width; + rect.size.height = row->visible_height; + + return rect; +} + + /* ========================================================================== Focus (clipping) and screen update @@ -1048,29 +1069,6 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) if (! tbar_visible != ! [toolbar isVisible]) [toolbar setVisible: tbar_visible]; } - - /* drawRect may have been called for say the minibuffer, and then clip path - is for the minibuffer. But the display engine may draw more because - we have set the frame as garbaged. So reset clip path to the whole - view. */ - /* FIXME: I don't think we need to do this. */ - if ([NSView focusView] == FRAME_NS_VIEW (f)) - { - NSBezierPath *bp; - NSRect r = [view frame]; - NSRect cr = [[view window] frame]; - /* If a large frame size is set, r may be larger than the window frame - before constrained. In that case don't change the clip path, as we - will clear in to the tool bar and title bar. */ - if (r.size.height - + FRAME_NS_TITLEBAR_HEIGHT (f) - + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) - { - bp = [[NSBezierPath bezierPathWithRect: r] retain]; - [bp setClip]; - [bp release]; - } - } #endif } @@ -1206,28 +1204,6 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen) } -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); -} - /* ========================================================================== Visible bell and beep. @@ -2692,7 +2668,7 @@ so some key presses (TAB) are swallowed by the system. */ 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) + dest.origin.y - src.origin.y); NSTRACE ("ns_copy_bits"); if (FRAME_NS_VIEW (f)) @@ -2911,6 +2887,9 @@ so some key presses (TAB) are swallowed by the system. */ struct face *face = p->face; static EmacsImage **bimgs = NULL; static int nBimgs = 0; + NSRect clearRect = NSZeroRect; + NSRect imageRect = NSZeroRect; + NSRect rowRect = ns_row_rect (w, row, ANY_AREA); NSTRACE_WHEN (NSTRACE_GROUP_FRINGE, "ns_draw_fringe_bitmap"); NSTRACE_MSG ("which:%d cursor:%d overlay:%d width:%d height:%d period:%d", @@ -2925,25 +2904,40 @@ so some key presses (TAB) are swallowed by the system. */ nBimgs = max_used_fringe_bitmap; } - /* Must clip because of partially visible lines. */ - if (ns_clip_to_row (w, row, ANY_AREA, YES)) + /* Work out the rectangle we will composite into. */ + if (p->which) + imageRect = NSMakeRect (p->x, p->y, p->wd, p->h); + + /* Work out the rectangle we will need to clear. Because we're + compositing rather than blitting, we need to clear the area under + the image regardless of anything else. */ + if (!p->overlay_p) { - if (!p->overlay_p) + clearRect = NSMakeRect (p->bx, p->by, p->nx, p->ny); + clearRect = NSUnionRect (clearRect, imageRect); + } + else + { + clearRect = imageRect; + } + + /* Handle partially visible rows. */ + clearRect = NSIntersectionRect (clearRect, rowRect); + + /* The visible portion of imageRect will always be contained within + clearRect. */ + if (ns_clip_to_rect (f, &clearRect, 1)) + { + if (! NSIsEmptyRect (clearRect)) { - int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny; + NSTRACE_RECT ("clearRect", clearRect); - if (bx >= 0 && nx > 0) - { - NSRect r = NSMakeRect (bx, by, nx, ny); - NSRectClip (r); - [ns_lookup_indexed_color (face->background, f) set]; - NSRectFill (r); - } + [ns_lookup_indexed_color(face->background, f) set]; + NSRectFill (clearRect); } if (p->which) { - NSRect r = NSMakeRect (p->x, p->y, p->wd, p->h); EmacsImage *img = bimgs[p->which - 1]; if (!img) @@ -2964,13 +2958,6 @@ so some key presses (TAB) are swallowed by the system. */ xfree (cbits); } - NSTRACE_RECT ("r", r); - - NSRectClip (r); - /* Since we composite the bitmap instead of just blitting it, we need - to erase the whole background. */ - [ns_lookup_indexed_color(face->background, f) set]; - NSRectFill (r); { NSColor *bm_color; @@ -2990,7 +2977,7 @@ so some key presses (TAB) are swallowed by the system. */ NSTRACE_RECT ("fromRect", fromRect); - [img drawInRect: r + [img drawInRect: imageRect fromRect: fromRect operation: NSCompositingOperationSourceOver fraction: 1.0 @@ -2998,7 +2985,7 @@ so some key presses (TAB) are swallowed by the system. */ hints: nil]; #else { - NSPoint pt = r.origin; + NSPoint pt = imageRect.origin; pt.y += p->h; [img compositeToPoint: pt operation: NSCompositingOperationSourceOver]; } @@ -3088,7 +3075,9 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. r.size.width = w->phys_cursor_width; /* Prevent the cursor from being drawn outside the text area. */ - if (ns_clip_to_row (w, glyph_row, TEXT_AREA, NO)) + r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA)); + + if (ns_clip_to_rect (f, &r, 1)) { face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id); if (face && NS_FACE_BACKGROUND (face) @@ -3128,11 +3117,18 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. NSRectFill (s); break; } - ns_reset_clipping (f); /* draw the character under the cursor */ if (cursor_type != NO_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]; } } @@ -8096,6 +8092,9 @@ - (void)drawRect: (NSRect)rect 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)); diff --git a/src/xdisp.c b/src/xdisp.c index 357f0fb30c..a59a62fb93 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -32258,7 +32258,11 @@ expose_window_tree (struct window *w, XRectangle *r) struct frame *f = XFRAME (w->frame); bool mouse_face_overwritten_p = false; - while (w && !FRAME_GARBAGED_P (f)) + while (w +#if !defined (HAVE_NS) + && !FRAME_GARBAGED_P (f) +#endif + ) { mouse_face_overwritten_p |= (WINDOWP (w->contents) @@ -32286,12 +32290,14 @@ expose_frame (struct frame *f, int x, int y, int w, int h) TRACE ((stderr, "expose_frame ")); +#if !defined (HAVE_NS) /* No need to redraw if frame will be redrawn soon. */ if (FRAME_GARBAGED_P (f)) { TRACE ((stderr, " garbaged\n")); return; } +#endif /* If basic faces haven't been realized yet, there is no point in trying to redraw anything. This can happen when we get an expose -- 2.19.1 -- Alan Third