mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 17:42:45 +08:00
Merge branch 'master' of https://github.com/microsoft/PowerToys into dev/PowerLauncher
This commit is contained in:
commit
65276f45f1
100
NOTICE.md
100
NOTICE.md
@ -18,11 +18,12 @@ Notwithstanding any other terms, you may reverse engineer this software to the
|
|||||||
extent required to debug changes to any libraries licensed under the GNU Lesser
|
extent required to debug changes to any libraries licensed under the GNU Lesser
|
||||||
General Public License.
|
General Public License.
|
||||||
|
|
||||||
## ImageResizer
|
## PowerToy: ImageResizer
|
||||||
|
|
||||||
|
### Brice Lams's Image Resizer License
|
||||||
|
|
||||||
**Source**: https://github.com/bricelam/ImageResizer/
|
**Source**: https://github.com/bricelam/ImageResizer/
|
||||||
|
|
||||||
### License
|
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) Brice Lambson. All rights reserved.
|
Copyright (c) Brice Lambson. All rights reserved.
|
||||||
@ -44,3 +45,98 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
## PowerToy: Launcher
|
||||||
|
|
||||||
|
### Wox License
|
||||||
|
|
||||||
|
**Source**: https://github.com/Wox-launcher/Wox
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Wox
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
### Beta Tadele's Window Walker License
|
||||||
|
|
||||||
|
**Source**: https://github.com/betsegaw/windowwalker
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright 2020 Betsegaw Tadele
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
### Squirrel.Windows License
|
||||||
|
|
||||||
|
**Source**: https://github.com/Squirrel/Squirrel.Windows/
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2012 GitHub, Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
## PowerToy: PowerRename
|
||||||
|
|
||||||
|
### Chris Davis's SmartRename License
|
||||||
|
|
||||||
|
**Source**: https://github.com/chrdavis/SmartRename
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017 Chris Davis
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
@ -17,11 +17,11 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
TRACELOGGING_DEFINE_PROVIDER(
|
TRACELOGGING_DEFINE_PROVIDER(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"Microsoft.PowerToysInstaller",
|
"Microsoft.PowerToysInstaller",
|
||||||
// {e1d8165d-5cb6-5c74-3b51-bdfbfe4f7a3b}
|
// {e1d8165d-5cb6-5c74-3b51-bdfbfe4f7a3b}
|
||||||
(0xe1d8165d, 0x5cb6, 0x5c74, 0x3b, 0x51, 0xbd, 0xfb, 0xfe, 0x4f, 0x7a, 0x3b),
|
(0xe1d8165d, 0x5cb6, 0x5c74, 0x3b, 0x51, 0xbd, 0xfb, 0xfe, 0x4f, 0x7a, 0x3b),
|
||||||
TraceLoggingOptionProjectTelemetry());
|
TraceLoggingOptionProjectTelemetry());
|
||||||
|
|
||||||
const DWORD USERNAME_DOMAIN_LEN = DNLEN + UNLEN + 2; // Domain Name + '\' + User Name + '\0'
|
const DWORD USERNAME_DOMAIN_LEN = DNLEN + UNLEN + 2; // Domain Name + '\' + User Name + '\0'
|
||||||
const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0'
|
const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0'
|
||||||
@ -30,502 +30,562 @@ const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0'
|
|||||||
// The path of the executable to run should be passed as the CustomActionData (Value).
|
// The path of the executable to run should be passed as the CustomActionData (Value).
|
||||||
// Based on the Task Scheduler Logon Trigger Example:
|
// Based on the Task Scheduler Logon Trigger Example:
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/taskschd/logon-trigger-example--c---/
|
// https://docs.microsoft.com/en-us/windows/win32/taskschd/logon-trigger-example--c---/
|
||||||
UINT __stdcall CreateScheduledTaskCA(MSIHANDLE hInstall) {
|
UINT __stdcall CreateScheduledTaskCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
TCHAR username_domain[USERNAME_DOMAIN_LEN];
|
TCHAR username_domain[USERNAME_DOMAIN_LEN];
|
||||||
TCHAR username[USERNAME_LEN];
|
TCHAR username[USERNAME_LEN];
|
||||||
|
|
||||||
std::wstring wstrTaskName;
|
std::wstring wstrTaskName;
|
||||||
|
|
||||||
ITaskService *pService = NULL;
|
ITaskService* pService = NULL;
|
||||||
ITaskFolder *pTaskFolder = NULL;
|
ITaskFolder* pTaskFolder = NULL;
|
||||||
ITaskDefinition *pTask = NULL;
|
ITaskDefinition* pTask = NULL;
|
||||||
IRegistrationInfo *pRegInfo = NULL;
|
IRegistrationInfo* pRegInfo = NULL;
|
||||||
ITaskSettings *pSettings = NULL;
|
ITaskSettings* pSettings = NULL;
|
||||||
ITriggerCollection *pTriggerCollection = NULL;
|
ITriggerCollection* pTriggerCollection = NULL;
|
||||||
IRegisteredTask *pRegisteredTask = NULL;
|
IRegisteredTask* pRegisteredTask = NULL;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "CreateScheduledTaskCA");
|
hr = WcaInitialize(hInstall, "CreateScheduledTaskCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "Initialized.");
|
WcaLog(LOGMSG_STANDARD, "Initialized.");
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Get the Domain/Username for the trigger.
|
// Get the Domain/Username for the trigger.
|
||||||
//
|
//
|
||||||
// This action needs to run as the system to get elevated privileges from the installation,
|
// This action needs to run as the system to get elevated privileges from the installation,
|
||||||
// so GetUserNameEx can't be used to get the current user details.
|
// so GetUserNameEx can't be used to get the current user details.
|
||||||
// The USERNAME and USERDOMAIN environment variables are used instead.
|
// The USERNAME and USERDOMAIN environment variables are used instead.
|
||||||
if (!GetEnvironmentVariable(L"USERNAME", username, USERNAME_LEN)) {
|
if (!GetEnvironmentVariable(L"USERNAME", username, USERNAME_LEN))
|
||||||
ExitWithLastError(hr, "Getting username failed: %x", hr);
|
{
|
||||||
}
|
ExitWithLastError(hr, "Getting username failed: %x", hr);
|
||||||
if (!GetEnvironmentVariable(L"USERDOMAIN", username_domain, USERNAME_DOMAIN_LEN)) {
|
|
||||||
ExitWithLastError(hr, "Getting the user's domain failed: %x", hr);
|
|
||||||
}
|
|
||||||
wcscat_s(username_domain, L"\\");
|
|
||||||
wcscat_s(username_domain, username);
|
|
||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "Current user detected: %ls", username_domain);
|
|
||||||
|
|
||||||
// Task Name.
|
|
||||||
wstrTaskName = L"Autorun for ";
|
|
||||||
wstrTaskName += username;
|
|
||||||
|
|
||||||
// Get the executable path passed to the custom action.
|
|
||||||
LPWSTR wszExecutablePath = NULL;
|
|
||||||
hr = WcaGetProperty(L"CustomActionData", &wszExecutablePath);
|
|
||||||
ExitOnFailure(hr, "Failed to get the executable path from CustomActionData.");
|
|
||||||
|
|
||||||
// COM and Security Initialization is expected to have been done by the MSI.
|
|
||||||
// It couldn't be done in the DLL, anyway.
|
|
||||||
// ------------------------------------------------------
|
|
||||||
// Create an instance of the Task Service.
|
|
||||||
hr = CoCreateInstance(CLSID_TaskScheduler,
|
|
||||||
NULL,
|
|
||||||
CLSCTX_INPROC_SERVER,
|
|
||||||
IID_ITaskService,
|
|
||||||
(void**)&pService);
|
|
||||||
ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr);
|
|
||||||
|
|
||||||
// Connect to the task service.
|
|
||||||
hr = pService->Connect(_variant_t(), _variant_t(),
|
|
||||||
_variant_t(), _variant_t());
|
|
||||||
ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr);
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
|
||||||
// Get the PowerToys task folder. Creates it if it doesn't exist.
|
|
||||||
hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
// Folder doesn't exist. Get the Root folder and create the PowerToys subfolder.
|
|
||||||
ITaskFolder *pRootFolder = NULL;
|
|
||||||
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
|
|
||||||
ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr);
|
|
||||||
hr = pRootFolder->CreateFolder(_bstr_t(L"\\PowerToys"), _variant_t(L""), &pTaskFolder);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
pRootFolder->Release();
|
|
||||||
ExitOnFailure(hr, "Cannot create PowerToys task folder: %x", hr);
|
|
||||||
}
|
}
|
||||||
WcaLog(LOGMSG_STANDARD, "PowerToys task folder created.");
|
if (!GetEnvironmentVariable(L"USERDOMAIN", username_domain, USERNAME_DOMAIN_LEN))
|
||||||
}
|
{
|
||||||
|
ExitWithLastError(hr, "Getting the user's domain failed: %x", hr);
|
||||||
|
}
|
||||||
|
wcscat_s(username_domain, L"\\");
|
||||||
|
wcscat_s(username_domain, username);
|
||||||
|
|
||||||
// If the same task exists, remove it.
|
WcaLog(LOGMSG_STANDARD, "Current user detected: %ls", username_domain);
|
||||||
pTaskFolder->DeleteTask(_bstr_t(wstrTaskName.c_str()), 0);
|
|
||||||
|
|
||||||
// Create the task builder object to create the task.
|
// Task Name.
|
||||||
hr = pService->NewTask(0, &pTask);
|
wstrTaskName = L"Autorun for ";
|
||||||
ExitOnFailure(hr, "Failed to create a task definition: %x", hr);
|
wstrTaskName += username;
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// Get the executable path passed to the custom action.
|
||||||
// Get the registration info for setting the identification.
|
LPWSTR wszExecutablePath = NULL;
|
||||||
hr = pTask->get_RegistrationInfo(&pRegInfo);
|
hr = WcaGetProperty(L"CustomActionData", &wszExecutablePath);
|
||||||
ExitOnFailure(hr, "Cannot get identification pointer: %x", hr);
|
ExitOnFailure(hr, "Failed to get the executable path from CustomActionData.");
|
||||||
hr = pRegInfo->put_Author(_bstr_t(username_domain));
|
|
||||||
ExitOnFailure(hr, "Cannot put identification info: %x", hr);
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// COM and Security Initialization is expected to have been done by the MSI.
|
||||||
// Create the settings for the task
|
// It couldn't be done in the DLL, anyway.
|
||||||
hr = pTask->get_Settings(&pSettings);
|
// ------------------------------------------------------
|
||||||
ExitOnFailure(hr, "Cannot get settings pointer: %x", hr);
|
// Create an instance of the Task Service.
|
||||||
|
hr = CoCreateInstance(CLSID_TaskScheduler,
|
||||||
|
NULL,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
IID_ITaskService,
|
||||||
|
(void**)&pService);
|
||||||
|
ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr);
|
||||||
|
|
||||||
hr = pSettings->put_StartWhenAvailable(VARIANT_FALSE);
|
// Connect to the task service.
|
||||||
ExitOnFailure(hr, "Cannot put_StartWhenAvailable setting info: %x", hr);
|
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
|
||||||
hr = pSettings->put_StopIfGoingOnBatteries(VARIANT_FALSE);
|
ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr);
|
||||||
ExitOnFailure(hr, "Cannot put_StopIfGoingOnBatteries setting info: %x", hr);
|
|
||||||
hr = pSettings->put_ExecutionTimeLimit(_bstr_t(L"PT0S")); //Unlimited
|
|
||||||
ExitOnFailure(hr, "Cannot put_ExecutionTimeLimit setting info: %x", hr);
|
|
||||||
hr = pSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE);
|
|
||||||
ExitOnFailure(hr, "Cannot put_DisallowStartIfOnBatteries setting info: %x", hr);
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Get the trigger collection to insert the logon trigger.
|
// Get the PowerToys task folder. Creates it if it doesn't exist.
|
||||||
hr = pTask->get_Triggers(&pTriggerCollection);
|
hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder);
|
||||||
ExitOnFailure(hr, "Cannot get trigger collection: %x", hr);
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// Folder doesn't exist. Get the Root folder and create the PowerToys subfolder.
|
||||||
|
ITaskFolder* pRootFolder = NULL;
|
||||||
|
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
|
||||||
|
ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr);
|
||||||
|
hr = pRootFolder->CreateFolder(_bstr_t(L"\\PowerToys"), _variant_t(L""), &pTaskFolder);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
pRootFolder->Release();
|
||||||
|
ExitOnFailure(hr, "Cannot create PowerToys task folder: %x", hr);
|
||||||
|
}
|
||||||
|
WcaLog(LOGMSG_STANDARD, "PowerToys task folder created.");
|
||||||
|
}
|
||||||
|
|
||||||
// Add the logon trigger to the task.
|
// If the same task exists, remove it.
|
||||||
ITrigger *pTrigger = NULL;
|
pTaskFolder->DeleteTask(_bstr_t(wstrTaskName.c_str()), 0);
|
||||||
hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
|
|
||||||
ExitOnFailure(hr, "Cannot create the trigger: %x", hr);
|
|
||||||
|
|
||||||
ILogonTrigger *pLogonTrigger = NULL;
|
// Create the task builder object to create the task.
|
||||||
hr = pTrigger->QueryInterface(
|
hr = pService->NewTask(0, &pTask);
|
||||||
IID_ILogonTrigger, (void**)&pLogonTrigger);
|
ExitOnFailure(hr, "Failed to create a task definition: %x", hr);
|
||||||
pTrigger->Release();
|
|
||||||
ExitOnFailure(hr, "QueryInterface call failed for ILogonTrigger: %x", hr);
|
|
||||||
|
|
||||||
hr = pLogonTrigger->put_Id(_bstr_t(L"Trigger1"));
|
// ------------------------------------------------------
|
||||||
if (FAILED(hr)) {
|
// Get the registration info for setting the identification.
|
||||||
WcaLogError(hr, "Cannot put the trigger ID: %x", hr);
|
hr = pTask->get_RegistrationInfo(&pRegInfo);
|
||||||
}
|
ExitOnFailure(hr, "Cannot get identification pointer: %x", hr);
|
||||||
|
hr = pRegInfo->put_Author(_bstr_t(username_domain));
|
||||||
|
ExitOnFailure(hr, "Cannot put identification info: %x", hr);
|
||||||
|
|
||||||
// Timing issues may make explorer not be started when the task runs.
|
// ------------------------------------------------------
|
||||||
// Add a little delay to mitigate this.
|
// Create the settings for the task
|
||||||
hr = pLogonTrigger->put_Delay(_bstr_t(L"PT03S"));
|
hr = pTask->get_Settings(&pSettings);
|
||||||
if (FAILED(hr)) {
|
ExitOnFailure(hr, "Cannot get settings pointer: %x", hr);
|
||||||
WcaLogError(hr, "Cannot put the trigger delay: %x", hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define the user. The task will execute when the user logs on.
|
hr = pSettings->put_StartWhenAvailable(VARIANT_FALSE);
|
||||||
// The specified user must be a user on this computer.
|
ExitOnFailure(hr, "Cannot put_StartWhenAvailable setting info: %x", hr);
|
||||||
hr = pLogonTrigger->put_UserId(_bstr_t(username_domain));
|
hr = pSettings->put_StopIfGoingOnBatteries(VARIANT_FALSE);
|
||||||
pLogonTrigger->Release();
|
ExitOnFailure(hr, "Cannot put_StopIfGoingOnBatteries setting info: %x", hr);
|
||||||
ExitOnFailure(hr, "Cannot add user ID to logon trigger: %x", hr);
|
hr = pSettings->put_ExecutionTimeLimit(_bstr_t(L"PT0S")); //Unlimited
|
||||||
|
ExitOnFailure(hr, "Cannot put_ExecutionTimeLimit setting info: %x", hr);
|
||||||
|
hr = pSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE);
|
||||||
|
ExitOnFailure(hr, "Cannot put_DisallowStartIfOnBatteries setting info: %x", hr);
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Add an Action to the task. This task will execute the path passed to this custom action.
|
// Get the trigger collection to insert the logon trigger.
|
||||||
IActionCollection *pActionCollection = NULL;
|
hr = pTask->get_Triggers(&pTriggerCollection);
|
||||||
|
ExitOnFailure(hr, "Cannot get trigger collection: %x", hr);
|
||||||
|
|
||||||
// Get the task action collection pointer.
|
// Add the logon trigger to the task.
|
||||||
hr = pTask->get_Actions(&pActionCollection);
|
ITrigger* pTrigger = NULL;
|
||||||
ExitOnFailure(hr, "Cannot get Task collection pointer: %x", hr);
|
hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger);
|
||||||
|
ExitOnFailure(hr, "Cannot create the trigger: %x", hr);
|
||||||
|
|
||||||
// Create the action, specifying that it is an executable action.
|
ILogonTrigger* pLogonTrigger = NULL;
|
||||||
IAction *pAction = NULL;
|
hr = pTrigger->QueryInterface(
|
||||||
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
|
IID_ILogonTrigger, (void**)&pLogonTrigger);
|
||||||
pActionCollection->Release();
|
pTrigger->Release();
|
||||||
ExitOnFailure(hr, "Cannot create the action: %x", hr);
|
ExitOnFailure(hr, "QueryInterface call failed for ILogonTrigger: %x", hr);
|
||||||
|
|
||||||
IExecAction *pExecAction = NULL;
|
hr = pLogonTrigger->put_Id(_bstr_t(L"Trigger1"));
|
||||||
// QI for the executable task pointer.
|
if (FAILED(hr))
|
||||||
hr = pAction->QueryInterface(
|
{
|
||||||
IID_IExecAction, (void**)&pExecAction);
|
WcaLogError(hr, "Cannot put the trigger ID: %x", hr);
|
||||||
pAction->Release();
|
}
|
||||||
ExitOnFailure(hr, "QueryInterface call failed for IExecAction: %x", hr);
|
|
||||||
|
|
||||||
// Set the path of the executable to PowerToys (passed as CustomActionData).
|
// Timing issues may make explorer not be started when the task runs.
|
||||||
hr = pExecAction->put_Path(_bstr_t(wszExecutablePath));
|
// Add a little delay to mitigate this.
|
||||||
pExecAction->Release();
|
hr = pLogonTrigger->put_Delay(_bstr_t(L"PT03S"));
|
||||||
ExitOnFailure(hr, "Cannot set path of executable: %x", hr);
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
WcaLogError(hr, "Cannot put the trigger delay: %x", hr);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// Define the user. The task will execute when the user logs on.
|
||||||
// Create the principal for the task
|
// The specified user must be a user on this computer.
|
||||||
IPrincipal *pPrincipal = NULL;
|
hr = pLogonTrigger->put_UserId(_bstr_t(username_domain));
|
||||||
hr = pTask->get_Principal(&pPrincipal);
|
pLogonTrigger->Release();
|
||||||
ExitOnFailure(hr, "Cannot get principal pointer: %x", hr);
|
ExitOnFailure(hr, "Cannot add user ID to logon trigger: %x", hr);
|
||||||
|
|
||||||
// Set up principal information:
|
// ------------------------------------------------------
|
||||||
hr = pPrincipal->put_Id(_bstr_t(L"Principal1"));
|
// Add an Action to the task. This task will execute the path passed to this custom action.
|
||||||
if (FAILED(hr)) {
|
IActionCollection* pActionCollection = NULL;
|
||||||
WcaLogError(hr, "Cannot put the principal ID: %x", hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = pPrincipal->put_UserId(_bstr_t(username_domain));
|
// Get the task action collection pointer.
|
||||||
if (FAILED(hr)) {
|
hr = pTask->get_Actions(&pActionCollection);
|
||||||
WcaLogError(hr, "Cannot put principal user Id: %x", hr);
|
ExitOnFailure(hr, "Cannot get Task collection pointer: %x", hr);
|
||||||
}
|
|
||||||
|
|
||||||
hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN);
|
// Create the action, specifying that it is an executable action.
|
||||||
if (FAILED(hr)) {
|
IAction* pAction = NULL;
|
||||||
WcaLogError(hr, "Cannot put principal logon type: %x", hr);
|
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
|
||||||
}
|
pActionCollection->Release();
|
||||||
|
ExitOnFailure(hr, "Cannot create the action: %x", hr);
|
||||||
|
|
||||||
// Run the task with the highest available privileges.
|
IExecAction* pExecAction = NULL;
|
||||||
hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_LUA);
|
// QI for the executable task pointer.
|
||||||
pPrincipal->Release();
|
hr = pAction->QueryInterface(
|
||||||
ExitOnFailure(hr, "Cannot put principal run level: %x", hr);
|
IID_IExecAction, (void**)&pExecAction);
|
||||||
|
pAction->Release();
|
||||||
|
ExitOnFailure(hr, "QueryInterface call failed for IExecAction: %x", hr);
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// Set the path of the executable to PowerToys (passed as CustomActionData).
|
||||||
// Save the task in the PowerToys folder.
|
hr = pExecAction->put_Path(_bstr_t(wszExecutablePath));
|
||||||
{
|
pExecAction->Release();
|
||||||
_variant_t SDDL_FULL_ACCESS_FOR_EVERYONE = L"D:(A;;FA;;;WD)";
|
ExitOnFailure(hr, "Cannot set path of executable: %x", hr);
|
||||||
hr = pTaskFolder->RegisterTaskDefinition(
|
|
||||||
_bstr_t(wstrTaskName.c_str()),
|
|
||||||
pTask,
|
|
||||||
TASK_CREATE_OR_UPDATE,
|
|
||||||
_variant_t(username_domain),
|
|
||||||
_variant_t(),
|
|
||||||
TASK_LOGON_INTERACTIVE_TOKEN,
|
|
||||||
SDDL_FULL_ACCESS_FOR_EVERYONE,
|
|
||||||
&pRegisteredTask);
|
|
||||||
ExitOnFailure(hr, "Error saving the Task : %x", hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "Scheduled task created for the current user.");
|
// ------------------------------------------------------
|
||||||
|
// Create the principal for the task
|
||||||
|
IPrincipal* pPrincipal = NULL;
|
||||||
|
hr = pTask->get_Principal(&pPrincipal);
|
||||||
|
ExitOnFailure(hr, "Cannot get principal pointer: %x", hr);
|
||||||
|
|
||||||
|
// Set up principal information:
|
||||||
|
hr = pPrincipal->put_Id(_bstr_t(L"Principal1"));
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
WcaLogError(hr, "Cannot put the principal ID: %x", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pPrincipal->put_UserId(_bstr_t(username_domain));
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
WcaLogError(hr, "Cannot put principal user Id: %x", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pPrincipal->put_LogonType(TASK_LOGON_INTERACTIVE_TOKEN);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
WcaLogError(hr, "Cannot put principal logon type: %x", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the task with the highest available privileges.
|
||||||
|
hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_LUA);
|
||||||
|
pPrincipal->Release();
|
||||||
|
ExitOnFailure(hr, "Cannot put principal run level: %x", hr);
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// Save the task in the PowerToys folder.
|
||||||
|
{
|
||||||
|
_variant_t SDDL_FULL_ACCESS_FOR_EVERYONE = L"D:(A;;FA;;;WD)";
|
||||||
|
hr = pTaskFolder->RegisterTaskDefinition(
|
||||||
|
_bstr_t(wstrTaskName.c_str()),
|
||||||
|
pTask,
|
||||||
|
TASK_CREATE_OR_UPDATE,
|
||||||
|
_variant_t(username_domain),
|
||||||
|
_variant_t(),
|
||||||
|
TASK_LOGON_INTERACTIVE_TOKEN,
|
||||||
|
SDDL_FULL_ACCESS_FOR_EVERYONE,
|
||||||
|
&pRegisteredTask);
|
||||||
|
ExitOnFailure(hr, "Error saving the Task : %x", hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Scheduled task created for the current user.");
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
ReleaseStr(wszExecutablePath);
|
ReleaseStr(wszExecutablePath);
|
||||||
if (pService) pService->Release();
|
if (pService)
|
||||||
if (pTaskFolder) pTaskFolder->Release();
|
{
|
||||||
if (pTask) pTask->Release();
|
pService->Release();
|
||||||
if (pRegInfo) pRegInfo->Release();
|
}
|
||||||
if (pSettings) pSettings->Release();
|
if (pTaskFolder)
|
||||||
if (pTriggerCollection) pTriggerCollection->Release();
|
{
|
||||||
if (pRegisteredTask) pRegisteredTask->Release();
|
pTaskFolder->Release();
|
||||||
|
}
|
||||||
|
if (pTask)
|
||||||
|
{
|
||||||
|
pTask->Release();
|
||||||
|
}
|
||||||
|
if (pRegInfo)
|
||||||
|
{
|
||||||
|
pRegInfo->Release();
|
||||||
|
}
|
||||||
|
if (pSettings)
|
||||||
|
{
|
||||||
|
pSettings->Release();
|
||||||
|
}
|
||||||
|
if (pTriggerCollection)
|
||||||
|
{
|
||||||
|
pTriggerCollection->Release();
|
||||||
|
}
|
||||||
|
if (pRegisteredTask)
|
||||||
|
{
|
||||||
|
pRegisteredTask->Release();
|
||||||
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(hr)) {
|
if (!SUCCEEDED(hr))
|
||||||
PMSIHANDLE hRecord = MsiCreateRecord(0);
|
{
|
||||||
MsiRecordSetString(hRecord, 0, TEXT("Failed to create a scheduled task to start PowerToys at user login. You can re-try to create the scheduled task using the PowerToys settings."));
|
PMSIHANDLE hRecord = MsiCreateRecord(0);
|
||||||
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord);
|
MsiRecordSetString(hRecord, 0, TEXT("Failed to create a scheduled task to start PowerToys at user login. You can re-try to create the scheduled task using the PowerToys settings."));
|
||||||
}
|
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord);
|
||||||
|
}
|
||||||
|
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes all Scheduled Tasks in the PowerToys folder and deletes the folder afterwards.
|
// Removes all Scheduled Tasks in the PowerToys folder and deletes the folder afterwards.
|
||||||
// Based on the Task Scheduler Displaying Task Names and State example:
|
// Based on the Task Scheduler Displaying Task Names and State example:
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/TaskSchd/displaying-task-names-and-state--c---/
|
// https://docs.microsoft.com/en-us/windows/desktop/TaskSchd/displaying-task-names-and-state--c---/
|
||||||
UINT __stdcall RemoveScheduledTasksCA(MSIHANDLE hInstall) {
|
UINT __stdcall RemoveScheduledTasksCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
ITaskService *pService = NULL;
|
ITaskService* pService = NULL;
|
||||||
ITaskFolder *pTaskFolder = NULL;
|
ITaskFolder* pTaskFolder = NULL;
|
||||||
IRegisteredTaskCollection* pTaskCollection = NULL;
|
IRegisteredTaskCollection* pTaskCollection = NULL;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "RemoveScheduledTasksCA");
|
hr = WcaInitialize(hInstall, "RemoveScheduledTasksCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "Initialized.");
|
WcaLog(LOGMSG_STANDARD, "Initialized.");
|
||||||
|
|
||||||
// COM and Security Initialization is expected to have been done by the MSI.
|
// COM and Security Initialization is expected to have been done by the MSI.
|
||||||
// It couldn't be done in the DLL, anyway.
|
// It couldn't be done in the DLL, anyway.
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Create an instance of the Task Service.
|
// Create an instance of the Task Service.
|
||||||
hr = CoCreateInstance(CLSID_TaskScheduler,
|
hr = CoCreateInstance(CLSID_TaskScheduler,
|
||||||
NULL,
|
NULL,
|
||||||
CLSCTX_INPROC_SERVER,
|
CLSCTX_INPROC_SERVER,
|
||||||
IID_ITaskService,
|
IID_ITaskService,
|
||||||
(void**)&pService);
|
(void**)&pService);
|
||||||
ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr);
|
ExitOnFailure(hr, "Failed to create an instance of ITaskService: %x", hr);
|
||||||
|
|
||||||
// Connect to the task service.
|
// Connect to the task service.
|
||||||
hr = pService->Connect(_variant_t(), _variant_t(),
|
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
|
||||||
_variant_t(), _variant_t());
|
ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr);
|
||||||
ExitOnFailure(hr, "ITaskService::Connect failed: %x", hr);
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Get the PowerToys task folder.
|
// Get the PowerToys task folder.
|
||||||
hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder);
|
hr = pService->GetFolder(_bstr_t(L"\\PowerToys"), &pTaskFolder);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr))
|
||||||
// Folder doesn't exist. No need to delete anything.
|
{
|
||||||
WcaLog(LOGMSG_STANDARD, "The PowerToys scheduled task folder wasn't found. Nothing to delete.");
|
// Folder doesn't exist. No need to delete anything.
|
||||||
hr = S_OK;
|
WcaLog(LOGMSG_STANDARD, "The PowerToys scheduled task folder wasn't found. Nothing to delete.");
|
||||||
ExitFunction();
|
hr = S_OK;
|
||||||
}
|
ExitFunction();
|
||||||
|
|
||||||
// -------------------------------------------------------
|
|
||||||
// Get the registered tasks in the folder.
|
|
||||||
hr = pTaskFolder->GetTasks(TASK_ENUM_HIDDEN, &pTaskCollection);
|
|
||||||
ExitOnFailure(hr, "Cannot get the registered tasks: %x", hr);
|
|
||||||
|
|
||||||
LONG numTasks = 0;
|
|
||||||
hr = pTaskCollection->get_Count(&numTasks);
|
|
||||||
for (LONG i = 0; i < numTasks; i++) {
|
|
||||||
// Delete all the tasks found.
|
|
||||||
// If some tasks can't be deleted, the folder won't be deleted later and the user will still be notified.
|
|
||||||
IRegisteredTask* pRegisteredTask = NULL;
|
|
||||||
hr = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
BSTR taskName = NULL;
|
|
||||||
hr = pRegisteredTask->get_Name(&taskName);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = pTaskFolder->DeleteTask(taskName, NULL);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
WcaLogError(hr, "Cannot delete the '%S' task: %x", taskName, hr);
|
|
||||||
}
|
|
||||||
SysFreeString(taskName);
|
|
||||||
} else {
|
|
||||||
WcaLogError(hr, "Cannot get the registered task name: %x", hr);
|
|
||||||
}
|
|
||||||
pRegisteredTask->Release();
|
|
||||||
} else {
|
|
||||||
WcaLogError(hr, "Cannot get the registered task item at index=%d: %x", i + 1, hr);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
// Get the pointer to the root task folder and delete the PowerToys subfolder.
|
// Get the registered tasks in the folder.
|
||||||
ITaskFolder *pRootFolder = NULL;
|
hr = pTaskFolder->GetTasks(TASK_ENUM_HIDDEN, &pTaskCollection);
|
||||||
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
|
ExitOnFailure(hr, "Cannot get the registered tasks: %x", hr);
|
||||||
ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr);
|
|
||||||
hr = pRootFolder->DeleteFolder(_bstr_t(L"PowerToys"), NULL);
|
|
||||||
pRootFolder->Release();
|
|
||||||
ExitOnFailure(hr, "Cannot delete the PowerToys folder: %x", hr);
|
|
||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "Deleted the PowerToys Task Scheduler folder.");
|
LONG numTasks = 0;
|
||||||
|
hr = pTaskCollection->get_Count(&numTasks);
|
||||||
|
for (LONG i = 0; i < numTasks; i++)
|
||||||
|
{
|
||||||
|
// Delete all the tasks found.
|
||||||
|
// If some tasks can't be deleted, the folder won't be deleted later and the user will still be notified.
|
||||||
|
IRegisteredTask* pRegisteredTask = NULL;
|
||||||
|
hr = pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
BSTR taskName = NULL;
|
||||||
|
hr = pRegisteredTask->get_Name(&taskName);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
hr = pTaskFolder->DeleteTask(taskName, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
WcaLogError(hr, "Cannot delete the '%S' task: %x", taskName, hr);
|
||||||
|
}
|
||||||
|
SysFreeString(taskName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WcaLogError(hr, "Cannot get the registered task name: %x", hr);
|
||||||
|
}
|
||||||
|
pRegisteredTask->Release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WcaLogError(hr, "Cannot get the registered task item at index=%d: %x", i + 1, hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// Get the pointer to the root task folder and delete the PowerToys subfolder.
|
||||||
|
ITaskFolder* pRootFolder = NULL;
|
||||||
|
hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
|
||||||
|
ExitOnFailure(hr, "Cannot get Root Folder pointer: %x", hr);
|
||||||
|
hr = pRootFolder->DeleteFolder(_bstr_t(L"PowerToys"), NULL);
|
||||||
|
pRootFolder->Release();
|
||||||
|
ExitOnFailure(hr, "Cannot delete the PowerToys folder: %x", hr);
|
||||||
|
|
||||||
|
WcaLog(LOGMSG_STANDARD, "Deleted the PowerToys Task Scheduler folder.");
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
if (pService) pService->Release();
|
if (pService)
|
||||||
if (pTaskFolder) pTaskFolder->Release();
|
{
|
||||||
if (pTaskCollection) pTaskCollection->Release();
|
pService->Release();
|
||||||
|
}
|
||||||
|
if (pTaskFolder)
|
||||||
|
{
|
||||||
|
pTaskFolder->Release();
|
||||||
|
}
|
||||||
|
if (pTaskCollection)
|
||||||
|
{
|
||||||
|
pTaskCollection->Release();
|
||||||
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(hr)) {
|
if (!SUCCEEDED(hr))
|
||||||
PMSIHANDLE hRecord = MsiCreateRecord(0);
|
{
|
||||||
MsiRecordSetString(hRecord, 0, TEXT("Failed to remove the PowerToys folder from the scheduled task. These can be removed manually later."));
|
PMSIHANDLE hRecord = MsiCreateRecord(0);
|
||||||
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord);
|
MsiRecordSetString(hRecord, 0, TEXT("Failed to remove the PowerToys folder from the scheduled task. These can be removed manually later."));
|
||||||
}
|
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord);
|
||||||
|
}
|
||||||
|
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogInstallSuccessCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogInstallSuccessCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogInstallSuccessCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogInstallSuccessCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"Install_Success",
|
"Install_Success",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogInstallCancelCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogInstallCancelCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogInstallCancelCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogInstallCancelCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"Install_Cancel",
|
"Install_Cancel",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogInstallFailCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogInstallFailCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogInstallFailCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogInstallFailCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"Install_Fail",
|
"Install_Fail",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogUninstallSuccessCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogUninstallSuccessCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogUninstallSuccessCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogUninstallSuccessCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"UnInstall_Success",
|
"UnInstall_Success",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogUninstallCancelCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogUninstallCancelCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogUninstallCancelCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogUninstallCancelCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"UnInstall_Cancel",
|
"UnInstall_Cancel",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogUninstallFailCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogUninstallFailCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogUninstallFailCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogUninstallFailCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"UnInstall_Fail",
|
"UnInstall_Fail",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogRepairCancelCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogRepairCancelCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogRepairCancelCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogRepairCancelCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"Repair_Cancel",
|
"Repair_Cancel",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT __stdcall TelemetryLogRepairFailCA(MSIHANDLE hInstall) {
|
UINT __stdcall TelemetryLogRepairFailCA(MSIHANDLE hInstall)
|
||||||
HRESULT hr = S_OK;
|
{
|
||||||
UINT er = ERROR_SUCCESS;
|
HRESULT hr = S_OK;
|
||||||
|
UINT er = ERROR_SUCCESS;
|
||||||
|
|
||||||
hr = WcaInitialize(hInstall, "TelemetryLogRepairFailCA");
|
hr = WcaInitialize(hInstall, "TelemetryLogRepairFailCA");
|
||||||
ExitOnFailure(hr, "Failed to initialize");
|
ExitOnFailure(hr, "Failed to initialize");
|
||||||
|
|
||||||
TraceLoggingWrite(
|
TraceLoggingWrite(
|
||||||
g_hProvider,
|
g_hProvider,
|
||||||
"Repair_Fail",
|
"Repair_Fail",
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||||
|
|
||||||
LExit:
|
LExit:
|
||||||
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
|
||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DllMain - Initialize and cleanup WiX custom action utils.
|
// DllMain - Initialize and cleanup WiX custom action utils.
|
||||||
extern "C" BOOL WINAPI DllMain(__in HINSTANCE hInst, __in ULONG ulReason, __in LPVOID) {
|
extern "C" BOOL WINAPI DllMain(__in HINSTANCE hInst, __in ULONG ulReason, __in LPVOID)
|
||||||
switch (ulReason) {
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
switch (ulReason)
|
||||||
WcaGlobalInitialize(hInst);
|
{
|
||||||
TraceLoggingRegister(g_hProvider);
|
case DLL_PROCESS_ATTACH:
|
||||||
break;
|
WcaGlobalInitialize(hInst);
|
||||||
|
TraceLoggingRegister(g_hProvider);
|
||||||
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
TraceLoggingUnregister(g_hProvider);
|
TraceLoggingUnregister(g_hProvider);
|
||||||
WcaGlobalFinalize();
|
WcaGlobalFinalize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -364,27 +364,31 @@ WindowState get_window_state(HWND hwnd)
|
|||||||
return RESTORED;
|
return RESTORED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_process_elevated()
|
bool is_process_elevated(const bool use_cached_value)
|
||||||
{
|
{
|
||||||
HANDLE token = nullptr;
|
auto detection_func = []() {
|
||||||
bool elevated = false;
|
HANDLE token = nullptr;
|
||||||
|
bool elevated = false;
|
||||||
|
|
||||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
||||||
{
|
|
||||||
TOKEN_ELEVATION elevation;
|
|
||||||
DWORD size;
|
|
||||||
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size))
|
|
||||||
{
|
{
|
||||||
elevated = (elevation.TokenIsElevated != 0);
|
TOKEN_ELEVATION elevation;
|
||||||
|
DWORD size;
|
||||||
|
if (GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size))
|
||||||
|
{
|
||||||
|
elevated = (elevation.TokenIsElevated != 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
return elevated;
|
return elevated;
|
||||||
|
};
|
||||||
|
static const bool cached_value = detection_func();
|
||||||
|
return use_cached_value ? cached_value : detection_func();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool drop_elevated_privileges()
|
bool drop_elevated_privileges()
|
||||||
|
@ -61,7 +61,7 @@ enum WindowState
|
|||||||
WindowState get_window_state(HWND hwnd);
|
WindowState get_window_state(HWND hwnd);
|
||||||
|
|
||||||
// Returns true if the current process is running with elevated privileges
|
// Returns true if the current process is running with elevated privileges
|
||||||
bool is_process_elevated();
|
bool is_process_elevated(const bool use_cached_value = true);
|
||||||
|
|
||||||
// Drops the elevated privilages if present
|
// Drops the elevated privilages if present
|
||||||
bool drop_elevated_privileges();
|
bool drop_elevated_privileges();
|
||||||
@ -78,7 +78,7 @@ bool run_same_elevation(const std::wstring& file, const std::wstring& params);
|
|||||||
// Returns true if the current process is running from administrator account
|
// Returns true if the current process is running from administrator account
|
||||||
bool check_user_is_admin();
|
bool check_user_is_admin();
|
||||||
|
|
||||||
//Returns true when one or more strings from vector found in string
|
// Returns true when one or more strings from vector found in string
|
||||||
bool find_app_name_in_path(const std::wstring& where, const std::vector<std::wstring>& what);
|
bool find_app_name_in_path(const std::wstring& where, const std::vector<std::wstring>& what);
|
||||||
|
|
||||||
// Get the executable path or module name for modern apps
|
// Get the executable path or module name for modern apps
|
||||||
|
@ -84,6 +84,9 @@
|
|||||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||||
<CodeAnalysisRuleSet>..\..\..\..\codeAnalysis\Rules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>..\..\..\..\codeAnalysis\Rules.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>images\FancyZonesEditor.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||||
@ -256,5 +259,8 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="images\Merge.png" />
|
<Resource Include="images\Merge.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="images\FancyZonesEditor.ico" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
@ -101,7 +101,16 @@ namespace FancyZonesEditor
|
|||||||
|
|
||||||
private int SplitterThickness
|
private int SplitterThickness
|
||||||
{
|
{
|
||||||
get { return Math.Max(((App)Application.Current).ZoneSettings.Spacing, 5); }
|
get
|
||||||
|
{
|
||||||
|
Settings settings = ((App)Application.Current).ZoneSettings;
|
||||||
|
if (!settings.ShowSpacing)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Max(settings.Spacing, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSplitter()
|
private void UpdateSplitter()
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
@ -150,6 +150,7 @@ public:
|
|||||||
void AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept;
|
void AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept;
|
||||||
|
|
||||||
void MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index) noexcept;
|
void MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index) noexcept;
|
||||||
|
void MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector<int>& indexSet) noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static LRESULT CALLBACK s_WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
static LRESULT CALLBACK s_WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
||||||
@ -680,7 +681,7 @@ void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept
|
|||||||
//const bool flash = m_settings->GetSettings()->zoneSetChange_flashZones && newWorkArea;
|
//const bool flash = m_settings->GetSettings()->zoneSetChange_flashZones && newWorkArea;
|
||||||
const bool flash = false;
|
const bool flash = false;
|
||||||
|
|
||||||
auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash);
|
auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash, newWorkArea);
|
||||||
if (zoneWindow)
|
if (zoneWindow)
|
||||||
{
|
{
|
||||||
m_zoneWindowMap[monitor] = std::move(zoneWindow);
|
m_zoneWindowMap[monitor] = std::move(zoneWindow);
|
||||||
@ -695,6 +696,12 @@ void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FancyZones::MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index) noexcept
|
void FancyZones::MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index) noexcept
|
||||||
|
{
|
||||||
|
std::shared_lock readLock(m_lock);
|
||||||
|
MoveWindowIntoZoneByIndexSet(window, monitor, { index });
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyZones::MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector<int>& indexSet) noexcept
|
||||||
{
|
{
|
||||||
std::shared_lock readLock(m_lock);
|
std::shared_lock readLock(m_lock);
|
||||||
if (window != m_windowMoveSize)
|
if (window != m_windowMoveSize)
|
||||||
@ -706,7 +713,7 @@ void FancyZones::MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int in
|
|||||||
if (zoneWindow != m_zoneWindowMap.end())
|
if (zoneWindow != m_zoneWindowMap.end())
|
||||||
{
|
{
|
||||||
const auto& zoneWindowPtr = zoneWindow->second;
|
const auto& zoneWindowPtr = zoneWindow->second;
|
||||||
zoneWindowPtr->MoveWindowIntoZoneByIndex(window, index);
|
zoneWindowPtr->MoveWindowIntoZoneByIndexSet(window, indexSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -860,10 +867,8 @@ void FancyZones::UpdateDragState(HWND window, require_write_lock) noexcept
|
|||||||
m_dragEnabled = !(shift | mouse);
|
m_dragEnabled = !(shift | mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool windowElevated = IsProcessOfWindowElevated(window);
|
|
||||||
static const bool meElevated = is_process_elevated();
|
|
||||||
static bool warning_shown = false;
|
static bool warning_shown = false;
|
||||||
if (windowElevated && !meElevated)
|
if (!is_process_elevated() && IsProcessOfWindowElevated(window))
|
||||||
{
|
{
|
||||||
m_dragEnabled = false;
|
m_dragEnabled = false;
|
||||||
if (!warning_shown && !is_cant_drag_elevated_warning_disabled())
|
if (!warning_shown && !is_cant_drag_elevated_warning_disabled())
|
||||||
|
@ -212,6 +212,11 @@ namespace JSONHelpers
|
|||||||
customZoneSetsMap.clear();
|
customZoneSetsMap.clear();
|
||||||
activeDeviceId.clear();
|
activeDeviceId.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void SetDeviceInfo(const std::wstring& deviceId, DeviceInfoData data)
|
||||||
|
{
|
||||||
|
deviceInfoMap[deviceId] = data;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void SetActiveDeviceId(const std::wstring& deviceId)
|
inline void SetActiveDeviceId(const std::wstring& deviceId)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <common/monitors.h>
|
#include <common/monitors.h>
|
||||||
#include "Zone.h"
|
#include "Zone.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
struct Zone : winrt::implements<Zone, IZone>
|
struct Zone : winrt::implements<Zone, IZone>
|
||||||
{
|
{
|
||||||
@ -20,6 +21,7 @@ public:
|
|||||||
IFACEMETHODIMP_(void) RemoveWindowFromZone(HWND window, bool restoreSize) noexcept;
|
IFACEMETHODIMP_(void) RemoveWindowFromZone(HWND window, bool restoreSize) noexcept;
|
||||||
IFACEMETHODIMP_(void) SetId(size_t id) noexcept { m_id = id; }
|
IFACEMETHODIMP_(void) SetId(size_t id) noexcept { m_id = id; }
|
||||||
IFACEMETHODIMP_(size_t) Id() noexcept { return m_id; }
|
IFACEMETHODIMP_(size_t) Id() noexcept { return m_id; }
|
||||||
|
IFACEMETHODIMP_(RECT) ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SizeWindowToZone(HWND window, HWND zoneWindow) noexcept;
|
void SizeWindowToZone(HWND window, HWND zoneWindow) noexcept;
|
||||||
@ -61,12 +63,11 @@ IFACEMETHODIMP_(void) Zone::RemoveWindowFromZone(HWND window, bool restoreSize)
|
|||||||
|
|
||||||
void Zone::SizeWindowToZone(HWND window, HWND zoneWindow) noexcept
|
void Zone::SizeWindowToZone(HWND window, HWND zoneWindow) noexcept
|
||||||
{
|
{
|
||||||
// Skip invisible windows
|
SizeWindowToRect(window, ComputeActualZoneRect(window, zoneWindow));
|
||||||
if (!IsWindowVisible(window))
|
}
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept
|
||||||
|
{
|
||||||
// Take care of 1px border
|
// Take care of 1px border
|
||||||
RECT newWindowRect = m_zoneRect;
|
RECT newWindowRect = m_zoneRect;
|
||||||
|
|
||||||
@ -111,29 +112,7 @@ void Zone::SizeWindowToZone(HWND window, HWND zoneWindow) noexcept
|
|||||||
newWindowRect.bottom = newWindowRect.top + (windowRect.bottom - windowRect.top);
|
newWindowRect.bottom = newWindowRect.top + (windowRect.bottom - windowRect.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
WINDOWPLACEMENT placement{};
|
return newWindowRect;
|
||||||
::GetWindowPlacement(window, &placement);
|
|
||||||
|
|
||||||
//wait if SW_SHOWMINIMIZED would be removed from window (Issue #1685)
|
|
||||||
for (int i = 0; i < 5 && (placement.showCmd & SW_SHOWMINIMIZED) != 0; i++)
|
|
||||||
{
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
::GetWindowPlacement(window, &placement);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not restore minimized windows. We change their placement though so they restore to the correct zone.
|
|
||||||
if ((placement.showCmd & SW_SHOWMINIMIZED) == 0)
|
|
||||||
{
|
|
||||||
placement.showCmd = SW_RESTORE | SW_SHOWNA;
|
|
||||||
}
|
|
||||||
|
|
||||||
placement.rcNormalPosition = newWindowRect;
|
|
||||||
placement.flags |= WPF_ASYNCWINDOWPLACEMENT;
|
|
||||||
|
|
||||||
::SetWindowPlacement(window, &placement);
|
|
||||||
// Do it again, allowing Windows to resize the window and set correct scaling
|
|
||||||
// This fixes Issue #365
|
|
||||||
::SetWindowPlacement(window, &placement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zone::StampZone(HWND window, bool stamp) noexcept
|
void Zone::StampZone(HWND window, bool stamp) noexcept
|
||||||
|
@ -42,9 +42,20 @@ interface __declspec(uuid("{8228E934-B6EF-402A-9892-15A1441BF8B0}")) IZone : pub
|
|||||||
*/
|
*/
|
||||||
IFACEMETHOD_(void, SetId)(size_t id) = 0;
|
IFACEMETHOD_(void, SetId)(size_t id) = 0;
|
||||||
/**
|
/**
|
||||||
* @retirns Zone identifier.
|
* @returns Zone identifier.
|
||||||
*/
|
*/
|
||||||
IFACEMETHOD_(size_t, Id)() = 0;
|
IFACEMETHOD_(size_t, Id)() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the coordinates of the rectangle to which a window should be resized.
|
||||||
|
*
|
||||||
|
* @param window Handle of window which should be assigned to zone.
|
||||||
|
* @param zoneWindow The m_window of a ZoneWindow, it's a hidden window representing the
|
||||||
|
* current monitor desktop work area.
|
||||||
|
* @returns a RECT structure, describing global coordinates to which a window should be resized
|
||||||
|
*/
|
||||||
|
IFACEMETHOD_(RECT, ComputeActualZoneRect)(HWND window, HWND zoneWindow) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
winrt::com_ptr<IZone> MakeZone(const RECT& zoneRect) noexcept;
|
winrt::com_ptr<IZone> MakeZone(const RECT& zoneRect) noexcept;
|
||||||
|
@ -122,14 +122,16 @@ public:
|
|||||||
IFACEMETHODIMP_(JSONHelpers::ZoneSetLayoutType)
|
IFACEMETHODIMP_(JSONHelpers::ZoneSetLayoutType)
|
||||||
LayoutType() noexcept { return m_config.LayoutType; }
|
LayoutType() noexcept { return m_config.LayoutType; }
|
||||||
IFACEMETHODIMP AddZone(winrt::com_ptr<IZone> zone) noexcept;
|
IFACEMETHODIMP AddZone(winrt::com_ptr<IZone> zone) noexcept;
|
||||||
IFACEMETHODIMP_(winrt::com_ptr<IZone>)
|
IFACEMETHODIMP_(std::vector<int>)
|
||||||
ZoneFromPoint(POINT pt) noexcept;
|
ZonesFromPoint(POINT pt) noexcept;
|
||||||
IFACEMETHODIMP_(int)
|
IFACEMETHODIMP_(int)
|
||||||
GetZoneIndexFromWindow(HWND window) noexcept;
|
GetZoneIndexFromWindow(HWND window) noexcept;
|
||||||
IFACEMETHODIMP_(std::vector<winrt::com_ptr<IZone>>)
|
IFACEMETHODIMP_(std::vector<winrt::com_ptr<IZone>>)
|
||||||
GetZones() noexcept { return m_zones; }
|
GetZones() noexcept { return m_zones; }
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
MoveWindowIntoZoneByIndex(HWND window, HWND zoneWindow, int index) noexcept;
|
MoveWindowIntoZoneByIndex(HWND window, HWND zoneWindow, int index, bool stampZone) noexcept;
|
||||||
|
IFACEMETHODIMP_(void)
|
||||||
|
MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::vector<int>& indexSet, bool stampZone) noexcept;
|
||||||
IFACEMETHODIMP_(bool)
|
IFACEMETHODIMP_(bool)
|
||||||
MoveWindowIntoZoneByDirection(HWND window, HWND zoneWindow, DWORD vkCode, bool cycle) noexcept;
|
MoveWindowIntoZoneByDirection(HWND window, HWND zoneWindow, DWORD vkCode, bool cycle) noexcept;
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
@ -162,41 +164,79 @@ IFACEMETHODIMP ZoneSet::AddZone(winrt::com_ptr<IZone> zone) noexcept
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP_(winrt::com_ptr<IZone>)
|
IFACEMETHODIMP_(std::vector<int>)
|
||||||
ZoneSet::ZoneFromPoint(POINT pt) noexcept
|
ZoneSet::ZonesFromPoint(POINT pt) noexcept
|
||||||
{
|
{
|
||||||
winrt::com_ptr<IZone> smallestKnownZone = nullptr;
|
const int SENSITIVITY_RADIUS = 20;
|
||||||
// To reduce redundant calculations, we will store the last known zones area.
|
std::vector<int> capturedZones;
|
||||||
int smallestKnownZoneArea = INT32_MAX;
|
std::vector<int> strictlyCapturedZones;
|
||||||
for (auto iter = m_zones.rbegin(); iter != m_zones.rend(); iter++)
|
for (size_t i = 0; i < m_zones.size(); i++)
|
||||||
{
|
{
|
||||||
if (winrt::com_ptr<IZone> zone = iter->try_as<IZone>())
|
auto zone = m_zones[i];
|
||||||
|
RECT newZoneRect = zone->GetZoneRect();
|
||||||
|
if (newZoneRect.left < newZoneRect.right && newZoneRect.top < newZoneRect.bottom) // proper zone
|
||||||
{
|
{
|
||||||
RECT* newZoneRect = &zone->GetZoneRect();
|
if (newZoneRect.left - SENSITIVITY_RADIUS <= pt.x && pt.x <= newZoneRect.right + SENSITIVITY_RADIUS &&
|
||||||
if (PtInRect(newZoneRect, pt))
|
newZoneRect.top - SENSITIVITY_RADIUS <= pt.y && pt.y <= newZoneRect.bottom + SENSITIVITY_RADIUS)
|
||||||
{
|
{
|
||||||
if (smallestKnownZone == nullptr)
|
capturedZones.emplace_back(static_cast<int>(i));
|
||||||
{
|
}
|
||||||
smallestKnownZone = zone;
|
|
||||||
|
if (newZoneRect.left <= pt.x && pt.x < newZoneRect.right &&
|
||||||
RECT* r = &smallestKnownZone->GetZoneRect();
|
newZoneRect.top <= pt.y && pt.y < newZoneRect.bottom)
|
||||||
smallestKnownZoneArea = (r->right - r->left) * (r->bottom - r->top);
|
{
|
||||||
}
|
strictlyCapturedZones.emplace_back(static_cast<int>(i));
|
||||||
else
|
|
||||||
{
|
|
||||||
int newZoneArea = (newZoneRect->right - newZoneRect->left) * (newZoneRect->bottom - newZoneRect->top);
|
|
||||||
|
|
||||||
if (newZoneArea < smallestKnownZoneArea)
|
|
||||||
{
|
|
||||||
smallestKnownZone = zone;
|
|
||||||
smallestKnownZoneArea = newZoneArea;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return smallestKnownZone;
|
// If only one zone is captured, but it's not strictly captured
|
||||||
|
// don't consider it as captured
|
||||||
|
if (capturedZones.size() == 1 && strictlyCapturedZones.size() == 0)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If captured zones do not overlap, return all of them
|
||||||
|
// Otherwise, return the smallest one
|
||||||
|
|
||||||
|
bool overlap = false;
|
||||||
|
for (size_t i = 0; i < capturedZones.size(); ++i)
|
||||||
|
{
|
||||||
|
for (size_t j = i + 1; j < capturedZones.size(); ++j)
|
||||||
|
{
|
||||||
|
auto rectI = m_zones[capturedZones[i]]->GetZoneRect();
|
||||||
|
auto rectJ = m_zones[capturedZones[j]]->GetZoneRect();
|
||||||
|
if (max(rectI.top, rectJ.top) < min(rectI.bottom, rectJ.bottom) &&
|
||||||
|
max(rectI.left, rectJ.left) < min(rectI.right, rectJ.right))
|
||||||
|
{
|
||||||
|
overlap = true;
|
||||||
|
i = capturedZones.size() - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlap)
|
||||||
|
{
|
||||||
|
size_t smallestIdx = 0;
|
||||||
|
for (size_t i = 1; i < capturedZones.size(); ++i)
|
||||||
|
{
|
||||||
|
auto rectS = m_zones[capturedZones[smallestIdx]]->GetZoneRect();
|
||||||
|
auto rectI = m_zones[capturedZones[i]]->GetZoneRect();
|
||||||
|
int smallestSize = (rectS.bottom - rectS.top) * (rectS.right - rectS.left);
|
||||||
|
int iSize = (rectI.bottom - rectI.top) * (rectI.right - rectI.left);
|
||||||
|
|
||||||
|
if (iSize <= smallestSize)
|
||||||
|
{
|
||||||
|
smallestIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
capturedZones = { capturedZones[smallestIdx] };
|
||||||
|
}
|
||||||
|
|
||||||
|
return capturedZones;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP_(int)
|
IFACEMETHODIMP_(int)
|
||||||
@ -217,7 +257,7 @@ ZoneSet::GetZoneIndexFromWindow(HWND window) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, int index) noexcept
|
ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, int index, bool stampZone) noexcept
|
||||||
{
|
{
|
||||||
if (m_zones.empty())
|
if (m_zones.empty())
|
||||||
{
|
{
|
||||||
@ -236,7 +276,55 @@ ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, int index) noex
|
|||||||
|
|
||||||
if (auto zone = m_zones.at(index))
|
if (auto zone = m_zones.at(index))
|
||||||
{
|
{
|
||||||
zone->AddWindowToZone(window, windowZone, false);
|
zone->AddWindowToZone(window, windowZone, stampZone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(void)
|
||||||
|
ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::vector<int>& indexSet, bool stampZone) noexcept
|
||||||
|
{
|
||||||
|
if (m_zones.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (auto zoneDrop = ZoneFromWindow(window))
|
||||||
|
{
|
||||||
|
zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexSet.size() == 1)
|
||||||
|
{
|
||||||
|
MoveWindowIntoZoneByIndex(window, windowZone, indexSet[0], stampZone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RECT size;
|
||||||
|
bool sizeEmpty = true;
|
||||||
|
|
||||||
|
for (int index : indexSet)
|
||||||
|
{
|
||||||
|
if (index < static_cast<int>(m_zones.size()))
|
||||||
|
{
|
||||||
|
RECT newSize = m_zones.at(index)->ComputeActualZoneRect(window, windowZone);
|
||||||
|
if (!sizeEmpty)
|
||||||
|
{
|
||||||
|
size.left = min(size.left, newSize.left);
|
||||||
|
size.top = min(size.top, newSize.top);
|
||||||
|
size.right = max(size.right, newSize.right);
|
||||||
|
size.bottom = max(size.bottom, newSize.bottom);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size = newSize;
|
||||||
|
sizeEmpty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sizeEmpty)
|
||||||
|
{
|
||||||
|
SizeWindowToRect(window, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,10 +394,8 @@ ZoneSet::MoveWindowIntoZoneByPoint(HWND window, HWND zoneWindow, POINT ptClient)
|
|||||||
zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window));
|
zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto zone = ZoneFromPoint(ptClient))
|
auto zones = ZonesFromPoint(ptClient);
|
||||||
{
|
MoveWindowIntoZoneByIndexSet(window, zoneWindow, zones, true);
|
||||||
zone->AddWindowToZone(window, zoneWindow, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IFACEMETHODIMP_(bool)
|
IFACEMETHODIMP_(bool)
|
||||||
|
@ -24,12 +24,12 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
|||||||
*/
|
*/
|
||||||
IFACEMETHOD(AddZone)(winrt::com_ptr<IZone> zone) = 0;
|
IFACEMETHOD(AddZone)(winrt::com_ptr<IZone> zone) = 0;
|
||||||
/**
|
/**
|
||||||
* Get zone from cursor coordinates.
|
* Get zones from cursor coordinates.
|
||||||
*
|
*
|
||||||
* @param pt Cursor coordinates.
|
* @param pt Cursor coordinates.
|
||||||
* @returns Zone object (defining coordinates of the zone).
|
* @returns Vector of indices, corresponding to the current set of zones - the zones considered active.
|
||||||
*/
|
*/
|
||||||
IFACEMETHOD_(winrt::com_ptr<IZone>, ZoneFromPoint)(POINT pt) = 0;
|
IFACEMETHOD_(std::vector<int>, ZonesFromPoint)(POINT pt) = 0;
|
||||||
/**
|
/**
|
||||||
* Get index of the zone inside zone layout by window assigned to it.
|
* Get index of the zone inside zone layout by window assigned to it.
|
||||||
*
|
*
|
||||||
@ -48,8 +48,20 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
|||||||
* @param zoneWindow The m_window of a ZoneWindow, it's a hidden window representing the
|
* @param zoneWindow The m_window of a ZoneWindow, it's a hidden window representing the
|
||||||
* current monitor desktop work area.
|
* current monitor desktop work area.
|
||||||
* @param index Zone index within zone layout.
|
* @param index Zone index within zone layout.
|
||||||
|
* @param stampZone Whether the window being added to the zone should be stamped.
|
||||||
*/
|
*/
|
||||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, HWND zoneWindow, int index) = 0;
|
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, HWND zoneWindow, int index, bool stampZone) = 0;
|
||||||
|
/**
|
||||||
|
* Assign window to the zones based on the set of zone indices inside zone layout.
|
||||||
|
*
|
||||||
|
* @param window Handle of window which should be assigned to zone.
|
||||||
|
* @param zoneWindow The m_window of a ZoneWindow, it's a hidden window representing the
|
||||||
|
* current monitor desktop work area.
|
||||||
|
* @param indexSet The set of zone indices within zone layout.
|
||||||
|
* @param stampZone Whether the window being added to the zone should be stamped,
|
||||||
|
in case a single window is to be added.
|
||||||
|
*/
|
||||||
|
IFACEMETHOD_(void, MoveWindowIntoZoneByIndexSet)(HWND window, HWND zoneWindow, const std::vector<int>& indexSet, bool stampZone) = 0;
|
||||||
/**
|
/**
|
||||||
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow).
|
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow).
|
||||||
*
|
*
|
||||||
|
@ -148,7 +148,7 @@ namespace ZoneWindowDrawUtils
|
|||||||
COLORREF highlightColor,
|
COLORREF highlightColor,
|
||||||
int zoneOpacity,
|
int zoneOpacity,
|
||||||
const std::vector<winrt::com_ptr<IZone>>& zones,
|
const std::vector<winrt::com_ptr<IZone>>& zones,
|
||||||
const winrt::com_ptr<IZone>& highlightZone,
|
const std::vector<int>& highlightZones,
|
||||||
bool flashMode,
|
bool flashMode,
|
||||||
bool drawHints) noexcept
|
bool drawHints) noexcept
|
||||||
{
|
{
|
||||||
@ -158,15 +158,22 @@ namespace ZoneWindowDrawUtils
|
|||||||
ColorSetting colorHighlight{ OpacitySettingToAlpha(zoneOpacity), 0, 255, 0, -2 };
|
ColorSetting colorHighlight{ OpacitySettingToAlpha(zoneOpacity), 0, 255, 0, -2 };
|
||||||
ColorSetting const colorFlash{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 };
|
ColorSetting const colorFlash{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 };
|
||||||
|
|
||||||
|
std::vector<bool> isHighlighted(zones.size(), false);
|
||||||
|
for (int x : highlightZones)
|
||||||
|
{
|
||||||
|
isHighlighted[x] = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto iter = zones.begin(); iter != zones.end(); iter++)
|
for (auto iter = zones.begin(); iter != zones.end(); iter++)
|
||||||
{
|
{
|
||||||
|
int zoneId = static_cast<int>(iter - zones.begin());
|
||||||
winrt::com_ptr<IZone> zone = iter->try_as<IZone>();
|
winrt::com_ptr<IZone> zone = iter->try_as<IZone>();
|
||||||
if (!zone)
|
if (!zone)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zone != highlightZone)
|
if (!isHighlighted[zoneId])
|
||||||
{
|
{
|
||||||
if (flashMode)
|
if (flashMode)
|
||||||
{
|
{
|
||||||
@ -182,13 +189,12 @@ namespace ZoneWindowDrawUtils
|
|||||||
DrawZone(hdc, colorViewer, zone, zones, flashMode);
|
DrawZone(hdc, colorViewer, zone, zones, flashMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
if (highlightZone)
|
colorHighlight.fill = highlightColor;
|
||||||
{
|
colorHighlight.border = zoneBorderColor;
|
||||||
colorHighlight.fill = highlightColor;
|
DrawZone(hdc, colorHighlight, zone, zones, flashMode);
|
||||||
colorHighlight.border = zoneBorderColor;
|
}
|
||||||
DrawZone(hdc, colorHighlight, highlightZone, zones, flashMode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,7 +205,7 @@ public:
|
|||||||
ZoneWindow(HINSTANCE hinstance);
|
ZoneWindow(HINSTANCE hinstance);
|
||||||
~ZoneWindow();
|
~ZoneWindow();
|
||||||
|
|
||||||
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones);
|
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea);
|
||||||
|
|
||||||
IFACEMETHODIMP MoveSizeEnter(HWND window, bool dragEnabled) noexcept;
|
IFACEMETHODIMP MoveSizeEnter(HWND window, bool dragEnabled) noexcept;
|
||||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
|
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
|
||||||
@ -210,6 +216,8 @@ public:
|
|||||||
IsDragEnabled() noexcept { return m_dragEnabled; }
|
IsDragEnabled() noexcept { return m_dragEnabled; }
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
|
MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
|
||||||
|
IFACEMETHODIMP_(void)
|
||||||
|
MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet) noexcept;
|
||||||
IFACEMETHODIMP_(bool)
|
IFACEMETHODIMP_(bool)
|
||||||
MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle) noexcept;
|
MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle) noexcept;
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
@ -232,13 +240,13 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadSettings() noexcept;
|
void LoadSettings() noexcept;
|
||||||
void InitializeZoneSets(MONITORINFO const& mi) noexcept;
|
void InitializeZoneSets(bool newWorkArea) noexcept;
|
||||||
void CalculateZoneSet() noexcept;
|
void CalculateZoneSet() noexcept;
|
||||||
void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept;
|
void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept;
|
||||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||||
void OnPaint(wil::unique_hdc& hdc) noexcept;
|
void OnPaint(wil::unique_hdc& hdc) noexcept;
|
||||||
void OnKeyUp(WPARAM wparam) noexcept;
|
void OnKeyUp(WPARAM wparam) noexcept;
|
||||||
winrt::com_ptr<IZone> ZoneFromPoint(POINT pt) noexcept;
|
std::vector<int> ZonesFromPoint(POINT pt) noexcept;
|
||||||
void CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept;
|
void CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept;
|
||||||
void FlashZones() noexcept;
|
void FlashZones() noexcept;
|
||||||
|
|
||||||
@ -253,7 +261,7 @@ private:
|
|||||||
bool m_dragEnabled{};
|
bool m_dragEnabled{};
|
||||||
winrt::com_ptr<IZoneSet> m_activeZoneSet;
|
winrt::com_ptr<IZoneSet> m_activeZoneSet;
|
||||||
std::vector<winrt::com_ptr<IZoneSet>> m_zoneSets;
|
std::vector<winrt::com_ptr<IZoneSet>> m_zoneSets;
|
||||||
winrt::com_ptr<IZone> m_highlightZone;
|
std::vector<int> m_highlightZone;
|
||||||
WPARAM m_keyLast{};
|
WPARAM m_keyLast{};
|
||||||
size_t m_keyCycle{};
|
size_t m_keyCycle{};
|
||||||
static const UINT m_showAnimationDuration = 200; // ms
|
static const UINT m_showAnimationDuration = 200; // ms
|
||||||
@ -289,7 +297,7 @@ ZoneWindow::~ZoneWindow()
|
|||||||
Gdiplus::GdiplusShutdown(gdiplusToken);
|
Gdiplus::GdiplusShutdown(gdiplusToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones)
|
bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea)
|
||||||
{
|
{
|
||||||
m_host.copy_from(host);
|
m_host.copy_from(host);
|
||||||
|
|
||||||
@ -308,7 +316,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
|
|||||||
|
|
||||||
m_uniqueId = uniqueId;
|
m_uniqueId = uniqueId;
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
InitializeZoneSets(mi);
|
InitializeZoneSets(newWorkArea);
|
||||||
|
|
||||||
m_window = wil::unique_hwnd{
|
m_window = wil::unique_hwnd{
|
||||||
CreateWindowExW(WS_EX_TOOLWINDOW, L"SuperFancyZones_ZoneWindow", L"", WS_POPUP, workAreaRect.left(), workAreaRect.top(), workAreaRect.width(), workAreaRect.height(), nullptr, nullptr, hinstance, this)
|
CreateWindowExW(WS_EX_TOOLWINDOW, L"SuperFancyZones_ZoneWindow", L"", WS_POPUP, workAreaRect.left(), workAreaRect.top(), workAreaRect.width(), workAreaRect.height(), nullptr, nullptr, hinstance, this)
|
||||||
@ -363,7 +371,7 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window, bool dragEnabled) noexcept
|
|||||||
m_dragEnabled = dragEnabled;
|
m_dragEnabled = dragEnabled;
|
||||||
m_windowMoveSize = window;
|
m_windowMoveSize = window;
|
||||||
m_drawHints = true;
|
m_drawHints = true;
|
||||||
m_highlightZone = nullptr;
|
m_highlightZone = {};
|
||||||
ShowZoneWindow();
|
ShowZoneWindow();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@ -378,13 +386,13 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable
|
|||||||
|
|
||||||
if (dragEnabled)
|
if (dragEnabled)
|
||||||
{
|
{
|
||||||
auto highlightZone = ZoneFromPoint(ptClient);
|
auto highlightZone = ZonesFromPoint(ptClient);
|
||||||
redraw = (highlightZone != m_highlightZone);
|
redraw = (highlightZone != m_highlightZone);
|
||||||
m_highlightZone = std::move(highlightZone);
|
m_highlightZone = std::move(highlightZone);
|
||||||
}
|
}
|
||||||
else if (m_highlightZone)
|
else if (m_highlightZone.size())
|
||||||
{
|
{
|
||||||
m_highlightZone = nullptr;
|
m_highlightZone = {};
|
||||||
redraw = true;
|
redraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,10 +440,16 @@ ZoneWindow::RestoreOrginalTransparency() noexcept
|
|||||||
|
|
||||||
IFACEMETHODIMP_(void)
|
IFACEMETHODIMP_(void)
|
||||||
ZoneWindow::MoveWindowIntoZoneByIndex(HWND window, int index) noexcept
|
ZoneWindow::MoveWindowIntoZoneByIndex(HWND window, int index) noexcept
|
||||||
|
{
|
||||||
|
MoveWindowIntoZoneByIndexSet(window, { index });
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(void)
|
||||||
|
ZoneWindow::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet) noexcept
|
||||||
{
|
{
|
||||||
if (m_activeZoneSet)
|
if (m_activeZoneSet)
|
||||||
{
|
{
|
||||||
m_activeZoneSet->MoveWindowIntoZoneByIndex(window, m_window.get(), index);
|
m_activeZoneSet->MoveWindowIntoZoneByIndexSet(window, m_window.get(), indexSet, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +532,7 @@ ZoneWindow::HideZoneWindow() noexcept
|
|||||||
m_keyLast = 0;
|
m_keyLast = 0;
|
||||||
m_windowMoveSize = nullptr;
|
m_windowMoveSize = nullptr;
|
||||||
m_drawHints = false;
|
m_drawHints = false;
|
||||||
m_highlightZone = nullptr;
|
m_highlightZone = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,10 +543,10 @@ void ZoneWindow::LoadSettings() noexcept
|
|||||||
JSONHelpers::FancyZonesDataInstance().AddDevice(m_uniqueId);
|
JSONHelpers::FancyZonesDataInstance().AddDevice(m_uniqueId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneWindow::InitializeZoneSets(MONITORINFO const& mi) noexcept
|
void ZoneWindow::InitializeZoneSets(bool newWorkArea) noexcept
|
||||||
{
|
{
|
||||||
auto parent = m_host->GetParentZoneWindow(m_monitor);
|
auto parent = m_host->GetParentZoneWindow(m_monitor);
|
||||||
if (parent)
|
if (newWorkArea && parent)
|
||||||
{
|
{
|
||||||
// Update device info with device info from parent virtual desktop (if empty).
|
// Update device info with device info from parent virtual desktop (if empty).
|
||||||
JSONHelpers::FancyZonesDataInstance().CloneDeviceInfo(parent->UniqueId(), m_uniqueId);
|
JSONHelpers::FancyZonesDataInstance().CloneDeviceInfo(parent->UniqueId(), m_uniqueId);
|
||||||
@ -685,13 +699,13 @@ void ZoneWindow::OnKeyUp(WPARAM wparam) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::com_ptr<IZone> ZoneWindow::ZoneFromPoint(POINT pt) noexcept
|
std::vector<int> ZoneWindow::ZonesFromPoint(POINT pt) noexcept
|
||||||
{
|
{
|
||||||
if (m_activeZoneSet)
|
if (m_activeZoneSet)
|
||||||
{
|
{
|
||||||
return m_activeZoneSet->ZoneFromPoint(pt);
|
return m_activeZoneSet->ZonesFromPoint(pt);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneWindow::CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept
|
void ZoneWindow::CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept
|
||||||
@ -739,7 +753,7 @@ void ZoneWindow::CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::Inp
|
|||||||
{
|
{
|
||||||
m_host->MoveWindowsOnActiveZoneSetChange();
|
m_host->MoveWindowsOnActiveZoneSetChange();
|
||||||
}
|
}
|
||||||
m_highlightZone = nullptr;
|
m_highlightZone = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneWindow::FlashZones() noexcept
|
void ZoneWindow::FlashZones() noexcept
|
||||||
@ -773,10 +787,10 @@ LRESULT CALLBACK ZoneWindow::s_WndProc(HWND window, UINT message, WPARAM wparam,
|
|||||||
DefWindowProc(window, message, wparam, lparam);
|
DefWindowProc(window, message, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones) noexcept
|
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept
|
||||||
{
|
{
|
||||||
auto self = winrt::make_self<ZoneWindow>(hinstance);
|
auto self = winrt::make_self<ZoneWindow>(hinstance);
|
||||||
if (self->Init(host, hinstance, monitor, uniqueId, flashZones))
|
if (self->Init(host, hinstance, monitor, uniqueId, flashZones, newWorkArea))
|
||||||
{
|
{
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,13 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
|||||||
* @param index Zone index within zone layout.
|
* @param index Zone index within zone layout.
|
||||||
*/
|
*/
|
||||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, int index) = 0;
|
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, int index) = 0;
|
||||||
|
/**
|
||||||
|
* Assign window to the zones based on the set of zone indices inside zone layout.
|
||||||
|
*
|
||||||
|
* @param window Handle of window which should be assigned to zone.
|
||||||
|
* @param indexSet The set of zone indices within zone layout.
|
||||||
|
*/
|
||||||
|
IFACEMETHOD_(void, MoveWindowIntoZoneByIndexSet)(HWND window, const std::vector<int>& indexSet) = 0;
|
||||||
/**
|
/**
|
||||||
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow).
|
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow).
|
||||||
*
|
*
|
||||||
@ -98,4 +105,4 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
|||||||
};
|
};
|
||||||
|
|
||||||
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor,
|
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor,
|
||||||
const std::wstring& uniqueId, bool flashZones) noexcept;
|
const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept;
|
||||||
|
@ -108,3 +108,30 @@ void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo)
|
|||||||
|
|
||||||
monitorInfo = std::move(sortedMonitorInfo);
|
monitorInfo = std::move(sortedMonitorInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SizeWindowToRect(HWND window, RECT rect) noexcept
|
||||||
|
{
|
||||||
|
WINDOWPLACEMENT placement{};
|
||||||
|
::GetWindowPlacement(window, &placement);
|
||||||
|
|
||||||
|
//wait if SW_SHOWMINIMIZED would be removed from window (Issue #1685)
|
||||||
|
for (int i = 0; i < 5 && (placement.showCmd & SW_SHOWMINIMIZED) != 0; i++)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
::GetWindowPlacement(window, &placement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not restore minimized windows. We change their placement though so they restore to the correct zone.
|
||||||
|
if ((placement.showCmd & SW_SHOWMINIMIZED) == 0)
|
||||||
|
{
|
||||||
|
placement.showCmd = SW_RESTORE | SW_SHOWNA;
|
||||||
|
}
|
||||||
|
|
||||||
|
placement.rcNormalPosition = rect;
|
||||||
|
placement.flags |= WPF_ASYNCWINDOWPLACEMENT;
|
||||||
|
|
||||||
|
::SetWindowPlacement(window, &placement);
|
||||||
|
// Do it again, allowing Windows to resize the window and set correct scaling
|
||||||
|
// This fixes Issue #365
|
||||||
|
::SetWindowPlacement(window, &placement);
|
||||||
|
}
|
||||||
|
@ -118,3 +118,4 @@ inline BYTE OpacitySettingToAlpha(int opacity)
|
|||||||
|
|
||||||
UINT GetDpiForMonitor(HMONITOR monitor) noexcept;
|
UINT GetDpiForMonitor(HMONITOR monitor) noexcept;
|
||||||
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
||||||
|
void SizeWindowToRect(HWND window, RECT rect) noexcept;
|
||||||
|
@ -132,8 +132,8 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD (ZoneFromPointEmpty)
|
TEST_METHOD (ZoneFromPointEmpty)
|
||||||
{
|
{
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ 0, 0 });
|
auto actual = m_set->ZonesFromPoint(POINT{ 0, 0 });
|
||||||
Assert::IsTrue(nullptr == actual);
|
Assert::IsTrue(actual.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (ZoneFromPointInner)
|
TEST_METHOD (ZoneFromPointInner)
|
||||||
@ -146,9 +146,9 @@ namespace FancyZonesUnitTests
|
|||||||
{
|
{
|
||||||
for (int j = top + 1; j < bottom; j++)
|
for (int j = top + 1; j < bottom; j++)
|
||||||
{
|
{
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ i, j });
|
auto actual = m_set->ZonesFromPoint(POINT{ i, j });
|
||||||
Assert::IsTrue(actual != nullptr);
|
Assert::IsTrue(actual.size() == 1);
|
||||||
compareZones(expected, actual);
|
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,29 +161,29 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
for (int i = left; i < right; i++)
|
for (int i = left; i < right; i++)
|
||||||
{
|
{
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ i, top });
|
auto actual = m_set->ZonesFromPoint(POINT{ i, top });
|
||||||
Assert::IsTrue(actual != nullptr);
|
Assert::IsTrue(actual.size() == 1);
|
||||||
compareZones(expected, actual);
|
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = top; i < bottom; i++)
|
for (int i = top; i < bottom; i++)
|
||||||
{
|
{
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ left, i });
|
auto actual = m_set->ZonesFromPoint(POINT{ left, i });
|
||||||
Assert::IsTrue(actual != nullptr);
|
Assert::IsTrue(actual.size() == 1);
|
||||||
compareZones(expected, actual);
|
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//bottom and right borders considered to be outside
|
//bottom and right borders considered to be outside
|
||||||
for (int i = left; i < right; i++)
|
for (int i = left; i < right; i++)
|
||||||
{
|
{
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ i, bottom });
|
auto actual = m_set->ZonesFromPoint(POINT{ i, bottom });
|
||||||
Assert::IsTrue(nullptr == actual);
|
Assert::IsTrue(actual.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = top; i < bottom; i++)
|
for (int i = top; i < bottom; i++)
|
||||||
{
|
{
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ right, i });
|
auto actual = m_set->ZonesFromPoint(POINT{ right, i });
|
||||||
Assert::IsTrue(nullptr == actual);
|
Assert::IsTrue(actual.size() == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,8 +193,8 @@ namespace FancyZonesUnitTests
|
|||||||
winrt::com_ptr<IZone> zone = MakeZone({ left, top, right, bottom });
|
winrt::com_ptr<IZone> zone = MakeZone({ left, top, right, bottom });
|
||||||
m_set->AddZone(zone);
|
m_set->AddZone(zone);
|
||||||
|
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ 101, 101 });
|
auto actual = m_set->ZonesFromPoint(POINT{ 200, 200 });
|
||||||
Assert::IsTrue(actual == nullptr);
|
Assert::IsTrue(actual.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (ZoneFromPointOverlapping)
|
TEST_METHOD (ZoneFromPointOverlapping)
|
||||||
@ -208,9 +208,65 @@ namespace FancyZonesUnitTests
|
|||||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 10, 10, 50, 50 });
|
winrt::com_ptr<IZone> zone4 = MakeZone({ 10, 10, 50, 50 });
|
||||||
m_set->AddZone(zone4);
|
m_set->AddZone(zone4);
|
||||||
|
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ 50, 50 });
|
// zone4 is expected because it's the smallest one, and it's considered to be inside
|
||||||
Assert::IsTrue(actual != nullptr);
|
// since Multizones support
|
||||||
compareZones(zone2, actual);
|
|
||||||
|
auto actual = m_set->ZonesFromPoint(POINT{ 50, 50 });
|
||||||
|
Assert::IsTrue(actual.size() == 1);
|
||||||
|
compareZones(zone4, m_set->GetZones()[actual[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (ZoneFromPointMultizoneHorizontal)
|
||||||
|
{
|
||||||
|
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 });
|
||||||
|
m_set->AddZone(zone1);
|
||||||
|
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 });
|
||||||
|
m_set->AddZone(zone2);
|
||||||
|
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 });
|
||||||
|
m_set->AddZone(zone3);
|
||||||
|
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 });
|
||||||
|
m_set->AddZone(zone4);
|
||||||
|
|
||||||
|
auto actual = m_set->ZonesFromPoint(POINT{ 50, 100 });
|
||||||
|
Assert::IsTrue(actual.size() == 2);
|
||||||
|
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||||
|
compareZones(zone3, m_set->GetZones()[actual[1]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (ZoneFromPointMultizoneVertical)
|
||||||
|
{
|
||||||
|
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 });
|
||||||
|
m_set->AddZone(zone1);
|
||||||
|
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 });
|
||||||
|
m_set->AddZone(zone2);
|
||||||
|
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 });
|
||||||
|
m_set->AddZone(zone3);
|
||||||
|
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 });
|
||||||
|
m_set->AddZone(zone4);
|
||||||
|
|
||||||
|
auto actual = m_set->ZonesFromPoint(POINT{ 100, 50 });
|
||||||
|
Assert::IsTrue(actual.size() == 2);
|
||||||
|
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||||
|
compareZones(zone2, m_set->GetZones()[actual[1]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(ZoneFromPointMultizoneQuad)
|
||||||
|
{
|
||||||
|
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 });
|
||||||
|
m_set->AddZone(zone1);
|
||||||
|
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 });
|
||||||
|
m_set->AddZone(zone2);
|
||||||
|
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 });
|
||||||
|
m_set->AddZone(zone3);
|
||||||
|
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 });
|
||||||
|
m_set->AddZone(zone4);
|
||||||
|
|
||||||
|
auto actual = m_set->ZonesFromPoint(POINT{ 100, 100 });
|
||||||
|
Assert::IsTrue(actual.size() == 4);
|
||||||
|
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||||
|
compareZones(zone2, m_set->GetZones()[actual[1]]);
|
||||||
|
compareZones(zone3, m_set->GetZones()[actual[2]]);
|
||||||
|
compareZones(zone4, m_set->GetZones()[actual[3]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (ZoneFromPointWithNotNormalizedRect)
|
TEST_METHOD (ZoneFromPointWithNotNormalizedRect)
|
||||||
@ -218,8 +274,8 @@ namespace FancyZonesUnitTests
|
|||||||
winrt::com_ptr<IZone> zone = MakeZone({ 100, 100, 0, 0 });
|
winrt::com_ptr<IZone> zone = MakeZone({ 100, 100, 0, 0 });
|
||||||
m_set->AddZone(zone);
|
m_set->AddZone(zone);
|
||||||
|
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ 50, 50 });
|
auto actual = m_set->ZonesFromPoint(POINT{ 50, 50 });
|
||||||
Assert::IsTrue(actual == nullptr);
|
Assert::IsTrue(actual.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (ZoneFromPointWithZeroRect)
|
TEST_METHOD (ZoneFromPointWithZeroRect)
|
||||||
@ -227,8 +283,8 @@ namespace FancyZonesUnitTests
|
|||||||
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 0, 0 });
|
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 0, 0 });
|
||||||
m_set->AddZone(zone);
|
m_set->AddZone(zone);
|
||||||
|
|
||||||
auto actual = m_set->ZoneFromPoint(POINT{ 0, 0 });
|
auto actual = m_set->ZonesFromPoint(POINT{ 0, 0 });
|
||||||
Assert::IsTrue(actual == nullptr);
|
Assert::IsTrue(actual.size() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (ZoneIndexFromWindow)
|
TEST_METHOD (ZoneIndexFromWindow)
|
||||||
@ -316,7 +372,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_set->AddZone(zone3);
|
m_set->AddZone(zone3);
|
||||||
|
|
||||||
HWND window = Mocks::Window();
|
HWND window = Mocks::Window();
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1, false);
|
||||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||||
Assert::IsTrue(zone2->ContainsWindow(window));
|
Assert::IsTrue(zone2->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||||
@ -325,7 +381,7 @@ namespace FancyZonesUnitTests
|
|||||||
TEST_METHOD (MoveWindowIntoZoneByIndexWithNoZones)
|
TEST_METHOD (MoveWindowIntoZoneByIndexWithNoZones)
|
||||||
{
|
{
|
||||||
HWND window = Mocks::Window();
|
HWND window = Mocks::Window();
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD (MoveWindowIntoZoneByIndexWithInvalidIndex)
|
TEST_METHOD (MoveWindowIntoZoneByIndexWithInvalidIndex)
|
||||||
@ -338,7 +394,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_set->AddZone(zone3);
|
m_set->AddZone(zone3);
|
||||||
|
|
||||||
HWND window = Mocks::Window();
|
HWND window = Mocks::Window();
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 100);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 100, false);
|
||||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||||
@ -355,17 +411,17 @@ namespace FancyZonesUnitTests
|
|||||||
m_set->AddZone(zone3);
|
m_set->AddZone(zone3);
|
||||||
|
|
||||||
HWND window = Mocks::Window();
|
HWND window = Mocks::Window();
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||||
Assert::IsTrue(zone1->ContainsWindow(window));
|
Assert::IsTrue(zone1->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||||
|
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1, false);
|
||||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||||
Assert::IsTrue(zone2->ContainsWindow(window));
|
Assert::IsTrue(zone2->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||||
|
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2, false);
|
||||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||||
Assert::IsTrue(zone3->ContainsWindow(window));
|
Assert::IsTrue(zone3->ContainsWindow(window));
|
||||||
@ -382,9 +438,9 @@ namespace FancyZonesUnitTests
|
|||||||
m_set->AddZone(zone3);
|
m_set->AddZone(zone3);
|
||||||
|
|
||||||
HWND window = Mocks::Window();
|
HWND window = Mocks::Window();
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||||
Assert::IsTrue(zone1->ContainsWindow(window));
|
Assert::IsTrue(zone1->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||||
@ -401,7 +457,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_set->AddZone(zone1);
|
m_set->AddZone(zone1);
|
||||||
|
|
||||||
auto window = Mocks::Window();
|
auto window = Mocks::Window();
|
||||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 101, 101 });
|
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 200, 200 });
|
||||||
|
|
||||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ namespace FancyZonesUnitTests
|
|||||||
{
|
{
|
||||||
const std::wstring m_deviceId = L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}";
|
const std::wstring m_deviceId = L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}";
|
||||||
const std::wstring m_virtualDesktopId = L"MyVirtualDesktopId";
|
const std::wstring m_virtualDesktopId = L"MyVirtualDesktopId";
|
||||||
|
std::wstringstream m_parentUniqueId;
|
||||||
std::wstringstream m_uniqueId;
|
std::wstringstream m_uniqueId;
|
||||||
|
|
||||||
HINSTANCE m_hInst{};
|
HINSTANCE m_hInst{};
|
||||||
@ -75,6 +76,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_monitorInfo.cbSize = sizeof(m_monitorInfo);
|
m_monitorInfo.cbSize = sizeof(m_monitorInfo);
|
||||||
Assert::AreNotEqual(0, GetMonitorInfoW(m_monitor, &m_monitorInfo));
|
Assert::AreNotEqual(0, GetMonitorInfoW(m_monitor, &m_monitorInfo));
|
||||||
|
|
||||||
|
m_parentUniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{61FA9FC0-26A6-4B37-A834-491C148DFC57}";
|
||||||
m_uniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{39B25DD2-130D-4B5D-8851-4791D66B1539}";
|
m_uniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{39B25DD2-130D-4B5D-8851-4791D66B1539}";
|
||||||
|
|
||||||
Assert::IsFalse(ZoneWindowUtils::GetActiveZoneSetTmpPath().empty());
|
Assert::IsFalse(ZoneWindowUtils::GetActiveZoneSetTmpPath().empty());
|
||||||
@ -113,7 +115,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||||
|
|
||||||
return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void testZoneWindow(winrt::com_ptr<IZoneWindow> zoneWindow)
|
void testZoneWindow(winrt::com_ptr<IZoneWindow> zoneWindow)
|
||||||
@ -129,14 +131,14 @@ namespace FancyZonesUnitTests
|
|||||||
public:
|
public:
|
||||||
TEST_METHOD(CreateZoneWindow)
|
TEST_METHOD(CreateZoneWindow)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
testZoneWindow(m_zoneWindow);
|
testZoneWindow(m_zoneWindow);
|
||||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(CreateZoneWindowNoHinst)
|
TEST_METHOD(CreateZoneWindowNoHinst)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
testZoneWindow(m_zoneWindow);
|
testZoneWindow(m_zoneWindow);
|
||||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||||
@ -144,7 +146,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(CreateZoneWindowNoHinstFlashZones)
|
TEST_METHOD(CreateZoneWindowNoHinstFlashZones)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true, false);
|
||||||
|
|
||||||
testZoneWindow(m_zoneWindow);
|
testZoneWindow(m_zoneWindow);
|
||||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||||
@ -152,7 +154,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(CreateZoneWindowNoMonitor)
|
TEST_METHOD(CreateZoneWindowNoMonitor)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
Assert::IsNull(m_zoneWindow.get());
|
Assert::IsNull(m_zoneWindow.get());
|
||||||
Assert::IsNotNull(m_hostPtr);
|
Assert::IsNotNull(m_hostPtr);
|
||||||
@ -160,7 +162,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(CreateZoneWindowNoMonitorFlashZones)
|
TEST_METHOD(CreateZoneWindowNoMonitorFlashZones)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true, false);
|
||||||
|
|
||||||
Assert::IsNull(m_zoneWindow.get());
|
Assert::IsNull(m_zoneWindow.get());
|
||||||
Assert::IsNotNull(m_hostPtr);
|
Assert::IsNotNull(m_hostPtr);
|
||||||
@ -170,7 +172,7 @@ namespace FancyZonesUnitTests
|
|||||||
{
|
{
|
||||||
// Generate unique id without device id
|
// Generate unique id without device id
|
||||||
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, nullptr, m_virtualDesktopId.c_str());
|
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, nullptr, m_virtualDesktopId.c_str());
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false);
|
||||||
|
|
||||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||||
const std::wstring expectedUniqueId = L"FallbackDevice_" + std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom) + L"_" + m_virtualDesktopId;
|
const std::wstring expectedUniqueId = L"FallbackDevice_" + std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom) + L"_" + m_virtualDesktopId;
|
||||||
@ -186,7 +188,7 @@ namespace FancyZonesUnitTests
|
|||||||
{
|
{
|
||||||
// Generate unique id without virtual desktop id
|
// Generate unique id without virtual desktop id
|
||||||
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, m_deviceId.c_str(), nullptr);
|
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, m_deviceId.c_str(), nullptr);
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false);
|
||||||
|
|
||||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||||
Assert::IsNotNull(m_zoneWindow.get());
|
Assert::IsNotNull(m_zoneWindow.get());
|
||||||
@ -213,7 +215,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||||
|
|
||||||
//temp file read on initialization
|
//temp file read on initialization
|
||||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
testZoneWindow(actual);
|
testZoneWindow(actual);
|
||||||
|
|
||||||
@ -237,7 +239,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||||
|
|
||||||
//temp file read on initialization
|
//temp file read on initialization
|
||||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
testZoneWindow(actual);
|
testZoneWindow(actual);
|
||||||
|
|
||||||
@ -273,7 +275,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||||
|
|
||||||
//temp file read on initialization
|
//temp file read on initialization
|
||||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
testZoneWindow(actual);
|
testZoneWindow(actual);
|
||||||
|
|
||||||
@ -320,7 +322,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||||
|
|
||||||
//temp file read on initialization
|
//temp file read on initialization
|
||||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
testZoneWindow(actual);
|
testZoneWindow(actual);
|
||||||
|
|
||||||
@ -367,7 +369,7 @@ namespace FancyZonesUnitTests
|
|||||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||||
|
|
||||||
//temp file read on initialization
|
//temp file read on initialization
|
||||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
testZoneWindow(actual);
|
testZoneWindow(actual);
|
||||||
|
|
||||||
@ -376,9 +378,68 @@ namespace FancyZonesUnitTests
|
|||||||
Assert::AreEqual((size_t)1, actualZoneSet.size());
|
Assert::AreEqual((size_t)1, actualZoneSet.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (CreateZoneWindowClonedFromParent)
|
||||||
|
{
|
||||||
|
using namespace JSONHelpers;
|
||||||
|
|
||||||
|
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
|
||||||
|
const int spacing = 10;
|
||||||
|
const int zoneCount = 5;
|
||||||
|
const auto customSetGuid = Helpers::CreateGuidString();
|
||||||
|
const auto parentZoneSet = ZoneSetData{ customSetGuid, type };
|
||||||
|
const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount };
|
||||||
|
m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo);
|
||||||
|
|
||||||
|
auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false);
|
||||||
|
m_zoneWindowHost.m_zoneWindow = parentZoneWindow.get();
|
||||||
|
|
||||||
|
// newWorkArea = true - zoneWindow will be cloned from parent
|
||||||
|
auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, true);
|
||||||
|
|
||||||
|
Assert::IsNotNull(actualZoneWindow->ActiveZoneSet());
|
||||||
|
const auto actualZoneSet = actualZoneWindow->ActiveZoneSet()->GetZones();
|
||||||
|
Assert::AreEqual((size_t)zoneCount, actualZoneSet.size());
|
||||||
|
|
||||||
|
Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str()));
|
||||||
|
auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str());
|
||||||
|
Assert::AreEqual(zoneCount, currentDeviceInfo.zoneCount);
|
||||||
|
Assert::AreEqual(spacing, currentDeviceInfo.spacing);
|
||||||
|
Assert::AreEqual(static_cast<int>(type), static_cast<int>(currentDeviceInfo.activeZoneSet.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (CreateZoneWindowNotClonedFromParent)
|
||||||
|
{
|
||||||
|
using namespace JSONHelpers;
|
||||||
|
|
||||||
|
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
|
||||||
|
const int spacing = 10;
|
||||||
|
const int zoneCount = 5;
|
||||||
|
const auto customSetGuid = Helpers::CreateGuidString();
|
||||||
|
const auto parentZoneSet = ZoneSetData{ customSetGuid, type };
|
||||||
|
const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount };
|
||||||
|
m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo);
|
||||||
|
|
||||||
|
auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false);
|
||||||
|
m_zoneWindowHost.m_zoneWindow = parentZoneWindow.get();
|
||||||
|
|
||||||
|
// newWorkArea = false - zoneWindow won't be cloned from parent
|
||||||
|
auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
|
Assert::IsNull(actualZoneWindow->ActiveZoneSet());
|
||||||
|
|
||||||
|
Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str()));
|
||||||
|
auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str());
|
||||||
|
// default values
|
||||||
|
Assert::AreEqual(false, currentDeviceInfo.showSpacing);
|
||||||
|
Assert::AreEqual(0, currentDeviceInfo.zoneCount);
|
||||||
|
Assert::AreEqual(0, currentDeviceInfo.spacing);
|
||||||
|
Assert::AreEqual(std::wstring{ L"null" }, currentDeviceInfo.activeZoneSet.uuid);
|
||||||
|
Assert::AreEqual(static_cast<int>(ZoneSetLayoutType::Blank), static_cast<int>(currentDeviceInfo.activeZoneSet.type));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_METHOD(MoveSizeEnter)
|
TEST_METHOD(MoveSizeEnter)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
const auto expected = S_OK;
|
const auto expected = S_OK;
|
||||||
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window(), true);
|
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window(), true);
|
||||||
@ -389,7 +450,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(MoveSizeEnterTwice)
|
TEST_METHOD(MoveSizeEnterTwice)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
const auto expected = E_INVALIDARG;
|
const auto expected = E_INVALIDARG;
|
||||||
|
|
||||||
@ -402,7 +463,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(MoveSizeUpdate)
|
TEST_METHOD(MoveSizeUpdate)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
const auto expected = S_OK;
|
const auto expected = S_OK;
|
||||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true);
|
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true);
|
||||||
@ -413,7 +474,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(MoveSizeUpdatePointNegativeCoordinates)
|
TEST_METHOD(MoveSizeUpdatePointNegativeCoordinates)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
const auto expected = S_OK;
|
const auto expected = S_OK;
|
||||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true);
|
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true);
|
||||||
@ -424,7 +485,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(MoveSizeUpdatePointBigCoordinates)
|
TEST_METHOD(MoveSizeUpdatePointBigCoordinates)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
const auto expected = S_OK;
|
const auto expected = S_OK;
|
||||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true);
|
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true);
|
||||||
@ -445,7 +506,7 @@ namespace FancyZonesUnitTests
|
|||||||
Assert::AreEqual(expected, actual);
|
Assert::AreEqual(expected, actual);
|
||||||
|
|
||||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), false);
|
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||||
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
||||||
Assert::AreNotEqual(-1, actualZoneIndex);
|
Assert::AreNotEqual(-1, actualZoneIndex);
|
||||||
}
|
}
|
||||||
@ -458,7 +519,7 @@ namespace FancyZonesUnitTests
|
|||||||
zoneWindow->MoveSizeEnter(window, true);
|
zoneWindow->MoveSizeEnter(window, true);
|
||||||
|
|
||||||
const auto expected = S_OK;
|
const auto expected = S_OK;
|
||||||
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ 0, 0 });
|
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ -100, -100 });
|
||||||
Assert::AreEqual(expected, actual);
|
Assert::AreEqual(expected, actual);
|
||||||
|
|
||||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||||
@ -468,7 +529,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(MoveSizeEndDifferentWindows)
|
TEST_METHOD(MoveSizeEndDifferentWindows)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
const auto window = Mocks::Window();
|
const auto window = Mocks::Window();
|
||||||
m_zoneWindow->MoveSizeEnter(window, true);
|
m_zoneWindow->MoveSizeEnter(window, true);
|
||||||
@ -481,7 +542,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(MoveSizeEndWindowNotSet)
|
TEST_METHOD(MoveSizeEndWindowNotSet)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
|
|
||||||
const auto expected = E_INVALIDARG;
|
const auto expected = E_INVALIDARG;
|
||||||
const auto actual = m_zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
const auto actual = m_zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
||||||
@ -501,14 +562,14 @@ namespace FancyZonesUnitTests
|
|||||||
Assert::AreEqual(expected, actual);
|
Assert::AreEqual(expected, actual);
|
||||||
|
|
||||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), false);
|
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||||
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
||||||
Assert::AreNotEqual(-1, actualZoneIndex); //with invalid point zone remains the same
|
Assert::AreNotEqual(-1, actualZoneIndex); //with invalid point zone remains the same
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(MoveWindowIntoZoneByIndexNoActiveZoneSet)
|
TEST_METHOD(MoveWindowIntoZoneByIndexNoActiveZoneSet)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||||
|
|
||||||
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||||
@ -526,7 +587,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(MoveWindowIntoZoneByDirectionNoActiveZoneSet)
|
TEST_METHOD(MoveWindowIntoZoneByDirectionNoActiveZoneSet)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||||
|
|
||||||
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||||
@ -564,7 +625,7 @@ namespace FancyZonesUnitTests
|
|||||||
|
|
||||||
TEST_METHOD(SaveWindowProcessToZoneIndexNoActiveZoneSet)
|
TEST_METHOD(SaveWindowProcessToZoneIndexNoActiveZoneSet)
|
||||||
{
|
{
|
||||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||||
|
|
||||||
m_zoneWindow->SaveWindowProcessToZoneIndex(Mocks::Window());
|
m_zoneWindow->SaveWindowProcessToZoneIndex(Mocks::Window());
|
||||||
@ -650,5 +711,29 @@ namespace FancyZonesUnitTests
|
|||||||
const auto actual = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex;
|
const auto actual = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex;
|
||||||
Assert::AreEqual(expected, actual);
|
Assert::AreEqual(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD (WhenWindowIsNotResizablePlacingItIntoTheZoneShouldNotResizeIt)
|
||||||
|
{
|
||||||
|
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||||
|
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||||
|
|
||||||
|
auto window = Mocks::WindowCreate(m_hInst);
|
||||||
|
|
||||||
|
int orginalWidth = 450;
|
||||||
|
int orginalHeight = 550;
|
||||||
|
|
||||||
|
SetWindowPos(window, nullptr, 150, 150, orginalWidth, orginalHeight, SWP_SHOWWINDOW);
|
||||||
|
SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_SIZEBOX);
|
||||||
|
|
||||||
|
auto zone = MakeZone(RECT{ 50, 50, 300, 300 });
|
||||||
|
m_zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||||
|
|
||||||
|
m_zoneWindow->MoveWindowIntoZoneByDirection(window, VK_LEFT, true);
|
||||||
|
|
||||||
|
RECT inZoneRect;
|
||||||
|
GetWindowRect(window, &inZoneRect);
|
||||||
|
Assert::AreEqual(orginalWidth, (int)inZoneRect.right - (int) inZoneRect.left);
|
||||||
|
Assert::AreEqual(orginalHeight, (int)inZoneRect.bottom - (int)inZoneRect.top);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>Pathcch.lib;comctl32.lib;$(SolutionDir)$(Platform)\$(Configuration)\obj\PowerRenameUI\PowerRenameUI.res;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>Pathcch.lib;comctl32.lib;$(SolutionDir)$(Platform)\$(Configuration)\obj\PowerRenameUI\PowerRenameUI.res;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<ModuleDefinitionFile>PowerRenameExt.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>PowerRenameExt.def</ModuleDefinitionFile>
|
||||||
<DelayLoadDLLs>gdi32.dll;advapi32.dll;shell32.dll;ole32.dll;shlwapi.dll;oleaut32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
<DelayLoadDLLs>gdi32.dll;shell32.dll;ole32.dll;shlwapi.dll;oleaut32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<IncludePath>..\lib\;$(IncludePath)</IncludePath>
|
<IncludePath>..\lib\;$(IncludePath)</IncludePath>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
|
||||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
|
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
|
||||||
|
@ -87,7 +87,6 @@
|
|||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
|
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\modules\</OutDir>
|
||||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
|
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) Microsoft Corporation
|
// Copyright (c) Microsoft Corporation
|
||||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information. Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
|
// See the LICENSE file in the project root for more information. Code forked from Betsegaw Tadele's https://github.com/betsegaw/windowwalker/
|
||||||
|
|
||||||
@ -603,167 +603,200 @@ namespace WindowWalker.Components
|
|||||||
/// The retrieved handle identifies the window of the same type that is highest in the Z order.
|
/// The retrieved handle identifies the window of the same type that is highest in the Z order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GW_HWNDFIRST = 0,
|
GW_HWNDFIRST = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The retrieved handle identifies the window of the same type that is lowest in the Z order.
|
/// The retrieved handle identifies the window of the same type that is lowest in the Z order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GW_HWNDLAST = 1,
|
GW_HWNDLAST = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The retrieved handle identifies the window below the specified window in the Z order.
|
/// The retrieved handle identifies the window below the specified window in the Z order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GW_HWNDNEXT = 2,
|
GW_HWNDNEXT = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The retrieved handle identifies the window above the specified window in the Z order.
|
/// The retrieved handle identifies the window above the specified window in the Z order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GW_HWNDPREV = 3,
|
GW_HWNDPREV = 3,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The retrieved handle identifies the specified window's owner window, if any.
|
/// The retrieved handle identifies the specified window's owner window, if any.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GW_OWNER = 4,
|
GW_OWNER = 4,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The retrieved handle identifies the child window at the top of the Z order, if the specified window
|
/// The retrieved handle identifies the child window at the top of the Z order, if the specified window
|
||||||
/// is a parent window.
|
/// is a parent window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GW_CHILD = 5,
|
GW_CHILD = 5,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The retrieved handle identifies the enabled popup window owned by the specified window.
|
/// The retrieved handle identifies the enabled popup window owned by the specified window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GW_ENABLEDPOPUP = 6
|
GW_ENABLEDPOPUP = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// GetWindowLong index to retrieves the extended window styles.
|
/// GetWindowLong index to retrieves the extended window styles.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
#pragma warning disable SA1310 // Field names should not contain underscore
|
||||||
public const int GWL_EXSTYLE = -20;
|
public const int GWL_EXSTYLE = -20;
|
||||||
|
#pragma warning restore SA1310 // Field names should not contain underscore
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The following are the extended window styles
|
/// The following are the extended window styles
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ExtendedWindowStyles : UInt32
|
public enum ExtendedWindowStyles : uint
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window has a double border; the window can, optionally, be created with a title bar by specifying
|
/// The window has a double border; the window can, optionally, be created with a title bar by specifying
|
||||||
/// the WS_CAPTION style in the dwStyle parameter.
|
/// the WS_CAPTION style in the dwStyle parameter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_DLGMODALFRAME = 0X0001,
|
WS_EX_DLGMODALFRAME = 0X0001,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The child window created with this style does not send the WM_PARENTNOTIFY message to its parent window
|
/// The child window created with this style does not send the WM_PARENTNOTIFY message to its parent window
|
||||||
/// when it is created or destroyed.
|
/// when it is created or destroyed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_NOPARENTNOTIFY = 0X0004,
|
WS_EX_NOPARENTNOTIFY = 0X0004,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window should be placed above all non-topmost windows and should stay above all non-topmost windows
|
/// The window should be placed above all non-topmost windows and should stay above all non-topmost windows
|
||||||
/// and should stay above them, even when the window is deactivated.
|
/// and should stay above them, even when the window is deactivated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_TOPMOST = 0X0008,
|
WS_EX_TOPMOST = 0X0008,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window accepts drag-drop files.
|
/// The window accepts drag-drop files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_ACCEPTFILES = 0x0010,
|
WS_EX_ACCEPTFILES = 0x0010,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window should not be painted until siblings beneath the window (that were created by the same thread)
|
/// The window should not be painted until siblings beneath the window (that were created by the same thread)
|
||||||
/// have been painted.
|
/// have been painted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_TRANSPARENT = 0x0020,
|
WS_EX_TRANSPARENT = 0x0020,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window is a MDI child window.
|
/// The window is a MDI child window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_MDICHILD = 0x0040,
|
WS_EX_MDICHILD = 0x0040,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window is intended to be used as a floating toolbar. A tool window has a title bar that is shorter
|
/// The window is intended to be used as a floating toolbar. A tool window has a title bar that is shorter
|
||||||
/// than a normal title bar, and the window title is drawn using a smaller font. A tool window does not
|
/// than a normal title bar, and the window title is drawn using a smaller font. A tool window does not
|
||||||
/// appear in the taskbar or in the dialog that appears when the user presses ALT+TAB.
|
/// appear in the taskbar or in the dialog that appears when the user presses ALT+TAB.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_TOOLWINDOW = 0x0080,
|
WS_EX_TOOLWINDOW = 0x0080,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window has a border with a raised edge.
|
/// The window has a border with a raised edge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_WINDOWEDGE = 0x0100,
|
WS_EX_WINDOWEDGE = 0x0100,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window has a border with a sunken edge.
|
/// The window has a border with a sunken edge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_CLIENTEDGE = 0x0200,
|
WS_EX_CLIENTEDGE = 0x0200,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title bar of the window includes a question mark.
|
/// The title bar of the window includes a question mark.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_CONTEXTHELP = 0x0400,
|
WS_EX_CONTEXTHELP = 0x0400,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window has generic "right-aligned" properties. This depends on the window class. This style has
|
/// The window has generic "right-aligned" properties. This depends on the window class. This style has
|
||||||
/// an effect only if the shell language supports reading-order alignment, otherwise is ignored.
|
/// an effect only if the shell language supports reading-order alignment, otherwise is ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_RIGHT = 0x1000,
|
WS_EX_RIGHT = 0x1000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window has generic left-aligned properties. This is the default.
|
/// The window has generic left-aligned properties. This is the default.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_LEFT = 0x0,
|
WS_EX_LEFT = 0x0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the shell language supports reading-order alignment, the window text is displayed using right-to-left
|
/// If the shell language supports reading-order alignment, the window text is displayed using right-to-left
|
||||||
/// reading-order properties. For other languages, the styles is ignored.
|
/// reading-order properties. For other languages, the styles is ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_RTLREADING = 0x2000,
|
WS_EX_RTLREADING = 0x2000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window text is displayed using left-to-right reading-order properties. This is the default.
|
/// The window text is displayed using left-to-right reading-order properties. This is the default.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_LTRREADING = 0x0,
|
WS_EX_LTRREADING = 0x0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the shell language supports reading order alignment, the vertical scroll bar (if present) is to
|
/// If the shell language supports reading order alignment, the vertical scroll bar (if present) is to
|
||||||
/// the left of the client area. For other languages, the style is ignored.
|
/// the left of the client area. For other languages, the style is ignored.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_LEFTSCROLLBAR = 0x4000,
|
WS_EX_LEFTSCROLLBAR = 0x4000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The vertical scroll bar (if present) is to the right of the client area. This is the default.
|
/// The vertical scroll bar (if present) is to the right of the client area. This is the default.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_RIGHTSCROLLBAR = 0x0,
|
WS_EX_RIGHTSCROLLBAR = 0x0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window itself contains child windows that should take part in dialog box, navigation. If this
|
/// The window itself contains child windows that should take part in dialog box, navigation. If this
|
||||||
/// style is specified, the dialog manager recurses into children of this window when performing
|
/// style is specified, the dialog manager recurses into children of this window when performing
|
||||||
/// navigation operations such as handling tha TAB key, an arrow key, or a keyboard mnemonic.
|
/// navigation operations such as handling tha TAB key, an arrow key, or a keyboard mnemonic.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_CONTROLPARENT = 0x10000,
|
WS_EX_CONTROLPARENT = 0x10000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window has a three-dimensional border style intended to be used for items that do not accept
|
/// The window has a three-dimensional border style intended to be used for items that do not accept
|
||||||
/// user input.
|
/// user input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_STATICEDGE = 0x20000,
|
WS_EX_STATICEDGE = 0x20000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Forces a top-level window onto the taskbar when the window is visible.
|
/// Forces a top-level window onto the taskbar when the window is visible.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_APPWINDOW = 0x40000,
|
WS_EX_APPWINDOW = 0x40000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window is an overlapped window.
|
/// The window is an overlapped window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
|
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window is palette window, which is a modeless dialog box that presents an array of commands.
|
/// The window is palette window, which is a modeless dialog box that presents an array of commands.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
|
WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window is a layered window. This style cannot be used if the window has a class style of either
|
/// The window is a layered window. This style cannot be used if the window has a class style of either
|
||||||
/// CS_OWNDC or CS_CLASSDC. Only for top level window before Windows 8, and child windows from Windows 8.
|
/// CS_OWNDC or CS_CLASSDC. Only for top level window before Windows 8, and child windows from Windows 8.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_LAYERED = 0x80000,
|
WS_EX_LAYERED = 0x80000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The window does not pass its window layout to its child windows.
|
/// The window does not pass its window layout to its child windows.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_NOINHERITLAYOUT = 0x100000,
|
WS_EX_NOINHERITLAYOUT = 0x100000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the shell language supports reading order alignment, the horizontal origin of the window is on the
|
/// If the shell language supports reading order alignment, the horizontal origin of the window is on the
|
||||||
/// right edge. Increasing horizontal values advance to the left.
|
/// right edge. Increasing horizontal values advance to the left.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_LAYOUTRTL = 0x400000,
|
WS_EX_LAYOUTRTL = 0x400000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Paints all descendants of a window in bottom-to-top painting order using double-buffering.
|
/// Paints all descendants of a window in bottom-to-top painting order using double-buffering.
|
||||||
/// Bottom-to-top painting order allows a descendent window to have translucency (alpha) and
|
/// Bottom-to-top painting order allows a descendent window to have translucency (alpha) and
|
||||||
/// transparency (color-key) effects, but only if the descendent window also has the WS_EX_TRANSPARENT
|
/// transparency (color-key) effects, but only if the descendent window also has the WS_EX_TRANSPARENT
|
||||||
/// bit set. Double-buffering allows the window and its descendents to be painted without flicker.
|
/// bit set. Double-buffering allows the window and its descendents to be painted without flicker.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_COMPOSITED = 0x2000000,
|
WS_EX_COMPOSITED = 0x2000000,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A top-level window created with this style does not become the foreground window when the user
|
/// A top-level window created with this style does not become the foreground window when the user
|
||||||
/// clicks it. The system does not bring this window to the foreground when the user minimizes or closes
|
/// clicks it. The system does not bring this window to the foreground when the user minimizes or closes
|
||||||
/// the foreground window.
|
/// the foreground window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WS_EX_NOACTIVATE = 0x8000000
|
WS_EX_NOACTIVATE = 0x8000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace WindowWalker.Components
|
namespace WindowWalker.Components
|
||||||
@ -19,11 +18,15 @@ namespace WindowWalker.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate void OpenWindowsUpdateHandler(object sender, SearchController.SearchResultUpdateEventArgs e);
|
public delegate void OpenWindowsUpdateHandler(object sender, SearchController.SearchResultUpdateEventArgs e);
|
||||||
|
|
||||||
|
#pragma warning disable 0067 // suppress false positive
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event raised when there is an update to the list of open windows
|
/// Event raised when there is an update to the list of open windows
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OpenWindowsUpdateHandler OnOpenWindowsUpdate;
|
public event OpenWindowsUpdateHandler OnOpenWindowsUpdate;
|
||||||
|
|
||||||
|
#pragma warning restore 0067
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of all the open windows
|
/// List of all the open windows
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -112,7 +112,7 @@ namespace WindowWalker.Components
|
|||||||
InteropAndHelpers.CallBackPtr callbackptr = new InteropAndHelpers.CallBackPtr((IntPtr hwnd, IntPtr lParam) =>
|
InteropAndHelpers.CallBackPtr callbackptr = new InteropAndHelpers.CallBackPtr((IntPtr hwnd, IntPtr lParam) =>
|
||||||
{
|
{
|
||||||
var childProcessId = GetProcessIDFromWindowHandle(hwnd);
|
var childProcessId = GetProcessIDFromWindowHandle(hwnd);
|
||||||
if (childProcessId != this.ProcessID)
|
if (childProcessId != ProcessID)
|
||||||
{
|
{
|
||||||
_handlesToProcessCache[Hwnd] = GetProcessNameFromWindowHandle(hwnd);
|
_handlesToProcessCache[Hwnd] = GetProcessNameFromWindowHandle(hwnd);
|
||||||
return false;
|
return false;
|
||||||
@ -191,7 +191,7 @@ namespace WindowWalker.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified window handle identifies an existing window.
|
/// Gets a value indicating whether the specified window handle identifies an existing window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsWindow
|
public bool IsWindow
|
||||||
{
|
{
|
||||||
@ -202,7 +202,7 @@ namespace WindowWalker.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a value indicating whether is the window GWL_EX_STYLE is a toolwindow
|
/// Gets a value indicating whether a value is the window GWL_EX_STYLE is a toolwindow
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsToolWindow
|
public bool IsToolWindow
|
||||||
{
|
{
|
||||||
@ -215,7 +215,7 @@ namespace WindowWalker.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a value indicating whether the window GWL_EX_STYLE is an appwindow
|
/// Gets a value indicating whether the window GWL_EX_STYLE is an appwindow
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsAppWindow
|
public bool IsAppWindow
|
||||||
{
|
{
|
||||||
@ -228,7 +228,7 @@ namespace WindowWalker.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a value indicating whether the window has ITaskList_Deleted property
|
/// Gets a value indicating whether the window has ITaskList_Deleted property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool TaskListDeleted
|
public bool TaskListDeleted
|
||||||
{
|
{
|
||||||
@ -239,18 +239,18 @@ namespace WindowWalker.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a value indicating whether the app is a cloaked UWP app
|
/// Gets a value indicating whether the app is a cloaked UWP app
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsUWPCloaked
|
public bool IsUWPCloaked
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (this.IsWindowCloaked() && this.ClassName == "ApplicationFrameWindow");
|
return IsWindowCloaked() && ClassName == "ApplicationFrameWindow";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified windows is the owner
|
/// Gets a value indicating whether the specified windows is the owner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsOwner
|
public bool IsOwner
|
||||||
{
|
{
|
||||||
@ -267,7 +267,7 @@ namespace WindowWalker.Components
|
|||||||
{
|
{
|
||||||
int isCloaked = 0;
|
int isCloaked = 0;
|
||||||
const int DWMWA_CLOAKED = 14;
|
const int DWMWA_CLOAKED = 14;
|
||||||
InteropAndHelpers.DwmGetWindowAttribute(this.hwnd, DWMWA_CLOAKED, out isCloaked, sizeof(int));
|
InteropAndHelpers.DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, out isCloaked, sizeof(int));
|
||||||
return isCloaked != 0;
|
return isCloaked != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ namespace WindowWalker
|
|||||||
|
|
||||||
private void Window_GotFocus(object sender, RoutedEventArgs e)
|
private void Window_GotFocus(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
this.searchBox.Focus();
|
searchBox.Focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using Microsoft.Win32;
|
|
||||||
using WindowWalker.Components;
|
using WindowWalker.Components;
|
||||||
using WindowWalker.MVVMHelpers;
|
using WindowWalker.MVVMHelpers;
|
||||||
|
|
||||||
@ -18,7 +18,6 @@ namespace WindowWalker.ViewModels
|
|||||||
private readonly List<string> _hints = new List<string>()
|
private readonly List<string> _hints = new List<string>()
|
||||||
{
|
{
|
||||||
"search for running processes or windows...",
|
"search for running processes or windows...",
|
||||||
// "you can reinvoke this app using CTRL + WIN",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private string _searchText = string.Empty;
|
private string _searchText = string.Empty;
|
||||||
|
453
src/settings-web/package-lock.json
generated
453
src/settings-web/package-lock.json
generated
@ -2437,6 +2437,16 @@
|
|||||||
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
|
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"bindings": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"file-uri-to-path": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"block-stream": {
|
"block-stream": {
|
||||||
"version": "0.0.9",
|
"version": "0.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
|
||||||
@ -2760,6 +2770,21 @@
|
|||||||
"y18n": "^4.0.0"
|
"y18n": "^4.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
@ -3272,6 +3297,21 @@
|
|||||||
"run-queue": "^1.0.0"
|
"run-queue": "^1.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
@ -4477,6 +4517,15 @@
|
|||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
@ -4552,6 +4601,13 @@
|
|||||||
"schema-utils": "^1.0.0"
|
"schema-utils": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"file-uri-to-path": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"filesize": {
|
"filesize": {
|
||||||
"version": "3.6.1",
|
"version": "3.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz",
|
||||||
@ -4810,14 +4866,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fsevents": {
|
"fsevents": {
|
||||||
"version": "1.2.9",
|
"version": "1.2.12",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz",
|
||||||
"integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==",
|
"integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
"nan": "^2.12.1",
|
"nan": "^2.12.1",
|
||||||
"node-pre-gyp": "^0.12.0"
|
"node-pre-gyp": "*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
@ -4865,7 +4922,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chownr": {
|
"chownr": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
@ -4895,7 +4952,7 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.1.1",
|
"version": "3.2.6",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -4922,12 +4979,12 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"fs-minipass": {
|
"fs-minipass": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.7",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minipass": "^2.2.1"
|
"minipass": "^2.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fs.realpath": {
|
"fs.realpath": {
|
||||||
@ -4953,7 +5010,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.3",
|
"version": "7.1.6",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -4982,7 +5039,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ignore-walk": {
|
"ignore-walk": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -5001,7 +5058,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
@ -5037,13 +5094,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "1.2.5",
|
||||||
"bundled": true,
|
"bundled": true
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.9.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -5053,48 +5108,47 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minizlib": {
|
"minizlib": {
|
||||||
"version": "1.2.1",
|
"version": "1.3.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minipass": "^2.2.1"
|
"minipass": "^2.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.5",
|
||||||
"bundled": true,
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
"dev": true,
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"needle": {
|
"needle": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^4.1.0",
|
"debug": "^3.2.6",
|
||||||
"iconv-lite": "^0.4.4",
|
"iconv-lite": "^0.4.4",
|
||||||
"sax": "^1.2.4"
|
"sax": "^1.2.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-pre-gyp": {
|
"node-pre-gyp": {
|
||||||
"version": "0.12.0",
|
"version": "0.14.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"detect-libc": "^1.0.2",
|
"detect-libc": "^1.0.2",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "0.5.5",
|
||||||
"needle": "^2.2.1",
|
"needle": "^2.2.1",
|
||||||
"nopt": "^4.0.1",
|
"nopt": "^4.0.1",
|
||||||
"npm-packlist": "^1.1.6",
|
"npm-packlist": "^1.1.6",
|
||||||
@ -5102,11 +5156,23 @@
|
|||||||
"rc": "^1.2.7",
|
"rc": "^1.2.7",
|
||||||
"rimraf": "^2.6.1",
|
"rimraf": "^2.6.1",
|
||||||
"semver": "^5.3.0",
|
"semver": "^5.3.0",
|
||||||
"tar": "^4"
|
"tar": "^4.4.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nopt": {
|
"nopt": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -5116,19 +5182,29 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npm-bundled": {
|
"npm-bundled": {
|
||||||
"version": "1.0.6",
|
"version": "1.1.1",
|
||||||
|
"bundled": true,
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"npm-normalize-package-bin": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npm-normalize-package-bin": {
|
||||||
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"npm-packlist": {
|
"npm-packlist": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.8",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ignore-walk": "^3.0.1",
|
"ignore-walk": "^3.0.1",
|
||||||
"npm-bundled": "^1.0.1"
|
"npm-bundled": "^1.0.1",
|
||||||
|
"npm-normalize-package-bin": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npmlog": {
|
"npmlog": {
|
||||||
@ -5193,7 +5269,7 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"process-nextick-args": {
|
"process-nextick-args": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
@ -5208,18 +5284,10 @@
|
|||||||
"ini": "~1.3.0",
|
"ini": "~1.3.0",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
"strip-json-comments": "~2.0.1"
|
"strip-json-comments": "~2.0.1"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"minimist": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"bundled": true,
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "2.3.6",
|
"version": "2.3.7",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -5234,7 +5302,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.6.3",
|
"version": "2.7.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@ -5261,7 +5329,7 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "5.7.0",
|
"version": "5.7.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
@ -5314,18 +5382,30 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"tar": {
|
"tar": {
|
||||||
"version": "4.4.8",
|
"version": "4.4.13",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chownr": "^1.1.1",
|
"chownr": "^1.1.1",
|
||||||
"fs-minipass": "^1.2.5",
|
"fs-minipass": "^1.2.5",
|
||||||
"minipass": "^2.3.4",
|
"minipass": "^2.8.6",
|
||||||
"minizlib": "^1.1.1",
|
"minizlib": "^1.2.1",
|
||||||
"mkdirp": "^0.5.0",
|
"mkdirp": "0.5.5",
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.2"
|
"yallist": "^3.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"util-deprecate": {
|
"util-deprecate": {
|
||||||
@ -5350,7 +5430,7 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.1.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
@ -5369,6 +5449,21 @@
|
|||||||
"rimraf": "2"
|
"rimraf": "2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
@ -5609,15 +5704,16 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"handlebars": {
|
"handlebars": {
|
||||||
"version": "4.5.3",
|
"version": "4.7.6",
|
||||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
|
||||||
"integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
|
"integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"minimist": "^1.2.5",
|
||||||
"neo-async": "^2.6.0",
|
"neo-async": "^2.6.0",
|
||||||
"optimist": "^0.6.1",
|
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
"uglify-js": "^3.1.4"
|
"uglify-js": "^3.1.4",
|
||||||
|
"wordwrap": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"har-schema": {
|
"har-schema": {
|
||||||
@ -7098,6 +7194,21 @@
|
|||||||
"semver": "^6.2.0"
|
"semver": "^6.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
@ -7124,6 +7235,23 @@
|
|||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"slash": "^2.0.0",
|
"slash": "^2.0.0",
|
||||||
"source-map": "^0.6.0"
|
"source-map": "^0.6.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jest-validate": {
|
"jest-validate": {
|
||||||
@ -8052,9 +8180,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.10",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
@ -8131,21 +8259,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mkdirp": {
|
|
||||||
"version": "0.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
|
||||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
|
||||||
"requires": {
|
|
||||||
"minimist": "0.0.8"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"minimist": {
|
|
||||||
"version": "0.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
|
||||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||||
@ -8160,6 +8273,21 @@
|
|||||||
"run-queue": "^1.0.3"
|
"run-queue": "^1.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
@ -8312,6 +8440,21 @@
|
|||||||
"which": "1"
|
"which": "1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
@ -8482,6 +8625,21 @@
|
|||||||
"yallist": "^2.1.2"
|
"yallist": "^2.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
@ -8813,16 +8971,6 @@
|
|||||||
"is-wsl": "^1.1.0"
|
"is-wsl": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"optimist": {
|
|
||||||
"version": "0.6.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
|
||||||
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minimist": "~0.0.1",
|
|
||||||
"wordwrap": "~0.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"optionator": {
|
"optionator": {
|
||||||
"version": "0.8.3",
|
"version": "0.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
|
||||||
@ -9184,6 +9332,21 @@
|
|||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
@ -9782,6 +9945,28 @@
|
|||||||
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
|
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "0.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||||
|
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
@ -11415,6 +11600,19 @@
|
|||||||
"dom-serializer": "0",
|
"dom-serializer": "0",
|
||||||
"domelementtype": "1"
|
"domelementtype": "1"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -11443,6 +11641,23 @@
|
|||||||
"mkdirp": "^0.5.0",
|
"mkdirp": "^0.5.0",
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.3"
|
"yallist": "^3.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"terser": {
|
"terser": {
|
||||||
@ -11494,8 +11709,25 @@
|
|||||||
"ssri": "^6.0.1",
|
"ssri": "^6.0.1",
|
||||||
"unique-filename": "^1.1.1",
|
"unique-filename": "^1.1.1",
|
||||||
"y18n": "^4.0.0"
|
"y18n": "^4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"rimraf": {
|
"rimraf": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
@ -11727,6 +11959,21 @@
|
|||||||
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
|
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"yargs-parser": {
|
"yargs-parser": {
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
|
||||||
@ -11815,23 +12062,14 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "3.7.3",
|
"version": "3.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.8.1.tgz",
|
||||||
"integrity": "sha512-7tINm46/3puUA4hCkKYo4Xdts+JDaVC9ZPRcG8Xw9R4nhO/gZgUM3TENq8IF4Vatk8qCig4MzP/c8G4u2BkVQg==",
|
"integrity": "sha512-W7KxyzeaQmZvUFbGj4+YFshhVrMBGSg2IbcYAjGWGvx8DHvJMclbTDMpffdxFUGPBHjIytk7KJUR/KUXstUGDw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"commander": "~2.20.3",
|
"commander": "~2.20.3",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"commander": {
|
|
||||||
"version": "2.20.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
|
||||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"undertaker": {
|
"undertaker": {
|
||||||
@ -12207,6 +12445,23 @@
|
|||||||
"terser-webpack-plugin": "^1.1.0",
|
"terser-webpack-plugin": "^1.1.0",
|
||||||
"watchpack": "^1.5.0",
|
"watchpack": "^1.5.0",
|
||||||
"webpack-sources": "^1.3.0"
|
"webpack-sources": "^1.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webpack-cli": {
|
"webpack-cli": {
|
||||||
@ -12537,9 +12792,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"wordwrap": {
|
"wordwrap": {
|
||||||
"version": "0.0.3",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||||
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
|
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"worker-farm": {
|
"worker-farm": {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"typings": "lib/index.d.ts",
|
"typings": "lib/index.d.ts",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"preinstall": "npx npm-force-resolutions",
|
||||||
"just": "just-scripts",
|
"just": "just-scripts",
|
||||||
"clean": "rimraf build lib lib-commonjs && just-scripts clean",
|
"clean": "rimraf build lib lib-commonjs && just-scripts clean",
|
||||||
"build": "rimraf build && just-scripts build --min --production && copy *.html build && react-snap && xcopy build\\* ..\\settings\\settings-html /sy",
|
"build": "rimraf build && just-scripts build --min --production && copy *.html build && react-snap && xcopy build\\* ..\\settings\\settings-html /sy",
|
||||||
@ -46,5 +47,8 @@
|
|||||||
},
|
},
|
||||||
"just": {
|
"just": {
|
||||||
"stack": "just-stack-uifabric"
|
"stack": "just-stack-uifabric"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"mkdirp": "0.5.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -567,7 +567,7 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _
|
|||||||
Trace::RegisterProvider();
|
Trace::RegisterProvider();
|
||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
|
|
||||||
const bool should_try_drop_privileges = !initialize_com_security_policy_for_webview() && is_process_elevated();
|
const bool should_try_drop_privileges = !initialize_com_security_policy_for_webview() && is_process_elevated(false);
|
||||||
|
|
||||||
if (should_try_drop_privileges)
|
if (should_try_drop_privileges)
|
||||||
{
|
{
|
||||||
|
@ -26,13 +26,18 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(topBorder);
|
Assert.IsNotNull(topBorder);
|
||||||
Assert.IsNotNull(bottomBorder);
|
Assert.IsNotNull(bottomBorder);
|
||||||
|
|
||||||
|
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
||||||
|
|
||||||
//up
|
//up
|
||||||
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
|
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
|
||||||
Assert.IsTrue(topBorder.Rect.Y >= 0);
|
Assert.IsTrue(topBorder.Rect.Y >= 0);
|
||||||
|
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
|
||||||
|
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
||||||
|
|
||||||
//down
|
//down
|
||||||
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
|
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
|
||||||
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
|
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
|
||||||
|
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -43,13 +48,18 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(topBorder);
|
Assert.IsNotNull(topBorder);
|
||||||
Assert.IsNotNull(bottomBorder);
|
Assert.IsNotNull(bottomBorder);
|
||||||
|
|
||||||
|
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
||||||
|
|
||||||
//up
|
//up
|
||||||
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
|
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
|
||||||
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
|
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
|
||||||
|
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
|
||||||
|
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
|
||||||
|
|
||||||
//down
|
//down
|
||||||
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
|
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
|
||||||
Assert.IsTrue(bottomBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
Assert.IsTrue(bottomBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
||||||
|
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -60,13 +70,18 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(leftBorder);
|
Assert.IsNotNull(leftBorder);
|
||||||
Assert.IsNotNull(rightBorder);
|
Assert.IsNotNull(rightBorder);
|
||||||
|
|
||||||
|
int width = rightBorder.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
//to the left
|
//to the left
|
||||||
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
|
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
|
||||||
Assert.IsTrue(leftBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
Assert.IsTrue(leftBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
||||||
|
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
|
||||||
|
width = rightBorder.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
//to the right
|
//to the right
|
||||||
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
|
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
|
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
|
||||||
|
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -77,13 +92,18 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(leftBorder);
|
Assert.IsNotNull(leftBorder);
|
||||||
Assert.IsNotNull(rightBorder);
|
Assert.IsNotNull(rightBorder);
|
||||||
|
|
||||||
|
int width = rightBorder.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
//to the left
|
//to the left
|
||||||
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
|
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
|
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
|
||||||
|
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
|
||||||
|
width = rightBorder.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
//to the right
|
//to the right
|
||||||
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
|
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
||||||
|
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -96,41 +116,32 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(bottomBorder);
|
Assert.IsNotNull(bottomBorder);
|
||||||
Assert.IsNotNull(rightBorder);
|
Assert.IsNotNull(rightBorder);
|
||||||
|
|
||||||
//up
|
int expectedWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
|
||||||
MoveCorner(topLeftCorner, true, true, 0, -5000);
|
int expectedHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y >= 0);
|
int actualWidth, actualHeight;
|
||||||
|
|
||||||
//down
|
|
||||||
MoveCorner(topLeftCorner, true, true, 0, 5000);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
|
|
||||||
//up-left
|
//up-left
|
||||||
MoveCorner(topLeftCorner, true, true, -5000, -5000);
|
MoveCorner(topLeftCorner, true, true, -5000, -5000);
|
||||||
|
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
|
||||||
|
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
|
||||||
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y >= 0);
|
Assert.IsTrue(topLeftCorner.Rect.Y >= 0);
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X >= 0);
|
Assert.IsTrue(topLeftCorner.Rect.X >= 0);
|
||||||
|
Assert.IsTrue(actualHeight > expectedHeight);
|
||||||
|
Assert.IsTrue(actualWidth > expectedWidth);
|
||||||
|
|
||||||
//up-right
|
expectedHeight = actualHeight;
|
||||||
MoveCorner(topLeftCorner, true, true, 5000, -5000);
|
expectedWidth = actualWidth;
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y >= 0);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X <= rightBorder.Rect.X);
|
|
||||||
|
|
||||||
//to the left
|
|
||||||
MoveCorner(topLeftCorner, true, true, -5000, 0);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X >= 0);
|
|
||||||
|
|
||||||
//to the right
|
|
||||||
MoveCorner(topLeftCorner, true, true, 5000, 0);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X <= rightBorder.Rect.X);
|
|
||||||
|
|
||||||
//down-left
|
|
||||||
MoveCorner(topLeftCorner, true, true, -5000, 5000);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X >= 0);
|
|
||||||
|
|
||||||
//down-right
|
//down-right
|
||||||
MoveCorner(topLeftCorner, true, true, 5000, 5000);
|
MoveCorner(topLeftCorner, true, true, 5000, 5000);
|
||||||
|
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
|
||||||
|
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
|
||||||
|
|
||||||
Assert.IsTrue(topLeftCorner.Rect.Y <= bottomBorder.Rect.Y);
|
Assert.IsTrue(topLeftCorner.Rect.Y <= bottomBorder.Rect.Y);
|
||||||
Assert.IsTrue(topLeftCorner.Rect.X <= rightBorder.Rect.X);
|
Assert.IsTrue(topLeftCorner.Rect.X <= rightBorder.Rect.X);
|
||||||
|
Assert.IsTrue(actualHeight < expectedHeight);
|
||||||
|
Assert.IsTrue(actualWidth < expectedWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -143,41 +154,32 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(bottomBorder);
|
Assert.IsNotNull(bottomBorder);
|
||||||
Assert.IsNotNull(leftBorder);
|
Assert.IsNotNull(leftBorder);
|
||||||
|
|
||||||
//up
|
int expectedWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
|
||||||
MoveCorner(topRightCorner, false, true, 0, -5000);
|
int expectedHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y >= 0);
|
int actualWidth, actualHeight;
|
||||||
|
|
||||||
//down
|
|
||||||
MoveCorner(topRightCorner, false, true, 0, 5000);
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
|
|
||||||
//up-left
|
|
||||||
MoveCorner(topRightCorner, false, true, -5000, -5000);
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y >= 0);
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.X >= leftBorder.Rect.X);
|
|
||||||
|
|
||||||
//up-right
|
//up-right
|
||||||
MoveCorner(topRightCorner, false, true, 5000, -5000);
|
MoveCorner(topRightCorner, false, true, 5000, -5000);
|
||||||
|
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
|
||||||
|
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y >= 0);
|
Assert.IsTrue(topRightCorner.Rect.Y >= 0);
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
||||||
|
Assert.IsTrue(actualHeight > expectedHeight);
|
||||||
|
Assert.IsTrue(actualWidth > expectedWidth);
|
||||||
|
|
||||||
//to the left
|
expectedHeight = actualHeight;
|
||||||
MoveCorner(topRightCorner, false, true, -5000, 0);
|
expectedWidth = actualWidth;
|
||||||
Assert.IsTrue(topRightCorner.Rect.X >= leftBorder.Rect.X);
|
|
||||||
|
|
||||||
//to the right
|
|
||||||
MoveCorner(topRightCorner, false, true, 5000, 0);
|
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
|
||||||
|
|
||||||
//down-right
|
|
||||||
MoveCorner(topRightCorner, false, true, 5000, 5000);
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y <= bottomBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
|
||||||
|
|
||||||
//down-left
|
//down-left
|
||||||
MoveCorner(topRightCorner, false, true, -5000, 5000);
|
MoveCorner(topRightCorner, false, true, -5000, 5000);
|
||||||
|
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
|
||||||
|
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
Assert.IsTrue(topRightCorner.Rect.Y <= bottomBorder.Rect.Y);
|
Assert.IsTrue(topRightCorner.Rect.Y <= bottomBorder.Rect.Y);
|
||||||
Assert.IsTrue(topRightCorner.Rect.X >= leftBorder.Rect.X);
|
Assert.IsTrue(topRightCorner.Rect.X >= leftBorder.Rect.X);
|
||||||
|
Assert.IsTrue(actualHeight < expectedHeight);
|
||||||
|
Assert.IsTrue(actualWidth < expectedWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -190,41 +192,32 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(topBorder);
|
Assert.IsNotNull(topBorder);
|
||||||
Assert.IsNotNull(rightBorder);
|
Assert.IsNotNull(rightBorder);
|
||||||
|
|
||||||
//down
|
int expectedWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
|
||||||
MoveCorner(bottomLeftCorner, true, false, 0, 5000);
|
int expectedHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
int actualWidth, actualHeight;
|
||||||
|
|
||||||
//up
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, 0, -5000);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y >= topBorder.Rect.Y);
|
|
||||||
|
|
||||||
//down-right
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, 5000, 5000);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X <= rightBorder.Rect.X);
|
|
||||||
|
|
||||||
//down-left
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, -5000, 5000);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X >= 0);
|
|
||||||
|
|
||||||
//to the right
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, 5000, 0);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X <= rightBorder.Rect.X);
|
|
||||||
|
|
||||||
//to the left
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, -5000, 0);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X >= 0);
|
|
||||||
|
|
||||||
//up-left
|
//up-left
|
||||||
MoveCorner(bottomLeftCorner, true, false, -5000, -5000);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y >= topBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X >= 0);
|
|
||||||
|
|
||||||
//up-right
|
|
||||||
MoveCorner(bottomLeftCorner, true, false, 5000, -5000);
|
MoveCorner(bottomLeftCorner, true, false, 5000, -5000);
|
||||||
|
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
|
||||||
|
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
|
||||||
|
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.Y >= topBorder.Rect.Y);
|
Assert.IsTrue(bottomLeftCorner.Rect.Y >= topBorder.Rect.Y);
|
||||||
Assert.IsTrue(bottomLeftCorner.Rect.X <= rightBorder.Rect.X);
|
Assert.IsTrue(bottomLeftCorner.Rect.X <= rightBorder.Rect.X);
|
||||||
|
Assert.IsTrue(actualHeight < expectedHeight);
|
||||||
|
Assert.IsTrue(actualWidth < expectedWidth);
|
||||||
|
|
||||||
|
expectedHeight = actualHeight;
|
||||||
|
expectedWidth = actualWidth;
|
||||||
|
|
||||||
|
//down-right
|
||||||
|
MoveCorner(bottomLeftCorner, true, false, -5000, 5000);
|
||||||
|
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
|
||||||
|
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
|
||||||
|
|
||||||
|
Assert.IsTrue(bottomLeftCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
||||||
|
Assert.IsTrue(bottomLeftCorner.Rect.X >= 0);
|
||||||
|
Assert.IsTrue(actualHeight > expectedHeight);
|
||||||
|
Assert.IsTrue(actualWidth > expectedWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
@ -237,41 +230,31 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(topBorder);
|
Assert.IsNotNull(topBorder);
|
||||||
Assert.IsNotNull(leftBorder);
|
Assert.IsNotNull(leftBorder);
|
||||||
|
|
||||||
//to the right
|
int expectedWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
|
||||||
MoveCorner(bottomRightCorner, false, false, 5000, 0);
|
int expectedHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
int actualWidth, actualHeight;
|
||||||
|
|
||||||
//to the left
|
|
||||||
MoveCorner(bottomRightCorner, false, false, -5000, 0);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X >= leftBorder.Rect.X);
|
|
||||||
|
|
||||||
//down
|
|
||||||
MoveCorner(bottomRightCorner, false, false, 0, 5000);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
|
|
||||||
//up
|
|
||||||
MoveCorner(bottomRightCorner, false, false, 0, -5000);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y >= topBorder.Rect.Y);
|
|
||||||
|
|
||||||
//up-left
|
//up-left
|
||||||
MoveCorner(bottomRightCorner, false, false, -5000, -5000);
|
MoveCorner(bottomRightCorner, false, false, -5000, -5000);
|
||||||
|
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
|
||||||
|
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y >= topBorder.Rect.Y);
|
Assert.IsTrue(bottomRightCorner.Rect.Y >= topBorder.Rect.Y);
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X >= leftBorder.Rect.X);
|
Assert.IsTrue(bottomRightCorner.Rect.X >= leftBorder.Rect.X);
|
||||||
|
Assert.IsTrue(actualHeight < expectedHeight);
|
||||||
|
Assert.IsTrue(actualWidth < expectedWidth);
|
||||||
|
|
||||||
//up-right
|
expectedHeight = actualHeight;
|
||||||
MoveCorner(bottomRightCorner, false, false, 5000, -5000);
|
expectedWidth = actualWidth;
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y >= topBorder.Rect.Y);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
|
||||||
|
|
||||||
//down-right
|
//down-right
|
||||||
MoveCorner(bottomRightCorner, false, false, 5000, 5000);
|
MoveCorner(bottomRightCorner, false, false, 5000, 5000);
|
||||||
|
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
|
||||||
|
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
|
||||||
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
Assert.IsTrue(bottomRightCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
Assert.IsTrue(bottomRightCorner.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
|
||||||
|
Assert.IsTrue(actualHeight > expectedHeight);
|
||||||
//down-left
|
|
||||||
MoveCorner(bottomRightCorner, false, false, -5000, 5000);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
|
|
||||||
Assert.IsTrue(bottomRightCorner.Rect.X >= leftBorder.Rect.X);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[ClassInitialize]
|
[ClassInitialize]
|
||||||
@ -285,17 +268,12 @@ namespace PowerToysTests
|
|||||||
LaunchPowerToys();
|
LaunchPowerToys();
|
||||||
}
|
}
|
||||||
OpenEditor();
|
OpenEditor();
|
||||||
OpenCustomLayouts();
|
OpenCustomLayouts();
|
||||||
|
|
||||||
//create canvas zone
|
|
||||||
OpenCreatorWindow("Create new custom", "Custom layout creator");
|
|
||||||
session.FindElementByAccessibilityId("newZoneButton").Click();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[ClassCleanup]
|
[ClassCleanup]
|
||||||
public static void ClassCleanup()
|
public static void ClassCleanup()
|
||||||
{
|
{
|
||||||
new Actions(session).MoveToElement(session.FindElementByXPath("//Button[@Name=\"Cancel\"]")).Click().Perform();
|
|
||||||
CloseEditor();
|
CloseEditor();
|
||||||
TearDown();
|
TearDown();
|
||||||
}
|
}
|
||||||
@ -303,13 +281,15 @@ namespace PowerToysTests
|
|||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void TestInitialize()
|
public void TestInitialize()
|
||||||
{
|
{
|
||||||
|
//create canvas zone
|
||||||
|
OpenCreatorWindow("Create new custom", "Custom layout creator");
|
||||||
|
session.FindElementByAccessibilityId("newZoneButton").Click();
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCleanup]
|
[TestCleanup]
|
||||||
public void TestCleanup()
|
public void TestCleanup()
|
||||||
{
|
{
|
||||||
|
new Actions(session).MoveToElement(session.FindElementByXPath("//Button[@Name=\"Cancel\"]")).Click().Perform();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ namespace PowerToysTests
|
|||||||
{
|
{
|
||||||
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
|
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
|
||||||
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
Assert.AreEqual(_initialZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
|
Assert.AreEqual(_initialZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ namespace PowerToysTests
|
|||||||
private void SaveTest(string type, string name, int zoneCount)
|
private void SaveTest(string type, string name, int zoneCount)
|
||||||
{
|
{
|
||||||
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
Assert.AreEqual(name, settings["custom-zone-sets"][0]["name"]);
|
Assert.AreEqual(name, settings["custom-zone-sets"][0]["name"]);
|
||||||
@ -149,7 +149,7 @@ namespace PowerToysTests
|
|||||||
string name = "My custom zone layout name";
|
string name = "My custom zone layout name";
|
||||||
SetLayoutName(name);
|
SetLayoutName(name);
|
||||||
SaveTest("canvas", name, 0);
|
SaveTest("canvas", name, 0);
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//rename layout
|
//rename layout
|
||||||
OpenEditor();
|
OpenEditor();
|
||||||
@ -168,7 +168,7 @@ namespace PowerToysTests
|
|||||||
string name = "Name";
|
string name = "Name";
|
||||||
SetLayoutName(name);
|
SetLayoutName(name);
|
||||||
SaveTest("canvas", name, 0);
|
SaveTest("canvas", name, 0);
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//save layout id
|
//save layout id
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
@ -183,7 +183,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
//settings are saved on window closing
|
//settings are saved on window closing
|
||||||
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//check settings
|
//check settings
|
||||||
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
@ -206,7 +206,7 @@ namespace PowerToysTests
|
|||||||
SetLayoutName(name);
|
SetLayoutName(name);
|
||||||
|
|
||||||
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//remove layout
|
//remove layout
|
||||||
OpenEditor();
|
OpenEditor();
|
||||||
@ -217,7 +217,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
//settings are saved on window closing
|
//settings are saved on window closing
|
||||||
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//check settings
|
//check settings
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
@ -236,8 +236,7 @@ namespace PowerToysTests
|
|||||||
SetLayoutName(name);
|
SetLayoutName(name);
|
||||||
|
|
||||||
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
//remove layout
|
//remove layout
|
||||||
OpenEditor();
|
OpenEditor();
|
||||||
OpenCustomLayouts();
|
OpenCustomLayouts();
|
||||||
@ -247,7 +246,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
//settings are saved on window closing
|
//settings are saved on window closing
|
||||||
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//check settings
|
//check settings
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
@ -263,7 +262,7 @@ namespace PowerToysTests
|
|||||||
OpenCreatorWindow("Create new custom", "Custom layout creator");
|
OpenCreatorWindow("Create new custom", "Custom layout creator");
|
||||||
SetLayoutName(name);
|
SetLayoutName(name);
|
||||||
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//save layout id
|
//save layout id
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
@ -278,7 +277,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
//apply
|
//apply
|
||||||
new Actions(session).MoveToElement(session.FindElementByName("Apply")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByName("Apply")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//check settings
|
//check settings
|
||||||
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
|
@ -59,11 +59,10 @@ namespace PowerToysTests
|
|||||||
WindowsElement errorMessage = null;
|
WindowsElement errorMessage = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
errorMessage = session.FindElementByName("FancyZones Editor Exception Handler");
|
errorMessage = WaitElementByName("FancyZones Editor Exception Handler");
|
||||||
if (errorMessage != null)
|
if (errorMessage != null)
|
||||||
{
|
{
|
||||||
errorMessage.FindElementByName("OK").Click();
|
errorMessage.FindElementByName("OK").Click();
|
||||||
ShortWait();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
catch (OpenQA.Selenium.WebDriverException)
|
||||||
@ -92,16 +91,12 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(editorButton);
|
Assert.IsNotNull(editorButton);
|
||||||
|
|
||||||
editorButton.Click();
|
editorButton.Click();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
TestEditorOpened();
|
TestEditorOpened();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenEditorByHotkey()
|
void OpenEditorByHotkey()
|
||||||
{
|
{
|
||||||
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
|
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
TestEditorOpened();
|
TestEditorOpened();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace PowerToysTests
|
|||||||
{
|
{
|
||||||
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
||||||
|
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual(editorZoneCountValue, GetEditZonesSetting<int>(editorZoneCount));
|
Assert.AreEqual(editorZoneCountValue, GetEditZonesSetting<int>(editorZoneCount));
|
||||||
OpenEditor();
|
OpenEditor();
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace PowerToysTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual(editorZoneCountValue, GetEditZonesSetting<int>(editorZoneCount));
|
Assert.AreEqual(editorZoneCountValue, GetEditZonesSetting<int>(editorZoneCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
||||||
|
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
Assert.AreNotEqual(spaceAroundSettingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
Assert.AreNotEqual(spaceAroundSettingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ namespace PowerToysTests
|
|||||||
bool editorShowSpacingValue = spaceAroundSetting.Selected;
|
bool editorShowSpacingValue = spaceAroundSetting.Selected;
|
||||||
|
|
||||||
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
string[] validValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
string[] validValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ namespace PowerToysTests
|
|||||||
paddingValue.SendKeys(editorSpacingValue);
|
paddingValue.SendKeys(editorSpacingValue);
|
||||||
|
|
||||||
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
Assert.AreEqual(editorShowSpacingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
Assert.AreEqual(editorShowSpacingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
||||||
Assert.AreEqual(editorSpacingValue, GetEditZonesSetting<string>(editorSpacing));
|
Assert.AreEqual(editorSpacingValue, GetEditZonesSetting<string>(editorSpacing));
|
||||||
@ -118,7 +118,7 @@ namespace PowerToysTests
|
|||||||
bool editorShowSpacingValue = spaceAroundSetting.Selected;
|
bool editorShowSpacingValue = spaceAroundSetting.Selected;
|
||||||
|
|
||||||
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
string[] invalidValues = { "!", "/", "<", "?", "D", "Z", "]", "m", "}", "1.5", "2,5" };
|
string[] invalidValues = { "!", "/", "<", "?", "D", "Z", "]", "m", "}", "1.5", "2,5" };
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ namespace PowerToysTests
|
|||||||
paddingValue.SendKeys(value);
|
paddingValue.SendKeys(value);
|
||||||
|
|
||||||
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
Assert.AreEqual(editorShowSpacingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
Assert.AreEqual(editorShowSpacingValue, GetEditZonesSetting<bool>(editorShowSpacing));
|
||||||
Assert.AreEqual(editorSpacingValue, GetEditZonesSetting<string>(editorSpacing));
|
Assert.AreEqual(editorSpacingValue, GetEditZonesSetting<string>(editorSpacing));
|
||||||
|
@ -18,7 +18,7 @@ namespace PowerToysTests
|
|||||||
{
|
{
|
||||||
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
|
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
|
||||||
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
new Actions(session).MoveToElement(cancelButton).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
Assert.AreEqual(_defaultZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
|
Assert.AreEqual(_defaultZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ namespace PowerToysTests
|
|||||||
private void SaveTest()
|
private void SaveTest()
|
||||||
{
|
{
|
||||||
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
|
||||||
Assert.AreEqual("Custom Layout 1", settings["custom-zone-sets"][0]["name"]);
|
Assert.AreEqual("Custom Layout 1", settings["custom-zone-sets"][0]["name"]);
|
||||||
@ -188,7 +188,6 @@ namespace PowerToysTests
|
|||||||
if (editorWindow != null)
|
if (editorWindow != null)
|
||||||
{
|
{
|
||||||
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
|
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
|
||||||
ShortWait();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(OpenQA.Selenium.WebDriverException)
|
catch(OpenQA.Selenium.WebDriverException)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using OpenQA.Selenium.Appium.Windows;
|
using OpenQA.Selenium.Appium.Windows;
|
||||||
using OpenQA.Selenium.Interactions;
|
using OpenQA.Selenium.Interactions;
|
||||||
|
|
||||||
@ -17,8 +17,10 @@ namespace PowerToysTests
|
|||||||
protected static void OpenEditor()
|
protected static void OpenEditor()
|
||||||
{
|
{
|
||||||
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
|
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
|
||||||
ShortWait();
|
//editorWindow = WaitElementByXPath("//Window[@Name=\"FancyZones Editor\"]");
|
||||||
editorWindow = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]");
|
//may not find editor by name in 0.16.1
|
||||||
|
editorWindow = WaitElementByAccessibilityId("MainWindow1");
|
||||||
|
Assert.IsNotNull(editorWindow, "Couldn't find editor window");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void CloseEditor()
|
protected static void CloseEditor()
|
||||||
@ -28,7 +30,6 @@ namespace PowerToysTests
|
|||||||
if (editorWindow != null)
|
if (editorWindow != null)
|
||||||
{
|
{
|
||||||
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
|
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
|
||||||
ShortWait();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OpenQA.Selenium.WebDriverException)
|
catch (OpenQA.Selenium.WebDriverException)
|
||||||
|
@ -25,8 +25,6 @@ namespace PowerToysTests
|
|||||||
private static void Init()
|
private static void Init()
|
||||||
{
|
{
|
||||||
OpenSettings();
|
OpenSettings();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
OpenFancyZonesSettings();
|
OpenFancyZonesSettings();
|
||||||
|
|
||||||
_saveButton = session.FindElementByName("Save");
|
_saveButton = session.FindElementByName("Save");
|
||||||
@ -94,7 +92,7 @@ namespace PowerToysTests
|
|||||||
Assert.AreEqual(expected.ToString() + "\r\n", editor.Text);
|
Assert.AreEqual(expected.ToString() + "\r\n", editor.Text);
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
int value = GetPropertyValue<int>("fancyzones_highlight_opacity");
|
int value = GetPropertyValue<int>("fancyzones_highlight_opacity");
|
||||||
Assert.AreEqual(expected, value);
|
Assert.AreEqual(expected, value);
|
||||||
@ -215,7 +213,7 @@ namespace PowerToysTests
|
|||||||
action.Perform();
|
action.Perform();
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
//Assert.AreEqual(expectedText, input.Text);
|
//Assert.AreEqual(expectedText, input.Text);
|
||||||
|
|
||||||
@ -235,7 +233,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
//black on the bottom
|
//black on the bottom
|
||||||
new Actions(session).MoveToElement(saturationAndBrightness).ClickAndHold().MoveByOffset(0, satRect.Height).Release().Perform();
|
new Actions(session).MoveToElement(saturationAndBrightness).ClickAndHold().MoveByOffset(0, satRect.Height).Release().Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
Assert.AreEqual("0\r\n", red.Text);
|
Assert.AreEqual("0\r\n", red.Text);
|
||||||
Assert.AreEqual("0\r\n", green.Text);
|
Assert.AreEqual("0\r\n", green.Text);
|
||||||
@ -243,7 +241,7 @@ namespace PowerToysTests
|
|||||||
Assert.AreEqual("000000\r\n", hex.Text);
|
Assert.AreEqual("000000\r\n", hex.Text);
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual("#000000", GetPropertyValue<string>(propertyName));
|
Assert.AreEqual("#000000", GetPropertyValue<string>(propertyName));
|
||||||
|
|
||||||
//white in left corner
|
//white in left corner
|
||||||
@ -254,7 +252,7 @@ namespace PowerToysTests
|
|||||||
Assert.AreEqual("ffffff\r\n", hex.Text);
|
Assert.AreEqual("ffffff\r\n", hex.Text);
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual("#ffffff", GetPropertyValue<string>(propertyName));
|
Assert.AreEqual("#ffffff", GetPropertyValue<string>(propertyName));
|
||||||
|
|
||||||
//color in right corner
|
//color in right corner
|
||||||
@ -266,7 +264,7 @@ namespace PowerToysTests
|
|||||||
Assert.AreEqual("ff0000\r\n", hex.Text);
|
Assert.AreEqual("ff0000\r\n", hex.Text);
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual("#ff0000", GetPropertyValue<string>(propertyName));
|
Assert.AreEqual("#ff0000", GetPropertyValue<string>(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,9 +297,10 @@ namespace PowerToysTests
|
|||||||
toggle.Click();
|
toggle.Click();
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WaitSeconds(1);
|
||||||
|
|
||||||
//check saved settings
|
//check saved settings
|
||||||
JObject savedProps = GetProperties();
|
JObject savedProps = GetProperties();
|
||||||
Assert.AreNotEqual(toggleValues[0], GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
Assert.AreNotEqual(toggleValues[0], GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
||||||
@ -339,7 +338,7 @@ namespace PowerToysTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
JObject savedProps = GetProperties();
|
JObject savedProps = GetProperties();
|
||||||
Assert.AreEqual(toggleValues[0], GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
Assert.AreEqual(toggleValues[0], GetPropertyValue<bool>(savedProps, "fancyzones_shiftDrag"));
|
||||||
@ -396,7 +395,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
Actions action = new Actions(session);
|
Actions action = new Actions(session);
|
||||||
action.MoveToElement(editor).MoveByOffset(editorRect.Width / 2 + 10, -editorRect.Height / 4).Perform();
|
action.MoveToElement(editor).MoveByOffset(editorRect.Width / 2 + 10, -editorRect.Height / 4).Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
action.Click().Perform();
|
action.Click().Perform();
|
||||||
Assert.AreEqual("100\r\n", editor.Text);
|
Assert.AreEqual("100\r\n", editor.Text);
|
||||||
@ -421,7 +420,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
Actions action = new Actions(session);
|
Actions action = new Actions(session);
|
||||||
action.MoveToElement(editor).MoveByOffset(editorRect.Width / 2 + 10, editorRect.Height / 4).Perform();
|
action.MoveToElement(editor).MoveByOffset(editorRect.Width / 2 + 10, editorRect.Height / 4).Perform();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
|
|
||||||
action.Click().Perform();
|
action.Click().Perform();
|
||||||
Assert.AreEqual("0\r\n", editor.Text);
|
Assert.AreEqual("0\r\n", editor.Text);
|
||||||
@ -494,7 +493,7 @@ namespace PowerToysTests
|
|||||||
Assert.AreEqual("152", hue.Text);
|
Assert.AreEqual("152", hue.Text);
|
||||||
|
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual("#63c99a", GetPropertyValue<string>("fancyzones_zoneHighlightColor"));
|
Assert.AreEqual("#63c99a", GetPropertyValue<string>("fancyzones_zoneHighlightColor"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +564,7 @@ namespace PowerToysTests
|
|||||||
input.SendKeys(inputValue);
|
input.SendKeys(inputValue);
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ClearInput(input);
|
ClearInput(input);
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
||||||
|
|
||||||
//invalid
|
//invalid
|
||||||
@ -573,28 +572,28 @@ namespace PowerToysTests
|
|||||||
input.SendKeys(inputValue);
|
input.SendKeys(inputValue);
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ClearInput(input);
|
ClearInput(input);
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
||||||
|
|
||||||
inputValue = "Notepad,Chrome";
|
inputValue = "Notepad,Chrome";
|
||||||
input.SendKeys(inputValue);
|
input.SendKeys(inputValue);
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ClearInput(input);
|
ClearInput(input);
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
||||||
|
|
||||||
inputValue = "Note*";
|
inputValue = "Note*";
|
||||||
input.SendKeys(inputValue);
|
input.SendKeys(inputValue);
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ClearInput(input);
|
ClearInput(input);
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
||||||
|
|
||||||
inputValue = "Кириллица";
|
inputValue = "Кириллица";
|
||||||
input.SendKeys(inputValue);
|
input.SendKeys(inputValue);
|
||||||
SaveChanges();
|
SaveChanges();
|
||||||
ClearInput(input);
|
ClearInput(input);
|
||||||
ShortWait();
|
WaitSeconds(1);
|
||||||
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
Assert.AreEqual(inputValue, GetPropertyValue<string>("fancyzones_excluded_apps"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ namespace PowerToysTests
|
|||||||
public class PowerToysSession
|
public class PowerToysSession
|
||||||
{
|
{
|
||||||
protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
|
protected const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
|
||||||
|
protected const string AppPath = "C:\\Program Files\\PowerToys\\PowerToys.exe";
|
||||||
|
|
||||||
protected static WindowsDriver<WindowsElement> session;
|
protected static WindowsDriver<WindowsElement> session;
|
||||||
protected static bool isPowerToysLaunched = false;
|
protected static bool isPowerToysLaunched = false;
|
||||||
protected static WindowsElement trayButton;
|
protected static WindowsElement trayButton;
|
||||||
@ -66,14 +68,27 @@ namespace PowerToysTests
|
|||||||
{
|
{
|
||||||
Thread.Sleep(TimeSpan.FromSeconds(seconds));
|
Thread.Sleep(TimeSpan.FromSeconds(seconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShortWait()
|
//Trying to find element by XPath
|
||||||
{
|
protected static WindowsElement WaitElementByName(string name, double maxTime = 10)
|
||||||
Thread.Sleep(TimeSpan.FromSeconds(0.5));
|
{
|
||||||
|
WindowsElement result = null;
|
||||||
|
Stopwatch timer = new Stopwatch();
|
||||||
|
timer.Start();
|
||||||
|
while (timer.Elapsed < TimeSpan.FromSeconds(maxTime))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = session.FindElementByName(name);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Trying to find element by XPath
|
//Trying to find element by XPath
|
||||||
protected WindowsElement WaitElementByXPath(string xPath, double maxTime = 10)
|
protected static WindowsElement WaitElementByXPath(string xPath, double maxTime = 10)
|
||||||
{
|
{
|
||||||
WindowsElement result = null;
|
WindowsElement result = null;
|
||||||
Stopwatch timer = new Stopwatch();
|
Stopwatch timer = new Stopwatch();
|
||||||
@ -85,17 +100,13 @@ namespace PowerToysTests
|
|||||||
result = session.FindElementByXPath(xPath);
|
result = session.FindElementByXPath(xPath);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
if (result != null)
|
return result;
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Assert.IsNotNull(result);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Trying to find element by AccessibilityId
|
//Trying to find element by AccessibilityId
|
||||||
protected WindowsElement WaitElementByAccessibilityId(string accessibilityId, double maxTime = 10)
|
protected static WindowsElement WaitElementByAccessibilityId(string accessibilityId, double maxTime = 10)
|
||||||
{
|
{
|
||||||
WindowsElement result = null;
|
WindowsElement result = null;
|
||||||
Stopwatch timer = new Stopwatch();
|
Stopwatch timer = new Stopwatch();
|
||||||
@ -107,12 +118,8 @@ namespace PowerToysTests
|
|||||||
result = session.FindElementByAccessibilityId(accessibilityId);
|
result = session.FindElementByAccessibilityId(accessibilityId);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
if (result != null)
|
return result;
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Assert.IsNotNull(result);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,13 +132,11 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
public static void OpenFancyZonesSettings()
|
public static void OpenFancyZonesSettings()
|
||||||
{
|
{
|
||||||
WindowsElement fzNavigationButton = session.FindElementByXPath("//Button[@Name=\"FancyZones\"]");
|
WindowsElement fzNavigationButton = WaitElementByXPath("//Button[@Name=\"FancyZones\"]");
|
||||||
Assert.IsNotNull(fzNavigationButton);
|
Assert.IsNotNull(fzNavigationButton);
|
||||||
|
|
||||||
fzNavigationButton.Click();
|
fzNavigationButton.Click();
|
||||||
fzNavigationButton.Click();
|
fzNavigationButton.Click();
|
||||||
|
|
||||||
ShortWait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CloseSettings()
|
public static void CloseSettings()
|
||||||
@ -157,7 +162,7 @@ namespace PowerToysTests
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WindowsElement pt = session.FindElementByXPath("//Button[@Name=\"PowerToys\"]");
|
WindowsElement pt = WaitElementByXPath("//Button[@Name=\"PowerToys\"]");
|
||||||
isLaunched = (pt != null);
|
isLaunched = (pt != null);
|
||||||
}
|
}
|
||||||
catch(OpenQA.Selenium.WebDriverException)
|
catch(OpenQA.Selenium.WebDriverException)
|
||||||
@ -174,11 +179,9 @@ namespace PowerToysTests
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
AppiumOptions opts = new AppiumOptions();
|
AppiumOptions opts = new AppiumOptions();
|
||||||
opts.PlatformName = "Windows";
|
opts.PlatformName = "Windows";
|
||||||
opts.AddAdditionalCapability("platformVersion", "10");
|
opts.AddAdditionalCapability("app", AppPath);
|
||||||
opts.AddAdditionalCapability("deviceName", "WindowsPC");
|
|
||||||
opts.AddAdditionalCapability("app", "C:/Program Files/PowerToys/PowerToys.exe");
|
|
||||||
|
|
||||||
WindowsDriver<WindowsElement> driver = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), opts);
|
WindowsDriver<WindowsElement> driver = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), opts);
|
||||||
Assert.IsNotNull(driver);
|
Assert.IsNotNull(driver);
|
||||||
driver.LaunchApp();
|
driver.LaunchApp();
|
||||||
@ -195,13 +198,12 @@ namespace PowerToysTests
|
|||||||
public static void ExitPowerToys()
|
public static void ExitPowerToys()
|
||||||
{
|
{
|
||||||
trayButton.Click();
|
trayButton.Click();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
WindowsElement pt = session.FindElementByXPath("//Button[@Name=\"PowerToys\"]");
|
WindowsElement pt = WaitElementByXPath("//Button[@Name=\"PowerToys\"]");
|
||||||
|
Assert.IsNotNull(pt, "Couldn't find \'PowerToys\' button");
|
||||||
new Actions(session).MoveToElement(pt).ContextClick().Perform();
|
new Actions(session).MoveToElement(pt).ContextClick().Perform();
|
||||||
ShortWait();
|
|
||||||
|
WaitElementByXPath("//MenuItem[@Name=\"Exit\"]").Click();
|
||||||
session.FindElementByXPath("//MenuItem[@Name=\"Exit\"]").Click();
|
|
||||||
trayButton.Click(); //close tray
|
trayButton.Click(); //close tray
|
||||||
isPowerToysLaunched = false;
|
isPowerToysLaunched = false;
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,9 @@ namespace PowerToysTests
|
|||||||
public void SettingsOpen()
|
public void SettingsOpen()
|
||||||
{
|
{
|
||||||
OpenSettings();
|
OpenSettings();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
//check settings window opened
|
//check settings window opened
|
||||||
WindowsElement settingsWindow = session.FindElementByName("PowerToys Settings");
|
WindowsElement settingsWindow = WaitElementByName("PowerToys Settings");
|
||||||
Assert.IsNotNull(settingsWindow);
|
Assert.IsNotNull(settingsWindow);
|
||||||
|
|
||||||
isSettingsOpened = true;
|
isSettingsOpened = true;
|
||||||
@ -36,14 +35,12 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(pt);
|
Assert.IsNotNull(pt);
|
||||||
|
|
||||||
new Actions(session).MoveToElement(pt).ContextClick().Perform();
|
new Actions(session).MoveToElement(pt).ContextClick().Perform();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
//open settings
|
//open settings
|
||||||
session.FindElementByXPath("//MenuItem[@Name=\"Settings\"]").Click();
|
WaitElementByXPath("//MenuItem[@Name=\"Settings\"]").Click();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
//check settings window opened
|
//check settings window opened
|
||||||
WindowsElement settingsWindow = session.FindElementByName("PowerToys Settings");
|
WindowsElement settingsWindow = WaitElementByName("PowerToys Settings");
|
||||||
Assert.IsNotNull(settingsWindow);
|
Assert.IsNotNull(settingsWindow);
|
||||||
|
|
||||||
isSettingsOpened = true;
|
isSettingsOpened = true;
|
||||||
@ -62,12 +59,10 @@ namespace PowerToysTests
|
|||||||
Assert.IsNotNull(powerToys);
|
Assert.IsNotNull(powerToys);
|
||||||
|
|
||||||
new Actions(session).MoveToElement(powerToys).ContextClick().Perform();
|
new Actions(session).MoveToElement(powerToys).ContextClick().Perform();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
//exit
|
//exit
|
||||||
session.FindElementByXPath("//MenuItem[@Name=\"Exit\"]").Click();
|
WaitElementByXPath("//MenuItem[@Name=\"Exit\"]").Click();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
//check PowerToys exited
|
//check PowerToys exited
|
||||||
powerToys = null;
|
powerToys = null;
|
||||||
try
|
try
|
||||||
@ -82,8 +77,6 @@ namespace PowerToysTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
LaunchPowerToys();
|
LaunchPowerToys();
|
||||||
ShortWait();
|
|
||||||
|
|
||||||
Assert.IsNull(powerToys);
|
Assert.IsNull(powerToys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user