[runner] Enable opening specific settings page (#13476)

* [runner] Enable opening specific settings page

* Error handling

* Spellcheck

* Address PR comments
This commit is contained in:
Stefan Markovic 2021-09-29 12:54:05 +02:00 committed by GitHub
parent 1984b3747e
commit 8853adda62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 195 additions and 26 deletions

View file

@ -569,6 +569,7 @@ errc
errorlevel
ERRORMESSAGE
ERRORTITLE
ESettings
esize
estdir
etcore
@ -994,6 +995,7 @@ IRepository
IResult
ISavable
isbi
iss
ISearch
IService
isetting

View file

@ -2,6 +2,7 @@
#include <ShellScalingApi.h>
#include <lmcons.h>
#include <filesystem>
#include <sstream>
#include "tray_icon.h"
#include "powertoy_module.h"
#include "trace.h"
@ -69,10 +70,15 @@ inline wil::unique_mutex_nothrow create_msi_mutex()
return createAppMutex(POWERTOYS_MSI_MUTEX_NAME);
}
void open_menu_from_another_instance()
void open_menu_from_another_instance(std::optional<std::string> settings_window)
{
const HWND hwnd_main = FindWindowW(L"PToyTrayIconWindow", nullptr);
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, 0);
LPARAM msg = static_cast<LPARAM>(ESettingsWindowNames::Overview);
if (settings_window.has_value())
{
msg = static_cast<LPARAM>(ESettingsWindowNames_from_string(settings_window.value()));
}
PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, msg);
}
void debug_verify_launcher_assets()
@ -99,7 +105,7 @@ void debug_verify_launcher_assets()
}
}
int runner(bool isProcessElevated, bool openSettings, bool openOobe)
int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe)
{
Logger::info("Runner is starting. Elevated={}", isProcessElevated);
DPIAware::EnableDPIAwarenessForThisProcess();
@ -176,7 +182,12 @@ int runner(bool isProcessElevated, bool openSettings, bool openOobe)
if (openSettings)
{
open_settings_window();
std::optional<std::wstring> window;
if (!settingsWindow.empty())
{
window = winrt::to_hstring(settingsWindow);
}
open_settings_window(window);
}
if (openOobe)
@ -263,7 +274,7 @@ toast_notification_handler_result toast_notification_handler(const std::wstring_
}
else if (param == open_settings)
{
open_menu_from_another_instance();
open_menu_from_another_instance(std::nullopt);
return toast_notification_handler_result::exit_success;
}
else
@ -325,11 +336,24 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
logFilePath.append(LogSettings::runnerLogPath);
Logger::init(LogSettings::runnerLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
const std::string cmdLine{ lpCmdLine };
auto open_settings_it = cmdLine.find("--open-settings");
const bool open_settings = open_settings_it != std::string::npos;
// Check if opening specific settings window
open_settings_it = cmdLine.find("--open-settings=");
std::string settings_window;
if (open_settings_it != std::string::npos)
{
std::string rest_of_cmd_line{ cmdLine, open_settings_it + std::string{ "--open-settings=" }.size() };
std::istringstream iss(rest_of_cmd_line);
iss >> settings_window;
}
// Check if another instance is already running.
wil::unique_mutex_nothrow msi_mutex = create_msi_mutex();
if (!msi_mutex)
{
open_menu_from_another_instance();
open_menu_from_another_instance(settings_window);
return 0;
}
@ -355,7 +379,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
modules();
auto general_settings = load_general_settings();
const bool openSettings = std::string(lpCmdLine).find("--open-settings") != std::string::npos;
// Apply the general settings but don't save it as the modules() variable has not been loaded yet
apply_general_settings(general_settings, false);
@ -363,13 +386,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
const bool elevated = is_process_elevated();
if ((elevated ||
general_settings.GetNamedBoolean(L"run_elevated", false) == false ||
std::string(lpCmdLine).find("--dont-elevate") != std::string::npos))
cmdLine.find("--dont-elevate") != std::string::npos))
{
result = runner(elevated, openSettings, openOobe);
result = runner(elevated, open_settings, settings_window, openOobe);
}
else
{
schedule_restart_as_elevated(openSettings);
schedule_restart_as_elevated(open_settings);
result = 0;
}
}

View file

