python: Fix flickering in the status bar (#36039)

- **util: Have maybe! use async closures instead of async blocks**
- **python: Fix flickering of virtual environment indicator in status
bar**

Closes #30723

Release Notes:

- Python: Fixed flickering of the status bar virtual environment
indicator

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
This commit is contained in:
Piotr Osiewicz 2025-08-12 15:36:28 +02:00 committed by GitHub
parent 44953375cc
commit 360d4db87c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 66 additions and 43 deletions

View file

@ -8,6 +8,7 @@ use gpui::{
use language::{Buffer, BufferEvent, LanguageName, Toolchain}; use language::{Buffer, BufferEvent, LanguageName, Toolchain};
use project::{Project, ProjectPath, WorktreeId, toolchain_store::ToolchainStoreEvent}; use project::{Project, ProjectPath, WorktreeId, toolchain_store::ToolchainStoreEvent};
use ui::{Button, ButtonCommon, Clickable, FluentBuilder, LabelSize, SharedString, Tooltip}; use ui::{Button, ButtonCommon, Clickable, FluentBuilder, LabelSize, SharedString, Tooltip};
use util::maybe;
use workspace::{StatusItemView, Workspace, item::ItemHandle}; use workspace::{StatusItemView, Workspace, item::ItemHandle};
use crate::ToolchainSelector; use crate::ToolchainSelector;
@ -55,6 +56,7 @@ impl ActiveToolchain {
} }
fn spawn_tracker_task(window: &mut Window, cx: &mut Context<Self>) -> Task<Option<()>> { fn spawn_tracker_task(window: &mut Window, cx: &mut Context<Self>) -> Task<Option<()>> {
cx.spawn_in(window, async move |this, cx| { cx.spawn_in(window, async move |this, cx| {
let did_set_toolchain = maybe!(async {
let active_file = this let active_file = this
.read_with(cx, |this, _| { .read_with(cx, |this, _| {
this.active_buffer this.active_buffer
@ -92,12 +94,23 @@ impl ActiveToolchain {
.flatten()?; .flatten()?;
let toolchain = let toolchain =
Self::active_toolchain(workspace, worktree_id, path, language_name, cx).await?; Self::active_toolchain(workspace, worktree_id, path, language_name, cx).await?;
let _ = this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.active_toolchain = Some(toolchain); this.active_toolchain = Some(toolchain);
cx.notify(); cx.notify();
}); })
Some(()) .ok()
})
.await
.is_some();
if !did_set_toolchain {
this.update(cx, |this, cx| {
this.active_toolchain = None;
cx.notify();
})
.ok();
}
did_set_toolchain.then_some(())
}) })
} }
@ -110,6 +123,17 @@ impl ActiveToolchain {
let editor = editor.read(cx); let editor = editor.read(cx);
if let Some((_, buffer, _)) = editor.active_excerpt(cx) { if let Some((_, buffer, _)) = editor.active_excerpt(cx) {
if let Some(worktree_id) = buffer.read(cx).file().map(|file| file.worktree_id(cx)) { if let Some(worktree_id) = buffer.read(cx).file().map(|file| file.worktree_id(cx)) {
if self
.active_buffer
.as_ref()
.is_some_and(|(old_worktree_id, old_buffer, _)| {
(old_worktree_id, old_buffer.entity_id())
== (&worktree_id, buffer.entity_id())
})
{
return;
}
let subscription = cx.subscribe_in( let subscription = cx.subscribe_in(
&buffer, &buffer,
window, window,
@ -231,7 +255,6 @@ impl StatusItemView for ActiveToolchain {
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
if let Some(editor) = active_pane_item.and_then(|item| item.downcast::<Editor>()) { if let Some(editor) = active_pane_item.and_then(|item| item.downcast::<Editor>()) {
self.active_toolchain.take();
self.update_lister(editor, window, cx); self.update_lister(editor, window, cx);
} }
cx.notify(); cx.notify();

View file

@ -887,10 +887,10 @@ macro_rules! maybe {
(|| $block)() (|| $block)()
}; };
(async $block:block) => { (async $block:block) => {
(|| async $block)() (async || $block)()
}; };
(async move $block:block) => { (async move $block:block) => {
(|| async move $block)() (async move || $block)()
}; };
} }