unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11
@ 2015-10-11  3:41 Steve Purcell
  2015-10-11 14:31 ` Spike Ilacqua
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Steve Purcell @ 2015-10-11  3:41 UTC (permalink / raw)
  To: 21662


I'm using snapshot builds from emacsformacosx.com on my Macbook, and I
have `visible-bell' set to t. Since upgrading OS X from 10.10 to 10.11 I
see display artifacts: specifically, there appears to be no redraw after
the visible bell square flashes in the centre of the frame, so the frame
contents are left obscured or blurred.

I had initially noticed this with an older snapshot build, and have
verified that it still occurs using the latest snapshot (dated Oct
10).

Happy to provide further info upon request.



In GNU Emacs 25.0.50.1 (x86_64-apple-darwin13.4.0, NS appkit-1265.21 Version 10.9.5 (Build 13F1112))
 of 2015-10-10
Windowing system distributor 'Apple', version 10.3.1404
Configured using:
 'configure --with-ns '--enable-locallisppath=/Library/Application
 Support/Emacs/${version}/site-lisp:/Library/Application
 Support/Emacs/site-lisp''

Configured features:
ACL LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS

Important settings:
  value of $LC_CTYPE: en_US.UTF-8
  value of $LANG: en_US
  locale-coding-system: utf-8

Major mode: Emacs-Lisp

Minor modes in effect:
  shell-dirtrack-mode: t
  global-flycheck-mode: t
  flycheck-mode: t
  elisp-slime-nav-mode: t
  redshank-mode: t
  aggressive-indent-mode: t
  rainbow-delimiters-mode: t
  highlight-quoted-mode: t
  highlight-symbol-nav-mode: t
  highlight-symbol-mode: t
  diff-hl-mode: t
  diff-auto-refine-mode: t
  bug-reference-prog-mode: t
  paredit-mode: t
  goto-address-prog-mode: t
  auto-insert-mode: t
  auto-compile-on-load-mode: t
  auto-compile-on-save-mode: t
  auto-compile-mode: t
  ipretty-mode: t
  global-rinari-mode: t
  guide-key-mode: t
  hes-mode: t
  global-page-break-lines-mode: t
  page-break-lines-mode: t
  delete-selection-mode: t
  cua-mode: t
  show-paren-mode: t
  global-undo-tree-mode: t
  undo-tree-mode: t
  global-whitespace-cleanup-mode: t
  whitespace-cleanup-mode: t
  global-auto-revert-mode: t
  electric-pair-mode: t
  savehist-mode: t
  desktop-save-mode: t
  winner-mode: t
  global-auto-complete-mode: t
  auto-complete-mode: t
  ido-ubiquitous-mode: t
  ido-everywhere: t
  recentf-mode: t
  global-anzu-mode: t
  anzu-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  global-prettify-symbols-mode: t
  prettify-symbols-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Recent messages:
Desktop: 26.79ms to restore nil
Desktop: 24.35ms to restore nil
Wrote /Users/steve/.emacs.d/.emacs.desktop.lock
Desktop: 1 frame, 72 buffers restored.
Desktop restored in 12698.73ms
For information about GNU Emacs and the GNU system, type C-h C-a.
Evaluating...
t
Quit [3 times]
Press key for agenda command:

Load-path shadows:
/Users/steve/.emacs.d/elpa/helm-20151009.1117/helm-multi-match hides /Users/steve/.emacs.d/elpa/helm-core-20151009.905/helm-multi-match
/Users/steve/.emacs.d/elpa/emms-20150810.832/tq hides /Applications/Emacs.app/Contents/Resources/lisp/emacs-lisp/tq

