Fix typing emoji (#47835) (cherry-pick to preview) (#47836)

zed-zippy[bot] and Conrad Irwin created

Cherry-pick of #47835 to preview

----
- **Revert "ui: Dismiss context menus when window loses focus
(#46866)"**
- **Revert "Preserve and restore focus across window activation cycles
(#47044)"**

Closes #ISSUE

Release Notes:

- (preview only) Fixed typing emoji using the macOS system palette
(cmd-ctrl-space)

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>

Change summary

crates/gpui/src/key_dispatch.rs          |  44 --------
crates/gpui/src/window.rs                |  10 -
crates/ui/src/components/context_menu.rs |  30 -----
crates/workspace/src/workspace.rs        | 137 --------------------------
4 files changed, 221 deletions(-)

Detailed changes

crates/gpui/src/key_dispatch.rs 🔗

@@ -1102,48 +1102,4 @@ mod tests {
         cx.simulate_keystrokes("ctrl-b [");
         test.update(cx, |test, _| assert_eq!(test.text.borrow().as_str(), "["))
     }
-
-    #[crate::test]
-    fn test_focus_preserved_across_window_activation(cx: &mut TestAppContext) {
-        let cx = cx.add_empty_window();
-
-        let focus_handle = cx.update(|window, cx| {
-            let handle = cx.focus_handle();
-            window.focus(&handle, cx);
-            window.activate_window();
-            handle
-        });
-        cx.run_until_parked();
-
-        cx.update(|window, _| {
-            assert!(window.is_window_active(), "Window should be active");
-            assert!(
-                focus_handle.is_focused(window),
-                "Element should be focused after window.focus() call"
-            );
-        });
-
-        cx.deactivate_window();
-
-        cx.update(|window, _| {
-            assert!(!window.is_window_active(), "Window should not be active");
-            assert!(
-                !focus_handle.is_focused(window),
-                "Element should not appear focused when window is inactive"
-            );
-        });
-
-        cx.update(|window, _| {
-            window.activate_window();
-        });
-        cx.run_until_parked();
-
-        cx.update(|window, _| {
-            assert!(window.is_window_active(), "Window should be active again");
-            assert!(
-                focus_handle.is_focused(window),
-                "Element should be focused after window reactivation"
-            );
-        });
-    }
 }

crates/gpui/src/window.rs 🔗

@@ -943,7 +943,6 @@ pub struct Window {
     pub(crate) refreshing: bool,
     pub(crate) activation_observers: SubscriberSet<(), AnyObserver>,
     pub(crate) focus: Option<FocusId>,
-    focus_before_deactivation: Option<FocusId>,
     focus_enabled: bool,
     pending_input: Option<PendingInput>,
     pending_modifier: ModifierState,
@@ -1255,14 +1254,6 @@ impl Window {
             move |active| {
                 handle
                     .update(&mut cx, |_, window, cx| {
-                        if active {
-                            if let Some(focus_id) = window.focus_before_deactivation.take() {
-                                window.focus = Some(focus_id);
-                            }
-                        } else {
-                            window.focus_before_deactivation = window.focus.take();
-                        }
-
                         window.active.set(active);
                         window.modifiers = window.platform_window.modifiers();
                         window.capslock = window.platform_window.capslock();
@@ -1420,7 +1411,6 @@ impl Window {
             refreshing: false,
             activation_observers: SubscriberSet::new(),
             focus: None,
-            focus_before_deactivation: None,
             focus_enabled: true,
             pending_input: None,
             pending_modifier: ModifierState::default(),

crates/ui/src/components/context_menu.rs 🔗

@@ -220,7 +220,6 @@ pub struct ContextMenu {
     end_slot_action: Option<Box<dyn Action>>,
     key_context: SharedString,
     _on_blur_subscription: Subscription,
-    _on_window_deactivate_subscription: Subscription,
     keep_open_on_confirm: bool,
     fixed_width: Option<DefiniteLength>,
     main_menu: Option<Entity<ContextMenu>>,
@@ -296,12 +295,6 @@ impl ContextMenu {
                 this.cancel(&menu::Cancel, window, cx)
             },
         );
-        let _on_window_deactivate_subscription =
-            cx.observe_window_activation(window, |this: &mut ContextMenu, window, cx| {
-                if !window.is_window_active() {
-                    this.cancel(&menu::Cancel, window, cx);
-                }
-            });
         window.refresh();
 
         f(
@@ -316,7 +309,6 @@ impl ContextMenu {
                 end_slot_action: None,
                 key_context: "menu".into(),
                 _on_blur_subscription,
-                _on_window_deactivate_subscription,
                 keep_open_on_confirm: false,
                 fixed_width: None,
                 main_menu: None,
@@ -380,12 +372,6 @@ impl ContextMenu {
                     this.cancel(&menu::Cancel, window, cx)
                 },
             );
-            let _on_window_deactivate_subscription =
-                cx.observe_window_activation(window, |this: &mut ContextMenu, window, cx| {
-                    if !window.is_window_active() {
-                        this.cancel(&menu::Cancel, window, cx);
-                    }
-                });
             window.refresh();
 
             (builder.clone())(
@@ -400,7 +386,6 @@ impl ContextMenu {
                     end_slot_action: None,
                     key_context: "menu".into(),
                     _on_blur_subscription,
-                    _on_window_deactivate_subscription,
                     keep_open_on_confirm: true,
                     fixed_width: None,
                     main_menu: None,
@@ -470,14 +455,6 @@ impl ContextMenu {
                         this.cancel(&menu::Cancel, window, cx)
                     },
                 ),
-                _on_window_deactivate_subscription: cx.observe_window_activation(
-                    window,
-                    |this: &mut ContextMenu, window, cx| {
-                        if !window.is_window_active() {
-                            this.cancel(&menu::Cancel, window, cx);
-                        }
-                    },
-                ),
                 keep_open_on_confirm: false,
                 fixed_width: None,
                 main_menu: None,
@@ -1229,12 +1206,6 @@ impl ContextMenu {
                 window,
                 |_this: &mut ContextMenu, _window, _cx| {},
             );
-            let _on_window_deactivate_subscription =
-                cx.observe_window_activation(window, |this: &mut ContextMenu, window, cx| {
-                    if !window.is_window_active() {
-                        this.cancel(&menu::Cancel, window, cx);
-                    }
-                });
 
             let mut menu = ContextMenu {
                 builder: None,
@@ -1247,7 +1218,6 @@ impl ContextMenu {
                 end_slot_action: None,
                 key_context: "menu".into(),
                 _on_blur_subscription,
-                _on_window_deactivate_subscription,
                 keep_open_on_confirm: false,
                 fixed_width: None,
                 documentation_aside: None,

crates/workspace/src/workspace.rs 🔗

@@ -10135,143 +10135,6 @@ mod tests {
         });
     }
 
-    #[gpui::test]
-    async fn test_zoomed_dock_persists_across_window_activation(cx: &mut gpui::TestAppContext) {
-        init_test(cx);
-        let fs = FakeFs::new(cx.executor());
-
-        let project = Project::test(fs, [], cx).await;
-        let (workspace, cx) =
-            cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
-
-        let panel = workspace.update_in(cx, |workspace, window, cx| {
-            let panel = cx.new(|cx| TestPanel::new(DockPosition::Bottom, 100, cx));
-            workspace.add_panel(panel.clone(), window, cx);
-            workspace.toggle_dock(DockPosition::Bottom, window, cx);
-            panel
-        });
-
-        // Activate and zoom the panel
-        panel.update(cx, |_, cx| cx.emit(PanelEvent::Activate));
-        panel.update(cx, |_, cx| cx.emit(PanelEvent::ZoomIn));
-
-        // Verify the dock is open and zoomed with focus in the panel
-        workspace.update_in(cx, |workspace, window, cx| {
-            assert!(
-                workspace.bottom_dock().read(cx).is_open(),
-                "Bottom dock should be open"
-            );
-            assert!(panel.is_zoomed(window, cx), "Panel should be zoomed");
-            assert!(
-                workspace.zoomed.is_some(),
-                "Workspace should track the zoomed panel"
-            );
-            assert!(
-                workspace.zoomed_position.is_some(),
-                "Workspace should track the zoomed dock position"
-            );
-            assert!(
-                panel.read(cx).focus_handle(cx).contains_focused(window, cx),
-                "Panel should be focused"
-            );
-        });
-
-        // Deactivate the window (simulates cmd-tab away from Zed)
-        cx.deactivate_window();
-
-        // Verify the dock is still open while window is deactivated
-        // (the bug manifests on REactivation, not deactivation)
-        workspace.update_in(cx, |workspace, window, cx| {
-            assert!(
-                workspace.bottom_dock().read(cx).is_open(),
-                "Bottom dock should still be open while window is deactivated"
-            );
-            assert!(
-                panel.is_zoomed(window, cx),
-                "Panel should still be zoomed while window is deactivated"
-            );
-            assert!(
-                workspace.zoomed_position.is_some(),
-                "zoomed_position should still be set while window is deactivated"
-            );
-        });
-
-        // Reactivate the window (simulates cmd-tab back to Zed)
-        // During reactivation, focus is restored to the dock panel
-        cx.update(|window, _cx| {
-            window.activate_window();
-        });
-        cx.run_until_parked();
-
-        // Verify zoomed dock remains open after reactivation
-        workspace.update_in(cx, |workspace, window, cx| {
-            assert!(
-                workspace.bottom_dock().read(cx).is_open(),
-                "Bottom dock should remain open after window reactivation"
-            );
-            assert!(
-                panel.is_zoomed(window, cx),
-                "Panel should remain zoomed after window reactivation"
-            );
-            assert!(
-                workspace.zoomed.is_some(),
-                "Workspace should still track the zoomed panel after window reactivation"
-            );
-        });
-    }
-
-    #[gpui::test]
-    async fn test_zoomed_dock_dismissed_when_focus_moves_to_center_pane(
-        cx: &mut gpui::TestAppContext,
-    ) {
-        init_test(cx);
-        let fs = FakeFs::new(cx.executor());
-
-        let project = Project::test(fs, [], cx).await;
-        let (workspace, cx) =
-            cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
-
-        let panel = workspace.update_in(cx, |workspace, window, cx| {
-            let panel = cx.new(|cx| TestPanel::new(DockPosition::Bottom, 100, cx));
-            workspace.add_panel(panel.clone(), window, cx);
-            workspace.toggle_dock(DockPosition::Bottom, window, cx);
-            panel
-        });
-
-        // Activate and zoom the panel
-        panel.update(cx, |_, cx| cx.emit(PanelEvent::Activate));
-        panel.update(cx, |_, cx| cx.emit(PanelEvent::ZoomIn));
-
-        // Verify setup
-        workspace.update_in(cx, |workspace, window, cx| {
-            assert!(workspace.bottom_dock().read(cx).is_open());
-            assert!(panel.is_zoomed(window, cx));
-            assert!(workspace.zoomed_position.is_some());
-        });
-
-        // Explicitly focus the center pane (simulates user clicking in the editor)
-        workspace.update_in(cx, |workspace, window, cx| {
-            window.focus(&workspace.active_pane().focus_handle(cx), cx);
-        });
-        cx.run_until_parked();
-
-        // When user explicitly focuses the center pane, the zoomed dock SHOULD be dismissed
-        workspace.update_in(cx, |workspace, _window, cx| {
-            assert!(
-                !workspace.bottom_dock().read(cx).is_open(),
-                "Bottom dock should be closed when focus explicitly moves to center pane"
-            );
-            assert!(
-                workspace.zoomed.is_none(),
-                "Workspace should not track zoomed panel when focus explicitly moves to center pane"
-            );
-            assert!(
-                workspace.zoomed_position.is_none(),
-                "Workspace zoomed_position should be None when focus explicitly moves to center pane"
-            );
-        });
-    }
-
     #[gpui::test]
     async fn test_toggle_all_docks(cx: &mut gpui::TestAppContext) {
         init_test(cx);