mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 17:56:44 +02:00
[Settings][runner]Quick access system tray launcher (#22408)
* Init * Fix running settings * UI design * Left click trigger Wire up colorpicker and pt run * Wire up others * Update FlyoutWindow.xaml.cs * Removed comments * Update FlyoutWindow.xaml * More work * Open Settings page * More UI work * Resolve conflicts * [General] SystemTray Flyout: Add update on tray items' visibility when module gets enabled/disabled Also remove context menu opening on tray icon. * Adding app list * Adding more buttons, resolving conflicts * [General] Flyout: improving opening, closing flyout/settings window. Implementing basic bahaviour on enabling/disabling modules. * [General] FlyoutWindow: proceed with implementation. GPO works. Main functionallity works (launching and enabling apps). * [general] flyout: fix exit button * [general] flyout: implement double click handling * Localization * [Generel] Flyout: Re-implement flyout launching, add workaround: disable flyout hiding in case the user switches on modules on the all apps page + minor changes * [general] flyout: restore the context menu when right clicking on system tray icon * Fix spellchecker * [installer] fixing missing dll files + suppress error on not signed script * Fix spell checker * Fix flyout not focusing when activated * Refresh Settings UI enabled state when flyout changes * fix spellcheck * Remove VCM from the list * [General] flyout: fix settings window opening. Switch to general page only if there is no page opened * [general] flyout: add launching hosts app * Fix CI build * adding check on elevation when launching hosts * Use localization strings that already exist * Remove dll not present in arm64 build * Adding GPO policy check for the launcher page items * fix hosts launching * Add telemetry * Also hide from all apps list when gpo is force enabling * fix spellchecker * Improve focus issues * Fix flickering Bitmap Icons * Fix telemetry error * Fix telemetry call * Fix wrong comment --------- Co-authored-by: Stefan Markovic <stefan@janeasystems.com> Co-authored-by: Laszlo Nemeth <laszlo.nemeth.hu@gmail.com> Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
This commit is contained in:
@@ -203,7 +203,7 @@ int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow
|
||||
{
|
||||
window = winrt::to_hstring(settingsWindow);
|
||||
}
|
||||
open_settings_window(window);
|
||||
open_settings_window(window, false);
|
||||
}
|
||||
|
||||
if (openOobe)
|
||||
|
||||
@@ -11,12 +11,14 @@
|
||||
#include "restart_elevated.h"
|
||||
#include "UpdateUtils.h"
|
||||
#include "centralized_kb_hook.h"
|
||||
#include "Generated files/resource.h"
|
||||
|
||||
#include <common/utils/json.h>
|
||||
#include <common/SettingsAPI/settings_helpers.cpp>
|
||||
#include <common/version/version.h>
|
||||
#include <common/version/helper.h>
|
||||
#include <common/logger/logger.h>
|
||||
#include <common/utils/resources.h>
|
||||
#include <common/utils/elevation.h>
|
||||
#include <common/utils/process_path.h>
|
||||
#include <common/utils/timeutil.h>
|
||||
@@ -175,7 +177,7 @@ void dispatch_received_json(const std::wstring& json_to_parse)
|
||||
const std::wstring settings_string{ get_all_settings().Stringify().c_str() };
|
||||
{
|
||||
std::unique_lock lock{ ipc_mutex };
|
||||
if(current_settings_ipc)
|
||||
if (current_settings_ipc)
|
||||
current_settings_ipc->send(settings_string);
|
||||
}
|
||||
}
|
||||
@@ -185,7 +187,7 @@ void dispatch_received_json(const std::wstring& json_to_parse)
|
||||
const std::wstring settings_string{ get_all_settings().Stringify().c_str() };
|
||||
{
|
||||
std::unique_lock lock{ ipc_mutex };
|
||||
if(current_settings_ipc)
|
||||
if (current_settings_ipc)
|
||||
current_settings_ipc->send(settings_string);
|
||||
}
|
||||
}
|
||||
@@ -194,7 +196,7 @@ void dispatch_received_json(const std::wstring& json_to_parse)
|
||||
const std::wstring settings_string{ get_all_settings().Stringify().c_str() };
|
||||
{
|
||||
std::unique_lock lock{ ipc_mutex };
|
||||
if(current_settings_ipc)
|
||||
if (current_settings_ipc)
|
||||
current_settings_ipc->send(settings_string);
|
||||
}
|
||||
}
|
||||
@@ -205,11 +207,35 @@ void dispatch_received_json(const std::wstring& json_to_parse)
|
||||
{
|
||||
{
|
||||
std::unique_lock lock{ ipc_mutex };
|
||||
if(current_settings_ipc)
|
||||
if (current_settings_ipc)
|
||||
current_settings_ipc->send(result.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (name == L"bugreport")
|
||||
{
|
||||
std::wstring bug_report_path = get_module_folderpath();
|
||||
bug_report_path += L"\\Tools\\PowerToys.BugReportTool.exe";
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_FLAG_NO_UI | SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE };
|
||||
sei.lpFile = bug_report_path.c_str();
|
||||
sei.nShow = SW_HIDE;
|
||||
if (ShellExecuteExW(&sei))
|
||||
{
|
||||
WaitForSingleObject(sei.hProcess, INFINITE);
|
||||
CloseHandle(sei.hProcess);
|
||||
static const std::wstring bugreport_success = GET_RESOURCE_STRING(IDS_BUGREPORT_SUCCESS);
|
||||
MessageBoxW(nullptr, bugreport_success.c_str(), L"PowerToys", MB_OK);
|
||||
}
|
||||
}
|
||||
else if (name == L"killrunner")
|
||||
{
|
||||
const auto pt_main_window = FindWindowW(pt_tray_icon_window_class, nullptr);
|
||||
if (pt_main_window != nullptr)
|
||||
{
|
||||
SendMessageW(pt_main_window, WM_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -290,7 +316,7 @@ BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args,
|
||||
|
||||
DWORD g_settings_process_id = 0;
|
||||
|
||||
void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::optional<std::wstring> settings_window)
|
||||
void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::optional<std::wstring> settings_window, bool show_flyout = false)
|
||||
{
|
||||
g_isLaunchInProgress = true;
|
||||
|
||||
@@ -360,11 +386,14 @@ void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::op
|
||||
// Arg 9: should scoobe window be shown
|
||||
std::wstring settings_showScoobe = show_scoobe_window ? L"true" : L"false";
|
||||
|
||||
// Arg 10: should flyout be shown
|
||||
std::wstring settings_showFlyout = show_flyout ? L"true" : L"false";
|
||||
|
||||
// create general settings file to initialize the settings file with installation configurations like :
|
||||
// 1. Run on start up.
|
||||
PTSettingsHelper::save_general_settings(save_settings.to_json());
|
||||
|
||||
std::wstring executable_args = fmt::format(L"\"{}\" {} {} {} {} {} {} {} {}",
|
||||
std::wstring executable_args = fmt::format(L"\"{}\" {} {} {} {} {} {} {} {} {}",
|
||||
executable_path,
|
||||
powertoys_pipe_name,
|
||||
settings_pipe_name,
|
||||
@@ -373,7 +402,8 @@ void run_settings_window(bool show_oobe_window, bool show_scoobe_window, std::op
|
||||
settings_elevatedStatus,
|
||||
settings_isUserAnAdmin,
|
||||
settings_showOobe,
|
||||
settings_showScoobe);
|
||||
settings_showScoobe,
|
||||
settings_showFlyout);
|
||||
|
||||
if (settings_window.has_value())
|
||||
{
|
||||
@@ -520,18 +550,33 @@ void bring_settings_to_front()
|
||||
EnumWindows(callback, 0);
|
||||
}
|
||||
|
||||
void open_settings_window(std::optional<std::wstring> settings_window)
|
||||
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout = false)
|
||||
{
|
||||
if (g_settings_process_id != 0)
|
||||
{
|
||||
bring_settings_to_front();
|
||||
if (show_flyout)
|
||||
{
|
||||
if (current_settings_ipc)
|
||||
{
|
||||
current_settings_ipc->send(L"{\"ShowYourself\":\"flyout\"}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// nl instead of showing the window, send message to it (flyout might need to be hidden, main setting window activated)
|
||||
// bring_settings_to_front();
|
||||
if (current_settings_ipc)
|
||||
{
|
||||
current_settings_ipc->send(L"{\"ShowYourself\":\"main_page\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!g_isLaunchInProgress)
|
||||
{
|
||||
std::thread([settings_window]() {
|
||||
run_settings_window(false, false, settings_window);
|
||||
std::thread([settings_window, show_flyout]() {
|
||||
run_settings_window(false, false, settings_window, show_flyout);
|
||||
}).detach();
|
||||
}
|
||||
}
|
||||
@@ -563,6 +608,13 @@ void open_scoobe_window()
|
||||
}).detach();
|
||||
}
|
||||
|
||||
void open_flyout()
|
||||
{
|
||||
std::thread([]() {
|
||||
run_settings_window(false, false, std::nullopt, true);
|
||||
}).detach();
|
||||
}
|
||||
|
||||
std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
|
||||
{
|
||||
switch (value)
|
||||
|
||||
@@ -22,8 +22,9 @@ enum class ESettingsWindowNames
|
||||
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 open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout);
|
||||
void close_settings_window();
|
||||
|
||||
void open_oobe_window();
|
||||
void open_scoobe_window();
|
||||
void open_flyout();
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace
|
||||
|
||||
HMENU h_menu = nullptr;
|
||||
HMENU h_sub_menu = nullptr;
|
||||
bool double_click_timer_running = false;
|
||||
bool double_clicked = false;
|
||||
}
|
||||
|
||||
// Struct to fill with callback and the data. The window_proc is responsible for cleaning it.
|
||||
@@ -69,7 +71,7 @@ void handle_tray_command(HWND window, const WPARAM command_id, LPARAM lparam)
|
||||
case ID_SETTINGS_MENU_COMMAND:
|
||||
{
|
||||
std::wstring settings_window{ winrt::to_hstring(ESettingsWindowNames_to_string(static_cast<ESettingsWindowNames>(lparam))) };
|
||||
open_settings_window(settings_window);
|
||||
open_settings_window(settings_window, false);
|
||||
}
|
||||
break;
|
||||
case ID_EXIT_MENU_COMMAND:
|
||||
@@ -116,6 +118,15 @@ void handle_tray_command(HWND window, const WPARAM command_id, LPARAM lparam)
|
||||
}
|
||||
}
|
||||
|
||||
void click_timer_elapsed()
|
||||
{
|
||||
double_click_timer_running = false;
|
||||
if (!double_clicked)
|
||||
{
|
||||
open_settings_window(std::nullopt, true);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (message)
|
||||
@@ -168,11 +179,6 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
|
||||
{
|
||||
switch (lparam)
|
||||
{
|
||||
case WM_LBUTTONDBLCLK:
|
||||
{
|
||||
open_settings_window(std::nullopt);
|
||||
break;
|
||||
}
|
||||
case WM_RBUTTONUP:
|
||||
case WM_CONTEXTMENU:
|
||||
{
|
||||
@@ -186,7 +192,6 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
|
||||
static std::wstring exit_menuitem_label = GET_RESOURCE_STRING(IDS_EXIT_MENU_TEXT);
|
||||
static std::wstring submit_bug_menuitem_label = GET_RESOURCE_STRING(IDS_SUBMIT_BUG_TEXT);
|
||||
static std::wstring documentation_menuitem_label = GET_RESOURCE_STRING(IDS_DOCUMENTATION_MENU_TEXT);
|
||||
|
||||
change_menu_item_text(ID_SETTINGS_MENU_COMMAND, settings_menuitem_label.data());
|
||||
change_menu_item_text(ID_EXIT_MENU_COMMAND, exit_menuitem_label.data());
|
||||
change_menu_item_text(ID_REPORT_BUG_COMMAND, submit_bug_menuitem_label.data());
|
||||
@@ -200,6 +205,30 @@ LRESULT __stdcall tray_icon_window_proc(HWND window, UINT message, WPARAM wparam
|
||||
GetCursorPos(&mouse_pointer);
|
||||
SetForegroundWindow(window); // Needed for the context menu to disappear.
|
||||
TrackPopupMenu(h_sub_menu, TPM_CENTERALIGN | TPM_BOTTOMALIGN, mouse_pointer.x, mouse_pointer.y, 0, window, nullptr);
|
||||
break;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
// ignore event if this is the second click of a double click
|
||||
if (!double_click_timer_running)
|
||||
{
|
||||
// start timer for detecting single or double click
|
||||
double_click_timer_running = true;
|
||||
double_clicked = false;
|
||||
|
||||
UINT doubleClickTime = GetDoubleClickTime();
|
||||
std::thread([doubleClickTime]() {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(doubleClickTime));
|
||||
click_timer_elapsed();
|
||||
}).detach();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_LBUTTONDBLCLK:
|
||||
{
|
||||
double_clicked = true;
|
||||
open_settings_window(std::nullopt, false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ void start_tray_icon();
|
||||
// Stop the Tray Icon
|
||||
void stop_tray_icon();
|
||||
// Open the Settings Window
|
||||
void open_settings_window(std::optional<std::wstring> settings_window);
|
||||
void open_settings_window(std::optional<std::wstring> settings_window, bool show_flyout);
|
||||
// Callback type to be called by the tray icon loop
|
||||
typedef void (*main_loop_callback_function)(PVOID);
|
||||
// Calls a callback in _callback
|
||||
|
||||
Reference in New Issue
Block a user