summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Lindgren <andlind@gmail.com>2016-03-17 21:07:04 +0100
committerAnders Lindgren <andlind@gmail.com>2016-03-17 21:07:04 +0100
commit1df7173eb23510ef5faabede04a487955aec2917 (patch)
tree836f4a39f614abe3fefcd735f047153c9ebbd364
parent7a2edd3427b8006805c8fd293c2e481114776e4d (diff)
downloademacs-1df7173eb23510ef5faabede04a487955aec2917.tar.gz
Avoid screen artifacts with new OS X visible bell after scrolling
* src/nsterm.m (EmacsBell): Save NSView when displaying the visible bell and set `needsDisplay' when removed. (hide_bell): Trace. (ns_copy_bits): Trace.
-rw-r--r--src/nsterm.m30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index 38aa4a3a413..b796193af77 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1172,10 +1172,31 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
========================================================================== */
+// This bell implementation shows the visual bell image asynchronously
+// from the rest of Emacs. This is done by adding a NSView to the
+// superview of the Emacs window and removing it using a timer.
+//
+// Unfortunately, some Emacs operations, like scrolling, is done using
+// low-level primitives that copy the content of the window, including
+// the bell image. To some extent, this is handled by removing the
+// image prior to scrolling and marking that the window is in need for
+// redisplay.
+//
+// To test this code, make sure that there is no artifacts of the bell
+// image in the following situations. Use a non-empty buffer (like the
+// tutorial) to ensure that a scroll is performed:
+//
+// * Single-window: C-g C-v
+//
+// * Side-by-windows: C-x 3 C-g C-v
+//
+// * Windows above each other: C-x 2 C-g C-v
+
@interface EmacsBell : NSImageView
{
// Number of currently active bell:s.
unsigned int nestCount;
+ NSView * mView;
bool isAttached;
}
- (void)show:(NSView *)view;
@@ -1204,7 +1225,6 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
[self.image unlockFocus];
#else
self.image = [NSImage imageNamed:NSImageNameCaution];
- [self.image setScalesWhenResized:YES];
[self.image setSize:NSMakeSize(self.image.size.width * 5,
self.image.size.height * 5)];
#endif
@@ -1229,6 +1249,7 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
[self setFrameSize:self.image.size];
isAttached = true;
+ mView = view;
[[[view window] contentView] addSubview:self
positioned:NSWindowAbove
relativeTo:nil];
@@ -1258,9 +1279,12 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
-(void)remove
{
+ NSTRACE ("[EmacsBell remove]");
if (isAttached)
{
+ NSTRACE_MSG ("removeFromSuperview");
[self removeFromSuperview];
+ mView.needsDisplay = YES;
isAttached = false;
}
}
@@ -1310,6 +1334,8 @@ static void hide_bell ()
Ensure the bell is hidden.
-------------------------------------------------------------------------- */
{
+ NSTRACE ("hide_bell");
+
if (bell_view != nil)
{
[bell_view remove];
@@ -2392,6 +2418,8 @@ 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)
{
+ NSTRACE ("ns_copy_bits");
+
if (FRAME_NS_VIEW (f))
{
hide_bell(); // Ensure the bell image isn't scrolled.