Features:
(shadow sort mail-extr emacsbug message rfc822 mml mml-sec mailabbrev
gmm-utils mailheader sendmail mail-utils smex cal-iso diary-lib
diary-loaddefs hl-line org-agenda gitconfig-mode conf-mode mmm-sample
mmm-mode mmm-univ mmm-class smerge-mode tidy css-eldoc
css-eldoc-hash-table css-mode yaml-mode markdown-mode cursor-sensor
js2-imenu-extras js2-mode sql-indent sql package-build mm-decode
mm-bodies mm-encode checkdoc cap-words superword subword robe url-http
tls url-auth mail-parse rfc2231 rfc2047 rfc2045 ietf-drums url-gw url
url-proxy url-privacy url-expand url-methods url-history url-cookie
url-domsuf url-util url-parse auth-source mm-util help-fns mail-prsvr
password-cache url-vars mailcap tabify view rainbow-mode color
org-element org-rmail org-mhe org-irc org-info org-gnus gnus-util
org-docview doc-view image-mode org-bibtex bibtex org-bbdb org-w3m
ob-sqlite ob-sh shell ob-ruby ob-python ob-octave ob-ledger ob-latex
ob-gnuplot ob-dot ob-ditaa ob-R org-clock org org-macro org-footnote
org-pcomplete org-list org-faces org-entities noutline outline
org-version ob-emacs-lisp ob ob-tangle ob-ref ob-lob ob-table ob-exp
org-src ob-keys ob-comint ob-core ob-eval org-compat org-macs
org-loaddefs cal-menu calendar cal-loaddefs mmm-erb mmm-region mmm-utils
tagedit sgml-mode json-mode json-reformat json-snatcher js cc-mode
cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars
cc-defs vc-mtn vc-hg vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs
diff-hl-dired dired-sort dired+ image-dired format-spec image-file
dired-x dired-aux dired disp-table vc-git vc-darcs xml flycheck-package
lisp-mnt flycheck find-func subr-x flymake elisp-slime-nav etags xref
project redshank skeleton aggressive-indent rainbow-delimiters
highlight-quoted highlight-symbol diff-hl vc-dir ewoc vc vc-dispatcher
diff-mode bug-reference paredit-everywhere paredit goto-addr init
init-locales init-local session sanityinc-tomorrow-bright-theme
color-theme-sanityinc-tomorrow autoinsert cus-start cus-load server
jka-compr init-ledger init-dash init-misc init-common-lisp
init-clojure-cider init-clojure init-slime init-lisp cl-lib-highlight
auto-compile packed ipretty pp init-paredit init-sql init-rails rinari
json jump inflections findr ruby-compilation which-func imenu pcomplete
inf-ruby compile comint ansi-color ruby-mode smie init-ruby-mode derived
init-elm init-haskell init-python-mode init-haml init-css init-html
init-nxml init-org init-php init-javascript easy-mmode init-erlang
erlang-start init-csv init-markdown init-textile init-crontab
init-compile init-github init-git init-darcs init-vc init-editing-utils
guide-key s ucs-normalize popwin dash highlight-escape-sequences
whole-line-or-region page-break-lines delsel cua-base paren undo-tree
diff whitespace-cleanup-mode whitespace autorevert filenotify elec-pair
init-mmm mmm-auto mmm-vars mmm-compat init-fonts init-sessions savehist
desktop frameset init-windows windmove switch-window quail winner ring
init-auto-complete auto-complete-config auto-complete popup
init-hippie-expand init-ido ido-ubiquitous ido-completing-read+ ido seq
init-recentf recentf tree-widget wid-edit init-flycheck init-ibuffer
ibuf-macs init-uniquify init-grep init-isearch diminish anzu thingatpt
init-dired init-gui-frames init-osx-keys edmacro kmacro init-themes
init-xterm init-frame-hooks init-exec-path exec-path-from-shell
init-elpa fullframe finder-inf eieio byte-opt bytecomp byte-compile
cl-extra help-mode cconv eieio-core rx cl-macs slime-autoloads info
package easymenu epg-config init-site-lisp cl-seq cl gv cl-loaddefs
pcase cl-lib init-utils init-compat init-benchmarking advice time-date
mule-util tooltip eldoc electric uniquify ediff-hook vc-hooks
lisp-float-type mwheel ns-win term/common-win tool-bar dnd fontset image
regexp-opt fringe tabulated-list newcomment elisp-mode lisp-mode
prog-mode register page menu-bar rfn-eshadow timer select scroll-bar
mouse jit-lock font-lock syntax facemenu font-core frame cl-generic cham
georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese charscript case-table epa-hook
jka-cmpr-hook help simple abbrev minibuffer cl-preloaded nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote cocoa ns multi-tty
make-network-process emacs)

Memory information:
((conses 16 1076507 477227)
 (symbols 48 57378 0)
 (miscs 40 7194 9146)
 (strings 32 159666 250836)
 (string-bytes 1 4581130)
 (vectors 16 113288)
 (vector-slots 8 1498997 875754)
 (floats 8 1030 1234)
 (intervals 56 30825 2420)
 (buffers 976 93))





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11
  2015-10-11  3:41 bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11 Steve Purcell