@ -23,6 +23,7 @@
#include <common/utils/winapi_error.h>
#include <common/updating/updateState.h>
#include <common/themes/windows_colors.h>
#include "settings_window.h"
#define BUFSIZE 1024
@ -259,7 +260,7 @@ BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args,
DWORD g_settings_process_id = 0;
void run_settings_window(bool showOobeWindow)
void run_settings_window(bool show_oobe_window, std::optional<std::wstring> settings_window)
{
g_isLaunchInProgress = true;
@ -324,7 +325,7 @@ void run_settings_window(bool showOobeWindow)
std::wstring settings_isUserAnAdmin = isAdmin ? L"true" : L"false";
// Arg 8: should oobe window be shown
std::wstring settings_showOobe = showOobeWindow ? L"true" : L"false";
std::wstring settings_showOobe = show_oobe_window ? L"true" : L"false";
// create general settings file to initialize the settings file with installation configurations like :
// 1. Run on start up.
@ -347,6 +348,12 @@ void run_settings_window(bool showOobeWindow)
executable_args.append(L" ");
executable_args.append(settings_showOobe);
if (settings_window.has_value())
{
executable_args.append(L" ");
executable_args.append(settings_window.value());
}
BOOL process_created = false;
if (is_process_elevated())
@ -462,7 +469,7 @@ void bring_settings_to_front()
EnumWindows(callback, 0);
}
void open_settings_window()
void open_settings_window(std::optional<std::wstring> settings_window)
{
if (g_settings_process_id != 0)
{
@ -472,8 +479,8 @@ void open_settings_window()
{
if (!g_isLaunchInProgress)
{
std::thread([]() {
run_settings_window(false);
std::thread([settings_window]() {
run_settings_window(false, settings_window);
}).detach();
}
}
@ -494,6 +501,96 @@ void close_settings_window()
void open_oobe_window()
{
std::thread([]() {
run_settings_window(true);
run_settings_window(true, std::nullopt);
}).detach();
}
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
{
switch (value)
{
case ESettingsWindowNames::Overview:
return "Overview";
case ESettingsWindowNames::Awake:
return "Awake";
case ESettingsWindowNames::ColorPicker:
return "ColorPicker";
case ESettingsWindowNames::FancyZones:
return "FancyZones";
case ESettingsWindowNames::Run:
return "Run";
case ESettingsWindowNames::ImageResizer:
return "ImageResizer";
case ESettingsWindowNames::KBM:
return "KBM";
case ESettingsWindowNames::PowerRename:
return "PowerRename";
case ESettingsWindowNames::FileExplorer:
return "FileExplorer";
case ESettingsWindowNames::ShortcutGuide:
return "ShortcutGuide";
case ESettingsWindowNames::VideoConference:
return "VideoConference";
default:
{
Logger::error(L"Can't convert ESettingsWindowNames value={} to string", static_cast<int>(value));
assert(false);
}
}
return "";
}
ESettingsWindowNames ESettingsWindowNames_from_string(std::string value)
{
if (value == "Overview")
{
return ESettingsWindowNames::Overview;
}
else if (value == "Awake")
{
return ESettingsWindowNames::Awake;
}
else if (value == "ColorPicker")
{
return ESettingsWindowNames::ColorPicker;
}
else if (value == "FancyZones")
{
return ESettingsWindowNames::FancyZones;
}
else if (value == "Run")
{
return ESettingsWindowNames::Run;
}
else if (value == "ImageResizer")
{
return ESettingsWindowNames::ImageResizer;
}
else if (value == "KBM")
{
return ESettingsWindowNames::KBM;
}
else if (value == "PowerRename")
{
return ESettingsWindowNames::PowerRename;
}
else if (value == "FileExplorer")
{
return ESettingsWindowNames::FileExplorer;
}
else if (value == "ShortcutGuide")
{
return ESettingsWindowNames::ShortcutGuide;
}
else if (value == "VideoConference")
{
return ESettingsWindowNames::VideoConference;
}
else
{
Logger::error(L"Can't convert string value={} to ESettingsWindowNames", winrt::to_hstring(value));
assert(false);
}
return ESettingsWindowNames::Overview;
}

View file

@ -1,5 +1,26 @@
#pragma once
void open_settings_window();
#include <optional>
#include <string>
enum class ESettingsWindowNames
{
Overview = 0,
Awake,
ColorPicker,
FancyZones,
Run,
ImageResizer,
KBM,
PowerRename,
FileExplorer,
ShortcutGuide,
VideoConference
};
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value);
ESettingsWindowNames ESettingsWindowNames_from_string(std::string value);
void open_settings_window(std::optional<std::wstring> settings_window);
void close_settings_window();
void open_oobe_window();

View file

@ -62,12 +62,15 @@ void change_menu_item_text(const UINT item_id, wchar_t* new_text)
SetMenuItemInfoW(h_menu, item_id, false, &menuitem);
}
void handle_tray_command(HWND window, const WPARAM command_id)
void handle_tray_command(HWND window, const WPARAM command_id, LPARAM lparam)
{
switch (command_id)
{
case ID_SETTINGS_MENU_COMMAND:
open_settings_window();
{
std::wstring settings_window{ winrt::to_hstring(ESettingsWindowNames_to_string(static_cast<ESettingsWindowNames>(lparam))) };
open_settings_window(settings_window);
}
break;
case ID_EXIT_MENU_COMMAND:
if (h_menu)
@ -147,7 +150,7 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
DestroyWindow(window);
break;
case WM_COMMAND:
handle_tray_command(window, wparam);
handle_tray_command(window, wparam, lparam);
break;
// Shell_NotifyIcon can fail when we invoke it during the time explorer.exe isn't present/ready to handle it.
// We'll also never receive wm_taskbar_restart message if the first call to Shell_NotifyIcon failed, so we use
@ -167,7 +170,7 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
{
case WM_LBUTTONUP:
{
open_settings_window();
open_settings_window(std::nullopt);
break;
}
case WM_RBUTTONUP:

View file

@ -1,10 +1,13 @@
#pragma once
#include <optional>
#include <string>
// Start the Tray Icon
void start_tray_icon();
// Stop the Tray Icon
void stop_tray_icon();
// Open the Settings Window
void open_settings_window();
void open_settings_window(std::optional<std::wstring> settings_window);
// Callback type to be called by the tray icon loop
typedef void (*main_loop_callback_function)(PVOID);
// Calls a callback in _callback

View file

@ -18,6 +18,8 @@ namespace PowerToys.Settings
public bool ShowOobe { get; set; }
public Type StartupPage { get; set; } = typeof(Microsoft.PowerToys.Settings.UI.Views.GeneralPage);
public void OpenSettingsWindow(Type type)
{
if (settingsWindow == null)
@ -47,6 +49,7 @@ namespace PowerToys.Settings
{
settingsWindow = new MainWindow();
settingsWindow.Show();
settingsWindow.NavigateToSection(StartupPage);
}
else
{

View file

@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.Windows;
using interop;
using ManagedCommon;
@ -20,11 +21,12 @@ namespace PowerToys.Settings
ElevatedStatus,
IsUserAdmin,
ShowOobeWindow,
SettingsWindow,
}
// Quantity of arguments
private const int RequiredArgumentsQty = 6;
private const int RequiredAndOptionalArgumentsQty = 7;
private const int RequiredArgumentsQty = 7;
private const int RequiredAndOptionalArgumentsQty = 8;
// Create an instance of the IPC wrapper.
private static TwoWayPipeMessageIPCManaged ipcmanager;
@ -52,11 +54,26 @@ namespace PowerToys.Settings
IsElevated = args[(int)Arguments.ElevatedStatus] == "true";
IsUserAnAdmin = args[(int)Arguments.IsUserAdmin] == "true";
app.ShowOobe = args[(int)Arguments.ShowOobeWindow] == "true";
if (args.Length == RequiredAndOptionalArgumentsQty)
{
// open oobe window
app.ShowOobe = args[(int)Arguments.ShowOobeWindow] == "true";
// open specific window
switch (args[(int)Arguments.SettingsWindow])
{
case "Overview": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.GeneralPage); break;
case "Awake": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.AwakePage); break;
case "ColorPicker": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.ColorPickerPage); break;
case "FancyZones": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.FancyZonesPage); break;
case "Run": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.PowerLauncherPage); break;
case "ImageResizer": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.ImageResizerPage); break;
case "KBM": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.KeyboardManagerPage); break;
case "PowerRename": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.PowerRenamePage); break;
case "FileExplorer": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.PowerPreviewPage); break;
case "ShortcutGuide": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.ShortcutGuidePage); break;
case "VideoConference": app.StartupPage = typeof(Microsoft.PowerToys.Settings.UI.Views.VideoConferencePage); break;
default: Debug.Assert(false, "Unexpected SettingsWindow argument value"); break;
}
}
RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>