Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove startOnUserLogin from the settings; use OS APIs only #18530

Merged
merged 12 commits into from
Feb 20, 2025
87 changes: 75 additions & 12 deletions src/cascadia/TerminalApp/AppLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,26 +363,89 @@
co_return;
}

const auto tryEnableStartupTask = _settings.GlobalSettings().StartOnUserLogin();
const auto task = co_await StartupTask::GetAsync(StartupTaskName);

switch (task.State())
// If user has not set in json:
// If user has enabled in settings - enable in user settings
// If user has disabled in settings - disable in user settings (can this happen?)
// If user has enabled in json:
// If user has enabled in settings - no change
// If policy has enabled in settings - no change
// If user has disabled in settings - disable in json
// If policy has disabled in settings - disable in json
// If user has disabled in json:
// If user has enabled in settings - enable in json
// If policy has enabled in settings - enable in json
// If user has disabled in settings - no change
// If policy has disabled in settings - no change
//
//... track json state transition
// if user goes from enabled to diabled, try to disable in settings
// if user goes from disabled to enabled, try to enable in settings
// can we detect if RequestEnable succeeded?
auto appState{ ApplicationState::SharedInstance() };
std::optional<bool> userRequestedStartupTaskState;
if (_settings.GlobalSettings().HasStartOnUserLogin())
{
case StartupTaskState::Disabled:
if (tryEnableStartupTask)
userRequestedStartupTaskState.emplace(_settings.GlobalSettings().StartOnUserLogin());
}

std::optional<bool> lastSyncedStartupTaskState;
if (appState.HasLastStartOnUserLoginStateSyncedWithOS())
{
lastSyncedStartupTaskState.emplace(appState.LastStartOnUserLoginStateSyncedWithOS());
}

if (userRequestedStartupTaskState == lastSyncedStartupTaskState)
{
// The user has not changed their state since we last checked (this could also indicate no state ever set);
// propagate changes from the OS down to the user settings file.
std::optional<bool> newFinalUserSettingsValue;
switch (task.State())
{
co_await task.RequestEnableAsync();
case StartupTaskState::Enabled: // user or Terminal enabled it
case StartupTaskState::EnabledByPolicy: // policy enabled it globally
newFinalUserSettingsValue = true;
break;
case StartupTaskState::DisabledByPolicy: // policy disabled it globally
case StartupTaskState::DisabledByUser: // user turned it off in Task Manager
newFinalUserSettingsValue = false;
break;
case StartupTaskState::Disabled: // never set
default:
break;
}

if (newFinalUserSettingsValue.has_value() && newFinalUserSettingsValue != userRequestedStartupTaskState)
{
_settings.GlobalSettings().StartOnUserLogin(*newFinalUserSettingsValue);
appState.LastStartOnUserLoginStateSyncedWithOS(*newFinalUserSettingsValue);
// TODO SAVE SETTINGS AND IGNORE NEXT RELOAD???
}
}
else
{
// The user changed their state since we last checked;
// propagate changes from the user up to the OS.
if (userRequestedStartupTaskState == true /* explicit comparison fails for nullopt */)
{
auto newState{ co_await task.RequestEnableAsync() };
if (newState != StartupTaskState::Enabled)
{
// We could not enable it. It was disabled by policy. Disable it.
_settings.GlobalSettings().StartOnUserLogin(false);
appState.LastStartOnUserLoginStateSyncedWithOS(false);
}
else
{
appState.LastStartOnUserLoginStateSyncedWithOS(true);
}
}
break;
case StartupTaskState::DisabledByUser:
// TODO: GH#6254: define UX for other StartupTaskStates
break;
case StartupTaskState::Enabled:
if (!tryEnableStartupTask)
else if (userRequestedStartupTaskState == false /* explicit comparison fails for nullopt */)
{
task.Disable();
appState.LastStartOnUserLoginStateSyncedWithOS(false);
}
break;
}
}
CATCH_LOG();
Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsModel/ApplicationState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
#undef MTSM_APPLICATION_STATE_GEN

bool ApplicationState::HasLastStartOnUserLoginStateSyncedWithOS() const noexcept
{
const auto state = _state.lock_shared();
return state->LastStartOnUserLoginStateSyncedWithOS.has_value();
}

// Method Description:
// - Read the contents of our "shared" state - state that should be shared
// for elevated and unelevated instances. This is things like the list of
Expand Down
5 changes: 4 additions & 1 deletion src/cascadia/TerminalSettingsModel/ApplicationState.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
X(FileSource::Local, Windows::Foundation::Collections::IVector<Model::WindowLayout>, PersistedWindowLayouts, "persistedWindowLayouts") \
X(FileSource::Shared, Windows::Foundation::Collections::IVector<hstring>, RecentCommands, "recentCommands") \
X(FileSource::Shared, Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage>, DismissedMessages, "dismissedMessages") \
X(FileSource::Local, Windows::Foundation::Collections::IVector<hstring>, AllowedCommandlines, "allowedCommandlines")
X(FileSource::Local, Windows::Foundation::Collections::IVector<hstring>, AllowedCommandlines, "allowedCommandlines") \
X(FileSource::Shared, bool, LastStartOnUserLoginStateSyncedWithOS, "lastStartOnUserLoginStateSyncedWithOS")

struct WindowLayout : WindowLayoutT<WindowLayout>
{
Expand Down Expand Up @@ -78,6 +79,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
MTSM_APPLICATION_STATE_FIELDS(MTSM_APPLICATION_STATE_GEN)
#undef MTSM_APPLICATION_STATE_GEN

bool HasLastStartOnUserLoginStateSyncedWithOS() const noexcept;

private:
struct state_t
{
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalSettingsModel/ApplicationState.idl
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,8 @@ namespace Microsoft.Terminal.Settings.Model
Windows.Foundation.Collections.IVector<String> RecentCommands;
Windows.Foundation.Collections.IVector<InfoBarMessage> DismissedMessages;
Windows.Foundation.Collections.IVector<String> AllowedCommandlines;

Boolean LastStartOnUserLoginStateSyncedWithOS;
Boolean HasLastStartOnUserLoginStateSyncedWithOS();
}
}
Loading