========================================================================== */
+// 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;
[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
[self setFrameSize:self.image.size];
isAttached = true;
+ mView = view;
[[[view window] contentView] addSubview:self
positioned:NSWindowAbove
relativeTo:nil];
-(void)remove
{
+ NSTRACE ("[EmacsBell remove]");
if (isAttached)
{
+ NSTRACE_MSG ("removeFromSuperview");
[self removeFromSuperview];
+ mView.needsDisplay = YES;
isAttached = false;
}
}
Ensure the bell is hidden.
-------------------------------------------------------------------------- */
{
+ NSTRACE ("hide_bell");
+
if (bell_view != nil)
{
[bell_view remove];
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.