Cargo.toml 🔗
@@ -791,6 +791,7 @@ features = [
"Win32_UI_Shell_Common",
"Win32_UI_Shell_PropertiesSystem",
"Win32_UI_WindowsAndMessaging",
+ "Win32_Media",
]
[patch.crates-io]
Lukas Wirth created
Otherwise block_with_timeout is effectively useless on windows as we
would block a minimum of 15ms which is our entire frame budget
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Cargo.toml | 1
crates/editor/src/indent_guides.rs | 2
crates/gpui/src/platform/windows/platform.rs | 6 +++++
crates/gpui/src/platform_scheduler.rs | 24 ++++++++++-----------
crates/language/src/buffer.rs | 20 +++++++++++++----
5 files changed, 34 insertions(+), 19 deletions(-)
@@ -791,6 +791,7 @@ features = [
"Win32_UI_Shell_Common",
"Win32_UI_Shell_PropertiesSystem",
"Win32_UI_WindowsAndMessaging",
+ "Win32_Media",
]
[patch.crates-io]
@@ -85,7 +85,7 @@ impl Editor {
snapshot,
)
})
- .unwrap_or(true)
+ .unwrap_or(state.cursor_row != cursor_row)
{
state.dirty = true;
} else {
@@ -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<Self> {
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();
@@ -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;
}
}
}
@@ -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<Duration>,
cx: &mut Context<Self>,
) {
self.non_text_state_update_count += 1;
@@ -1951,9 +1951,19 @@ impl Buffer {
}
}
- fn request_autoindent(&mut self, cx: &mut Context<Self>, block_budget: Duration) {
+ fn request_autoindent(&mut self, cx: &mut Context<Self>, block_budget: Option<Duration>) {
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.