mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-04 18:26:39 +02:00
Fix Keyboard Navigation and Xaml Island focus issues for KBM (dev/build-features) (#2429)
* Added XamlBridge code and implemented keyboard focus navigation for xaml islands * Change global pointer to static
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "EditShortcutsWindow.h"
|
||||
#include "ShortcutControl.h"
|
||||
#include "KeyDropDownControl.h"
|
||||
#include "XamlBridge.h"
|
||||
|
||||
LRESULT CALLBACK EditShortcutsWindowProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
@@ -12,6 +13,8 @@ bool isEditShortcutsWindowRegistrationCompleted = false;
|
||||
// Holds the native window handle of EditShortcuts Window.
|
||||
HWND hwndEditShortcutsNativeWindow = nullptr;
|
||||
std::mutex editShortcutsWindowMutex;
|
||||
// Stores a pointer to the Xaml Bridge object so that it can be accessed from the window procedure
|
||||
static XamlBridge* xamlBridgePtr = nullptr;
|
||||
|
||||
// Function to create the Edit Shortcuts Window
|
||||
void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardManagerState)
|
||||
@@ -61,18 +64,15 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
hwndEditShortcutsNativeWindow = _hWndEditShortcutsWindow;
|
||||
hwndLock.unlock();
|
||||
|
||||
// This DesktopWindowXamlSource is the object that enables a non-UWP desktop application
|
||||
// to host UWP controls in any UI element that is associated with a window handle (HWND).
|
||||
DesktopWindowXamlSource desktopSource;
|
||||
// Get handle to corewindow
|
||||
auto interop = desktopSource.as<IDesktopWindowXamlSourceNative>();
|
||||
// Parent the DesktopWindowXamlSource object to current window
|
||||
check_hresult(interop->AttachToWindow(_hWndEditShortcutsWindow));
|
||||
// Create the xaml bridge object
|
||||
XamlBridge xamlBridge(_hWndEditShortcutsWindow);
|
||||
// DesktopSource needs to be declared before the RelativePanel xamlContainer object to avoid errors
|
||||
winrt::Windows::UI::Xaml::Hosting::DesktopWindowXamlSource desktopSource;
|
||||
// Create the desktop window xaml source object and set its content
|
||||
hWndXamlIslandEditShortcutsWindow = xamlBridge.InitDesktopWindowsXamlSource(desktopSource);
|
||||
|
||||
// Get the new child window's hwnd
|
||||
interop->get_WindowHandle(&hWndXamlIslandEditShortcutsWindow);
|
||||
// Update the xaml island window size becuase initially is 0,0
|
||||
SetWindowPos(hWndXamlIslandEditShortcutsWindow, 0, 0, 0, 400, 400, SWP_SHOWWINDOW);
|
||||
// Set the pointer to the xaml bridge object
|
||||
xamlBridgePtr = &xamlBridge;
|
||||
|
||||
// Header for the window
|
||||
Windows::UI::Xaml::Controls::RelativePanel header;
|
||||
@@ -233,8 +233,8 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
xamlContainer.SetAlignRightWithPanel(scrollViewer, true);
|
||||
xamlContainer.Children().Append(header);
|
||||
xamlContainer.Children().Append(scrollViewer);
|
||||
|
||||
xamlContainer.UpdateLayout();
|
||||
|
||||
desktopSource.Content(xamlContainer);
|
||||
|
||||
////End XAML Island section
|
||||
@@ -245,17 +245,16 @@ void createEditShortcutsWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMa
|
||||
}
|
||||
|
||||
// Message loop:
|
||||
MSG msg = {};
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
desktopSource.Close();
|
||||
xamlBridge.MessageLoop();
|
||||
|
||||
// Reset pointers to nullptr
|
||||
xamlBridgePtr = nullptr;
|
||||
hWndXamlIslandEditShortcutsWindow = nullptr;
|
||||
hwndLock.lock();
|
||||
hwndEditShortcutsNativeWindow = nullptr;
|
||||
|
||||
// Cannot be done in WM_DESTROY because that causes crashes due to fatal app exit
|
||||
xamlBridge.ClearXamlIslands();
|
||||
}
|
||||
|
||||
LRESULT CALLBACK EditShortcutsWindowProc(HWND hWnd, UINT messageCode, WPARAM wParam, LPARAM lParam)
|
||||
@@ -269,10 +268,17 @@ LRESULT CALLBACK EditShortcutsWindowProc(HWND hWnd, UINT messageCode, WPARAM wPa
|
||||
GetClientRect(hWnd, &rcClient);
|
||||
SetWindowPos(hWndXamlIslandEditShortcutsWindow, 0, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom, SWP_SHOWWINDOW);
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
default:
|
||||
// If the Xaml Bridge object exists, then use it's message handler to handle keyboard focus operations
|
||||
if (xamlBridgePtr != nullptr)
|
||||
{
|
||||
return xamlBridgePtr->MessageHandler(messageCode, wParam, lParam);
|
||||
}
|
||||
else if (messageCode == WM_DESTROY)
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hWnd, messageCode, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
@@ -280,6 +286,7 @@ LRESULT CALLBACK EditShortcutsWindowProc(HWND hWnd, UINT messageCode, WPARAM wPa
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Function to check if there is already a window active if yes bring to foreground
|
||||
bool CheckEditShortcutsWindowActive()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
Reference in New Issue
Block a user