patches: fix O(overlays) performance regression
Performance issue: editing large files (>~10KB, >2000 lines) caused progressive slowdown regardless of VoiceOver status. Root causes: 1. ns_zoom_find_overlay_candidate_line: called Foverlays_in on the entire visible buffer range on every redisplay when UAZoomEnabled(). In files with many overlays (font-lock, hl-line, show-paren etc.) this was O(overlays) Lisp work per keystroke. 2. postAccessibilityNotificationsForFrame: when ns-accessibility-enabled is non-nil, checked BUF_OVERLAY_MODIFF every redisplay. font-lock bumps this on every redraw, triggering ns_ax_selected_overlay_text (another O(overlays) scan) for non-minibuffer windows. Fix: Both scans now guard with MINI_WINDOW_P check. Overlay completion frameworks (Vertico, Icomplete, Ivy) only display candidates in minibuffer windows --- no completion framework puts selected-face overlays in normal editing buffers. For non-minibuffer windows both functions return immediately with zero Lisp calls. Additionally: ns_zoom_find_child_frame_candidate is skipped when f->child_frame_list is nil (no child frames = no Corfu popup).
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
From 54cae6f8afe265c12cffaef121bad32bc165a777 Mon Sep 17 00:00:00 2001
|
||||
From 19ab5ca41d38959b8f92ae2e1b7f724972515c3d Mon Sep 17 00:00:00 2001
|
||||
From: Martin Sukany <martin@sukany.cz>
|
||||
Date: Sat, 28 Feb 2026 22:39:35 +0100
|
||||
Subject: [PATCH 1/9] ns: integrate with macOS Zoom for cursor tracking
|
||||
@@ -38,8 +38,8 @@ window splits, switches (C-x o), and completion frameworks.
|
||||
---
|
||||
etc/NEWS | 11 ++
|
||||
src/nsterm.h | 6 ++
|
||||
src/nsterm.m | 280 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 297 insertions(+)
|
||||
src/nsterm.m | 289 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 306 insertions(+)
|
||||
|
||||
diff --git a/etc/NEWS b/etc/NEWS
|
||||
index ef36df5..80661a9 100644
|
||||
@@ -81,10 +81,10 @@ index 7c1ee4c..ea6e7ba 100644
|
||||
}
|
||||
|
||||
diff --git a/src/nsterm.m b/src/nsterm.m
|
||||
index 74e4ad5..2dd79ca 100644
|
||||
index 74e4ad5..eee4cd9 100644
|
||||
--- a/src/nsterm.m
|
||||
+++ b/src/nsterm.m
|
||||
@@ -1081,6 +1081,209 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
||||
@@ -1081,6 +1081,218 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,13 @@ index 74e4ad5..2dd79ca 100644
|
||||
+static int
|
||||
+ns_zoom_find_overlay_candidate_line (struct window *w)
|
||||
+{
|
||||
+ /* Overlay completion frameworks (Vertico, Icomplete, Ivy) place
|
||||
+ candidates as overlay strings in the minibuffer only. Scanning
|
||||
+ overlays in large normal buffers causes O(overlays) work per
|
||||
+ redisplay --- return immediately for non-minibuffer windows. */
|
||||
+ if (!MINI_WINDOW_P (w))
|
||||
+ return -1;
|
||||
+
|
||||
+ struct buffer *b = XBUFFER (w->contents);
|
||||
+ ptrdiff_t beg = marker_position (w->start);
|
||||
+ ptrdiff_t end = BUF_ZV (b);
|
||||
@@ -259,7 +266,9 @@ index 74e4ad5..2dd79ca 100644
|
||||
+
|
||||
+ /* 2. Check child frame completions (Corfu, Company-box). */
|
||||
+ struct frame *cf = NULL;
|
||||
+ int cf_line = ns_zoom_find_child_frame_candidate (f, &cf);
|
||||
+ int cf_line = -1;
|
||||
+ if (!NILP (f->child_frame_list))
|
||||
+ cf_line = ns_zoom_find_child_frame_candidate (f, &cf);
|
||||
+ if (cf_line >= 0 && cf)
|
||||
+ {
|
||||
+ EmacsView *cv = FRAME_NS_VIEW (cf);
|
||||
@@ -294,7 +303,7 @@ index 74e4ad5..2dd79ca 100644
|
||||
static void
|
||||
ns_update_end (struct frame *f)
|
||||
/* --------------------------------------------------------------------------
|
||||
@@ -1104,6 +1307,41 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
||||
@@ -1104,6 +1316,41 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
|
||||
|
||||
unblock_input ();
|
||||
ns_updating_frame = NULL;
|
||||
@@ -336,7 +345,7 @@ index 74e4ad5..2dd79ca 100644
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3232,6 +3470,45 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
||||
@@ -3232,6 +3479,45 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
|
||||
/* Prevent the cursor from being drawn outside the text area. */
|
||||
r = NSIntersectionRect (r, ns_row_rect (w, glyph_row, TEXT_AREA));
|
||||
|
||||
@@ -382,7 +391,7 @@ index 74e4ad5..2dd79ca 100644
|
||||
ns_focus (f, NULL, 0);
|
||||
|
||||
NSGraphicsContext *ctx = [NSGraphicsContext currentContext];
|
||||
@@ -8321,6 +8598,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
|
||||
@@ -8321,6 +8607,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f
|
||||
|
||||
windowClosing = NO;
|
||||
processingCompose = NO;
|
||||
|
||||
Reference in New Issue
Block a user