@@ -135,7 +135,7 @@ impl OverlayWindow { |
| 135 | 135 | let stroke_ref: *mut AnyObject = |
| 136 | 136 | objc2_core_foundation::CFRetained::as_ptr(&stroke).as_ptr() as *mut AnyObject; |
| 137 | 137 | let _: () = msg_send![&*border_layer, setStrokeColor: stroke_ref]; |
| 138 | | - border_layer.setLineWidth(border_width * 2.0); |
| 138 | + border_layer.setLineWidth(border_width); |
| 139 | 139 | border_layer.setFrame(CGRect::new( |
| 140 | 140 | CGPoint::new(0.0, 0.0), |
| 141 | 141 | CGSize::new(outer_cg.size.width, outer_cg.size.height), |
@@ -217,14 +217,21 @@ impl OverlayWindow { |
| 217 | 217 | |
| 218 | 218 | impl Drop for OverlayWindow { |
| 219 | 219 | fn drop(&mut self) { |
| 220 | + // orderOut first so the visual disappears synchronously; |
| 221 | + // close() afterward releases the window. Without orderOut a |
| 222 | + // closed-but-still-onscreen window can briefly linger on |
| 223 | + // Tahoe before Retained drops the last ref. |
| 224 | + self.window.orderOut(None); |
| 220 | 225 | self.window.close(); |
| 221 | 226 | } |
| 222 | 227 | } |
| 223 | 228 | |
| 224 | 229 | fn inset_for_stroke(size: CGSize, border_width: f64) -> CGRect { |
| 225 | | - // CAShapeLayer strokes centered on the path. To get the stroke |
| 226 | | - // exactly inside the layer bounds we inset by half the line width. |
| 227 | | - let half = border_width; |
| 230 | + // CAShapeLayer strokes centered on the path. To get an exactly |
| 231 | + // border_width-thick visible ring sitting inside the layer bounds, |
| 232 | + // inset the path by half the line width and stroke at line_width |
| 233 | + // = border_width. |
| 234 | + let half = border_width / 2.0; |
| 228 | 235 | CGRect::new( |
| 229 | 236 | CGPoint::new(half, half), |
| 230 | 237 | CGSize::new( |