diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 12cec3594..cba5ea4a9 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -457,6 +457,11 @@ namespace winrt::TerminalApp::implementation co_return; } } + + // GH#6586: now that we're done processing all startup commands, + // focus the active control. This will work as expected for both + // commandline invocations and for `wt` action invocations. + _GetActiveControl().Focus(FocusState::Programmatic); } if (initial) { @@ -1414,6 +1419,14 @@ namespace winrt::TerminalApp::implementation _UnZoomIfNeeded(); tab.SplitPane(realSplitType, splitSize, profile, newControl); + + // After GH#6586, the control will no longer focus itself + // automatically when it's finished being laid out. Manually focus + // the control here instead. + if (_startupState == StartupState::Initialized) + { + _GetActiveControl().Focus(FocusState::Programmatic); + } } CATCH_LOG(); } diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index aaa562c34..e36fadd6a 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -681,8 +681,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation DispatcherTimer cursorTimer; cursorTimer.Interval(std::chrono::milliseconds(blinkTime)); cursorTimer.Tick({ get_weak(), &TermControl::_CursorTimerTick }); - cursorTimer.Start(); _cursorTimer.emplace(std::move(cursorTimer)); + // As of GH#6586, don't start the cursor timer immediately, and + // don't show the cursor initially. We'll show the cursor and start + // the timer when the control is first focused. cursorTimer.Start(); + _core.CursorOn(false); } else { @@ -711,12 +714,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation // Now that the renderer is set up, update the appearance for initialization _UpdateAppearanceFromUIThread(_settings); - // Focus the control here. If we do it during control initialization, then - // focus won't actually get passed to us. I believe this is because - // we're not technically a part of the UI tree yet, so focusing us - // becomes a no-op. - this->Focus(FocusState::Programmatic); - _initializedTerminal = true; // MSFT 33353327: If the AutomationPeer was created before we were done initializing,