@ 2015-10-11 14:31 ` Spike Ilacqua
  2015-10-14  2:13 ` Mustafa Kocaturk
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Spike Ilacqua @ 2015-10-11 14:31 UTC (permalink / raw)
  To: 21662

I can confirm this issue exists in 24.5.50 (build from source) as well. It appear with the upgrade to El Capitan and persists after rebuilding from scratch.






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11
  2015-10-11  3:41 bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11 Steve Purcell
  2015-10-11 14:31 ` Spike Ilacqua
@ 2015-10-14  2:13 ` Mustafa Kocaturk
  2015-10-22 14:41 ` Mustafa Kocaturk
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Mustafa Kocaturk @ 2015-10-14  2:13 UTC (permalink / raw)
  To: 21662; +Cc: steve

Hi,

The current implementation of the visual bell on NextStep is to cache and redraw a rectangle on the current Emacs frame *from outside the NextStep run loop*. It seems this was good enough so far but is no longer a particularly supported one for the latest Mac OS X version.
Maintaining it might still be possible, only with sufficient effort and caution.

Alternative: Switch to an implementation that is particularly supported in this release of OS X, as follows:
Create a temporary NSView object and attach it to the selected EmacsView object.
This new subview draws itself, starts an NSTimer, with a callback in the current NS run loop. 
When the timer expires the callback is entered, which updates, hides, and finally removes the subview from its superview.
The view is garbage collected, all as part of the NS run loop. 
The required change is small: Add a NSView-derived class in nsterm.m and replace old cache/draw/restore code with new temporary local instance of this new class.

Best regards,
Mustafa






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11
  2015-10-11  3:41 bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11 Steve Purcell
  2015-10-11 14:31 ` Spike Ilacqua
  2015-10-14  2:13 ` Mustafa Kocaturk
@ 2015-10-22 14:41 ` Mustafa Kocaturk
  2015-10-22 16:07   ` Mustafa Kocaturk
  2015-11-18 20:27 ` bug#21662: " Anders Lindgren
  2015-11-23 22:09 ` bug#21662: Fixed Anders Lindgren
  4 siblings, 1 reply; 8+ messages in thread
From: Mustafa Kocaturk @ 2015-10-22 14:41 UTC (permalink / raw)
  To: 21662; +Cc: murskt

Implemented a patch with a few small corrections to the proposed solution:
> Create a temporary NSView object and attach it to the selected EmacsView object.

Not temporary, but a shared instance, a singleton.

> This new subview draws itself, starts an NSTimer, with a callback in the 
> current NS run loop. 

Instead of starting a timer, the subview sends itself a message with delay.

> When the timer expires the callback is entered, which updates, hides, and 
> finally removes the subview from its superview.
> The view is garbage collected, all as part of the NS run loop. 

The view is retained for re-use.

> The required change is small: Add a NSView-derived class in nsterm.m and 
> replace old cache/draw/restore code with new temporary local instance of this 
> new class.

As already mentioned, not temporary, but retained.

Patch follows.

diff --git a/src/nsterm.m b/src/nsterm.m
index c4bfd7c..f16ebe2 100644
--- src/nsterm.m~
+++ src/nsterm.m
@@ -987,6 +987,59 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
 }
 
 
+@interface BellView : NSImageView {
+    NSColor *bellColor;
+}
+
+@property(readwrite,copy) NSColor *bellColor;
+
+- (IBAction)ring:(id)sender;
+@end
+
+@implementation BellView
+@synthesize bellColor;
+
+- (id)initWithFrame:(NSRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) { self.image=[NSApp applicationIconImage]; }
+  return self;
+}
+
++ (instancetype)sharedInstance {
+  static id _si=nil;
+  static dispatch_once_t onceT;
+  dispatch_once(&onceT, ^{ _si=[[self alloc] init]; });
+  return _si;
+}
+
+- (BOOL)isOpaque {
+  return NO;
+}
+
+static const CGFloat BELL_T = 0.2;
+
+- (IBAction)ring:(NSView*)nv color:(NSColor*)fg {
+  self.hidden=NO;
+  self.image=[NSImage imageNamed:NSImageNameCaution];
+  NSRect dr=[nv bounds];
+  dr.origin.x+=(dr.size.width-self.image.size.width)/2;
+  dr.origin.y+=(dr.size.height-self.image.size.height)/2;
+  [self setFrameOrigin:dr.origin];
+  [self setFrameSize:self.image.size];
+  /* find a use for color fg */
+  [nv addSubview:self];
+  [self setNeedsDisplay:YES];
+  [self performSelector:@selector(dismiss) withObject:self afterDelay:BELL_T];
+}
+
+- (void)dismiss {
+    self.hidden=YES;
+    [self setNeedsDisplay:YES];
+    [self removeFromSuperview];
+}
+
+@end
+
 static void
 ns_ring_bell (struct frame *f)
 /* --------------------------------------------------------------------------
@@ -996,41 +1049,18 @@ ns_ring_bell (struct frame *f)
   NSTRACE (ns_ring_bell);
   if (visible_bell)
     {
-      NSAutoreleasePool *pool;
       struct frame *frame = SELECTED_FRAME ();
       NSView *view;
 
       block_input ();
-      pool = [[NSAutoreleasePool alloc] init];
 
       view = FRAME_NS_VIEW (frame);
-      if (view != nil)
-        {
-          NSRect r, surr;
-          NSPoint dim = NSMakePoint (128, 128);
-
-          r = [view bounds];
-          r.origin.x += (r.size.width - dim.x) / 2;
-          r.origin.y += (r.size.height - dim.y) / 2;
-          r.size.width = dim.x;
-          r.size.height = dim.y;
-          surr = NSInsetRect (r, -2, -2);
-          ns_focus (frame, &surr, 1);
-          [[view window] cacheImageInRect: [view convertRect: surr toView:nil]];
-          [ns_lookup_indexed_color (NS_FACE_FOREGROUND
-                                      (FRAME_DEFAULT_FACE (frame)), frame) set];
-          NSRectFill (r);
-          [[view window] flushWindow];
-          ns_timeout (150000);
-          [[view window] restoreCachedImage];
-          [[view window] flushWindow];
-          ns_unfocus (frame);
+      if (view != nil) {
+	  [BellView.sharedInstance ring:view color:ns_lookup_indexed_color(NS_FACE_FOREGROUND(FRAME_DEFAULT_FACE (frame)), frame)];
         }
-      [pool release];
+      
       unblock_input ();
-    }
-  else
-    {
+    } else {
       NSBeep ();
     }
 }
diff --git a/src/nsterm.m b/src/nsterm.m
index c4bfd7c..f16ebe2 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -987,6 +987,59 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
 }
 
 
+@interface BellView : NSImageView {
+    NSColor *bellColor;
+}
+
+@property(readwrite,copy) NSColor *bellColor;
+
+- (IBAction)ring:(id)sender;
+@end
+
+@implementation BellView
+@synthesize bellColor;
+
+- (id)initWithFrame:(NSRect)frame {
+  self = [super initWithFrame:frame];
+  if (self) { self.image=[NSApp applicationIconImage]; }
+  return self;
+}
+
++ (instancetype)sharedInstance {
+  static id _si=nil;
+  static dispatch_once_t onceT;
+  dispatch_once(&onceT, ^{ _si=[[self alloc] init]; });
+  return _si;
+}
+
+- (BOOL)isOpaque {
+  return NO;
+}
+
+static const CGFloat BELL_T = 0.2;
+
+- (IBAction)ring:(NSView*)nv color:(NSColor*)fg {
+  self.hidden=NO;
+  self.image=[NSImage imageNamed:NSImageNameCaution];
+  NSRect dr=[nv bounds];
+  dr.origin.x+=(dr.size.width-self.image.size.width)/2;
+  dr.origin.y+=(dr.size.height-self.image.size.height)/2;
+  [self setFrameOrigin:dr.origin];
+  [self setFrameSize:self.image.size];
+  /* find a use for color fg */
+  [nv addSubview:self];
+  [self setNeedsDisplay:YES];
+  [self performSelector:@selector(dismiss) withObject:self afterDelay:BELL_T];
+}
+
+- (void)dismiss {
+    self.hidden=YES;
+    [self setNeedsDisplay:YES];
+    [self removeFromSuperview];
+}
+
+@end
+
 static void
 ns_ring_bell (struct frame *f)
 /* --------------------------------------------------------------------------
@@ -996,41 +1049,18 @@ ns_ring_bell (struct frame *f)
   NSTRACE (ns_ring_bell);
   if (visible_bell)
     {
-      NSAutoreleasePool *pool;
       struct frame *frame = SELECTED_FRAME ();
       NSView *view;
 
       block_input ();
-      pool = [[NSAutoreleasePool alloc] init];
 
       view = FRAME_NS_VIEW (frame);
-      if (view != nil)
-        {
-          NSRect r, surr;
-          NSPoint dim = NSMakePoint (128, 128);
-
-          r = [view bounds];
-          r.origin.x += (r.size.width - dim.x) / 2;
-          r.origin.y += (r.size.height - dim.y) / 2;
-          r.size.width = dim.x;
-          r.size.height = dim.y;
-          surr = NSInsetRect (r, -2, -2);
-          ns_focus (frame, &surr, 1);
-          [[view window] cacheImageInRect: [view convertRect: surr toView:nil]];
-          [ns_lookup_indexed_color (NS_FACE_FOREGROUND
-                                      (FRAME_DEFAULT_FACE (frame)), frame) set];
-          NSRectFill (r);
-          [[view window] flushWindow];
-          ns_timeout (150000);
-          [[view window] restoreCachedImage];
-          [[view window] flushWindow];
-          ns_unfocus (frame);
+      if (view != nil) {
+	  [BellView.sharedInstance ring:view color:ns_lookup_indexed_color(NS_FACE_FOREGROUND(FRAME_DEFAULT_FACE (frame)), frame)];
         }
-      [pool release];
+      
       unblock_input ();
-    }
-  else
-    {
+    } else {
       NSBeep ();
     }
 }

This displays an image named NSImageNameCaution, a small yellow triangle with an exclamation mark, for ~200 ms in the center of the selected frame.
It is possible to choose another image from the workspace, wide open to improvement (e.g., select favorite image by name in lisp ?).
The current foreground color is also sent to the BellView object, but no use case is implemented (ignored) in this patch, also wide open to improvement.

For use as appropriate,
Mustafa







^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11
  2015-10-22 14:41 ` Mustafa Kocaturk
