editor: Fix pane's tab buttons flicker on right-click (#42549)

Dino created

Whenever right-click was used on the editor, the pane's tab buttons
would flicker, which was confirmed to happen because of the following
check:

```
self.focus_handle.contains_focused(window, cx)
    || self
        .active_item()
        .is_some_and(|item| {
            item.item_focus_handle(cx).contains_focused(window, cx)
        })
```

This check was returning `false` right after right-clicking but
returning `true` right after. When digging into it a little bit more,
this appears to be happening because the editor's `MouseContextMenu`
relies on `ContextMenu` which is rendered in a deferred fashion but
`MouseContextMenu` updates the window's focus to it instantaneously.

Since the `ContextMenu` is rendered in a deferred fashion, its focus
handle is not yet a descendant of the editor (pane's active item) focus
handle, so the `contains_focused(window, cx)` call would return `false`,
with it returning `true` after the menu was rendered.

This commit updates the `MouseContextMenu::new` function to leverage
`cx.on_next_frame` and ensure that the focus is only moved to the
`ContextMenu` 2 frames later, ensuring that by the time the focus is
moved, the `ContextMenu`'s focus handle is a descendant of the editor's.

Closes #41771 

Release Notes:

- Fixed pane's tab buttons flickering when using right-click on the
editor

Change summary

crates/editor/src/mouse_context_menu.rs | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)

Detailed changes

crates/editor/src/mouse_context_menu.rs 🔗

@@ -81,7 +81,19 @@ impl MouseContextMenu {
         cx: &mut Context<Editor>,
     ) -> Self {
         let context_menu_focus = context_menu.focus_handle(cx);
-        window.focus(&context_menu_focus);
+
+        // Since `ContextMenu` is rendered in a deferred fashion its focus
+        // handle is not linked to the Editor's until after the deferred draw
+        // callback runs.
+        // We need to wait for that to happen before focusing it, so that
+        // calling `contains_focused` on the editor's focus handle returns
+        // `true` when the `ContextMenu` is focused.
+        let focus_handle = context_menu_focus.clone();
+        cx.on_next_frame(window, move |_, window, cx| {
+            cx.on_next_frame(window, move |_, window, _cx| {
+                window.focus(&focus_handle);
+            });
+        });
 
         let _dismiss_subscription = cx.subscribe_in(&context_menu, window, {
             let context_menu_focus = context_menu_focus.clone();
@@ -329,8 +341,18 @@ mod tests {
             }
         "});
         cx.editor(|editor, _window, _app| assert!(editor.mouse_context_menu.is_none()));
+
         cx.update_editor(|editor, window, cx| {
-            deploy_context_menu(editor, Some(Default::default()), point, window, cx)
+            deploy_context_menu(editor, Some(Default::default()), point, window, cx);
+
+            // Assert that, even after deploying the editor's mouse context
+            // menu, the editor's focus handle still contains the focused
+            // element. The pane's tab bar relies on this to determine whether
+            // to show the tab bar buttons and there was a small flicker when
+            // deploying the mouse context menu that would cause this to not be
+            // true, making it so that the buttons would disappear for a couple
+            // of frames.
+            assert!(editor.focus_handle.contains_focused(window, cx));
         });
 
         cx.assert_editor_state(indoc! {"