diff --git a/Cargo.toml b/Cargo.toml index e4e7b048bbc5e0be26d1ea84c469c7b470fbf7d9..bc1b2abd643058f96637b63c6416abeeb1bff503 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -791,6 +791,7 @@ features = [ "Win32_UI_Shell_Common", "Win32_UI_Shell_PropertiesSystem", "Win32_UI_WindowsAndMessaging", + "Win32_Media", ] [patch.crates-io] diff --git a/crates/editor/src/indent_guides.rs b/crates/editor/src/indent_guides.rs index 571af03a29a63e4a0ee4e42136d2e2bd6b597c95..469099c6adf5b42f0d5e976abded4f7f3f639075 100644 --- a/crates/editor/src/indent_guides.rs +++ b/crates/editor/src/indent_guides.rs @@ -85,7 +85,7 @@ impl Editor { snapshot, ) }) - .unwrap_or(true) + .unwrap_or(state.cursor_row != cursor_row) { state.dirty = true; } else { diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index d1d71000999eece29670c1cb5b32ce51c70786c9..262e1d6bb0dfe07f724baed115d0184857388b74 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -20,6 +20,7 @@ use windows::{ Win32::{ Foundation::*, Graphics::{Direct3D11::ID3D11Device, Gdi::*}, + Media::{timeBeginPeriod, timeEndPeriod}, Security::Credentials::*, System::{Com::*, LibraryLoader::*, Ole::*, SystemInformation::*}, UI::{Input::KeyboardAndMouse::*, Shell::*, WindowsAndMessaging::*}, @@ -97,6 +98,10 @@ impl WindowsPlatform { pub(crate) fn new(headless: bool) -> Result { unsafe { OleInitialize(None).context("unable to initialize Windows OLE")?; + // Set the system timer resolution to 1ms so that short timeouts + // (e.g. in Scheduler::block) are not rounded up to the default + // ~15.6ms tick interval. + timeBeginPeriod(1); } let (directx_devices, text_system, direct_write_text_system) = if !headless { let devices = DirectXDevices::new().context("Creating DirectX devices")?; @@ -980,6 +985,7 @@ impl WindowsPlatformInner { impl Drop for WindowsPlatform { fn drop(&mut self) { unsafe { + timeEndPeriod(1); DestroyWindow(self.handle) .context("Destroying platform window") .log_err(); diff --git a/crates/gpui/src/platform_scheduler.rs b/crates/gpui/src/platform_scheduler.rs index 4306a730d2ef7b6f19ff071041cb5ca672de8a12..6ed965c068dafe0cdbdb4bd625c0ce7c33206ba7 100644 --- a/crates/gpui/src/platform_scheduler.rs +++ b/crates/gpui/src/platform_scheduler.rs @@ -53,21 +53,19 @@ impl Scheduler for PlatformScheduler { unparker.unpark(); }); let mut cx = Context::from_waker(&waker); - + if let Poll::Ready(()) = future.as_mut().poll(&mut cx) { + return true; + } loop { - match future.as_mut().poll(&mut cx) { - Poll::Ready(()) => return true, - Poll::Pending => { - if let Some(deadline) = deadline { - let now = Instant::now(); - if now >= deadline { - return false; - } - parker.park_timeout(deadline - now); - } else { - parker.park(); - } + match deadline { + Some(deadline) if !parker.park_deadline(deadline) && deadline <= Instant::now() => { + return false; } + Some(_) => (), + None => parker.park(), + } + if let Poll::Ready(()) = future.as_mut().poll(&mut cx) { + break true; } } } diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 293a72d682b2f6edec18e0e25d56111e1164abed..9e601bf1ff34fd71c489eeab09787d1952ad6c61 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -1842,7 +1842,7 @@ impl Buffer { language.clone(), sync_parse_timeout, ) { - self.did_finish_parsing(syntax_snapshot, Duration::from_millis(300), cx); + self.did_finish_parsing(syntax_snapshot, Some(Duration::from_millis(300)), cx); self.reparse = None; return; } @@ -1874,7 +1874,7 @@ impl Buffer { let parse_again = this.version.changed_since(&parsed_version) || language_registry_changed() || grammar_changed(); - this.did_finish_parsing(new_syntax_map, Duration::ZERO, cx); + this.did_finish_parsing(new_syntax_map, None, cx); this.reparse = None; if parse_again { this.reparse(cx, false); @@ -1887,7 +1887,7 @@ impl Buffer { fn did_finish_parsing( &mut self, syntax_snapshot: SyntaxSnapshot, - block_budget: Duration, + block_budget: Option, cx: &mut Context, ) { self.non_text_state_update_count += 1; @@ -1951,9 +1951,19 @@ impl Buffer { } } - fn request_autoindent(&mut self, cx: &mut Context, block_budget: Duration) { + fn request_autoindent(&mut self, cx: &mut Context, block_budget: Option) { if let Some(indent_sizes) = self.compute_autoindents() { let indent_sizes = cx.background_spawn(indent_sizes); + let Some(block_budget) = block_budget else { + self.pending_autoindent = Some(cx.spawn(async move |this, cx| { + let indent_sizes = indent_sizes.await; + this.update(cx, |this, cx| { + this.apply_autoindents(indent_sizes, cx); + }) + .ok(); + })); + return; + }; match cx .foreground_executor() .block_with_timeout(block_budget, indent_sizes) @@ -2861,7 +2871,7 @@ impl Buffer { is_block_mode: false, ignore_empty_lines: true, })); - self.request_autoindent(cx, Duration::from_micros(300)); + self.request_autoindent(cx, Some(Duration::from_micros(300))); } // Inserts newlines at the given position to create an empty line, returning the start of the new line.