diff options
| author | Anders Lindgren | 2015-11-23 22:03:56 +0100 |
|---|---|---|
| committer | Anders Lindgren | 2015-11-23 22:09:06 +0100 |
| commit | 345a9c8cd07111a8c8367e59404688544e8b8b1d (patch) | |
| tree | 7ace6cdac43843ac6e7eade0040d16b636fb38ee | |
| parent | e395cafbc1b3833d5738f7556e1ac33e8363aece (diff) | |
| download | emacs-345a9c8cd07111a8c8367e59404688544e8b8b1d.tar.gz emacs-345a9c8cd07111a8c8367e59404688544e8b8b1d.zip | |
New visible-bell for NextStep (OS X El Capitan compatible).
Instead of inverting a rectangle in the middle of the frame, use
the standard NextStep image "caution", represented using an
warning sign with an exclamation mark. (Bug#21662)
Implemented based on a suggestion drafted by Mustafa Kocaturk.
* src/nsterm.m (EmacsBell): New class for managing the caution
image. Support multiple active bells, the image is removed once
all bells have timed out.
(ns_timeout): Removed, no longer used.
(ns_ring_bell): Reimplemented to use EmacsBell.
| -rw-r--r-- | src/nsterm.m | 125 |
1 files changed, 81 insertions, 44 deletions
diff --git a/src/nsterm.m b/src/nsterm.m index 58ace4830b8..5f22405cffc 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -584,28 +584,6 @@ ns_load_path (void) | |||
| 584 | return NULL; | 584 | return NULL; |
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | static void | ||
| 588 | ns_timeout (int usecs) | ||
| 589 | /* -------------------------------------------------------------------------- | ||
| 590 | Blocking timer utility used by ns_ring_bell | ||
| 591 | -------------------------------------------------------------------------- */ | ||
| 592 | { | ||
| 593 | struct timespec wakeup = timespec_add (current_timespec (), | ||
| 594 | make_timespec (0, usecs * 1000)); | ||
| 595 | |||
| 596 | /* Keep waiting until past the time wakeup. */ | ||
| 597 | while (1) | ||
| 598 | { | ||
| 599 | struct timespec timeout, now = current_timespec (); | ||
| 600 | if (timespec_cmp (wakeup, now) <= 0) | ||
| 601 | break; | ||
| 602 | timeout = timespec_sub (wakeup, now); | ||
| 603 | |||
| 604 | /* Try to wait that long--but we might wake up sooner. */ | ||
| 605 | pselect (0, NULL, NULL, NULL, &timeout, NULL); | ||
| 606 | } | ||
| 607 | } | ||
| 608 | |||
| 609 | 587 | ||
| 610 | void | 588 | void |
| 611 | ns_release_object (void *obj) | 589 | ns_release_object (void *obj) |
| @@ -1161,6 +1139,77 @@ ns_clip_to_row (struct window *w, struct glyph_row *row, | |||
| 1161 | } | 1139 | } |
| 1162 | 1140 | ||
| 1163 | 1141 | ||
| 1142 | /* ========================================================================== | ||
| 1143 | |||
| 1144 | Visibel bell and beep. | ||
| 1145 | |||
| 1146 | ========================================================================== */ | ||
| 1147 | |||
| 1148 | |||
| 1149 | @interface EmacsBell : NSImageView | ||
| 1150 | { | ||
| 1151 | // Number of currently active bell:s. | ||
| 1152 | unsigned int nestCount; | ||
| 1153 | } | ||
| 1154 | - (void)show:(NSView *)view; | ||
| 1155 | - (void)hide; | ||
| 1156 | @end | ||
| 1157 | |||
| 1158 | @implementation EmacsBell | ||
| 1159 | |||
| 1160 | - (id)init; | ||
| 1161 | { | ||
| 1162 | if ((self = [super init])) | ||
| 1163 | { | ||
| 1164 | nestCount = 0; | ||
| 1165 | self.image = [NSImage imageNamed:NSImageNameCaution]; | ||
| 1166 | } | ||
| 1167 | return self; | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | - (void)show:(NSView *)view | ||
| 1171 | { | ||
| 1172 | NSTRACE ("[EmacsBell show:]"); | ||
| 1173 | NSTRACE_MSG ("nestCount: %u", nestCount); | ||
| 1174 | |||
| 1175 | // Show the image, unless it's already shown. | ||
| 1176 | if (nestCount == 0) | ||
| 1177 | { | ||
| 1178 | NSRect rect = [view bounds]; | ||
| 1179 | NSPoint pos; | ||
| 1180 | pos.x = rect.origin.x + (rect.size.width - self.image.size.width )/2; | ||
| 1181 | pos.y = rect.origin.y + (rect.size.height - self.image.size.height)/2; | ||
| 1182 | |||
| 1183 | [self setFrameOrigin:pos]; | ||
| 1184 | [self setFrameSize:self.image.size]; | ||
| 1185 | |||
| 1186 | [[[view window] contentView] addSubview:self | ||
| 1187 | positioned:NSWindowAbove | ||
| 1188 | relativeTo:nil]; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | ++nestCount; | ||
| 1192 | |||
| 1193 | [self performSelector:@selector(hide) withObject:self afterDelay:0.5]; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | |||
| 1197 | - (void)hide | ||
| 1198 | { | ||
| 1199 | // Note: Trace output from this method isn't shown, reason unknown. | ||
| 1200 | // NSTRACE ("[EmacsBell hide]"); | ||
| 1201 | |||
| 1202 | --nestCount; | ||
| 1203 | |||
| 1204 | // Remove the image once the last bell became inactive. | ||
| 1205 | if (nestCount == 0) | ||
| 1206 | { | ||
| 1207 | [self removeFromSuperview]; | ||
| 1208 | } | ||
| 1209 | } | ||
| 1210 | |||
| 1211 | @end | ||
| 1212 | |||
| 1164 | static void | 1213 | static void |
| 1165 | ns_ring_bell (struct frame *f) | 1214 | ns_ring_bell (struct frame *f) |
| 1166 | /* -------------------------------------------------------------------------- | 1215 | /* -------------------------------------------------------------------------- |
| @@ -1170,37 +1219,24 @@ ns_ring_bell (struct frame *f) | |||
| 1170 | NSTRACE ("ns_ring_bell"); | 1219 | NSTRACE ("ns_ring_bell"); |
| 1171 | if (visible_bell) | 1220 | if (visible_bell) |
| 1172 | { | 1221 | { |
| 1173 | NSAutoreleasePool *pool; | ||
| 1174 | struct frame *frame = SELECTED_FRAME (); | 1222 | struct frame *frame = SELECTED_FRAME (); |
| 1175 | NSView *view; | 1223 | NSView *view; |
| 1176 | 1224 | ||
| 1225 | static EmacsBell * bell_view = nil; | ||
| 1226 | if (bell_view == nil) | ||
| 1227 | { | ||
| 1228 | bell_view = [[EmacsBell alloc] init]; | ||
| 1229 | [bell_view retain]; | ||
| 1230 | } | ||
| 1231 | |||
| 1177 | block_input (); | 1232 | block_input (); |
| 1178 | pool = [[NSAutoreleasePool alloc] init]; | ||
| 1179 | 1233 | ||
| 1180 | view = FRAME_NS_VIEW (frame); | 1234 | view = FRAME_NS_VIEW (frame); |
| 1181 | if (view != nil) | 1235 | if (view != nil) |
| 1182 | { | 1236 | { |
| 1183 | NSRect r, surr; | 1237 | [bell_view show:view]; |
| 1184 | NSPoint dim = NSMakePoint (128, 128); | ||
| 1185 | |||
| 1186 | r = [view bounds]; | ||
| 1187 | r.origin.x += (r.size.width - dim.x) / 2; | ||
| 1188 | r.origin.y += (r.size.height - dim.y) / 2; | ||
| 1189 | r.size.width = dim.x; | ||
| 1190 | r.size.height = dim.y; | ||
| 1191 | surr = NSInsetRect (r, -2, -2); | ||
| 1192 | ns_focus (frame, &surr, 1); | ||
| 1193 | [[view window] cacheImageInRect: [view convertRect: surr toView:nil]]; | ||
| 1194 | [ns_lookup_indexed_color (NS_FACE_FOREGROUND | ||
| 1195 | (FRAME_DEFAULT_FACE (frame)), frame) set]; | ||
| 1196 | NSRectFill (r); | ||
| 1197 | [[view window] flushWindow]; | ||
| 1198 | ns_timeout (150000); | ||
| 1199 | [[view window] restoreCachedImage]; | ||
| 1200 | [[view window] flushWindow]; | ||
| 1201 | ns_unfocus (frame); | ||
| 1202 | } | 1238 | } |
| 1203 | [pool release]; | 1239 | |
| 1204 | unblock_input (); | 1240 | unblock_input (); |
| 1205 | } | 1241 | } |
| 1206 | else | 1242 | else |
| @@ -1209,6 +1245,7 @@ ns_ring_bell (struct frame *f) | |||
| 1209 | } | 1245 | } |
| 1210 | } | 1246 | } |
| 1211 | 1247 | ||
| 1248 | |||
| 1212 | /* ========================================================================== | 1249 | /* ========================================================================== |
| 1213 | 1250 | ||
| 1214 | Frame / window manager related functions | 1251 | Frame / window manager related functions |