From: Alan Third <alan@idiocy.org>
To: Aaron Jensen <aaronjensen@gmail.com>
Cc: Boris Buliga <boris@d12frosted.io>, 32932@debbugs.gnu.org
Subject: bug#32932: [PATCH v2] Fix more drawing bugs in NS port (bug#32932)
Date: Fri, 23 Nov 2018 18:17:54 +0000 [thread overview]
Message-ID: <20181123181754.GB24527@breton.holly.idiocy.org> (raw)
In-Reply-To: <CAHyO48zDDD2oPTOF9qW3K35whjhivR7ADhB9B5113vtoGWOGkw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1325 bytes --]
On Mon, Nov 19, 2018 at 06:30:05PM -0800, Aaron Jensen wrote:
> On November 19, 2018 at 2:35:51 PM, Alan Third
> (alan@idiocy.org(mailto:alan@idiocy.org)) wrote:
>
> > Given that Emacs 26.2 is in pre‐release now I’m inclined to leave
> > emacs-26 as‐is for now, unless we require the 8th of November patch
> > (Further changes to NS drawing (bug#32932))? I don’t think we do as
> > iirc it just solves a minor redrawing issue (i.e. Emacs is still
> > usable without it). Is that right?
>
> Yes, it is still usable, though if I remember correctly it lessens the
> overall blank glitches (which still happen even w/ the patch). So yes,
> it’s usable, but you do occasionally have to resize the window or do
> something else to get it to repaint. You still have to w/ the patch,
> just less often.
Final (hopefully) version of this patch attached.
I guess there are still issues with it, but we’re running out of time
to sort them for Emacs 26.2.
From a practical stand point I don’t think this is really any
different from the last one, but it has some comment changes and a
change to how we handle requests to copy parts of the screen, since
they were the major issue still with ghosting cursors.
I probably need to double check it’s OK on GNUstep, but I don’t
foresee any issues there.
--
Alan Third
[-- Attachment #2: v3-0001-Fix-more-drawing-bugs-in-NS-port-bug-32932.patch --]
[-- Type: text/plain, Size: 11236 bytes --]
From a55e5259341e054023727de4dc86b77c7a7d5db6 Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Mon, 29 Oct 2018 15:37:35 +0000
Subject: [PATCH v3] Fix more drawing bugs in NS port (bug#32932)
* src/nsterm.m (ns_row_rect): New function.
(ns_clip_to_row): Remove function.
(ns_copy_bits): Fix mistake.
(ns_shift_glyphs_for_insert): Mark the frame as dirty instead of
directly copying.
(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.
---
src/nsterm.m | 149 +++++++++++++++++++++++++++------------------------
src/xdisp.c | 15 +++++-
2 files changed, 91 insertions(+), 73 deletions(-)
diff --git a/src/nsterm.m b/src/nsterm.m
index 4b5d025ee3..948dd1da2e 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))
@@ -2825,12 +2801,20 @@ so some key presses (TAB) are swallowed by the system. */
External (RIF): copy an area horizontally, don't worry about clearing src
-------------------------------------------------------------------------- */
{
- NSRect srcRect = NSMakeRect (x, y, width, height);
+ //NSRect srcRect = NSMakeRect (x, y, width, height);
NSRect dstRect = NSMakeRect (x+shift_by, y, width, height);
NSTRACE ("ns_shift_glyphs_for_insert");
- ns_copy_bits (f, srcRect, dstRect);
+ /* This doesn't work now as we copy the "bits" before we've had a
+ chance to actually draw any changes to the screen. This means in
+ certain circumstances we end up with copies of the cursor all
+ over the place. Just mark the area dirty so it is redrawn later.
+
+ FIXME: Work out how to do this properly. */
+ // ns_copy_bits (f, srcRect, dstRect);
+
+ [FRAME_NS_VIEW (f) setNeedsDisplayInRect:dstRect];
}
@@ -2911,6 +2895,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 +2912,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)
+ {
+ 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 (!p->overlay_p)
+ 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 +2966,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 +2985,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 +2993,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 +3083,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 +3125,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 +8100,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..808eab7e53 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -32258,7 +32258,14 @@ 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))
+ /* NS toolkits may have aleady modified the frame in expectation of
+ a successful redraw, so don't bail out here if the frame is
+ garbaged. */
+ while (w
+#if !defined (HAVE_NS)
+ && !FRAME_GARBAGED_P (f)
+#endif
+ )
{
mouse_face_overwritten_p
|= (WINDOWP (w->contents)
@@ -32286,12 +32293,16 @@ expose_frame (struct frame *f, int x, int y, int w, int h)
TRACE ((stderr, "expose_frame "));
- /* No need to redraw if frame will be redrawn soon. */
+#if !defined (HAVE_NS)
+ /* No need to redraw if frame will be redrawn soon except under NS
+ where the toolkit may have already modified the frame in
+ expectation of us redrawing it. */
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
next prev parent reply other threads:[~2018-11-23 18:17 UTC|newest]
Thread overview: 144+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-04 13:05 bug#32932: 27.0.50; render bugs on macOS Mojave Aaron Jensen
2018-10-04 14:07 ` Alan Third
2018-10-04 17:33 ` Charles A. Roelli
2018-10-04 17:48 ` Aaron Jensen
2018-10-04 18:25 ` Alan Third
[not found] ` <CAHyO48xS6yOWVvw2Gu+Hjumahe5BC3-EA+Mwztz4831Ac2U6aA@mail.gmail.com>
2018-10-04 18:45 ` Alan Third
2018-10-04 21:51 ` Alan Third
2018-10-04 23:03 ` Aaron Jensen
[not found] ` <CAHyO48zMuX95RB7hRYxAxt6wH_XB6sF1kmnbWZWmjpPhnkqjdg@mail.gmail.com>
2018-10-09 7:15 ` Boris Buliga
2018-10-10 18:27 ` Alan Third
2018-10-11 3:40 ` Aaron Jensen
2018-10-14 8:19 ` Aaron Jensen
2018-10-14 9:04 ` Boris Buliga
2018-10-14 18:20 ` Alan Third
2018-10-14 20:17 ` Aaron Jensen
2018-10-16 4:53 ` Boris Buliga
2018-10-16 8:39 ` Boris Buliga
2018-10-16 19:04 ` Aaron Jensen
2018-10-19 16:26 ` Aaron Jensen
2018-10-19 18:48 ` Alan Third
2018-10-19 19:24 ` Aaron Jensen
2018-10-20 20:04 ` Alan Third
2018-10-23 2:15 ` Aaron Jensen
2018-10-24 10:42 ` Alan Third
2018-10-29 2:18 ` Aaron Jensen
2018-10-29 16:09 ` Alan Third
2018-10-29 17:41 ` Boris Buliga
2018-10-30 5:56 ` Aaron Jensen
2018-10-30 15:35 ` Boris Buliga
2018-10-31 21:59 ` Alan Third
2018-11-01 4:25 ` Aaron Jensen
2018-10-31 17:12 ` Alan Third
2018-11-01 4:51 ` Aaron Jensen
2018-11-01 4:58 ` Aaron Jensen
2018-11-01 5:11 ` Aaron Jensen
2018-11-01 6:13 ` Boris Buliga
2018-11-01 6:51 ` Aaron Jensen
2018-11-01 18:10 ` Eli Zaretskii
2018-11-01 19:52 ` Aaron Jensen
2018-11-01 20:12 ` Eli Zaretskii
2018-11-01 20:29 ` Aaron Jensen
2018-11-03 9:23 ` Eli Zaretskii
2018-11-01 22:55 ` Alan Third
2018-11-03 9:31 ` Eli Zaretskii
2018-11-03 20:36 ` Alan Third
2018-11-03 21:03 ` Eli Zaretskii
2018-11-04 13:24 ` Alan Third
2018-11-04 20:11 ` Alan Third
2018-11-05 16:11 ` Aaron Jensen
2018-11-05 18:55 ` Alan Third
2018-11-06 4:04 ` Aaron Jensen
2018-11-06 14:58 ` Aaron Jensen
2018-11-08 15:21 ` Alan Third
2018-11-08 15:35 ` Eli Zaretskii
2018-11-08 16:17 ` Alan Third
2018-11-08 16:28 ` Aaron Jensen
2018-11-08 23:21 ` Alan Third
2018-11-09 1:02 ` Aaron Jensen
2018-11-09 9:08 ` bug#32932: [PATCH v2] Fix more drawing bugs in NS port (bug#32932) Alan Third
2018-11-09 13:45 ` Aaron Jensen
2018-11-09 14:15 ` Aaron Jensen
2018-11-13 22:13 ` Alan Third
2018-11-14 17:08 ` Aaron Jensen
2018-11-14 18:19 ` Alan Third
2018-11-16 1:20 ` Aaron Jensen
2018-11-19 22:35 ` Alan Third
2018-11-20 2:30 ` Aaron Jensen
2018-11-23 18:17 ` Alan Third [this message]
2018-11-26 16:20 ` Aaron Jensen
2019-01-25 14:02 ` Aaron Jensen
2019-01-25 22:01 ` Alan Third
2018-11-09 8:02 ` bug#32932: 27.0.50; render bugs on macOS Mojave Eli Zaretskii
2018-11-08 16:51 ` Eli Zaretskii
2018-11-08 23:23 ` Alan Third
2018-11-03 17:57 ` Aaron Jensen
2018-11-03 19:09 ` Alan Third
2018-11-03 20:51 ` Alan Third
2018-11-03 23:56 ` Aaron Jensen
2018-11-04 13:24 ` Alan Third
2018-11-04 17:12 ` Aaron Jensen
2018-11-04 18:28 ` Eli Zaretskii
2018-10-04 19:43 ` Aaron Jensen
2018-11-03 17:56 ` Aaron Jensen
2018-11-03 18:17 ` Eli Zaretskii
2018-11-05 16:20 ` Aaron Jensen
2018-11-27 1:42 ` bug#32932: 26.2: Too many flickers with normal operations on macOS 10.13.6 Zhang Haijun
2019-11-11 18:16 ` bug#32932: 27.0.50; render bugs on macOS Mojave Alan Third
2019-11-12 13:27 ` Robert Pluim
2019-11-12 14:38 ` Alan Third
2020-01-25 12:44 ` Alan Third
2020-01-25 13:37 ` Eli Zaretskii
2020-01-27 11:06 ` Robert Pluim
2020-01-27 20:45 ` Alan Third
2020-01-28 3:21 ` Eli Zaretskii
2020-01-28 18:23 ` Alan Third
2020-01-28 19:35 ` Aaron Jensen
2020-01-28 20:07 ` Eli Zaretskii
2020-01-28 20:11 ` Aaron Jensen
2020-01-28 20:21 ` Eli Zaretskii
2020-01-28 20:24 ` Aaron Jensen
2020-01-29 10:08 ` Alan Third via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-01-29 16:32 ` Aaron Jensen
2020-01-29 20:04 ` Alan Third
2020-01-30 1:40 ` Aaron Jensen
2020-01-30 19:11 ` Alan Third
2020-01-30 20:07 ` Aaron Jensen
2020-01-31 14:57 ` Robert Pluim
2020-01-31 20:23 ` Alan Third
2020-01-31 20:26 ` Aaron Jensen
2020-02-01 1:26 ` Aaron Jensen
2020-02-01 14:22 ` Alan Third
2020-02-01 16:29 ` Aaron Jensen
2020-02-01 21:20 ` Alan Third
2020-02-01 23:05 ` Aaron Jensen
2020-02-02 13:42 ` Alan Third
2020-01-31 1:16 ` Stefan Kangas
2020-01-31 21:34 ` Mattias Engdegård
2020-02-02 12:31 ` Mattias Engdegård
2020-02-02 13:46 ` Alan Third
2020-02-02 16:49 ` Aaron Jensen
2020-02-02 22:30 ` Alan Third
2020-02-02 22:44 ` Mattias Engdegård
2020-02-03 0:14 ` Aaron Jensen
2020-02-03 7:39 ` Alan Third
2020-02-03 8:16 ` Aaron Jensen
2020-02-03 20:44 ` Alan Third
2020-02-03 20:46 ` Aaron Jensen
2020-02-03 21:30 ` Alan Third
2020-02-06 18:04 ` Aaron Jensen
2020-02-07 20:18 ` Alan Third
2020-02-08 1:26 ` Aaron Jensen
2020-02-08 14:13 ` Alan Third
2020-02-08 16:45 ` Aaron Jensen
2020-02-10 7:44 ` Alan Third
2020-02-10 15:21 ` Aaron Jensen
2020-02-10 17:14 ` Aaron Jensen
2020-02-10 21:33 ` Alan Third
2020-02-13 17:24 ` Aaron Jensen
2020-02-13 18:32 ` Alan Third
2020-02-03 16:04 ` Mattias Engdegård
2020-02-03 16:05 ` Aaron Jensen
2020-02-03 16:09 ` Mattias Engdegård
2020-02-03 21:28 ` Alan Third
2020-02-10 8:59 ` Robert Pluim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181123181754.GB24527@breton.holly.idiocy.org \
--to=alan@idiocy.org \
--cc=32932@debbugs.gnu.org \
--cc=aaronjensen@gmail.com \
--cc=boris@d12frosted.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).