@ 2015-10-22 16:07   ` Mustafa Kocaturk
  0 siblings, 0 replies; 8+ messages in thread
From: Mustafa Kocaturk @ 2015-10-22 16:07 UTC (permalink / raw)
  To: 21662; +Cc: K M

The patch file had a duplicate of itself; the first half is sufficient.

> diff --git a/src/nsterm.m b/src/nsterm.m
> index c4bfd7c..f16ebe2 100644
> --- src/nsterm.m~
> +++ src/nsterm.m
> @@ -987,6 +987,59 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
> 
[…]
> -          ns_timeout (150000);

[…]
> }

The rest of the patch, starting with the lines below, should be removed:
> diff --git a/src/nsterm.m b/src/nsterm.m
> index c4bfd7c..f16ebe2 100644
> --- a/src/nsterm.m
> +++ b/src/nsterm.m
> @@ -987,6 +987,59 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
[…]
> 


The affected file, nsterm.m, defines a function called ns_timeout (int usecs), whose only use case appears to be removed by this change.
I think there is no other use of this function, but will verify by recompiling and send an updated patch, also removing the definition of ns_timeout if unused.

Best regards,
Mustafa




^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#21662: visible-bell causes display artifacts on OS X 10.11
  2015-10-11  3:41 bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11 Steve Purcell
                   ` (2 preceding siblings ...)
  2015-10-22 14:41 ` Mustafa Kocaturk
@ 2015-11-18 20:27 ` Anders Lindgren
  2015-11-21 20:05   ` Anders Lindgren
  2015-11-23 22:09 ` bug#21662: Fixed Anders Lindgren
  4 siblings, 1 reply; 8+ messages in thread
