Cmdpal Powertoys Extension: Support mouse without borders easy mouse … (#45350)

## Description

You don't have to go to powertoys settings to 
* toggle the mouse move from machine to another
* you can trigger reconnect when connection lost from cmdpal
* You can toggle whether kbm is turning on or not from cmdpal

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Add several missing cmd to powretoys cmdpal extension


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed


https://github.com/user-attachments/assets/9ea019f7-988b-4542-afc5-a80f0fc99ef8

For the kbm toggle, when it's off, kbm will not map anything, if it's
on, kbm will take effect

For the mouse without borders, add these two functionality as command
<img width="1182" height="158" alt="image"
src="https://github.com/user-attachments/assets/27f526b1-9c91-4923-be6c-e505673f5892"
/>

And verified for the two command, works as expected
This commit is contained in:
Kai Tao
2026-03-09 10:25:11 +08:00
committed by GitHub
parent f6b0996c9b
commit 3d69785ca4
28 changed files with 574 additions and 24 deletions

View File

@@ -12,7 +12,7 @@
#include <keyboardmanager/KeyboardManagerEngineLibrary/trace.h>
#include <common/interop/shared_constants.h>
const std::wstring instanceMutexName = L"Local\\PowerToys_KBMEngine_InstanceMutex";
const std::wstring instanceMutexName = CommonSharedConstants::KEYBOARD_MANAGER_ENGINE_INSTANCE_MUTEX;
int WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/,
_In_opt_ HINSTANCE /*hPrevInstance*/,
@@ -90,3 +90,4 @@ int WINAPI wWinMain(_In_ HINSTANCE /*hInstance*/,
return 0;
}

View File

@@ -73,6 +73,7 @@ private:
HANDLE m_hTerminateEngineEvent = nullptr;
HANDLE m_open_new_editor_event_handle{ nullptr };
HANDLE m_toggle_active_event_handle{ nullptr };
std::thread m_toggle_thread;
std::atomic<bool> m_toggle_thread_running{ false };
@@ -87,6 +88,19 @@ private:
}
}
void toggle_engine()
{
refresh_process_state();
if (m_active)
{
stop_engine();
}
else
{
start_engine();
}
}
bool start_engine()
{
refresh_process_state();
@@ -273,6 +287,7 @@ public:
}
m_open_new_editor_event_handle = CreateDefaultEvent(CommonSharedConstants::OPEN_NEW_KEYBOARD_MANAGER_EVENT);
m_toggle_active_event_handle = CreateDefaultEvent(CommonSharedConstants::TOGGLE_KEYBOARD_MANAGER_ACTIVE_EVENT);
init_settings();
};
@@ -291,6 +306,11 @@ public:
CloseHandle(m_open_new_editor_event_handle);
m_open_new_editor_event_handle = nullptr;
}
if (m_toggle_active_event_handle)
{
CloseHandle(m_toggle_active_event_handle);
m_toggle_active_event_handle = nullptr;
}
if (m_hEditorProcess)
{
CloseHandle(m_hEditorProcess);
@@ -422,25 +442,45 @@ public:
void StartOpenEditorListener()
{
if (m_toggle_thread_running || !m_open_new_editor_event_handle)
if (m_toggle_thread_running || (!m_open_new_editor_event_handle && !m_toggle_active_event_handle))
{
return;
}
m_toggle_thread_running = true;
m_toggle_thread = std::thread([this]() {
HANDLE handles[2]{};
DWORD handle_count = 0;
DWORD open_editor_index = MAXDWORD;
DWORD toggle_active_index = MAXDWORD;
if (m_open_new_editor_event_handle)
{
open_editor_index = handle_count;
handles[handle_count++] = m_open_new_editor_event_handle;
}
if (m_toggle_active_event_handle)
{
toggle_active_index = handle_count;
handles[handle_count++] = m_toggle_active_event_handle;
}
while (m_toggle_thread_running)
{
const DWORD wait_result = WaitForSingleObject(m_open_new_editor_event_handle, 500);
const DWORD wait_result = WaitForMultipleObjects(handle_count, handles, FALSE, 500);
if (!m_toggle_thread_running)
{
break;
}
if (wait_result == WAIT_OBJECT_0)
if (open_editor_index != MAXDWORD && wait_result == (WAIT_OBJECT_0 + open_editor_index))
{
launch_editor();
ResetEvent(m_open_new_editor_event_handle);
}
else if (toggle_active_index != MAXDWORD && wait_result == (WAIT_OBJECT_0 + toggle_active_index))
{
toggle_engine();
}
}
});
@@ -458,6 +498,10 @@ public:
{
SetEvent(m_open_new_editor_event_handle);
}
if (m_toggle_active_event_handle)
{
SetEvent(m_toggle_active_event_handle);
}
if (m_toggle_thread.joinable())
{
m_toggle_thread.join();
@@ -551,15 +595,7 @@ public:
if (hotkeyId == 0)
{
// Toggle engine on/off
refresh_process_state();
if (m_active)
{
stop_engine();
}
else
{
start_engine();
}
toggle_engine();
}
else if (hotkeyId == 1)
{
@@ -575,3 +611,4 @@ extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new KeyboardManager();
}