From: Anders Lindgren @ 2015-11-18 20:27 UTC (permalink / raw)
  To: 21662, John Wiegley, Steve Purcell, Mustafa Kocaturk

[-- Attachment #1: Type: text/plain, Size: 790 bytes --]

Hi,

Today I tested suggested patch on an 10.11 and on 10.6.8.

The good news is that, visually, the patch looks really good! It replaced
the boring black square with the standard OS X icon "Caution" icon -- an
exclamation mark on a triangle. It is less intrusive, which I consider a
good thing.

Unfortunately, the code doesn't compile under 10.6.8. The code use the
"hidden" property of NSView (introduced in 10.10), and it the compiler
complains about the "." in the "[BellView.instance ..." construct.

I notices a minor problem under 10.11 as well. The icon is shadowed by
scroll bars, if they happen to be displayed in the middle of the frame,
like when having two side-by-side windows.

I will make an attempt to rewrite to code to work under 10.6.8.

Sincerely,
    Anders Lindgren

[-- Attachment #2: Type: text/html, Size: 1035 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#21662: visible-bell causes display artifacts on OS X 10.11
  2015-11-18 20:27 ` bug#21662: " Anders Lindgren
@ 2015-11-21 20:05   ` Anders Lindgren
  0 siblings, 0 replies; 8+ messages in thread
From: Anders Lindgren @ 2015-11-21 20:05 UTC (permalink / raw)
  To: 21662, John Wiegley, Steve Purcell, Mustafa Kocaturk


[-- Attachment #1.1: Type: text/plain, Size: 1356 bytes --]

Hi again,

I decided to reimplement Mustafas ideas in a 10.6.8 compatible manner, and
to address the problem with the image being covered by scroll bars I
mentioned before. In addition, my implementation is aware that several
bell:s may be active at once and won't remove the image until the last one
times out, which eliminated flickering.

Unless anyone objects, I will publish this in the beginning of next week.

Sincerely,
    Anders Lindgren

On Wed, Nov 18, 2015 at 9:27 PM, Anders Lindgren <andlind@gmail.com> wrote:

> Hi,
>
> Today I tested suggested patch on an 10.11 and on 10.6.8.
>
> The good news is that, visually, the patch looks really good! It replaced
> the boring black square with the standard OS X icon "Caution" icon -- an
> exclamation mark on a triangle. It is less intrusive, which I consider a
> good thing.
>
> Unfortunately, the code doesn't compile under 10.6.8. The code use the
> "hidden" property of NSView (introduced in 10.10), and it the compiler
> complains about the "." in the "[BellView.instance ..." construct.
>
> I notices a minor problem under 10.11 as well. The icon is shadowed by
> scroll bars, if they happen to be displayed in the middle of the frame,
> like when having two side-by-side windows.
>
> I will make an attempt to rewrite to code to work under 10.6.8.
>
> Sincerely,
>     Anders Lindgren
>
>

[-- Attachment #1.2: Type: text/html, Size: 1941 bytes --]

[-- Attachment #2: bell-3.diff --]
[-- Type: text/plain, Size: 4382 bytes --]

diff --git a/src/nsterm.m b/src/nsterm.m
index 58ace48..5f22405 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -584,28 +584,6 @@ ns_load_path (void)
   return NULL;
 }
 
-static void
-ns_timeout (int usecs)
-/* --------------------------------------------------------------------------
-     Blocking timer utility used by ns_ring_bell
-   -------------------------------------------------------------------------- */
-{
-  struct timespec wakeup = timespec_add (current_timespec (),
-					 make_timespec (0, usecs * 1000));
-
-  /* Keep waiting until past the time wakeup.  */
-  while (1)
-    {
-      struct timespec timeout, now = current_timespec ();
-      if (timespec_cmp (wakeup, now) <= 0)
-	break;
-      timeout = timespec_sub (wakeup, now);
-
-      /* Try to wait that long--but we might wake up sooner.  */
-      pselect (0, NULL, NULL, NULL, &timeout, NULL);
-    }
-}
-
 
 void
 ns_release_object (void *obj)
@@ -1161,6 +1139,77 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
 }
 
 
+/* ==========================================================================
+
+    Visibel bell and beep.
+
+   ========================================================================== */
+
+
+@interface EmacsBell : NSImageView
+{
+  // Number of currently active bell:s.
+  unsigned int nestCount;
+}
+- (void)show:(NSView *)view;
+- (void)hide;
+@end
+
+@implementation EmacsBell
+
+- (id)init;
+{
+  if ((self = [super init]))
+    {
+      nestCount = 0;
+      self.image = [NSImage imageNamed:NSImageNameCaution];
+    }
+  return self;
+}
+
+- (void)show:(NSView *)view
+{
+  NSTRACE ("[EmacsBell show:]");
+  NSTRACE_MSG ("nestCount: %u", nestCount);
+
+  // Show the image, unless it's already shown.
+  if (nestCount == 0)
+    {
+      NSRect rect = [view bounds];
+      NSPoint pos;
+      pos.x = rect.origin.x + (rect.size.width  - self.image.size.width )/2;
+      pos.y = rect.origin.y + (rect.size.height - self.image.size.height)/2;
+
+      [self setFrameOrigin:pos];
+      [self setFrameSize:self.image.size];
+
+      [[[view window] contentView] addSubview:self
+                                   positioned:NSWindowAbove
+                                   relativeTo:nil];
+    }
+
+  ++nestCount;
+
+  [self performSelector:@selector(hide) withObject:self afterDelay:0.5];
+}
+
+
+- (void)hide
+{
+  // Note: Trace output from this method isn't shown, reason unknown.
+  // NSTRACE ("[EmacsBell hide]");
+
+  --nestCount;
+
+  // Remove the image once the last bell became inactive.
+  if (nestCount == 0)
+    {
+      [self removeFromSuperview];
+    }
+}
+
+@end
+
 static void
 ns_ring_bell (struct frame *f)
 /* --------------------------------------------------------------------------
@@ -1170,37 +1219,24 @@ ns_ring_bell (struct frame *f)
   NSTRACE ("ns_ring_bell");
   if (visible_bell)
     {
-      NSAutoreleasePool *pool;
       struct frame *frame = SELECTED_FRAME ();
       NSView *view;
 
+      static EmacsBell * bell_view = nil;
+      if (bell_view == nil)
+        {
+          bell_view = [[EmacsBell alloc] init];
+          [bell_view retain];
+        }
+
       block_input ();
-      pool = [[NSAutoreleasePool alloc] init];
 
       view = FRAME_NS_VIEW (frame);
       if (view != nil)
         {
-          NSRect r, surr;
-          NSPoint dim = NSMakePoint (128, 128);
-
-          r = [view bounds];
-          r.origin.x += (r.size.width - dim.x) / 2;
-          r.origin.y += (r.size.height - dim.y) / 2;
-          r.size.width = dim.x;
-          r.size.height = dim.y;
-          surr = NSInsetRect (r, -2, -2);
-          ns_focus (frame, &surr, 1);
-          [[view window] cacheImageInRect: [view convertRect: surr toView:nil]];
-          [ns_lookup_indexed_color (NS_FACE_FOREGROUND
-                                      (FRAME_DEFAULT_FACE (frame)), frame) set];
-          NSRectFill (r);
-          [[view window] flushWindow];
-          ns_timeout (150000);
-          [[view window] restoreCachedImage];
-          [[view window] flushWindow];
-          ns_unfocus (frame);
+          [bell_view show:view];
         }
-      [pool release];
+
       unblock_input ();
     }
   else
@@ -1209,6 +1245,7 @@ ns_ring_bell (struct frame *f)
     }
 }
 
+
 /* ==========================================================================
 
     Frame / window manager related functions

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#21662: Fixed
  2015-10-11  3:41 bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11 Steve Purcell
                   ` (3 preceding siblings ...)
  2015-11-18 20:27 ` bug#21662: " Anders Lindgren
@ 2015-11-23 22:09 ` Anders Lindgren
  4 siblings, 0 replies; 8+ messages in thread
From: Anders Lindgren @ 2015-11-23 22:09 UTC (permalink / raw)
  To: 21662-done

[-- Attachment #1: Type: text/plain, Size: 154 bytes --]

Fixed, see
http://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-25&id=345a9c8cd07111a8c8367e59404688544e8b8b1d
for details.

    -- Anders Lindgren

[-- Attachment #2: Type: text/html, Size: 346 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-11-23 22:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-11  3:41 bug#21662: 25.0.50; visible-bell causes display artifacts on OS X 10.11 Steve Purcell
2015-10-11 14:31 ` Spike Ilacqua
2015-10-14  2:13 ` Mustafa Kocaturk
2015-10-22 14:41 ` Mustafa Kocaturk
2015-10-22 16:07   ` Mustafa Kocaturk
2015-11-18 20:27 ` bug#21662: " Anders Lindgren
2015-11-21 20:05   ` Anders Lindgren
2015-11-23 22:09 ` bug#21662: Fixed Anders Lindgren

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).