From 539b834da94c91607836ee51afd6e55ae4b08423 Mon Sep 17 00:00:00 2001 From: Niels Laute Date: Tue, 13 Oct 2020 21:30:57 +0200 Subject: [PATCH 01/65] Added placeholder labels --- .../Strings/en-us/Resources.resw | 8 +++++++- .../Views/ImageResizerPage.xaml | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw b/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw index 380e19b3c3..774adf76d0 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw +++ b/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw @@ -768,4 +768,10 @@ A reboot may be required for changes to these settings to take effect - + + Example: outlook.exe + + + Example: %1 (%2) + + \ No newline at end of file diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Views/ImageResizerPage.xaml b/src/core/Microsoft.PowerToys.Settings.UI/Views/ImageResizerPage.xaml index 3939cea8ec..180b3e4fd3 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Views/ImageResizerPage.xaml +++ b/src/core/Microsoft.PowerToys.Settings.UI/Views/ImageResizerPage.xaml @@ -253,6 +253,7 @@ From d1372af581d74298447d14ad7116b6f7f4a1a04b Mon Sep 17 00:00:00 2001 From: stefansjfw <57057282+stefansjfw@users.noreply.github.com> Date: Wed, 14 Oct 2020 09:00:50 +0200 Subject: [PATCH 02/65] [FancyZones] Refactor Zone class (#7022) * Pass zoneId on zone creaton and make it const Refactor IZone and Zone - make methods const and remove SetId * Update tests * Fix Grid layout zone order --- src/modules/fancyzones/lib/Zone.cpp | 103 +++++++------ src/modules/fancyzones/lib/Zone.h | 12 +- src/modules/fancyzones/lib/ZoneSet.cpp | 11 +- .../fancyzones/tests/UnitTests/Zone.Spec.cpp | 11 +- .../tests/UnitTests/ZoneSet.Spec.cpp | 138 +++++++++--------- .../tests/UnitTests/ZoneWindow.Spec.cpp | 8 +- 6 files changed, 135 insertions(+), 148 deletions(-) diff --git a/src/modules/fancyzones/lib/Zone.cpp b/src/modules/fancyzones/lib/Zone.cpp index 7b03eb9d72..360677830b 100644 --- a/src/modules/fancyzones/lib/Zone.cpp +++ b/src/modules/fancyzones/lib/Zone.cpp @@ -9,8 +9,6 @@ #include "Settings.h" #include "util.h" -#include "common/monitors.h" - namespace { bool ValidateZoneRect(const RECT& rect) @@ -19,67 +17,68 @@ namespace int height = rect.bottom - rect.top; return rect.left >= 0 && rect.right >= 0 && rect.top >= 0 && rect.bottom >= 0 && width >= 0 && height >= 0; } + + BOOL CALLBACK saveDisplayToVector(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) + { + reinterpret_cast*>(data)->emplace_back(monitor); + return true; + } + + bool allMonitorsHaveSameDpiScaling() + { + std::vector monitors; + EnumDisplayMonitors(NULL, NULL, saveDisplayToVector, reinterpret_cast(&monitors)); + + if (monitors.size() < 2) + { + return true; + } + + UINT firstMonitorDpiX; + UINT firstMonitorDpiY; + + if (S_OK != GetDpiForMonitor(monitors[0], MDT_EFFECTIVE_DPI, &firstMonitorDpiX, &firstMonitorDpiY)) + { + return false; + } + + for (int i = 1; i < monitors.size(); i++) + { + UINT iteratedMonitorDpiX; + UINT iteratedMonitorDpiY; + + if (S_OK != GetDpiForMonitor(monitors[i], MDT_EFFECTIVE_DPI, &iteratedMonitorDpiX, &iteratedMonitorDpiY) || + iteratedMonitorDpiX != firstMonitorDpiX) + { + return false; + } + } + + return true; + } + } struct Zone : winrt::implements { public: - Zone(RECT zoneRect) : - m_zoneRect(zoneRect) + Zone(RECT zoneRect, const size_t zoneId) : + m_zoneRect(zoneRect), + m_id(zoneId) { } - IFACEMETHODIMP_(RECT) GetZoneRect() noexcept { return m_zoneRect; } - IFACEMETHODIMP_(void) SetId(size_t id) noexcept { m_id = id; } - IFACEMETHODIMP_(size_t) Id() noexcept { return m_id; } - IFACEMETHODIMP_(RECT) ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept; + IFACEMETHODIMP_(RECT) GetZoneRect() const noexcept { return m_zoneRect; } + IFACEMETHODIMP_(size_t) Id() const noexcept { return m_id; } + IFACEMETHODIMP_(RECT) ComputeActualZoneRect(HWND window, HWND zoneWindow) const noexcept; private: RECT m_zoneRect{}; - size_t m_id{}; + const size_t m_id{}; std::map m_windows{}; }; -static BOOL CALLBACK saveDisplayToVector(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) -{ - reinterpret_cast*>(data)->emplace_back(monitor); - return true; -} - -bool allMonitorsHaveSameDpiScaling() -{ - std::vector monitors; - EnumDisplayMonitors(NULL, NULL, saveDisplayToVector, reinterpret_cast(&monitors)); - - if (monitors.size() < 2) - { - return true; - } - - UINT firstMonitorDpiX; - UINT firstMonitorDpiY; - - if (S_OK != GetDpiForMonitor(monitors[0], MDT_EFFECTIVE_DPI, &firstMonitorDpiX, &firstMonitorDpiY)) - { - return false; - } - - for (int i = 1; i < monitors.size(); i++) - { - UINT iteratedMonitorDpiX; - UINT iteratedMonitorDpiY; - - if (S_OK != GetDpiForMonitor(monitors[i], MDT_EFFECTIVE_DPI, &iteratedMonitorDpiX, &iteratedMonitorDpiY) || - iteratedMonitorDpiX != firstMonitorDpiX) - { - return false; - } - } - - return true; -} - -RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept +RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) const noexcept { // Take care of 1px border RECT newWindowRect = m_zoneRect; @@ -130,11 +129,11 @@ RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept return newWindowRect; } -winrt::com_ptr MakeZone(const RECT& zoneRect) noexcept +winrt::com_ptr MakeZone(const RECT& zoneRect, const size_t zoneId) noexcept { - if (ValidateZoneRect(zoneRect)) + if (ValidateZoneRect(zoneRect) && zoneId > 0) { - return winrt::make_self(zoneRect); + return winrt::make_self(zoneRect, zoneId); } else { diff --git a/src/modules/fancyzones/lib/Zone.h b/src/modules/fancyzones/lib/Zone.h index 465ae4fc37..0ebab608ba 100644 --- a/src/modules/fancyzones/lib/Zone.h +++ b/src/modules/fancyzones/lib/Zone.h @@ -8,15 +8,11 @@ interface __declspec(uuid("{8228E934-B6EF-402A-9892-15A1441BF8B0}")) IZone : pub /** * @returns Zone coordinates (top-left and bottom-right corner) represented as RECT structure. */ - IFACEMETHOD_(RECT, GetZoneRect)() = 0; - /** - * @param id Zone identifier. - */ - IFACEMETHOD_(void, SetId)(size_t id) = 0; + IFACEMETHOD_(RECT, GetZoneRect)() const = 0; /** * @returns Zone identifier. */ - IFACEMETHOD_(size_t, Id)() = 0; + IFACEMETHOD_(size_t, Id)() const = 0; /** * Compute the coordinates of the rectangle to which a window should be resized. * @@ -25,8 +21,8 @@ interface __declspec(uuid("{8228E934-B6EF-402A-9892-15A1441BF8B0}")) IZone : pub * 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; + IFACEMETHOD_(RECT, ComputeActualZoneRect)(HWND window, HWND zoneWindow) const = 0; }; -winrt::com_ptr MakeZone(const RECT& zoneRect) noexcept; +winrt::com_ptr MakeZone(const RECT& zoneRect, const size_t zoneId) noexcept; diff --git a/src/modules/fancyzones/lib/ZoneSet.cpp b/src/modules/fancyzones/lib/ZoneSet.cpp index 70799c3e71..70c0d93469 100644 --- a/src/modules/fancyzones/lib/ZoneSet.cpp +++ b/src/modules/fancyzones/lib/ZoneSet.cpp @@ -178,9 +178,6 @@ IFACEMETHODIMP ZoneSet::AddZone(winrt::com_ptr zone) noexcept { m_zones.emplace_back(zone); - // Important not to set Id 0 since we store it in the HWND using SetProp. - // SetProp(0) doesn't really work. - zone->SetId(m_zones.size()); return S_OK; } @@ -603,7 +600,7 @@ bool ZoneSet::CalculateFocusLayout(Rect workArea, int zoneCount) noexcept for (int i = 0; i < zoneCount; i++) { - auto zone = MakeZone(focusZoneRect); + auto zone = MakeZone(focusZoneRect, m_zones.size() + 1); if (zone) { AddZone(zone); @@ -660,7 +657,7 @@ bool ZoneSet::CalculateColumnsAndRowsLayout(Rect workArea, FancyZonesDataTypes:: } - auto zone = MakeZone(RECT{ left, top, right, bottom }); + auto zone = MakeZone(RECT{ left, top, right, bottom }, m_zones.size() + 1); if (zone) { AddZone(zone); @@ -780,7 +777,7 @@ bool ZoneSet::CalculateCustomLayout(Rect workArea, int spacing) noexcept DPIAware::Convert(m_config.Monitor, x, y); DPIAware::Convert(m_config.Monitor, width, height); - auto zone = MakeZone(RECT{ x, y, x + width, y + height }); + auto zone = MakeZone(RECT{ x, y, x + width, y + height }, m_zones.size() + 1); if (zone) { AddZone(zone); @@ -863,7 +860,7 @@ bool ZoneSet::CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutI long right = columnInfo[maxCol].End; long bottom = rowInfo[maxRow].End; - auto zone = MakeZone(RECT{ left, top, right, bottom }); + auto zone = MakeZone(RECT{ left, top, right, bottom }, m_zones.size() + 1); if (zone) { AddZone(zone); diff --git a/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp index 6c13af916e..b2b5750429 100644 --- a/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/Zone.Spec.cpp @@ -22,7 +22,7 @@ namespace FancyZonesUnitTests public: TEST_METHOD(TestCreateZone) { - winrt::com_ptr zone = MakeZone(m_zoneRect); + winrt::com_ptr zone = MakeZone(m_zoneRect, 1); Assert::IsNotNull(&zone); CustomAssert::AreEqual(m_zoneRect, zone->GetZoneRect()); } @@ -30,18 +30,17 @@ namespace FancyZonesUnitTests TEST_METHOD(TestCreateZoneZeroRect) { RECT zoneRect{ 0, 0, 0, 0 }; - winrt::com_ptr zone = MakeZone(zoneRect); + winrt::com_ptr zone = MakeZone(zoneRect, 1); Assert::IsNotNull(&zone); CustomAssert::AreEqual(zoneRect, zone->GetZoneRect()); } TEST_METHOD(GetSetId) { - winrt::com_ptr zone = MakeZone(m_zoneRect); + constexpr size_t zoneId = 123; + winrt::com_ptr zone = MakeZone(m_zoneRect, zoneId); - constexpr size_t id = 10; - zone->SetId(id); - Assert::AreEqual(zone->Id(), id); + Assert::AreEqual(zone->Id(), zoneId); } }; } diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp index 1124214118..6eceb9170b 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp @@ -85,40 +85,28 @@ namespace FancyZonesUnitTests TEST_METHOD (AddOne) { - winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }); + constexpr size_t zoneId = 1; + winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }, zoneId); Assert::IsNotNull(zone.get()); m_set->AddZone(zone); auto zones = m_set->GetZones(); Assert::AreEqual((size_t)1, zones.size()); compareZones(zone, zones[0]); - Assert::AreEqual((size_t)1, zones[0]->Id()); - } - - TEST_METHOD (AddManySame) - { - winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }); - Assert::IsNotNull(zone.get()); - for (size_t i = 0; i < 1024; i++) - { - m_set->AddZone(zone); - auto zones = m_set->GetZones(); - Assert::AreEqual(i + 1, zones.size()); - compareZones(zone, zones[i]); - Assert::AreEqual(i + 1, zones[i]->Id()); - } + Assert::AreEqual(zoneId, zones[0]->Id()); } TEST_METHOD (AddManyEqual) { for (size_t i = 0; i < 1024; i++) { - winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }); + size_t zoneId = i + 1; + winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }, zoneId); Assert::IsNotNull(zone.get()); m_set->AddZone(zone); auto zones = m_set->GetZones(); Assert::AreEqual(i + 1, zones.size()); compareZones(zone, zones[i]); - Assert::AreEqual(i + 1, zones[i]->Id()); + Assert::AreEqual(zoneId, zones[i]->Id()); } } @@ -126,41 +114,49 @@ namespace FancyZonesUnitTests { for (size_t i = 0; i < 1024; i++) { + size_t zoneId = i + 1; int left = rand() % 10; int top = rand() % 10; int right = left + 1 + rand() % 100; int bottom = top + 1 + rand() % 100; - winrt::com_ptr zone = MakeZone({ left, top, right, bottom }); + winrt::com_ptr zone = MakeZone({ left, top, right, bottom }, zoneId); Assert::IsNotNull(zone.get()); m_set->AddZone(zone); auto zones = m_set->GetZones(); Assert::AreEqual(i + 1, zones.size()); compareZones(zone, zones[i]); - Assert::AreEqual(i + 1, zones[i]->Id()); + Assert::AreEqual(zoneId, zones[i]->Id()); } } TEST_METHOD (MakeZoneFromZeroRect) { - winrt::com_ptr zone = MakeZone({ 0, 0, 0, 0 }); + winrt::com_ptr zone = MakeZone({ 0, 0, 0, 0 }, 1); Assert::IsNotNull(zone.get()); } + TEST_METHOD (MakeZoneWithInvalidId) + { + constexpr size_t invalidZoneId = 0; + winrt::com_ptr zone = MakeZone({ 0, 0, 0, 0 }, invalidZoneId); + Assert::IsNull(zone.get()); + } + TEST_METHOD (MakeZoneFromInvalidRectWidth) { - winrt::com_ptr zone = MakeZone({ 100, 100, 99, 101 }); + winrt::com_ptr zone = MakeZone({ 100, 100, 99, 101 }, 1); Assert::IsNull(zone.get()); } TEST_METHOD (MakeZoneFromInvalidRectHeight) { - winrt::com_ptr zone = MakeZone({ 100, 100, 101, 99 }); + winrt::com_ptr zone = MakeZone({ 100, 100, 101, 99 }, 1); Assert::IsNull(zone.get()); } TEST_METHOD (MakeZoneFromInvalidRectCoords) { - winrt::com_ptr zone = MakeZone({ -1, -1, -1, -1 }); + winrt::com_ptr zone = MakeZone({ -1, -1, -1, -1 }, 1); Assert::IsNull(zone.get()); } @@ -173,7 +169,7 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneFromPointInner) { const int left = 0, top = 0, right = 100, bottom = 100; - winrt::com_ptr expected = MakeZone({ left, top, right, bottom }); + winrt::com_ptr expected = MakeZone({ left, top, right, bottom }, 1); m_set->AddZone(expected); for (int i = left + 1; i < right; i++) @@ -190,7 +186,7 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneFromPointBorder) { const int left = 0, top = 0, right = 100, bottom = 100; - winrt::com_ptr expected = MakeZone({ left, top, right, bottom }); + winrt::com_ptr expected = MakeZone({ left, top, right, bottom }, 1); m_set->AddZone(expected); for (int i = left; i < right; i++) @@ -224,7 +220,7 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneFromPointOuter) { const int left = 0, top = 0, right = 100, bottom = 100; - winrt::com_ptr zone = MakeZone({ left, top, right, bottom }); + winrt::com_ptr zone = MakeZone({ left, top, right, bottom }, 1); m_set->AddZone(zone); auto actual = m_set->ZonesFromPoint(POINT{ 200, 200 }); @@ -233,13 +229,13 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneFromPointOverlapping) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); m_set->AddZone(zone1); - winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); + winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }, 2); m_set->AddZone(zone2); - winrt::com_ptr zone3 = MakeZone({ 10, 10, 150, 150 }); + winrt::com_ptr zone3 = MakeZone({ 10, 10, 150, 150 }, 3); m_set->AddZone(zone3); - winrt::com_ptr zone4 = MakeZone({ 10, 10, 50, 50 }); + winrt::com_ptr zone4 = MakeZone({ 10, 10, 50, 50 }, 4); m_set->AddZone(zone4); // zone4 is expected because it's the smallest one, and it's considered to be inside @@ -252,13 +248,13 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneFromPointMultizoneHorizontal) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); m_set->AddZone(zone1); - winrt::com_ptr zone2 = MakeZone({ 100, 0, 200, 100 }); + winrt::com_ptr zone2 = MakeZone({ 100, 0, 200, 100 }, 2); m_set->AddZone(zone2); - winrt::com_ptr zone3 = MakeZone({ 0, 100, 100, 200 }); + winrt::com_ptr zone3 = MakeZone({ 0, 100, 100, 200 }, 3); m_set->AddZone(zone3); - winrt::com_ptr zone4 = MakeZone({ 100, 100, 200, 200 }); + winrt::com_ptr zone4 = MakeZone({ 100, 100, 200, 200 }, 4); m_set->AddZone(zone4); auto actual = m_set->ZonesFromPoint(POINT{ 50, 100 }); @@ -269,13 +265,13 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneFromPointMultizoneVertical) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); m_set->AddZone(zone1); - winrt::com_ptr zone2 = MakeZone({ 100, 0, 200, 100 }); + winrt::com_ptr zone2 = MakeZone({ 100, 0, 200, 100 }, 2); m_set->AddZone(zone2); - winrt::com_ptr zone3 = MakeZone({ 0, 100, 100, 200 }); + winrt::com_ptr zone3 = MakeZone({ 0, 100, 100, 200 }, 3); m_set->AddZone(zone3); - winrt::com_ptr zone4 = MakeZone({ 100, 100, 200, 200 }); + winrt::com_ptr zone4 = MakeZone({ 100, 100, 200, 200 }, 4); m_set->AddZone(zone4); auto actual = m_set->ZonesFromPoint(POINT{ 100, 50 }); @@ -286,13 +282,13 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneFromPointMultizoneQuad) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); m_set->AddZone(zone1); - winrt::com_ptr zone2 = MakeZone({ 100, 0, 200, 100 }); + winrt::com_ptr zone2 = MakeZone({ 100, 0, 200, 100 }, 2); m_set->AddZone(zone2); - winrt::com_ptr zone3 = MakeZone({ 0, 100, 100, 200 }); + winrt::com_ptr zone3 = MakeZone({ 0, 100, 100, 200 }, 3); m_set->AddZone(zone3); - winrt::com_ptr zone4 = MakeZone({ 100, 100, 200, 200 }); + winrt::com_ptr zone4 = MakeZone({ 100, 100, 200, 200 }, 4); m_set->AddZone(zone4); auto actual = m_set->ZonesFromPoint(POINT{ 100, 100 }); @@ -305,7 +301,7 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneIndexFromWindowUnknown) { - winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }, 1); HWND window = Mocks::Window(); HWND zoneWindow = Mocks::Window(); m_set->AddZone(zone); @@ -317,7 +313,7 @@ namespace FancyZonesUnitTests TEST_METHOD (ZoneIndexFromWindowNull) { - winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone = MakeZone({ 0, 0, 100, 100 }, 1); HWND window = Mocks::Window(); HWND zoneWindow = Mocks::Window(); m_set->AddZone(zone); @@ -329,9 +325,9 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveWindowIntoZoneByIndex) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone3 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 0, 0, 100, 100 }, 2); + winrt::com_ptr zone3 = MakeZone({ 0, 0, 100, 100 }, 3); m_set->AddZone(zone1); m_set->AddZone(zone2); m_set->AddZone(zone3); @@ -349,9 +345,9 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveWindowIntoZoneByIndexWithInvalidIndex) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone3 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 0, 0, 100, 100 }, 2); + winrt::com_ptr zone3 = MakeZone({ 0, 0, 100, 100 }, 3); m_set->AddZone(zone1); m_set->AddZone(zone2); m_set->AddZone(zone3); @@ -364,9 +360,9 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveWindowIntoZoneByIndexSeveralTimesSameWindow) { // Add a couple of zones. - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 1, 1, 101, 101 }); - winrt::com_ptr zone3 = MakeZone({ 2, 2, 102, 102 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 1, 1, 101, 101 }, 2); + winrt::com_ptr zone3 = MakeZone({ 2, 2, 102, 102 }, 3); m_set->AddZone(zone1); m_set->AddZone(zone2); m_set->AddZone(zone3); @@ -385,9 +381,9 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveWindowIntoZoneByIndexSeveralTimesSameIndex) { // Add a couple of zones. - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 1, 1, 101, 101 }); - winrt::com_ptr zone3 = MakeZone({ 2, 2, 102, 102 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 1, 1, 101, 101 }, 2); + winrt::com_ptr zone3 = MakeZone({ 2, 2, 102, 102 }, 3); m_set->AddZone(zone1); m_set->AddZone(zone2); m_set->AddZone(zone3); @@ -406,7 +402,7 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveWindowIntoZoneByPointOuterPoint) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); m_set->AddZone(zone1); auto window = Mocks::Window(); @@ -417,7 +413,7 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveWindowIntoZoneByPointInnerPoint) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); m_set->AddZone(zone1); auto window = Mocks::Window(); @@ -428,8 +424,8 @@ namespace FancyZonesUnitTests TEST_METHOD (MoveWindowIntoZoneByPointInnerPointOverlappingZones) { - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }, 2); m_set->AddZone(zone1); m_set->AddZone(zone2); @@ -444,8 +440,8 @@ namespace FancyZonesUnitTests const auto window = Mocks::Window(); const auto zoneWindow = Mocks::Window(); - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }, 2); m_set->AddZone(zone1); m_set->AddZone(zone2); @@ -462,8 +458,8 @@ namespace FancyZonesUnitTests const auto window = Mocks::Window(); const auto zoneWindow = Mocks::Window(); - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }, 2); m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1); @@ -480,9 +476,9 @@ namespace FancyZonesUnitTests const auto window = Mocks::Window(); const auto zoneWindow = Mocks::Window(); - winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }); - winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }); - winrt::com_ptr zone3 = MakeZone({ 20, 20, 80, 80 }); + winrt::com_ptr zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + winrt::com_ptr zone2 = MakeZone({ 10, 10, 90, 90 }, 2); + winrt::com_ptr zone3 = MakeZone({ 20, 20, 80, 80 }, 3); m_set->AddZone(zone1); m_set->AddZone(zone2); @@ -510,9 +506,9 @@ namespace FancyZonesUnitTests m_set = MakeZoneSet(config); // Add a couple of zones. - m_zone1 = MakeZone({ 0, 0, 100, 100 }); - m_zone2 = MakeZone({ 0, 0, 100, 100 }); - m_zone3 = MakeZone({ 0, 0, 100, 100 }); + m_zone1 = MakeZone({ 0, 0, 100, 100 }, 1); + m_zone2 = MakeZone({ 0, 0, 100, 100 }, 2); + m_zone3 = MakeZone({ 0, 0, 100, 100 }, 3); m_set->AddZone(m_zone1); m_set->AddZone(m_zone2); m_set->AddZone(m_zone3); diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp index c02685b6e1..73c3a46c27 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneWindow.Spec.cpp @@ -657,7 +657,7 @@ namespace FancyZonesUnitTests Assert::IsNotNull(zoneWindow->ActiveZoneSet()); auto window = Mocks::WindowCreate(m_hInst); - auto zone = MakeZone(RECT{ 0, 0, 100, 100 }); + auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1); zoneWindow->ActiveZoneSet()->AddZone(zone); zoneWindow->SaveWindowProcessToZoneIndex(window); @@ -684,7 +684,7 @@ namespace FancyZonesUnitTests Assert::IsTrue(std::vector{ 0 } == appHistoryArray1[0].zoneIndexSet); // add zone without window - const auto zone = MakeZone(RECT{ 0, 0, 100, 100 }); + const auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1); zoneWindow->ActiveZoneSet()->AddZone(zone); zoneWindow->SaveWindowProcessToZoneIndex(window); @@ -704,7 +704,7 @@ namespace FancyZonesUnitTests const auto deviceId = zoneWindow->UniqueId(); const auto zoneSetId = zoneWindow->ActiveZoneSet()->Id(); - auto zone = MakeZone(RECT{ 0, 0, 100, 100 }); + auto zone = MakeZone(RECT{ 0, 0, 100, 100 }, 1); zoneWindow->ActiveZoneSet()->AddZone(zone); zoneWindow->MoveWindowIntoZoneByIndex(window, 0); @@ -737,7 +737,7 @@ namespace FancyZonesUnitTests SetWindowPos(window, nullptr, 150, 150, originalWidth, originalHeight, SWP_SHOWWINDOW); SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_SIZEBOX); - auto zone = MakeZone(RECT{ 50, 50, 300, 300 }); + auto zone = MakeZone(RECT{ 50, 50, 300, 300 }, 1); zoneWindow->ActiveZoneSet()->AddZone(zone); zoneWindow->MoveWindowIntoZoneByDirectionAndIndex(window, VK_LEFT, true); From 944e605f064cad2861d54e40f44d688477d1987f Mon Sep 17 00:00:00 2001 From: vldmr11080 <57061786+vldmr11080@users.noreply.github.com> Date: Wed, 14 Oct 2020 17:42:47 +0200 Subject: [PATCH 03/65] Allow negative spacing between zones up to -10 (#7284) --- .../fancyzones/editor/FancyZonesEditor/Models/Settings.cs | 4 +++- src/modules/fancyzones/lib/Zone.cpp | 6 +++++- src/modules/fancyzones/lib/Zone.h | 5 +++++ src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp | 7 ++++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs b/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs index c215a11254..87a0af5015 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs +++ b/src/modules/fancyzones/editor/FancyZonesEditor/Models/Settings.cs @@ -54,6 +54,8 @@ namespace FancyZonesEditor public const ushort _blankCustomModelId = 0xFFFA; public const ushort _lastDefinedId = _blankCustomModelId; + private const int MaxNegativeSpacing = -10; + // Localizable strings private const string ErrorMessageBoxTitle = "FancyZones Editor Error"; private const string ErrorParsingDeviceInfo = "Error parsing device info data."; @@ -209,7 +211,7 @@ namespace FancyZonesEditor { if (_spacing != value) { - _spacing = Math.Max(0, value); + _spacing = Math.Max(MaxNegativeSpacing, value); FirePropertyChanged(); } } diff --git a/src/modules/fancyzones/lib/Zone.cpp b/src/modules/fancyzones/lib/Zone.cpp index 360677830b..0e1e428d30 100644 --- a/src/modules/fancyzones/lib/Zone.cpp +++ b/src/modules/fancyzones/lib/Zone.cpp @@ -15,7 +15,11 @@ namespace { int width = rect.right - rect.left; int height = rect.bottom - rect.top; - return rect.left >= 0 && rect.right >= 0 && rect.top >= 0 && rect.bottom >= 0 && width >= 0 && height >= 0; + return rect.left >= ZoneConstants::MAX_NEGATIVE_SPACING && + rect.right >= ZoneConstants::MAX_NEGATIVE_SPACING && + rect.top >= ZoneConstants::MAX_NEGATIVE_SPACING && + rect.bottom >= ZoneConstants::MAX_NEGATIVE_SPACING && + width >= 0 && height >= 0; } BOOL CALLBACK saveDisplayToVector(HMONITOR monitor, HDC hdc, LPRECT rect, LPARAM data) diff --git a/src/modules/fancyzones/lib/Zone.h b/src/modules/fancyzones/lib/Zone.h index 0ebab608ba..77b69abaa7 100644 --- a/src/modules/fancyzones/lib/Zone.h +++ b/src/modules/fancyzones/lib/Zone.h @@ -1,5 +1,10 @@ #pragma once +namespace ZoneConstants +{ + constexpr int MAX_NEGATIVE_SPACING = -10; +} + /** * Class representing one zone inside applied zone layout, which is basically wrapper around rectangle structure. */ diff --git a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp index 6eceb9170b..93aabe4d72 100644 --- a/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/ZoneSet.Spec.cpp @@ -156,7 +156,8 @@ namespace FancyZonesUnitTests TEST_METHOD (MakeZoneFromInvalidRectCoords) { - winrt::com_ptr zone = MakeZone({ -1, -1, -1, -1 }, 1); + const int invalid = ZoneConstants::MAX_NEGATIVE_SPACING - 1; + winrt::com_ptr zone = MakeZone({ invalid, invalid, invalid, invalid }, 1); Assert::IsNull(zone.get()); } @@ -846,9 +847,9 @@ namespace FancyZonesUnitTests } } - TEST_METHOD (NegativeSpacing) + TEST_METHOD (LargeNegativeSpacing) { - const int spacing = -1; + const int spacing = ZoneConstants::MAX_NEGATIVE_SPACING - 1; const int zoneCount = 10; for (int type = static_cast(ZoneSetLayoutType::Focus); type < static_cast(ZoneSetLayoutType::Custom); type++) From 70bc9672197b3dd69b5d7fa466b42f65935e31cc Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Wed, 14 Oct 2020 09:03:45 -0700 Subject: [PATCH 04/65] Updated double quotes logic (#7268) --- src/modules/keyboardmanager/dll/Resources.resx | 4 ++-- .../cs/src/modules/keyboardmanager/dll/Resources.resx.lcl | 4 ++-- .../de/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../es/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../fr/src/modules/keyboardmanager/dll/Resources.resx.lcl | 4 ++-- .../hu/src/modules/keyboardmanager/dll/Resources.resx.lcl | 4 ++-- .../it/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../ja/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../ko/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../nl/src/modules/keyboardmanager/dll/Resources.resx.lcl | 4 ++-- .../pl/src/modules/keyboardmanager/dll/Resources.resx.lcl | 4 ++-- .../src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../src/modules/keyboardmanager/dll/Resources.resx.lcl | 4 ++-- .../ru/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../sv/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../tr/src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- .../src/modules/keyboardmanager/dll/Resources.resx.lcl | 4 ++-- .../src/modules/keyboardmanager/dll/Resources.resx.lcl | 8 ++++---- tools/build/convert-resx-to-rc.ps1 | 4 ++-- 19 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/modules/keyboardmanager/dll/Resources.resx b/src/modules/keyboardmanager/dll/Resources.resx index a226598fa0..7bb610b383 100644 --- a/src/modules/keyboardmanager/dll/Resources.resx +++ b/src/modules/keyboardmanager/dll/Resources.resx @@ -178,13 +178,13 @@ Select the key you want to change (Key) and then the key or shortcut you want it to become (Mapped To). - For example, if you want to press A and get ""Ctrl+C"", key ""A"" would be your ""Key"" column and the shortcut ""Ctrl+C"" would be your ""Mapped To"" column. + For example, if you want to press A and get "Ctrl+C", key "A" would be your "Key" column and the shortcut "Ctrl+C" would be your "Mapped To" column. Select the shortcut you want to change (Shortcut) and then the key or shortcut you want it to invoke (Mapped To). - For example, if you want to press ""Ctrl+C"" and get ""Alt"" only on Microsoft Edge, ""Ctrl+C"" would be your ""Shortcut"" column, the key ""Alt"" would be your ""Mapped To"" column, and ""MSEdge"" would be your ""Target App"" column. If no target app is entered, it will apply globally. The name must be the process name and not the app name. + For example, if you want to press "Ctrl+C" and get "Alt" only on Microsoft Edge, "Ctrl+C" would be your "Shortcut" column, the key "Alt" would be your "Mapped To" column, and "MSEdge" would be your "Target App" column. If no target app is entered, it will apply globally. The name must be the process name and not the app name. Type diff --git a/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl index d67e2e27c1..0a0a06ad4b 100644 --- a/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,7 +102,7 @@ - + @@ -174,7 +174,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl index fa00800342..ee32c9c112 100644 --- a/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl index a462da484b..6e0943237a 100644 --- a/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl index a4919280fe..6ce4a30903 100644 --- a/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,7 +102,7 @@ - + @@ -174,7 +174,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl index 3d8b0042b4..af0471f9e3 100644 --- a/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,7 +102,7 @@ - + @@ -174,7 +174,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl index bebf3856c5..26ceee6b61 100644 --- a/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl index 8e63090d16..8e07cb2ea9 100644 --- a/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl index 7292739578..47d4174e99 100644 --- a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl index adfb47f061..5a8d9fa496 100644 --- a/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,7 +102,7 @@ - + @@ -174,7 +174,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl index a9c2712ac1..386a4cfa1c 100644 --- a/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,7 +102,7 @@ - + @@ -174,7 +174,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl index 88091d18c5..bd687d2d07 100644 --- a/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl index 2b4f7a703f..f165e5e2fd 100644 --- a/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,7 +102,7 @@ - + @@ -174,7 +174,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl index edcec90002..491cecb7f9 100644 --- a/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl index 797e9b2c96..8106738860 100644 --- a/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl index 7f7387118f..975c423038 100644 --- a/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl index 8d88b55487..c3b4d28a86 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,7 +102,7 @@ - + @@ -174,7 +174,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl index cb208596f2..b1bb91cb98 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -102,9 +102,9 @@ - + - + @@ -174,9 +174,9 @@ - + - + diff --git a/tools/build/convert-resx-to-rc.ps1 b/tools/build/convert-resx-to-rc.ps1 index 071b80907f..6a6fab526b 100644 --- a/tools/build/convert-resx-to-rc.ps1 +++ b/tools/build/convert-resx-to-rc.ps1 @@ -110,8 +110,8 @@ Foreach-Object { $content = $line -split "=", 2 $culture = [System.Globalization.CultureInfo]::GetCultureInfo('en-US') - # Each resource is named as IDS_ResxResourceName, in uppercase - $lineInRCFormat = "IDS_" + $content[0].ToUpper($culture) + " L`"" + $content[1] + "`"" + # Each resource is named as IDS_ResxResourceName, in uppercase. Escape occurrences of double quotes in the string + $lineInRCFormat = "IDS_" + $content[0].ToUpper($culture) + " L`"" + $content[1].Replace("`"", "`"`"") + "`"" $newLinesForRCFile = $newLinesForRCFile + "`r`n " + $lineInRCFormat # Resource header file needs to be updated only for one language From 184b6c5bd027915105b530c0b9b8863dde24e2bd Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 14 Oct 2020 10:42:15 -0700 Subject: [PATCH 05/65] LEGO: check in for master to temporary branch. (#7265) --- .../Strings/en-us/Resources.resw.lcl | 3 +++ .../editor/FancyZonesEditor/Properties/Resources.resx.lcl | 6 ++++++ .../Microsoft.Plugin.Folder/Properties/Resources.resx.lcl | 4 ++-- .../src/modules/previewpane/powerpreview/Resources.resx.lcl | 6 ++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index c084da315a..c19e754145 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -508,6 +508,9 @@ + + + diff --git a/src/modules/fancyzones/editor/FancyZonesEditor/loc/zh-Hant/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx.lcl b/src/modules/fancyzones/editor/FancyZonesEditor/loc/zh-Hant/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx.lcl index 60b8f184e1..d05dd50aca 100644 --- a/src/modules/fancyzones/editor/FancyZonesEditor/loc/zh-Hant/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx.lcl +++ b/src/modules/fancyzones/editor/FancyZonesEditor/loc/zh-Hant/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx.lcl @@ -49,12 +49,18 @@ + + + + + + diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/zh-Hant/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/zh-Hant/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl index b45933394e..60c3f30c2b 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/zh-Hant/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/zh-Hant/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl @@ -58,8 +58,8 @@ - - + + diff --git a/src/modules/previewpane/powerpreview/loc/zh-Hant/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/zh-Hant/src/modules/previewpane/powerpreview/Resources.resx.lcl index a9e4db299e..15c5a40313 100644 --- a/src/modules/previewpane/powerpreview/loc/zh-Hant/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/zh-Hant/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -40,12 +40,18 @@ + + + + + + From eeeae654931a3f361cf7d40d094b88efa3e44148 Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 14 Oct 2020 10:42:43 -0700 Subject: [PATCH 06/65] LEGO: check in for master to temporary branch. (#7276) --- .../Strings/en-us/Resources.resw.lcl | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index f235aee13a..d465f998fa 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -460,6 +460,15 @@ + + + + + + + + + @@ -496,6 +505,24 @@ + + + + + + + + + + + + + + + + + + From 598729f84c9e46ca954078207893a216b08817c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Sto=C5=A1i=C4=87?= Date: Thu, 15 Oct 2020 17:08:55 +0200 Subject: [PATCH 07/65] Remove m_drawHints, fix duplicate zone drawing (#7300) --- src/modules/fancyzones/lib/Settings.h | 2 +- src/modules/fancyzones/lib/ZoneWindow.cpp | 13 +++---------- src/modules/fancyzones/lib/ZoneWindowDrawing.cpp | 9 ++------- src/modules/fancyzones/lib/ZoneWindowDrawing.h | 3 +-- 4 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/modules/fancyzones/lib/Settings.h b/src/modules/fancyzones/lib/Settings.h index fa0632bba5..f5a7b173c0 100644 --- a/src/modules/fancyzones/lib/Settings.h +++ b/src/modules/fancyzones/lib/Settings.h @@ -30,7 +30,7 @@ struct Settings bool showZonesOnAllMonitors = false; bool spanZonesAcrossMonitors = false; bool makeDraggedWindowTransparent = true; - std::wstring zoneColor = L"#F5FCFF"; + std::wstring zoneColor = L"#AACDFF"; std::wstring zoneBorderColor = L"#FFFFFF"; std::wstring zoneHighlightColor = L"#008CFF"; int zoneHighlightOpacity = 50; diff --git a/src/modules/fancyzones/lib/ZoneWindow.cpp b/src/modules/fancyzones/lib/ZoneWindow.cpp index a5b3566cfa..abdad6e7bf 100644 --- a/src/modules/fancyzones/lib/ZoneWindow.cpp +++ b/src/modules/fancyzones/lib/ZoneWindow.cpp @@ -71,8 +71,7 @@ namespace ZoneWindowUtils int hostZoneHighlightOpacity, std::vector> zones, std::vector highlightZone, - bool flashMode, - bool drawHints) + bool flashMode) { PAINTSTRUCT ps; HDC oldHdc = hdc; @@ -99,8 +98,7 @@ namespace ZoneWindowUtils hostZoneHighlightOpacity, zones, highlightZone, - flashMode, - drawHints); + flashMode); } EndBufferedPaint(bufferedPaint, TRUE); @@ -170,7 +168,6 @@ private: std::wstring m_uniqueId; // Parsed deviceId + resolution + virtualDesktopId wil::unique_hwnd m_window{}; // Hidden tool window used to represent current monitor desktop work area. HWND m_windowMoveSize{}; - bool m_drawHints{}; bool m_flashMode{}; winrt::com_ptr m_activeZoneSet; std::vector> m_zoneSets; @@ -266,7 +263,6 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window) noexcept { m_windowMoveSize = window; - m_drawHints = true; m_highlightZone = {}; m_initialHighlightZone = {}; ShowZoneWindow(); @@ -477,7 +473,6 @@ ZoneWindow::HideZoneWindow() noexcept ShowWindow(m_window.get(), SW_HIDE); m_keyLast = 0; m_windowMoveSize = nullptr; - m_drawHints = false; m_highlightZone = {}; } } @@ -629,7 +624,6 @@ void ZoneWindow::OnPaint(HDC hdc) noexcept std::vector> zones{}; std::vector highlightZone = m_highlightZone; bool flashMode = m_flashMode; - bool drawHints = m_drawHints; if (hasActiveZoneSet) { @@ -651,8 +645,7 @@ void ZoneWindow::OnPaint(HDC hdc) noexcept hostZoneHighlightOpacity, zones, highlightZone, - flashMode, - drawHints); + flashMode); } }; if (m_animating) diff --git a/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp b/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp index 2730bda905..2e3275b8d4 100644 --- a/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp +++ b/src/modules/fancyzones/lib/ZoneWindowDrawing.cpp @@ -114,11 +114,9 @@ namespace ZoneWindowDrawing int zoneOpacity, const std::vector>& zones, const std::vector& highlightZones, - bool flashMode, - bool drawHints) noexcept + bool flashMode) noexcept { // { fillAlpha, fill, borderAlpha, border, thickness } - ColorSetting const colorHints{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 255, RGB(104, 118, 138), -2 }; ColorSetting colorViewer{ OpacitySettingToAlpha(zoneOpacity), 0, 255, RGB(40, 50, 60), -2 }; ColorSetting colorHighlight{ OpacitySettingToAlpha(zoneOpacity), 0, 255, 0, -2 }; ColorSetting const colorFlash{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 }; @@ -145,10 +143,7 @@ namespace ZoneWindowDrawing { DrawZone(hdc, colorFlash, zone, zones, flashMode); } - else if (drawHints) - { - DrawZone(hdc, colorHints, zone, zones, flashMode); - } + else { colorViewer.fill = zoneColor; colorViewer.border = zoneBorderColor; diff --git a/src/modules/fancyzones/lib/ZoneWindowDrawing.h b/src/modules/fancyzones/lib/ZoneWindowDrawing.h index 14bb0f5818..3b0e31fefc 100644 --- a/src/modules/fancyzones/lib/ZoneWindowDrawing.h +++ b/src/modules/fancyzones/lib/ZoneWindowDrawing.h @@ -26,6 +26,5 @@ namespace ZoneWindowDrawing int zoneOpacity, const std::vector>& zones, const std::vector& highlightZones, - bool flashMode, - bool drawHints) noexcept; + bool flashMode) noexcept; } From 438169e64f8323308251d3290278135c19ca5fc2 Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Thu, 15 Oct 2020 08:53:43 -0700 Subject: [PATCH 08/65] [KBM] Fix shortcut remap scenarios that should/should not open start menu (#7171) * Modify shortcut to key code more similar to shortcut to shortcuts code. Manually tested cases * Fixed existing tests and fixed scenario with other keys pressed and action key released * Fixed dummy key usage * Updated comments and removed dummy key usage in key to shortcut remaps * Added tests for disable and shortcut to key. Pending tests for dummy key * Added test cases for each usage of dummy key event * Remove redundant check --- .../keyboardmanager/common/RemapShortcut.h | 6 +- .../dll/KeyboardEventHandlers.cpp | 226 ++++--- .../test/OSLevelShortcutRemappingTests.cpp | 638 +++++++++++++++++- 3 files changed, 766 insertions(+), 104 deletions(-) diff --git a/src/modules/keyboardmanager/common/RemapShortcut.h b/src/modules/keyboardmanager/common/RemapShortcut.h index a22ef83b45..b5bb283b19 100644 --- a/src/modules/keyboardmanager/common/RemapShortcut.h +++ b/src/modules/keyboardmanager/common/RemapShortcut.h @@ -9,14 +9,16 @@ public: KeyShortcutUnion targetShortcut; bool isShortcutInvoked; ModifierKey winKeyInvoked; + // This bool value is only required for remapping shortcuts to Disable + bool isOriginalActionKeyPressed; RemapShortcut(const KeyShortcutUnion& sc) : - targetShortcut(sc), isShortcutInvoked(false), winKeyInvoked(ModifierKey::Disabled) + targetShortcut(sc), isShortcutInvoked(false), winKeyInvoked(ModifierKey::Disabled), isOriginalActionKeyPressed(false) { } RemapShortcut() : - targetShortcut(Shortcut()), isShortcutInvoked(false), winKeyInvoked(ModifierKey::Disabled) + targetShortcut(Shortcut()), isShortcutInvoked(false), winKeyInvoked(ModifierKey::Disabled), isOriginalActionKeyPressed(false) { } diff --git a/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp b/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp index 013d77860f..ca33018b8a 100644 --- a/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp +++ b/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp @@ -40,7 +40,7 @@ namespace KeyboardEventHandlers } else { - key_count = std::get(it->second).Size() + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE; + key_count = std::get(it->second).Size(); } LPINPUT keyEventList = new INPUT[size_t(key_count)](); memset(keyEventList, 0, sizeof(keyEventList)); @@ -82,11 +82,11 @@ namespace KeyboardEventHandlers KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)targetShortcut.GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG); i++; KeyboardManagerHelper::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG); - KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG); + // Dummy key is not required here since SetModifierKeyEvents will only add key-up events for the modifiers here, and the action key key-up is already sent before it } else { - KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG); + // Dummy key is not required here since SetModifierKeyEvents will only add key-down events for the modifiers here, and the action key key-down is already sent after it KeyboardManagerHelper::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG); KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)targetShortcut.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG); i++; @@ -248,7 +248,7 @@ namespace KeyboardEventHandlers keyEventList = new INPUT[key_count](); memset(keyEventList, 0, sizeof(keyEventList)); - // Send dummy key + // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->Ctrl+V, press Win+A, since Win will be released here we need to send a dummy event before it int i = 0; KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); @@ -279,12 +279,14 @@ namespace KeyboardEventHandlers if (std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED) { key_count--; + // Since the original shortcut's action key is pressed, set it to true + it->second.isOriginalActionKeyPressed = true; } keyEventList = new INPUT[key_count](); memset(keyEventList, 0, sizeof(keyEventList)); - // Send dummy key + // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->V, press Win+A, since Win will be released here we need to send a dummy event before it int i = 0; KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); @@ -345,18 +347,18 @@ namespace KeyboardEventHandlers // if the released key is present in both shortcuts' modifiers (i.e part of the common modifiers) if (std::get(it->second.targetShortcut).CheckWinKey(data->lParam->vkCode) || std::get(it->second.targetShortcut).CheckCtrlKey(data->lParam->vkCode) || std::get(it->second.targetShortcut).CheckAltKey(data->lParam->vkCode) || std::get(it->second.targetShortcut).CheckShiftKey(data->lParam->vkCode)) { - // release all new shortcut keys and the common released modifier except the other common modifiers, and add all original shortcut modifiers except the common ones - key_count = (dest_size - commonKeys) + (src_size - 1 - commonKeys); + // release all new shortcut keys and the common released modifier except the other common modifiers, and add all original shortcut modifiers except the common ones, and dummy key + key_count = (dest_size - commonKeys) + (src_size - 1 - commonKeys) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE; } else { - // release all new shortcut keys except the common modifiers and add all original shortcut modifiers except the common ones - key_count = (dest_size - 1) + (src_size - 2) - (2 * (size_t)commonKeys); + // release all new shortcut keys except the common modifiers and add all original shortcut modifiers except the common ones, and dummy key + key_count = (dest_size - 1) + (src_size - 2) - (2 * (size_t)commonKeys) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE; } // If the target shortcut's action key is pressed, then it should be released bool isActionKeyPressed = false; - if (GetAsyncKeyState(std::get(it->second.targetShortcut).GetActionKey()) & 0x8000) + if (ii.GetVirtualKeyState((std::get(it->second.targetShortcut).GetActionKey()))) { isActionKeyPressed = true; key_count += 1; @@ -376,11 +378,14 @@ namespace KeyboardEventHandlers // Set original shortcut key down state except the action key and the released modifier since the original action key may or may not be held down. If it is held down it will generate it's own key message KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get(it->second.targetShortcut), data->lParam->vkCode); + + // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+Ctrl+A->Ctrl+V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it + KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); } else { - // 1 for releasing new key and original shortcut modifiers except the one released - key_count = dest_size + src_size - 2; + // 1 for releasing new key and original shortcut modifiers except the one released and dummy key + key_count = dest_size + src_size - 2 + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE; // Do not send Disable key up if (std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED) { @@ -400,10 +405,15 @@ namespace KeyboardEventHandlers // Set original shortcut key down state except the action key and the released modifier since the original action key may or may not be held down. If it is held down it will generate it's own key message KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, Shortcut(), data->lParam->vkCode); + + // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+Ctrl+A->V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it + KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); } + // Reset the remap state it->second.isShortcutInvoked = false; it->second.winKeyInvoked = ModifierKey::Disabled; + it->second.isOriginalActionKeyPressed = false; // If app specific shortcut has finished invoking, reset the target application if (activatedApp) { @@ -428,6 +438,8 @@ namespace KeyboardEventHandlers // In case of mapping to disable do not send anything if (!remapToShortcut && std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED) { + // Since the original shortcut's action key is pressed, set it to true + it->second.isOriginalActionKeyPressed = true; return 1; } @@ -443,13 +455,12 @@ namespace KeyboardEventHandlers KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut)), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); } - it->second.isShortcutInvoked = true; UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT)); delete[] keyEventList; return 1; } - // Case 3: If the action key is released from the original shortcut keep modifiers of the new shortcut until some other key event which doesn't apply to the original shortcut + // Case 3: If the action key is released from the original shortcut, keep modifiers of the new shortcut until some other key event which doesn't apply to the original shortcut if (data->lParam->vkCode == it->first.GetActionKey() && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)) { size_t key_count = 1; @@ -459,44 +470,54 @@ namespace KeyboardEventHandlers keyEventList = new INPUT[key_count](); memset(keyEventList, 0, sizeof(keyEventList)); KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)std::get(it->second.targetShortcut).GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); - it->second.isShortcutInvoked = true; } - - // for remap from shortcut to key, when the action key is released, the remap invoke is completed so revert to original shortcut state + // If remapped to disable, do nothing and suppress the key event + else if (std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED) + { + // Since the original shortcut's action key is released, set it to false + it->second.isOriginalActionKeyPressed = false; + return 1; + } else { - // 1 for releasing new key and original shortcut modifiers, and dummy key - key_count = dest_size + (src_size - 1) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE; - // Do not send Disable key - if (std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED) + // Check if the keyboard state is clear apart from the target remap key (by creating a temp Shortcut object with the target key) + bool isKeyboardStateClear = Shortcut(std::vector({ KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut)) })).IsKeyboardStateClearExceptShortcut(ii); + // If the keyboard state is clear, we release the target key but do not reset the remap state + if (isKeyboardStateClear) { - key_count--; + keyEventList = new INPUT[key_count](); + memset(keyEventList, 0, sizeof(keyEventList)); + KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); } - - keyEventList = new INPUT[key_count](); - memset(keyEventList, 0, sizeof(keyEventList)); - - // Release new key state - int i = 0; - // Do not send Disable key - if (std::get(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED) + // If any other key is pressed, then the keyboard state must be reverted back to the physical keys. This is to take cases like Ctrl+A->D remap and user presses B+Ctrl+A and releases A, or Ctrl+A+B and releases A + else { + // 1 for releasing new key and original shortcut modifiers, and dummy key + key_count = dest_size + (src_size - 1) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE; + + keyEventList = new INPUT[key_count](); + memset(keyEventList, 0, sizeof(keyEventList)); + + // Release new key state + int i = 0; KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); i++; - } - // Set original shortcut key down state except the action key and the released modifier - KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); + // Set original shortcut key down state except the action key and the released modifier + KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); - // Send dummy key - KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); + // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->V, press Shift+Win+A and release A, since Win will be pressed here we need to send a dummy event after it + KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); - it->second.isShortcutInvoked = false; - it->second.winKeyInvoked = ModifierKey::Disabled; - // If app specific shortcut has finished invoking, reset the target application - if (activatedApp) - { - keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp); + // Reset the remap state + it->second.isShortcutInvoked = false; + it->second.winKeyInvoked = ModifierKey::Disabled; + it->second.isOriginalActionKeyPressed = false; + // If app specific shortcut has finished invoking, reset the target application + if (activatedApp != KeyboardManagerConstants::NoActivatedApp) + { + keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp); + } } } @@ -516,13 +537,17 @@ namespace KeyboardEventHandlers if (std::get(it->second.targetShortcut).GetCtrlKey() == NULL && std::get(it->second.targetShortcut).GetAltKey() == NULL && std::get(it->second.targetShortcut).GetShiftKey() == NULL) { ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, std::get(it->second.targetShortcut).GetActionKey()); - return 1; } } - else if (std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED) + // If it is not remapped to Disable + else if (std::get(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED) { - return 1; + // Modifier state reset might be required for this key depending on the target key - ex: Ctrl+A -> Caps + ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut))); } + + // Suppress the modifier as it is already physically pressed + return 1; } // Case 5: If any key apart from the action key or a modifier key in the original shortcut is pressed then revert the keyboard state to just the original modifiers being held down along with the current key press @@ -542,11 +567,11 @@ namespace KeyboardEventHandlers // If the original shortcut is a subset of the new shortcut if (commonKeys == src_size - 1) { - key_count = dest_size - commonKeys + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE; + key_count = dest_size - commonKeys; // If the target shortcut's action key is pressed, then it should be released and original shortcut's action key should be set bool isActionKeyPressed = false; - if (GetAsyncKeyState(std::get(it->second.targetShortcut).GetActionKey()) & 0x8000) + if (ii.GetVirtualKeyState((std::get(it->second.targetShortcut).GetActionKey()))) { isActionKeyPressed = true; key_count += 2; @@ -574,17 +599,16 @@ namespace KeyboardEventHandlers KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0); i++; - // Send dummy key since the current key pressed could be a modifier - KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); + // Do not send a dummy key as we want the current key press to behave as normal i.e. it can do press+release functionality if required. Required to allow a shortcut to Win key remap invoked directly after shortcut to shortcut is released to open start menu } else { - // Key up for all new shortcut keys, key down for original shortcut modifiers, dummy key and current key press but common keys aren't repeated - key_count = (dest_size) + (src_size - 1) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE - (2 * (size_t)commonKeys); + // Key up for all new shortcut keys, key down for original shortcut modifiers and current key press but common keys aren't repeated + key_count = (dest_size) + (src_size - 1) - (2 * (size_t)commonKeys); // If the target shortcut's action key is pressed, then it should be released and original shortcut's action key should be set bool isActionKeyPressed = false; - if (GetAsyncKeyState(std::get(it->second.targetShortcut).GetActionKey()) & 0x8000) + if (ii.GetVirtualKeyState((std::get(it->second.targetShortcut).GetActionKey()))) { isActionKeyPressed = true; key_count += 2; @@ -616,12 +640,13 @@ namespace KeyboardEventHandlers KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0); i++; - // Send dummy key - KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); + // Do not send a dummy key as we want the current key press to behave as normal i.e. it can do press+release functionality if required. Required to allow a shortcut to Win key remap invoked directly after shortcut to shortcut is released to open start menu } + // Reset the remap state it->second.isShortcutInvoked = false; it->second.winKeyInvoked = ModifierKey::Disabled; + it->second.isOriginalActionKeyPressed = false; // If app specific shortcut has finished invoking, reset the target application if (activatedApp) { @@ -632,44 +657,79 @@ namespace KeyboardEventHandlers delete[] keyEventList; return 1; } - // All modifier keys and action key will be pressed down because if they are not pressed that means that handler has already been invoked on key release - else if (std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED) + // For remap to key, if the original action key is not currently pressed, we should revert the keyboard state to the physical keys. If it is pressed we should not suppress the event so that shortcut to key remaps can be pressed with other keys. Example use-case: Alt+D->Win, allows Alt+D+A to perform Win+A + else { - // Key down for original shortcut modifiers and action key, dummy key, and current key press - size_t key_count = src_size + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE + 1; + // Modifier state reset might be required for this key depending on the target key - ex: Ctrl+A -> Caps, Shift is pressed. System should not see Shift and Caps pressed together + ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut))); - LPINPUT keyEventList = new INPUT[key_count](); - memset(keyEventList, 0, sizeof(keyEventList)); + // If the shortcut is remapped to Disable then we have to revert the keyboard state to the physical keys + bool isRemapToDisable = (std::get(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED); + bool isOriginalActionKeyPressed = false; - // Set old shortcut key down state - int i = 0; - KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); - - // Set old action key - KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); - i++; - - // Send current key pressed without shortcut flag so that it can be reprocessed in case the physical keys pressed are a different remapped shortcut - KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0); - i++; - - // Send dummy key - KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); - - it->second.isShortcutInvoked = false; - it->second.winKeyInvoked = ModifierKey::Disabled; - // If app specific shortcut has finished invoking, reset the target application - if (activatedApp != KeyboardManagerConstants::NoActivatedApp) + if (!isRemapToDisable) { - keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp); + // If the remap target key is currently pressed, then we do not have to revert the keyboard state to the physical keys + if (ii.GetVirtualKeyState((KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut))))) + { + isOriginalActionKeyPressed = true; + } + } + else + { + isOriginalActionKeyPressed = it->second.isOriginalActionKeyPressed; } - UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT)); - delete[] keyEventList; - return 1; + if (isRemapToDisable || !isOriginalActionKeyPressed) + { + // Key down for original shortcut modifiers and action key, and current key press + size_t key_count = src_size + 1; + + LPINPUT keyEventList = new INPUT[key_count](); + memset(keyEventList, 0, sizeof(keyEventList)); + + // Set original shortcut key down state + int i = 0; + KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); + + // Send the original action key only if it is physically pressed. For remappings to keys other than disabled we already check earlier that it is not pressed in this scenario. For remap to disable + if (isRemapToDisable && isOriginalActionKeyPressed) + { + // Set original action key + KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG); + i++; + } + else + { + key_count--; + } + + // Send current key pressed without shortcut flag so that it can be reprocessed in case the physical keys pressed are a different remapped shortcut + KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0); + i++; + + // Do not send a dummy key as we want the current key press to behave as normal i.e. it can do press+release functionality if required. Required to allow a shortcut to Win key remap invoked directly after another shortcut to key remap is released to open start menu + + // Reset the remap state + it->second.isShortcutInvoked = false; + it->second.winKeyInvoked = ModifierKey::Disabled; + it->second.isOriginalActionKeyPressed = false; + // If app specific shortcut has finished invoking, reset the target application + if (activatedApp != KeyboardManagerConstants::NoActivatedApp) + { + keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp); + } + + UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT)); + delete[] keyEventList; + return 1; + } + else + { + return 0; + } } } - // For remap to key, nothing should be done since the shortcut should only get released on releasing any of the original shortcut keys. // Case 6: If any key apart from original modifier or original action key is released - This can't happen since the key down would have to happen first, which is handled above. If a key up message is generated for some other key (maybe by code) do not suppress it } } diff --git a/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp b/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp index fa98385762..fa3aad3a1a 100644 --- a/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp +++ b/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp @@ -37,6 +37,8 @@ namespace RemappingLogicTests }); } + // Tests for shortcut to shortcut remappings + // Test if correct keyboard states are set for a 2 key shortcut remap wih different modifiers key down TEST_METHOD (RemappedTwoKeyShortcutWithDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown) { @@ -1115,6 +1117,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true); } + // Tests for shortcut to key remappings + // Test if correct keyboard states are set for a 2 key shortcut to a single key remap not containing that key on key down followed by key up TEST_METHOD (RemappedTwoKeyShortcutToSingleKeyNotContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents) { @@ -1287,8 +1291,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); } - // Test if keyboard state is reverted for a shortcut to a single key remap (target key is not a part of the shortcut) on key down followed by releasing the action key - TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsNotInShortcut_ShouldSetOriginalModifier_OnReleasingActionKey) + // Test if keyboard state is not reverted for a shortcut to a single key remap (target key is not a part of the shortcut) on key down followed by releasing the action key + TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsNotInShortcut_ShouldNotSetOriginalModifier_OnReleasingActionKey) { // Remap Ctrl+A to Alt Shortcut src; @@ -1309,14 +1313,16 @@ namespace RemappingLogicTests // Press Ctrl+A, release A mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); - // A, Alt should be false, Ctrl should be true - Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true); + // Ctrl, A, Alt should be false + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false); + // Shortcut invoked state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); } - // Test if keyboard state is reverted for a shortcut to a single key remap (target key is a modifier in the shortcut) on key down followed by releasing the action key - TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsAModifierInShortcut_ShouldSetOriginalModifier_OnReleasingActionKey) + // Test if keyboard state is not reverted for a shortcut to a single key remap (target key is a modifier in the shortcut) on key down followed by releasing the action key + TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsAModifierInShortcut_ShouldNotSetOriginalModifier_OnReleasingActionKey) { // Remap Ctrl+A to Ctrl Shortcut src; @@ -1337,13 +1343,15 @@ namespace RemappingLogicTests // Press Ctrl+A, release A mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); - // A should be false, Ctrl should be true - Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true); + // Both A and Ctrl should be false + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); + // Shortcut invoked state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); } - // Test if keyboard state is reverted for a shortcut to a single key remap (target key is the action key in the shortcut) on key down followed by releasing the action key - TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsActionKeyInShortcut_ShouldSetOriginalModifier_OnReleasingActionKey) + // Test if keyboard state is not reverted for a shortcut to a single key remap (target key is the action key in the shortcut) on key down followed by releasing the action key + TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsActionKeyInShortcut_ShouldNotSetOriginalModifier_OnReleasingActionKey) { // Remap Ctrl+A to A Shortcut src; @@ -1364,9 +1372,11 @@ namespace RemappingLogicTests // Press Ctrl+A, release A mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); - // A should be false, Ctrl should be true - Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true); + // Ctrl, A should be false + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); + // Shortcut invoked state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); } // Test if keyboard state is reverted for a shortcut to a single key remap (target key is not a part of the shortcut) on key down followed by releasing the modifier key @@ -1395,6 +1405,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); } // Test if keyboard state is reverted for a shortcut to a single key remap (target key is a modifier in the shortcut) on key down followed by releasing the modifier key @@ -1422,6 +1434,8 @@ namespace RemappingLogicTests // A, Ctrl should be false Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); } // Test if keyboard state is reverted for a shortcut to a single key remap (target key is the action key in the shortcut) on key down followed by releasing the modifier key @@ -1479,6 +1493,39 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); } + // Test if remap is invoked for a shortcut to a single key remap and the keyboard state is reverted back to the physical keys when the shortcut is invoked along with other keys pressed before it and the action key is released + TEST_METHOD (RemappedShortcutToSingleKey_ShouldRevertBackToPhysicalKeys_IfOtherKeysArePressedAlongWithItAndThenActionKeyIsReleased) + { + // Remap Ctrl+A to Alt + Shortcut src; + src.SetKey(VK_CONTROL); + src.SetKey(0x41); + testState.AddOSLevelShortcut(src, VK_MENU); + + const int nInputs = 4; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = 0x42; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = VK_CONTROL; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = 0x41; + input[3].type = INPUT_KEYBOARD; + input[3].ki.wVk = 0x41; + input[3].ki.dwFlags = KEYEVENTF_KEYUP; + + // Press B+Ctrl+A, release A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // Alt, A should be false, Ctrl, B should be true + Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_CONTROL)); + Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(0x41)); + Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(VK_MENU)); + Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(0x42)); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); + } + // Test that remap is not invoked for a shortcut to a single key remap when a larger remapped shortcut to shortcut containing those shortcut keys is invoked TEST_METHOD (RemappedShortcutToSingleKey_ShouldNotBeInvoked_IfALargerRemappedShortcutToShortcutContainingThoseShortcutKeysIsInvoked) { @@ -1546,8 +1593,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); } - // Test if remap is invoked for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and then action key is released - TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvoked_IfOtherKeysArePressedAfterItAndActionKeyIsReleased) + // Test if remap is invoked and then reverted to physical keys for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and then action key is released + TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvokedAndThenRevertToPhysicalKeys_IfOtherKeysArePressedAfterItAndActionKeyIsReleased) { // Remap Ctrl+A to Alt Shortcut src; @@ -1572,6 +1619,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); + // Shortcut invoked state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); input[0].type = INPUT_KEYBOARD; input[0].ki.wVk = 0x41; @@ -1585,10 +1634,12 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); } - // Test if remap is invoked for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and modifier key is released - TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvoked_IfOtherKeysArePressedAfterItAndModifierKeyIsReleased) + // Test if remap is invoked and then reverted to physical keys for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and modifier key is released + TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvokedAndThenRevertToPhysicalKeys_IfOtherKeysArePressedAfterItAndModifierKeyIsReleased) { // Remap Ctrl+A to Alt Shortcut src; @@ -1613,6 +1664,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); + // Shortcut invoked state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); input[0].type = INPUT_KEYBOARD; input[0].ki.wVk = VK_CONTROL; @@ -1626,6 +1679,53 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); + } + + // Test if remap is invoked and then reverted to physical keys for a shortcut to a single key remap when the shortcut is invoked and action key is released and then other keys pressed after it + TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvokedAndThenRevertToPhysicalKeys_IfActionKeyIsReleasedAndThenOtherKeysArePressedAfterIt) + { + // Remap Ctrl+A to Alt + Shortcut src; + src.SetKey(VK_CONTROL); + src.SetKey(0x41); + testState.AddOSLevelShortcut(src, VK_MENU); + + const int nInputs = 3; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = 0x41; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = 0x41; + input[2].ki.dwFlags = KEYEVENTF_KEYUP; + + // Press Ctrl+A, release A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // A, Ctrl, Alt should be false + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false); + // Shortcut invoked state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = 0x42; + input[0].ki.dwFlags = 0; + + // Press B + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // A, Alt should be false, Ctrl, B should be true + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); } // Test if Windows left key state is set when a shortcut remap to Win both is invoked @@ -1668,6 +1768,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false); } + // Tests for interaction between shortcut to shortcut and shortcut to key remappings + // Test if invoking two remapped shortcuts that share modifiers, where the first one remaps to a key and the second one remaps to a shortcut, in succession sets the correct keyboard states TEST_METHOD (TwoRemappedShortcutsThatShareModifiersWhereFirstOneRemapsToAKeyAndSecondOneRemapsToAShortcut_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap) { @@ -1830,6 +1932,8 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), true); } + // Tests for IME Caps Lock workaround on shortcut remappings + // Test if SendVirtualInput is sent exactly once with the suppress flag when Win+CapsLock is remapped to shortcut containing Ctrl TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenWinCapsLockIsMappedToShortcutContainingCtrl) { @@ -1927,7 +2031,7 @@ namespace RemappingLogicTests input[2].type = INPUT_KEYBOARD; input[2].ki.wVk = VK_CONTROL; - // Send LWin+CapsLock keydown followed by Ctrl + // Send Ctrl+A keydown followed by Ctrl mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); // SendVirtualInput should be called exactly once with the above condition @@ -1964,13 +2068,83 @@ namespace RemappingLogicTests input[2].type = INPUT_KEYBOARD; input[2].ki.wVk = VK_SHIFT; - // Send LWin+CapsLock keydown followed by Ctrl + // Send Ctrl+A keydown followed by Ctrl mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); // SendVirtualInput should be called exactly once with the above condition Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount()); } + // Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to CapsLock and Ctrl is pressed again while shortcut remap is invoked + TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToCapsLockAndCtrlIsPressedWhileInvoked) + { + // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag + mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) { + if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG) + return true; + else + return false; + }); + + // Remap Ctrl+A to CapsLock + Shortcut src; + src.SetKey(VK_CONTROL); + src.SetKey(0x41); + testState.AddOSLevelShortcut(src, VK_CAPITAL); + + const int nInputs = 3; + + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = 0x41; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = VK_CONTROL; + + // Send Ctrl+A keydown followed by Ctrl + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // SendVirtualInput should be called exactly once with the above condition + Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount()); + } + + // Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to CapsLock and Shift is pressed again while shortcut remap is invoked + TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToCapsLockAndShiftIsPressedWhileInvoked) + { + // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag + mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) { + if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG) + return true; + else + return false; + }); + + // Remap Ctrl+A to CapsLock + Shortcut src; + src.SetKey(VK_CONTROL); + src.SetKey(0x41); + testState.AddOSLevelShortcut(src, VK_CAPITAL); + + const int nInputs = 3; + + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = 0x41; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = VK_SHIFT; + + // Send Ctrl+A keydown followed by Ctrl + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // SendVirtualInput should be called exactly once with the above condition + Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount()); + } + + // Tests for all types of shortcut remappings + // Test that the shortcut remap state is not reset when an unrelated key up message is sent - required to handle programs sending dummy key up messages TEST_METHOD (ShortcutRemap_ShouldNotGetReset_OnSendingKeyUpForAKeyNotPresentInTheShortcutAfterInvokingTheShortcut) { @@ -2005,6 +2179,9 @@ namespace RemappingLogicTests Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); } + // Tests for shortcut disable remappings + + // Test that shortcut is disabled if the current shortcut pressed matches the exact shortcut which was remapped to Disable TEST_METHOD (ShortcutDisable_ShouldDisableShortcut_OnExactMatch) { Shortcut src; @@ -2030,6 +2207,7 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), false); } + // Test that shortcut is not disabled if the shortcut which was remapped to Disable is a subset of the keys currently pressed TEST_METHOD (ShortcutDisable_ShouldNotDisableShortcut_OnSubsetMatch) { Shortcut src; @@ -2052,11 +2230,13 @@ namespace RemappingLogicTests // send Ctrl+Shift+A mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); - // Check that Ctrl+A was not released and Disable key was not sent + // Check that Ctrl+Shift+A was not released and Disable key was not sent Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), true); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), true); } + // Test that shortcut is not disabled if the shortcut which was remapped to Disable is pressed followed by another key TEST_METHOD (ShortcutDisable_ShouldNotDisableShortcutSuperset_AfterShorcutWasDisabled) { Shortcut src; @@ -2086,6 +2266,426 @@ namespace RemappingLogicTests Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), true); Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); + } + + // Test that shortcut is not disabled if the shortcut which was remapped to Disable is pressed and the action key is released, followed by pressing another key + TEST_METHOD (ShortcutDisable_ShouldNotDisableShortcutSuperset_AfterActionKeyWasReleasedAndAnotherKeyWasPressedAfterIt) + { + Shortcut src; + src.SetKey(VK_CONTROL); + WORD actionKey = 0x41; + src.SetKey(actionKey); + WORD disableKey = CommonSharedConstants::VK_DISABLED; + + testState.AddOSLevelShortcut(src, disableKey); + + const int nInputs = 3; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = actionKey; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = actionKey; + input[2].ki.dwFlags = KEYEVENTF_KEYUP; + + // send Ctrl+A, release A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // Check that no keys are pressed + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), false); + // Shortcut invoked state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = 0x42; + // send B + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // Check that Ctrl+B was pressed + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), false); + Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true); + // Shortcut invoked state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked); + } + + // Test that the isOriginalActionKeyPressed flag is set to true on exact match of the shortcut + TEST_METHOD (ShortcutDisable_ShouldSetIsOriginalActionKeyPressed_OnExactMatch) + { + Shortcut src; + src.SetKey(VK_CONTROL); + WORD actionKey = 0x41; + src.SetKey(actionKey); + WORD disableKey = CommonSharedConstants::VK_DISABLED; + + testState.AddOSLevelShortcut(src, disableKey); + + const int nInputs = 2; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = actionKey; + + // send Ctrl+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + } + + // Test that the isOriginalActionKeyPressed flag is set to false on releasing the action key + TEST_METHOD (ShortcutDisable_ShouldResetIsOriginalActionKeyPressed_OnReleasingActionKey) + { + Shortcut src; + src.SetKey(VK_CONTROL); + WORD actionKey = 0x41; + src.SetKey(actionKey); + WORD disableKey = CommonSharedConstants::VK_DISABLED; + + testState.AddOSLevelShortcut(src, disableKey); + + const int nInputs = 2; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = actionKey; + + // send Ctrl+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = actionKey; + input[0].ki.dwFlags = KEYEVENTF_KEYUP; + + // release A + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + } + + // Test that the isOriginalActionKeyPressed flag is set to true on pressing the action key again after releasing the action key + TEST_METHOD (ShortcutDisable_ShouldSetIsOriginalActionKeyPressed_OnPressingActionKeyAfterReleasingActionKey) + { + Shortcut src; + src.SetKey(VK_CONTROL); + WORD actionKey = 0x41; + src.SetKey(actionKey); + WORD disableKey = CommonSharedConstants::VK_DISABLED; + + testState.AddOSLevelShortcut(src, disableKey); + + const int nInputs = 3; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = actionKey; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = actionKey; + input[2].ki.dwFlags = KEYEVENTF_KEYUP; + + // send Ctrl+A, release A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = actionKey; + input[0].ki.dwFlags = 0; + + // press A + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + } + + // Test that the isOriginalActionKeyPressed flag is set to false on releasing the modifier key + TEST_METHOD (ShortcutDisable_ShouldResetIsOriginalActionKeyPressed_OnReleasingModifierKey) + { + Shortcut src; + src.SetKey(VK_CONTROL); + WORD actionKey = 0x41; + src.SetKey(actionKey); + WORD disableKey = CommonSharedConstants::VK_DISABLED; + + testState.AddOSLevelShortcut(src, disableKey); + + const int nInputs = 2; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = actionKey; + + // send Ctrl+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[0].ki.dwFlags = KEYEVENTF_KEYUP; + + // release Ctrl + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + } + + // Test that the isOriginalActionKeyPressed flag is set to false on pressing another key + TEST_METHOD (ShortcutDisable_ShouldResetIsOriginalActionKeyPressed_OnPressingAnotherKey) + { + Shortcut src; + src.SetKey(VK_CONTROL); + WORD actionKey = 0x41; + src.SetKey(actionKey); + WORD disableKey = CommonSharedConstants::VK_DISABLED; + + testState.AddOSLevelShortcut(src, disableKey); + + const int nInputs = 2; + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = actionKey; + + // send Ctrl+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be true + Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = 0x42; + input[0].ki.dwFlags = 0; + + // press B + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // IsOriginalActionKeyPressed state should be false + Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed); + } + + // Tests for dummy key events in shortcut remaps + + // Test if one set of dummy key events is sent before releasing the modifier when shortcut is remapped to a shortcut not containing original shortcut modifiers on invoking the shortcut. Example: Win+A->Ctrl+V, press Win+A, since Win will be released here we need to send a dummy event before it + TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsBeforeReleasingTheModifier_WhenShortcutIsRemappedToAShortcutNotContainingOriginalShortcutModifiersOnInvoke) + { + // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed + mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) { + if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN)) + return true; + else + return false; + }); + + // Remap Win+A to Ctrl+V + Shortcut src; + src.SetKey(CommonSharedConstants::VK_WIN_BOTH); + src.SetKey(0x41); + Shortcut dest; + dest.SetKey(VK_CONTROL); + dest.SetKey(0x56); + testState.AddOSLevelShortcut(src, dest); + + const int nInputs = 2; + + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_LWIN; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = 0x41; + + // Send LWin+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set) + Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount()); + // LWin should be released + Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(VK_LWIN)); + } + + // Test if one set of dummy key events is sent after setting the modifier when three key shortcut is remapped to a shortcut on releasing action key and a modifier. Example: Win+Ctrl+A->Ctrl+V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it + TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsAfterSettingTheModifier_When3KeyShortcutIsRemappedToShortcutOnReleasingActionKeyAndAModifier) + { + // Remap Win+Ctrl+A to Ctrl+V + Shortcut src; + src.SetKey(CommonSharedConstants::VK_WIN_BOTH); + src.SetKey(VK_CONTROL); + src.SetKey(0x41); + Shortcut dest; + dest.SetKey(VK_CONTROL); + dest.SetKey(0x56); + testState.AddOSLevelShortcut(src, dest); + + const int nInputs = 3; + + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_LWIN; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = VK_CONTROL; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = 0x41; + + // Send LWin+Ctrl+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed + mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) { + if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN)) + return true; + else + return false; + }); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[0].ki.dwFlags = KEYEVENTF_KEYUP; + + // Release Ctrl + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set) + Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount()); + // LWin should be pressed + Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_LWIN)); + } + + // Test if one set of dummy key events is sent before releasing the modifier when shortcut is remapped to a single key on invoking the shortcut. Example: Win+A->V, press Win+A, since Win will be released here we need to send a dummy event before it + TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsBeforeReleasingTheModifier_WhenShortcutIsRemappedToASingleKeyOnInvoke) + { + // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed + mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) { + if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN)) + return true; + else + return false; + }); + + // Remap Win+A toV + Shortcut src; + src.SetKey(CommonSharedConstants::VK_WIN_BOTH); + src.SetKey(0x41); + testState.AddOSLevelShortcut(src, 0x56); + + const int nInputs = 2; + + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_LWIN; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = 0x41; + + // Send LWin+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set) + Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount()); + // LWin should be released + Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(VK_LWIN)); + } + + // Test if one set of dummy key events is sent after setting the modifier when shortcut is remapped to a single key on releasing action key and a modifier. Example: Win+A->V, press Shift+Win+A and release A, since Win will be pressed here we need to send a dummy event after it + TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsAfterSettingTheModifier_WhenShortcutIsRemappedToSingleKeyOnReleasingActionKeyAndAModifier) + { + // Remap Win+Ctrl+A to V + Shortcut src; + src.SetKey(CommonSharedConstants::VK_WIN_BOTH); + src.SetKey(VK_CONTROL); + src.SetKey(0x41); + testState.AddOSLevelShortcut(src, 0x56); + + const int nInputs = 3; + + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_LWIN; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = VK_CONTROL; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = 0x41; + + // Send LWin+Ctrl+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed + mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) { + if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN)) + return true; + else + return false; + }); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_CONTROL; + input[0].ki.dwFlags = KEYEVENTF_KEYUP; + + // Release Ctrl + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set) + Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount()); + // LWin should be pressed + Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_LWIN)); + } + + // Test if one set of dummy key events is sent after setting the modifier when shortcut is remapped to a single key on invoking shortcut after pressing another key and then releasing the action key. Example: Win+A->V, press Shift+Win+A and release A, since Win will be pressed here we need to send a dummy event after it + TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsAfterSettingTheModifier_WhenShortcutIsRemappedToSingleKeyOnInvokingTheShortcutAfterPressingAnotherKeyAndThenReleasingTheActionKey) + { + // Remap Win+A to V + Shortcut src; + src.SetKey(CommonSharedConstants::VK_WIN_BOTH); + src.SetKey(0x41); + testState.AddOSLevelShortcut(src, 0x56); + + const int nInputs = 3; + + INPUT input[nInputs] = {}; + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = VK_SHIFT; + input[1].type = INPUT_KEYBOARD; + input[1].ki.wVk = VK_LWIN; + input[2].type = INPUT_KEYBOARD; + input[2].ki.wVk = 0x41; + + // Send Shift+LWin+A + mockedInputHandler.SendVirtualInput(nInputs, input, sizeof(INPUT)); + + // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed + mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) { + if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN)) + return true; + else + return false; + }); + + input[0].type = INPUT_KEYBOARD; + input[0].ki.wVk = 0x41; + input[0].ki.dwFlags = KEYEVENTF_KEYUP; + + // Release A + mockedInputHandler.SendVirtualInput(1, input, sizeof(INPUT)); + + // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set) + Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount()); + // LWin should be pressed + Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_LWIN)); } }; } From fd7c7ffd5712541e597b0fe5d8aa74a7bd40a08b Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 15 Oct 2020 10:33:40 -0700 Subject: [PATCH 09/65] LEGO: check in for master to temporary branch. (#7294) --- .../Strings/en-us/Resources.resw.lcl | 27 +++++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 27 +++++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 27 +++++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 27 +++++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 27 +++++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 27 +++++++++++++++++++ .../Properties/Resources.resx.lcl | 4 +-- .../powerpreview/Resources.resx.lcl | 18 +++++++++++++ .../powerpreview/Resources.resx.lcl | 18 +++++++++++++ .../powerpreview/Resources.resx.lcl | 18 +++++++++++++ .../powerpreview/Resources.resx.lcl | 18 +++++++++++++ .../powerpreview/Resources.resx.lcl | 18 +++++++++++++ .../powerpreview/Resources.resx.lcl | 15 +++++++++++ .../powerpreview/Resources.resx.lcl | 18 +++++++++++++ 14 files changed, 287 insertions(+), 2 deletions(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index c074d69a44..dd1997cd68 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -460,6 +460,15 @@ + + + + + + + + + @@ -496,6 +505,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index dd2f0a4050..243b60665b 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -460,6 +460,15 @@ + + + + + + + + + @@ -496,6 +505,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index d2cab7bea7..8661aba18d 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -460,6 +460,15 @@ + + + + + + + + + @@ -496,6 +505,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index cad9c6b243..a4a1bad506 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -460,6 +460,15 @@ + + + + + + + + + @@ -496,6 +505,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 28735ba9cb..eb6c4600bb 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -460,6 +460,15 @@ + + + + + + + + + @@ -496,6 +505,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 4fcbde21c8..3e44099134 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -460,6 +460,15 @@ + + + + + + + + + @@ -496,6 +505,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/cs/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/cs/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl index 6c11e88c25..7264291cb3 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/cs/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/loc/cs/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx.lcl @@ -58,8 +58,8 @@ - - + + diff --git a/src/modules/previewpane/powerpreview/loc/cs/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/cs/src/modules/previewpane/powerpreview/Resources.resx.lcl index e2af16eae8..05258b2cb4 100644 --- a/src/modules/previewpane/powerpreview/loc/cs/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/cs/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/es/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/es/src/modules/previewpane/powerpreview/Resources.resx.lcl index 83b1283ca7..0d02e9fd42 100644 --- a/src/modules/previewpane/powerpreview/loc/es/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/es/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/fr/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/fr/src/modules/previewpane/powerpreview/Resources.resx.lcl index ae607efd89..59629e0334 100644 --- a/src/modules/previewpane/powerpreview/loc/fr/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/fr/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/it/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/it/src/modules/previewpane/powerpreview/Resources.resx.lcl index a964398efc..2d7386acad 100644 --- a/src/modules/previewpane/powerpreview/loc/it/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/it/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/ja/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/ja/src/modules/previewpane/powerpreview/Resources.resx.lcl index 5a8d70e831..340ffcd258 100644 --- a/src/modules/previewpane/powerpreview/loc/ja/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/ja/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl index 5f991834dd..a5e466a760 100644 --- a/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,21 @@ + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/pt-PT/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/pt-PT/src/modules/previewpane/powerpreview/Resources.resx.lcl index 2502e1b927..2440653d45 100644 --- a/src/modules/previewpane/powerpreview/loc/pt-PT/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/pt-PT/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + From 5f86956a4142748e56275a77aca7c7dccae60c8d Mon Sep 17 00:00:00 2001 From: Enrico Giordani Date: Thu, 15 Oct 2020 20:13:58 +0200 Subject: [PATCH 10/65] [PowerRename] new icon (#7309) --- src/modules/powerrename/ui/PowerRename.ico | Bin 100586 -> 118203 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/modules/powerrename/ui/PowerRename.ico b/src/modules/powerrename/ui/PowerRename.ico index e365002805e54817b88d6c15b165159eb48a7e3a..4f111feaac04a0afa2cf9b52350541051f1654eb 100644 GIT binary patch literal 118203 zcmb??1y`HT6K;aLI}|8Rac!`m#kDvTD^8#|6bKL;3KVyDCD$PCnvj^li4Tx&hE_4&I14d0VsffFCc&xpdt?dSiQ7iu>bX0(13utm+vGb{%>Cj z09aB70=T*V*DqxR01y*ieo6a(`*;9Ac{31z_wxBqpA8ZKpg9BtM5wFEVPjBWyr{-j zke7M?Px|kT_HXD9E~PJH$`dKbNNRmvJo5FafG=s!Iad1qY^hpl|5P(4<5z*q@hM8t`^ z7qkLqx$zwr^YQNypMAUg7(I}=+H|ddP|?=9Ycp=-0~hKLqQ2nir!pVC10teek#U=L z!v4QE%q4^cfr!VVKh}-LGXdw_!F!m+3dTtU&qzo&OofC1JTw?mIH1h$3tBbDkN~Ze zI2j&(;ay9x*3xn^Lh1-F#!{56VYS0RqY(u+2g`X2!(U0PtwxToEkOLZ42gRd*lI@g z9bB{J`p;jl>9)5q%PCEm=D=pD(|gb1p`oE^Tqflz75N<8wFZPc1OQjinwJtLK;~EG zk7-Pa@}n$Lz>LQa09vQRmvB+cLR^GfKHqrny+f!^d2IA?ts20(4stww4|DBiVt8@6Z0~ZP$crEup7ze#N(!*=*Iv&Nk#&6 zeBWNf7Ng0}3)A2ULM#M`-h5D1>Nmq+( zFgs+Y`6%hZM>C>{Y`7QqnybYqvgbmZDuj?hED$ocindmO>p$Z=aD1F)st3>oRA$*f z(;-!b=8D~2z(QwlIpltO(7jvCrj}>@b#3|Di3wn9eXzx66*hCLnm`_1l?h!)TwlmO z^N|j(2~-J8JHd|sp{MHjq$1SjzDKmL2dD&uD_0?(@^*r5^eA1z#}Bg%jc@OV48B*A zeDbf%meXUluhU>I^JqQ;MIrl1Go4IyJ*;pjy{xA*`-gE;p+sjrP4d2l?V^3QD4?qm2&t<2*bGA}fX zdt(v`jnlDPqkxTnIQtV4R0H^c9t)9Jl#pKvvx0kl=`o4#7~t{T1Ft%^>YRTCYwHT+ zvdsv;Z)nE0o*MtOfy(y#BdAVC1))V(hl7UnpG^?Mx~+xlXK@Z3Xz1lkV*7O44rdZ$ zdK??Z-ZQ^jf9ufW`O24S5pnIuBd2ui=b!b}xavb+&N7J1NO6_7J5n4G|E&e!6GN7O zJ4mf_PT|<=X`r@1ZF;jJ(N-+_O&oKn`7-55gv>!gG-n>J)62X86FojLo|{_IsnOSy zz5@ox(#5#a**To>w<~Np=ZW!r1)m1B$z->v<{lm7(F#fuP?gK_r(nNeMW&tlxjPA6 z9C4Hmsqy$!yx`I8)Fi!`uC*oz7tUm@6RH)|Vo8}mBE#&|2I%N-GbaotAP|45_YKX@ z%0lmSP?``dlV4etTYo!sD;O8n?Ff!zcExXm3kdN>|7ygxcFCaPz0`;v*+c%P0rrjy zDjrv21F?H^{_0PoX6{|Xj*;Tl5RvgHbR4x9|ZB3O2aSwBjQcrfKK95Np71 zgju0)y*6*x#VN+CDDJ1qGNEah68vzZG}?8{#gRvpd;{BCjRJcCv$_%fX=|)Ohu1jxa_Oqvh6=?)VG~p^X^u3 zrFDj&1o5QDL!IzOg1U>-Vu=+2f&i2c^7DmbRZ?3)2yra+O-giXPi0AingY-JGSr)Y zAUTtB>!VAGTeiX1hqj%H>|aJ*TDL@@cJT>KDlRU2IxxrplWFJrdOzRI)8klc_M^8% zyA17(Uj=^n`^>9Qqz>g zl$MM~AkUKSj~8}4ll)-pwYRGmDaNO(Uzf*s1I&OQut5ol&jp2-)A8{#5uzGI+=^T1 zCu`C(*DBF!i+((DCC;*|*(mJpJB^+STehLsL^B4Pu7lMsNh{)#D+s2-9?UtY|IBD@ zcQug~{e*B$Tw<#PCNDB~|6*^moVx+)@E;^VNY=%hjna(GIFvLw4zjjCPL~HGu z1w2**PQF)^!BS#2fV-hwPul|~nK1F3*mfK`N4!DEdqvN_0soY$$8W_gVgslS3Jfeq zKadX=ZkU0(MtjR`=jC7<2a@wJ@0AgfE(Uam94JZPs%&=^+NlTrUC0ge3Xw+4V>O%f z1!3Qs`^o41Y$UHflxc{}*0^bcF?yG^gp-MADpU)?};vw)un>P$vyq9$l-&%tgR zRnOOFA_w6yi&j{M24@TeE4XWEpCzYfBczIXNqXdAXs60j_s!vteu{hez!e{+bCHv$ zeNu71-_&hlFUC$BHurR%kdsnemm=xZVE`cTSej8SMMrc+BxJI$?n>O^K>sX&-% z2OE3Q(2J@R^z@i8Im$b9Lbq-Lyd8Am|4Q;2-?XlaUuAwYM^Yz#kV&jXNQnmFwDsgU zom9+c6uiV7g>2f{weH?=IzNtZ?p^3+lC?hb-Bc+beOQSm^RJvYS!WaYafj4zZT``i ziA=Q<=n2S|p+2zL`tIzay0tcvlYmyNlp5)8{{k2$0(g?4c6Q(7yJw7(>!WCLaO6h0 z@G>2=@9fH>d2^Zf9aK*mfCi19_JNfG7?`E#DYa8Xbk4uO!_boS_8lWiJnG_ z-c$MB$Wr^rii07VYKKMqp%<0h41#NG+;I6Vd}5T|$G6?W&rL{iw(aSTot)g=Fhm?2 zO3!aNob@HgjIikYJxZ^}m?eh1ypf-X(snPxX_<$|!%D}jJ2}G(AIw1Z2-`sA9)x+~ zegy8d(~0@su(#(d;w#s3KJ>U*V{>!3(czsx{{i&`1olYi`7NMmNyU0KkRfz*)-3!8 z{wE1T)xR@jJqUif_1c5dRAcfIG{SM*M6-j(*j7{NG;=yM=#u z&h8i{bmH3hW3=C5%7caW;vHYW)!=gbEy#NDph2Klc3iGq%rux(O#d4nH7qlCT5ap> z1}Kx)?VST_z~P1hc3(CztY*a6F#Yzfri#NTW~hYS8@<+ML)K6e`Yd+0$y!X;eM zGT9$rq1peMSf=LJE$=8Y17;HbgSnQg?2$2Oesg#IjyjWJOBHcaNhuU}?F08u1S~zo zvNJJ`$0dOLG<>(xv2s~{=ZfZg-`B8?tHH*fQ0BEU>l5#N-xDYpwu=bLfb9NWi^vFR zB-Js!y9^291aRH0i#JoIQUkUm!$s9#51NW|uQ%rQS2AAzV#{6Ymf1hzA1Ibq73ZpqwPj6$tR zQw#8DWkM$p2)%U^!Ou?)|5_#Ej6%N0GO9VtnPN|)O4Cnsm1UdX-9$l9OWkk&iAM-` z82cH}MwuM3r%R>m+d*^xt9HkGQj^TeRo~DAO6$GFD+R$hhOFPIQ$ts*S@tqh?g|-% zT|)w0J2J6?fcQd{KvQ~Fhv8(#Rq4c4<--*L9n|E60tr>1XacN6X3CsZh30}XW z_KB+DNeIS{p~s^+9ihZ4ck*wC0AtY=mE6D05CwovGuQy|M4zR^tu=K$6j})!Q$V_JydWwYGsx&>M2S%l$79ER&g(V zCj8pSo|Q%O#MwGJywOU#vujr;ZG`KjBd+${LCdYvm+v7t&0?rDEkgXKd`4-w5`*8; zZO+jNijOYnmIyz)G-6+!NpY*h)@e$po-v#J-F3QAG7cUaiYR(HE!f?iR^j40KBndP zUr)-NMR<15jElKq?rjOb7hd4hVwIdi7tA1(@4ogNbv)-F>9rzJAA5T`7w>jY|A)hn(6&=YkW)f7auS9CkOf>nrYrUXgr&7|7+-<#KE`he-*^LR$ z^9*Fnz(n4d2tUXg%w~7_BONZp2Yx1GQF@Q@TRn-ZT6<^l`veBV2{*y|@W!ajERlts zyapEqdeYf_JnSW&Ub9H>vp{@AgN>s)1!4kxOaR7io0sJTTa>^bE^MHj{h=Iqtv8~* zubl6UZ1ir)6{wqP>bxbfd8(5~-{8QySI!p<`E5xR{^u?9*RDs8#vGnBnuNl949mZjOSVCW|4uC#g zIA8EN15K+iJC*!SZ)oO~&zI%*T=O0=wKdEtfTS&5p76h%;#5IfY^bPo$4E3A8`aWyss7f;w)2jvoo~OgvOB9?eCG4#(V6u z@5=gd?&0C%d0j<3B}b)*KGuwcOMt9((J$vA%b9x8gHdD<=Auzo3}>{hPZH0Z z1nrM2Cl5tF&KC0r2()uQS2AH-1aZ4FH0BQK!+4O<#vQDBN$FOe=VgBD>M2hrhWb6V zZUcv|KyHwzpIV1%F8U$~|J{T^`?&^6`D86YyoP|)wiH>?GauAgn9An+TF^$Po zyuegOF*b;DZdq3@77~l%H@9fiN|Fg>+CoG_yf|X>jP}YLNE?)j$0c8}4BjV{zHw#q zFs5KbAMxGH#VlKQc4AWC@wMp4%lE&yui z>M3W9OkT~WseC|{5_@yGEn#0-282RoCxL#5cE|EkC@^iluy?^&zV?G}eQvhx=n`e$ zfHZ)*H_mLF1O}ysQLa>s?XaYI4z}u`qvV4wJ}rn^6LP5|dWpI%>I;tZIao+ZzoGf* zw&Nhn}j!!UE0JkahpE#V`P|Un+~1UdJ7M8f15@xcg|M z#hzo7A5@# zYjsQwJ^CJjsC~NO70xWZAatOE^m3!elaT@G&2&;kATbmP1e*QRZOr*73oSiO%MSh; zb2zb~NbX-szA!mZTif*XOE`|qt}vE-=yQUB9%!}sme2n7=Q~1`v<465aBdAoPIGbD zXb%f8C=&zFjN2&|nXunkZNhB&_Jd}RXN4C*Znt$~miEuOT5q*GR2%Fs=Qougko~rJ zQP+VtRVr5W%OeH<45H5$+A^o3vRrF&>ilJHaN+-%NAI|fOs+%qsrAhlI=1ek3Zi7k zXCI8=@BE9;rFpX#pz0XxhX#O^({flMRlw|ISo7mgoaVZ zPVTR?(A_)OX2D0BwbZ|)#|vq=snQ_ z*Nd^Ni`pi%dIDUAyv8~TPe$-g6q;EAfE4)y=VsJ92lQ%z*b()LY@2bH-E~tE2}4&G zx|jt+m2ILgf7s!sQQ zAYMrDa2Y}UpnhT8P>J@Y5d%M-QN61aOnia;pNr{V`Vz$aa@Efzs|J?RPd=}*% zlaxsYH!-A7%rJ+`T!*zm-kbu=9u34X98hyoaC>f~yQktlr#G zPin)9nA)x->pTWUBQMSC)vX+IzCrQxs{gn!?}lCtt6aU`M*K11Rg_OB{?V@hIsePg zuUVtx1c;tEIIi^Sj+T+bg=f-LpHRapI`euG!XN1Et&tt@X_P>tfxkAS4M5eDUyt*r zg8~cY-ey^698Kw1NoJ~eHTTs9@gK@I0MGn6&a7{3rhR#s#H&v@U_3XG*FV|l@rH&mO)l3~Kqo-+hb8#-dEz`b6NCM#WV?Vb=kpT%g0cx2 z-$x?7Q+=DnWYLuS&08k`Gp!J$S}+b(QK?mjUPb>S&k;jLBV&GpA5=Cc-X7_vZL)!? z0{dBCQJrs8 zO66_0+>UlM;q3Flor>dqYxLC7Ye74;I&^B6OO@v1*Isk}ZVdCSxB$~4`Nh-*ey(*L zGR$Py%%_TVvM{ABjmXpYbZV4gt99ezAPB79_e*yy&sQrt+(Lb;n}cI&K*QdLE;%Og zo7ZpPKNsn$8o&6C??}yVxm(~>4ac87_%O;2J%3g9nA&7%7NO;V)ZbJ_%8SG?k2tf& z$%WyTDGQ|xu2?9oA+RHbDIpvGHYXn=_eFR&vFxi=C}bJE!@yAkD<~6MDEl>mVz0xs zj%FJ|bkW*mtzAD{Sz8HhrgTGK8?f8v-PyIuL{_(`K8h1~_}DSt1a)$W^>4ORu)y(o zcsOK3v!uS|{XmCrc)NV&`(fVy4Y%WPd1@|y3Wvgbo}H1^jrf^|BQ<{x3ozhtuc+5tXj^T%Hdsw<0Y&UJp$)D`^M4!GEQ{VEpmliY z^oAhkMbb;y2o&9NHAT}G>yuEM^yk@%VSU~9u-C6rS@)9fP<)63yfaa&oXPJx?@iD^ zu+*N_-{YUleQ(gwVBz@zG)Mx_kdw2DC1>z;ok*P+#xg{kLjut~a)Wd(cv2#}USnGN zWo+D4gQUR9X@=~DU13PRvwOG=17XDi5UZUY&yS}G?w828Ho`j`!Aa5+x*xZy8;T3v ze0Z(elf4XamYus?*f&R}@VR0KV2Jj>osN1V!;oq8oGSvadE4YMsqM9c)QOot=c+?e zq>gN}r}&_0`+1HsUjGoU^@2n%FjT~W%3Vu;aq#Ev!iXxHjRD8kAH-$#l0(fONu@?E z|KPu87;XPyBNJDkHiWSyiZ%MT+x?mtX35DozncL4CYl%&GhCr2@EfC3`y0(Q?J)j2 zfCMH1q1yA`*_EffbBdnKyj*ZUZRi&GAX{GJW>epB6xhSm)I9Fx((q?BB1WLLG3TQ* zzs1+@czS*x4|@GhHcO#4(H*Kdb_@s%u6k+K;MxY#XfeGohux_K^;x$2LxfJhafAwa zSXp=3Vnf6<)hkmiqo>hJ6DQL}Rx1osME;`dKGR(p0l-yX@win;|2+$nd@t4mDrP-dZ8G z_lrx?JdmLV$m*yl!9q262K4ddLVZ`!OT}j#*$7P&nLgPl-~Z~!VvZY_7+Wp*b9cdT zetD-pj=7$?2%@72ZUEf#qd*e{trm;rT@`BpRAPrYaf`dL=`y{(J9lXfzS0*1I*QK$ z!4iwh27p*^xxDGeu6c8PvyhO3tp!RSQoyx8MQn;^pUv!kg(Ps+Nifd(!SlhAvJVyZ zO_CfHfy!7(XE8k)aL2gew)BPmS^?0;KqFGRAwwNcZvd4zE3F{XV+-lFvB;gdW3cj9 zZ9!8Qcpd|st`fSw^DV02@O!9g46b<3@jiC|v9H{3*nQ!>nS(tC&_SMcAc6;Qxw1;b z$qS0&+MIX#jG0UHuH58@H-dX${q?9KWku&}l|>}DwrK5Sz8K$TH3i>>^kjO2rJ9an zD>++;t%Ds!H@;2Le#>h5ouzMHt(2rjZB);wC|$}xXfheZ>uK1{KPBe?#W5fi3_mBO zr6P3}+2^ipRvcFR$h0XRP@FUJ`{#wcQ|beNEQ&Gq_C_D{Nm2IIsv&z;!@BdK7Rfq4 zVq4{jPw(V!G7k#*cEx>BPCu)D5K^@8lwC6%V8DLmm(pCyD$543)v-UF-4G$moeX>{ z%^P$6afsmq5$HFxhsePaLifUi1%q?& ztD#NK1kMs#>kn4130G3}7=RdD;liB4Pxx7^EaY)=p*<#;D=c+)zc^6!)5_zf2Muz> z2;28W%d?hUiDaR@yVyTkI!MB{3y!qlh5>`4CL88MWf$XGmdo=9P9k=BXPX%V%4)L%!B06T4A#`@4K-o~Cnf~=5cOAa7dSnE zh{R!2@fFS$JL;eIie$1o6(wil$5I^dULp_f6n8=|5Cd|7*I<>Evke<#ZQ~$MQ4+rp zR`iap2X5TzT0zDj;b`bSjdF-AWSjQvV}3+6!+DyFgFHF7&_u_p>Sw#RxYTAJ?FL5x zrYV4G5CN^nx=?73FYKfOWz5}YNB{#BLhrXAT~;V9wA(fLD>FX9yqEwig8Q{H>HRmS zTUF*-y*tCS5@hhk^VTKgcBr@_Q}F4`7tr2jsqcj;WoXEflP;_A_^aAFa_9c$zL#Ai zZ(88>p?Qy_Dk2k3jzG7kAj1}+S7XPGaj-^%h~{fp9TK33+OtywPNZYi%5aW{<3`{m z)e&5Slqh(-S(+TKkau*N*QA9q@MBOr=N+R)2KQyt`#N-`2vPkdpJ+#^P_GK2G*>B& zzMSFLu|yMur)CXe*v#@yZzdAa>u27>ft(NgIEb8fssZVb#%$zAp-VHFp@L^1J?;96 zq=t09;<#H=wxX7fn;eMK=^;nGN?cNH=BLB$fHYh!e-jyh2h#_C%LskUPCuOwv)0u~ zM*G8ESiR&X#Ub^+X0%Ke4Qh-mbvpKJZoc@L{^Zw(h!T^zUVoZ?{t@9rm!yk%&lGn< z-Ox~trETscVzYU=2ws!UwdKs%85W1A(=&1uz5^RXh&CwinV2aBzbtO-TNb10~n8 zfXKBMU+D{AXg&&?>u=cttB|b?mo6ZHtM`Iik}IicE^q_4Ye{hEYMB=1 z(?4426byyS4&?L`3)(7R^?e*rm@ux(sB=%bRQo|D&x>93hE1W=@o#mrFtkP{I%&d0 zIR-Jz_igSeox|AcD^vDTdt8q(i+5cg^#%GasY8sL`q9s!(F6wu*dT$i9Cgy#ds@*0K$6e zWN6suM>ss5!c~|&y~i`XGP}Zjx7xRzLV)1<t z+YqEolxwW>OMohLsWJ|ELInVzIQcSr4#ydFxHhgBBmDzZ7cYcN<+hT&Ie+AfM~;6J zGh(@BqVVOQ69Chcb=^E`EAJSB6pC1ndl8A^SK^dQHfC2&Rb~nE(Nq&Fut)r z;#RLe?*w>iKwUwdbl5jh=(I&aM=Y0y_rWvU@0Hi0m_HkP`Jx+Bc%m9*d%;C$b_{FA zA49PHAAa|}@H-oWP*MQSsf&6Wjwhj4Evx-o7dG~Q2GFp^hbHUe-?QcfUKluU*e)+` zO_g%->3-=b_Gu7X)5kG;fjzqN*zp^YerLBNGpcWB@PhUUB+{p-PWPD3@!psV)iiPu zDrHT^^nZ~xtmn&Pv3%F6OEB^|l%w2C;ks(x;x%=xalgT@f#4n)V0h0CM%gulW6XAu zX{?}d{?~B6aVfq(uffvS^`J90nqCYr1*m=qF7V3dEQQc(5j0Ql;5Zz8eWQ#zlI`Vi z)Ya5|L`tJ|VqJEvY(t^~+Uf=n&F$Fqv&v8@!Me>GLUcd0Pp=I6Ke4`Z@ciKI_G6 zi?(xA1!!)|JHbeU4!gA+-|_26ke%q;cp~HEz42!EW-C-##erT9=ZEy4+FuN~vZv>q zoY$bp#ppb+niVXeTcjT|p_pmoYh$3wI!Lq?C=*Y7x9)&EGce;56LmG$J^@$dj5R(` zfhHm)f5oi9CB{chej{wDO$H@q8U1t%RglL}IR%6jMK@7eT{#Y!VdI>1ot#QK9EIQ} zUr~U$nSaVV%^KON_^uSR$d_{N!j`cqU2(^S;=UDzQ1}5;WkAOmkT*bHJ87 z*1J2O#}PUi1}=ZDR|)3%-g4u9*SY0vhcm0zzFd=r<5saEgsI}SADngV6k)GAjBHdB zie%7%KipRKh4IR1mc^e;y3Xk#E=Vwiv8tpel5#!K;S{Tmd{J@2Fq)z^$#{sk=i57; z(A!_lZ&JBSOXpd5xzOqiyCxV4>Hp!Pn9lP`=x@cvUU;<$W@m6!POvO&~Q&FGspiIYhgYIC_R-FY?Vp{NT z2?YJDWcJoqDD`9u(Md;HVf9B|O7z zKCL8^A6rQxit6Z$0e3pS=QJ|Co6Oec0CBvp)4!wmYJp$MEPGR>ysru zF{gQOb_zR@(ZGzJG6nM)D1Q;V3uT>CrPr|>l7-dwdatKf_V1rcqDVKqUxa32%CTbI zaxdD<^|H5?klNa)hUk2IN2e^y6&F@wA1OQc>gTvdGTvG8+I8zMWZl`3Jh65kF6<%k zvGJSt%P~l(&BUp~Q#^``*~zXxxUd*|0Rpdc39R7?#wq^=l=}XdTQqk3Z7y04JCjBr zo)Yg|b?J*<_ULdRY! zv3i+ZZPdrdL6hNPnNsOzK0#!P;To^;4>!^+u9m{J)4NT%pq?LOy@xlA@AN7E5NG5> z#zQMSXBh|Z7Avi(G}81N;3y4N|AfBV5Fs+xSf+kVyi2L z+j=!*k8W0zLQRF=j@MIPawnIa>t&~@o#k=mygqcl@mcTLKr8=ZTcS>bN2KSZ(zi{T zD@Y?5!LFO~6Omw&5gs}(9Bo^x^iJ8HmThmwB)&T{pBBq?6sT)?D|>UCr!JR>_Lr80u*a zikyL5Yt<(xS~`iTYJO45){{&bd`~_*XJ2?7Ysod$0zD>n3wEQnB4)7VtQe+t5yikZ zOTW7D9a4s6(*D*6wLfKs;|T69xLNT=7n$z&yIdwKZ$)Xj!I;E3=6?)$f}+Zf2}gD8 zfx_lLL)x%$4sOK+54|u=Gj#yA7?d90D1NtJN2(>fW8O@>fCm*^CnMEQdRI^dNye+x zn9ees%bTJzY^!UgGk31D$JNKjP+`=8a-EwkUd3~n_!n^`VSmWyJS8ja)}#Hw${Mr)1=AU z7JC&0W#c;^uBB?w4rkX(zBo3%h}4d@ljp6INQ9`(I$m^;0u~3*uy~7d(^RR@H@e~L zg|*a%58_@&MYu+eCgMkusHy8>5n6*Kk?1O^P}k|9Fc!EmoOLXX=8X;s(e(6-pUv_s zJX;_bbbF^8Qpb2|yNjsTDrL8;C+C`PM@-{kXQO&m77m#T*9IBX+kw+v^a5V;(uaee zBXDO$l^q!%ZR)ZH-kkIy`YPvBW@CP6-+L}JpH+A293{zKkJUyyvxXjJ8{KIM^QL&{ zFTa-2ne9uxCC7=ysL;J%5qkVY7c==~@jFa|Iqn7=^nUz%77orVXS!e`k~05CRH|}9 zFU1A>h%JxzG+~FGVST`UNs3>Hp20|#zd4^O`X$>P!rJb<6J?+>rRkKA?Y6hXGudJv zCuPyTsTJBlWk|F~7VX|Ce?|0Z$E979FEpyk`=jN8^_N6+sTXn(f+-#OObn9IB-RyT zrpb4{ly^(O%(DIyIlcew3qN&=AdVqtK>rce=VklfwrzPtq-fowLG0158s~gOuZ5g- zqy{(Q)+KZUi49{d76h~4LuGQ($MS5-nzKA&Y$|bkEFs2%#O1}KR)+S%eB`aC0VFi+ zF{YB?$ zi=*L2 zV+w%mEr$sv`#{~i(&ZcU0weVW@aP~etg@X_cRg<~nH(JzEU(qAbl*PSS2Xs{=<_Ib z3~H8y`9shNno~5X>kr$(chFLo@q+Kyn8b3N<{`2Y!)})-amFXXl-LKFmKv zOIW&(FN%3DpxAz#?RTcbRTn5iqDZVSMPG%hY@zqW1|)T>*6GAYPq|kxYDUH^O0db; zI5(eWsn4Tp^=s6>a{7h-v4TU3e2Ldm<24X{c=5fN*o=oef*lwu_FbpBa?WF6$@xu1 zG9{FsBabeFC64)Q5MqFEeQDy%bpFNH0(4s5Wizvt;$R9#UK3C;bZu;)#CVo>Me#gU zP;%v5`!l)7@^X?Ufpf4a6)!ufTVAAj?b)myM&k7Yo%F^-uPYjLkK=O3?R;^F_pSGn z-$Cir!v1>H;*WS@Z~z{nlnQxkThW~6Q-Ux~(iAR68zOaF7AMMfo7wAWHyAQzg`h7f zwjYeum^e(6w(6YpY-Z@FBToO4#@9N9{H|{gyHOwgl8K$LGZ>$O_G4J$!X(_?-}^Et zg8Bo2RB%gwllK8_f;thREi{Qyn=;f-9|=`;aV&^eC_jGy#Ue{|1n6{}r`?#9&NBUx zEOHjM3@(ZYqK>(-|E}CrH!Ame#{EwT%-=YH>^#n9!;q`)UdyJfe-k`)+g8C&^X8mj zqdLlFA$A4(&uRWgD#fJ>zi+lJu{*dAQFoC7{urlne!17p+(ZqJ?4+g~potMlYn)|^ zu@Udf`gxR6c{;`|r)m`KA@q-%!#@CeEAj zvnZNJuNe(1t-bXy?-_Xf!1K4|nG;3K-LDD z%m!kH^H|2MT-#%lC}PvUTqr{jI(RK?>?n{@T~+W?HOdw8k#Oy;bP;iSKVHXrL5y@% z%WCor27&H6+TEY^KY9iG`a9A?AOQv0n5Iy3%UzVYEsed>3S@$A2+|4i!hFb?t zBcyCHxh>jADiGA8J)*!BM|^``kxIWuj_Cbx-ZY4+h4SmfhqpN^HH<{<>54NH!?pYc zmCIYEGo_20felaJ!7+>YeRWlQlMQQN$!PJ{Q@)c*KG11_bv6rM`*|NSbz7ejR`a7u z0x!MRqF=rXvVX{2lVP*@U?3BON^zn(Iea=%jLniD+$m3uQwv8AXlUs3} zHuKqlkZF`_4()b=fVTuqVM#=(0wYv~_vDY;CWhsq{Xm4bEvZn5{!+m?(4czMK`iO- zOO6|&QN!4YGdpbFWAvE_)QmhampO?sZbnjz5jfLaCNu-?i0L^-l{PqXeBV*kWd_e^ zPnw#7`a1MNO_6DQsfxwx7~=(skOJ=KfgH#D-zVrfL)&bfh3i(PL{HLvP%7l@lVnGbuU_{be>;{eB+WnEsYbU4^6j z@vu`)pGA8PkH*_m778d4WM^~f?TV|qmJFzHOY>GUo4wxN(07;6)kmjt zHq9K9q2`$I&)eO)q8Ee|wzXQ_Sk;D9X&@wT~ z{I?<`XYF}bGKa{242WeUw0wn>Y{&y~#3cgp(li{X+Fkji^|$MZ^*5y56l=OCDeOI3 zi)32qX%6L5{pXevM`IG*`wh5e-h8{XGRjc-GewgGtYfr`F8>v)eJt0O>ewn;qG1Sj zYhv6?HT*RJPkQ50N$~XZZcZ=kgrDlVkM`2@?Mv0UW~M5~bQ%*$M#EzS&e!ZZCX6|G zM7c;@$WE2BFnrxSTC-u-ZU0Q;X%>E@n3N)zg=ncTyR?yp#3+Y;P`#@% z8|R7gOr?oe8dRUO+2jNR}&gZDa`9js&WeN78DhT5xLw(!_>B3f1EiPR(5&a zt;JVYI=ag2WDg2QRySruKFm}$6HudC>v?5@l)h z5Ts1Td?2t%he1=^BL2Bcl!>YrHFtbnbAC(@!J8+B(CfFKaCe@Rk7RfhJH9o#`r}9m z<~^Bl(0xFz?N3nKzEV=Z zzH7gNl==>WrwNH%T2+y96r+U%{=3yaZpd(aal0LKQ>j#gB;yk_#2AafZqEKZKTpVZ ze8He>uA)1%`F`&@a0HZ!t7J|v9`X?)mz2S5GeVV*TiC<2}C+$F97f*Ap(gSgHr7coDp6hOBj_=}Mu^-fsnU0EI@!fyw zJgVyAcx!qzoTahkyx6A2OHuEZU;0L}XsWOQX})Ef&`X_nHD4y1J8tki0EOny#d<=> z2CsDyH%%!;VpdX-xC2r5*T2OmhO_p9aV6*LzPw*_q~E8#o1|`wQZhW&DWHuDV-~*? zyCp9;i)<|6m0ThKwLgpZ`U0lzB^Q&Fi9O4LeXWSUHn?>ux6ks8fVM)9Y zX6bPSaRyGU#D&_TZGmG{*}uS{Uvp%S=rOs+v-Nb+^;IdEqwCY_MTBtIT^`W{!&fsQN zIMh(>r5KDSVY)PHkPtFqd|T;jIPOiw|B%ZMhD_vEWDS~kdvbtFqY{$nFzKc~t)n+t zpaFG<(sd1qIV*I>D&hxw7L9G8W%A{gWwJkzo_=+FO~emZBx^`u^$&QDI<-7DOMRG0LeB z1*cKw9E0X4P5aiqe_bl8?A*nWYsqPG-p01OOHpNYwg*G)!t88duRl$Y|eDqPfPtT5gFnw z=qr|wDzd6L;u?C~QOK~@IpWh(%(CGgQs#RF|9un^X9-)XECAtA7Uq6GSPMd3UY7OE z89Ml-77tag6%{JuGyBT<&v(%?1(AIEgFF2>eu(ZI{H(cD6?||A8LZJ`o0Y1#tS&IK z{m^)QgC6jXP1M6jhcr8Au$6I$9>ja-4op>jdxEq@3cS<8M_`qpH;UJU;BEh{XLc)0 zi~mHcWh}BO(G);NpsOE4-!gDS+kps`-y9L0(5#E5HCMe?vHK(v`9+TSbTyQ=xzLve z|LFCx>Di|l%#m#~;EHqdmh{LV4yKP0fcoz<*F!Ks9HsCEbBpOBd#uZ4`{MfG!z|`% z&2I@Nem6$m>8t|m84Bk#s7+b{N*EpvZ(fV?(sZ_r90U>7k+3^b+KUY!PHlAi2^hvU zjnxMY@6%W^$VgHE#9tkI5+1utO* z7>t>_egc!r8Uj>s6Bc>1;AIhto>x)sjRd~ndcInB;rHdz1OEKd=|APiW1Rd)-MfPs z?1ojdNnRb{EuHJbk~v{<@Z^S6;hKsibEadTR${barf|_Wo#Pm%d}>)Mx7?h7LtkL0 z;q>MFa#Op1;G-*=A25&^=*7vHDM_oS1W_|1Ax&gllk(xF;P*&}w}KLTtlJneBsN8` z?S?D73r>x24v;K4%5`U0zz; zUzePGzXJZaGSoQ~z`;fR{FWBh^kZ*!v-9ug=bNXgsv-sx^e&SC<*N8ZFe#yNaB%co zrbR-=j8G#?<@nC>ZS)g^qei%*)UM6%9O$Sgbw} zo&gE*s>Kuvl}@Eq&{dX=)G7;DV9~PN@_-b$3)@ zW;Vep^l|wL`(Bj75&L~AjWR!K$i(Wr@$w#%=C zSH5E2ORxEFjDB@GXn&?`GLm6Rdu|fFIc)O#vt;rVfI?2%z142xWb?w|n+e!KQj({m zizjd_pRcPDI|O{ZL0UKw5NJJIXIyTU<7T>7t@dYLg8@f zVu#&ls7*Jdiwa-R7~*CA0sTJ-3KOB8!@a`NxS5#$^D31hK{G=haQB5ViUk76Fn1hr zh;I`<`QRF5{Jzyg_xO*Z1d`7!HlkB&u^ONjoqB-29T$pvq2-A5=mAiE3&oy}&m{Fz z`~UrqB@`x9Uqa|bQ35b)#9E6uxdE7CI{EyQcmmG#eSG0>X^v~IMKT^E7AGTQX1qXa z(EpKzjszB8eC8kF`;XS9PZ^7uJN}3sf&XDD#16X}uG*GX)*H8l798~jW51sNy2X?3 z8Tz^wh#GdSr1hIo-J5L{jX3lMS#{7cn6eu2AEE3OOw|Ur%RNA1^3ixH(r;oV0%Xek zzbU^YAWFfgpf0sM6v30%WA=Y#*1i0XnskiDzO%16TD3PrLkKxc1wBZE{cwNlWel9l+G^J1t%raxo(50fjj}U)+FO;B5 zKNR`8*?9bL=P(`pN=95-O0_M6$+V8g5p_zSgRqk=b}IV5kr{pmZ+syD1|JIKB`RFL z#=mn$1LNp2-^wQU)@O>-B8bKnk39e%@8vo!w$)zMj9g>9@ZCS2p8NledjQ@ABHir= zUv9%h(Fz}sT-ttUPZ;+!jP%wE-h1SWr^X&HW?xwn(%5yq9MH6f=K?36fEORnsbDeE zPLRmerm>UItr7WVho?q5A zQ8B2ffFL5*T(0HXp7*KGO0hRUA{Ic35siw7L8=fSKmr632qlDsgd~J6AS#Mnxk`Xg z6lsE>fSLFIv-ixN(;!g{0T17|n3DrJXV3coS!>OjH8W-3KGJvBvWuJD{$AMm=eMi2 z;G*-EW;ZQ-;&60P$~niI$1nKj7x(=A==jWE);@V;PakfyKCknECmRi@KCItAI~)xS z=u-EqIZ>C73x4Lqga><$Id=5e@b&o(gSQ-?a>1o9Uhvz6QyzV{X8idBzPxAPZ8z_a zirSxf(}7N5o$k2vvFod4o^w34+tB?_2Naxtu=MI40S`PF*YwpUiM@({%`N%vnZY2!bi{?BjPithU&-rF0}?cvA< zb&svOb@y{mb!}R$SM{l1uevmU*mK+|-#TgSZvlIMSk$e_jW2{f*FAaI`d?O!4Qlmf zw~cEzo*Q^=*S@_r-P3z!&VdG(q!-U$zOMTf6MraszV@B(^uPG%i~o%1xaqNjZIkZ2 zeth#r%g%l6f{3>N7!cBBcj(`@m2NAp`?ra^b5duHU%TzVm^WHwwfweW{coc-zVK+$ zjyu||=-X@1rjL#{n)7tG?bmm0I%ws$qYqs31$O_RcV%I>CDooU_@T}{rTs75GjDg3 z1FsitcxS|_7Z&Xcy{Y|GhhKW|k(&m;)_mQvQE$I~NA-bs*V*0XA6L%4^Yu$Vzv$e~ z*A1<4Q=8p!7soy}I%(DBl^0Lgee(;ybxchPoZGR>sBd;XnBVX9f{-QWi=`=q~m*Uolt*r&^H?%t={OHCtvO|=J| z=z-#2+RcAAe%!mIH_g8K>X=_@tRER1`fTUo%S+J3bFO?hJL|Q*Up;^6ch6mz^!2AR zZ*F+ro^P8E8MUurquDi=-qrQF1`iER{c6Xhu)ZCu#cgR5x@XU@m2X|1^=wxA8qF{J zY3MC$2i@3tTbtq@yDs@D?XwBDm&T0xpnJV3o!X2HS=XWa?$%e=;>a&*wQAnMYd8G6 zUFO}TTM9?dfBB~SH~vrQmd{G}wwiT&>70+=OWS*R@Xof`Pkqtq?)Aghzn^qV^Sb!G zX0dl9pSS;&4Kr2`y7AGwcMR)3`LhY1A3prSfcdS1Z_n;Nt^KNAvB&y7y8XsMH#WPc zao4iWn+9E3eQWMD0d4P$>3@9)+;qa*Z*RU}|Lp-+MD=-MX5Bq;BOkcxo?cna?n-)m z+njxk2VDE!i?@xv{{GgBo2?Dol)be{^5F1*oa!Z879H8tfP3Z75C65soBiTu4xX`l z^$U0X@M@p)I%Q1x?U}i2>t66>>2G$@yCGCpBnf=3l8~#b@6<53$ zy63CD)t<->tn=ZJU0)2$9aT~%qR&$|moIJm{OUBO$YYwJ0C|a{*Vgu3fg^%~Ylot1B=E$9e^_$&4c;$y%?)vA7I`QJ& ztY25%(|_ISzaO5yug`xXUO#g9vD94+_#|ckbTqy88VidmlcuK05opzWo+nm-g!F9@&2%_}PSo#aG@D zIq-#j!~fO$SkuB|^WNCC@wdL6VV=HvGilv_7w+8r$%ulx&)c`_`GSA7d$#+g?9kYC zE4pV^ud#g9tqZ>9CdX{+a9P1GZJvtkb7i$g;Uy2o9~xY}cXDjm z{^9GsJ9vHBfwx9~`s--wH@xBTUT@@7E1l5l?yK8>^!=MLTl!T0{)SIR7R@~WvDWJl zp`Bkd;I4}oMD9-wc;md(#HQUQ9AA1bJxp_oX)2gJqGyPe%CD%V6*iQrYWfFgKzzYwynLN<=D=wUb2bu%qf`z~0 z0{P&=0rJ7*0r{XgP@@bSDB3YJ;`}pR?^Wgbfq#qAS+J0fPsc3m&$>jSG?o(TCv+VylY&&h+O1<_`kI1@sHH zZ*Z{(jx8V$=ohyB5gxeN1NejAHjjvYi4D3ygpzH_4!Cnb+5(3M7WRl0 z6bBe1XdXBmkoenn!6iO$u?22^!L$SFwe$&Ad;ku_R~7x8>CaI*si6!0k_V^QMxlv`||i=K;bHt2*fYQkgy8!zG ziUZ(7xp|=HjAne`K3{bA3oblxjT0>%_>2(`BUkj25Px;lPHq3Ur!=|{*gp&@hI|j% z2TtsRE%20y4ferjSd!deAL7HG86#@H;KBnZHjsH`?HB4E!CY~ltJK*C?Dt`gun+zK zQrnS_YyW_J(JIJuTSwOlJhi>|f10U*9Vrbj!T7%(^Mba(-$S-dY|vIpGTP+&l(&Gt zlRq-?*Z#oC8;}Q>Ba8<2Z7Ex{)M*RsEg4h0E%4W}_2XKXZyR0vT=O~oud9XzfIagE zM>$`l9bgXGyH7A|!MJ*_SB3{5~*e{s`mW z$Qh_Sk~vo}{la)Z{#69NKl~WL-ojty4cvJkeS$~+$Upx7u;#1A2W*>!@jn^kU*WG> zWdl^}Y76}MR}J|7@KbEFatB8-XGH#}e0c-Jh<^P4u;#1A2guw}N+TP8OC6+fy3@|Hc;ncy{x2T~SOUUk|cyrvYs5@yNEVSxpZ!k5F*LV8-V z=%uhgN4u*sT&Uz{&F#U<(z{#D0gOVN!4jS_B zz~Hy;tRCF^=ISAv#x;C)$CSSvmDno|sMfRxHV+sdZW>#E;EU}q3hj5xMIrCpQ9XF* zJ%K@E?hgtY_h3-a)JKB@r#>1aWm-qR4h~eU^>4v}Qy#G-_2J;^DGvo-kosWtN$t&Ta(3F?M1@ITZU&^AMVFLI|0SAPX zxG(|iE$I;^fWIRzh6(UM z2iBxM6!iS$ju%wwo`7Y&!=6~$JA5xhETI5@isXUK1<3&~JSb8;0RFH8HV=S3IiN&w zfUV*HTW=ij!h;;m18_odpsT?FazSx`t>OS%n**=`Vm2fb9DofF8Q?(LV<957vxR?> z!avo*UU5LS$_A*`@C$Qai54S>{{t5OlODG4p8~w6O3aD9g?}2jHmzfbEjB;E1H}Qm z{WbOBpbsGzR)$kt-aEYZvOeM8F6$E^mi7r300ek{@08#j>_K)y@cER8Qd;)9% zMA-q=dgB2(0PH0Ph(Cn*Pk%f_Odze3#L3Ayf5{UpbnLR|FYM^?}z+K{FNvkNLygr z1Jf4JHz=Q={Q~TOwgt2a$`)uIgu@;{zyV6ReS#NzVEG051e*hz2Vq|Q0)4{VXMsON z*#P0`axtve;rZ=5#RwhK%p&g?13+zVDi9>4ZQLIHbC10lLO>} zFP}jF;3GCLZGq_%-0gvi4dy);qB%exFcUst2FHJw5P?`wjKkQ=Qut3(_^Z~H2ivFE z^8@f8>owqizk~l|*z;75eT6-7*8>;52Q~(T<9Jj zdWj9pd4kv2K*j~+ftoAWaRFmQ6&HB%33{%e{DB=8c=7-o=%#q!%oip8HV0?}=mXLb z15AStNC8F@h(CP!_Nl<0_)89)oCou5{KsMbpzxo{v5(K3uCWgm>EM|Z+YY$f0#`1` zn4nVdUq$@;M+nUUuRJhggFnUtoi|YUt5(esOdeqT`-}}t9@tz^xdSIYR5=4{uBbRb z8^Aa)9X=opHXs!^C1c#qhb`Ye4VX_iIG}l8aY5Px!zaw|RYQ#C-0xxFPv39b{^`gq zaNMV(wZz8X=7I7D-gyB2bgG>3Py8W5aX|CH_6gc1xY+|~3uq5)o8S>6+CITojHr2_ z;{!8)WX%(_Pw-+7bp8m~`-%~r*nsoI5IHwsJjgg;Hf%tK!XFq}_}8%UzXTkBC_7-b zre6RL=J&24KDP0nqz|JVqwg6l(c`(D(FI3L>9{~IZLRKVWP41j8Ow3jUt}e~6GAC@&AREl_^Jo-dlYqu&`DXb$MSft^P*d0_el zUpYjR2h1DUxdP4$6#g>}{3incYy*D}4!HXS+b?AIsVT-t{1N+e{zm*ct}))zIp&`T z7Bi(_&Iw;bQFg$c2QIdtOGxG5{|4}XBSMe^O1#+u(=Rx-z{a0*1v`Hv^9CjlOj}^* zlC?c>vjy57=orz+8AzL8_yu1aux)|6Phd=#4N*2=E^C3E&{WRxh&^$Zcw6|-vawejm}&Tf48s-}9HodFG2|TtGg+ADHeL`;IuUZC(#xA3P8kaoa@1M~?_e7NBCnpius@dt-EpPWwHk1;RD zKK#opcQLqN+5$5!!0SrEe+}`ExA50IFl~YD6U_L~v;|IlXmWt|z%@27<3nFOIB^cq z!e4X1oF|xZ0lDDD1FkLRbPvV)fnx*c12Pcz*u zyfZFy@OR^ZyHCjJi}7#cKLs`<4R)RQbA5p#aVPdt@STzej!n@1z~+Nt4=M-$fsyfR z-vs^?#RJ|LNRu0iUe`MH$^6&t0fu1MWxn$4Sz??6-#fV;FgWMN^KZW?i z4saeY8!E{vOy9ec0BwN6e-80S3@{yI(iQ)v76;sUAi3Zg z8|3t>CD#tQhQzfb>HF0f2llGwfbAUCAwd)eW=js(Ho}bum5o0+;P4; zq{42?@eho@pGEwYxY+__7i@nZ@yFb6GJHSR5@rBL+J3GtFvo1+u38I!$phOCxch`m z$paZDR?7Ha_f|ywy0?Hm#TN&(U$A+gY=M_~Lisu1oSXfKYKeee%;%Vf*jC1@WKT%KJ@SjC*gryTeR1e z^nB6F8lzrQC=U;O`2?9au;&RfZ(#9&`2vYQc)&P-K42bVfJ__zDe$|w{c4I`9QO); z)f%>77kq-^0$Yhc=6(`?`hJXkt}Scqi9dvOh^iJ*a>4cmiVI$RLgnC}5E%~+2+09= z9%y@D_ycpEaH9Co%o})FU(`G>bIEQw1NV9Zvo6_}Ptfa1W^ADSfMWwR{)hq6F+QhY z+%8o3XI?J8rzreYYx2PM1Gxigi3yzhV-11xNUkX`ugEoK3iC`>?FsM)*IYPY+5+-H z+XERBR0{r|6aR!rK@Mmh*tS601I+=(hl&Sku3*K99(e=X9{9=|c(n(r{>-jHtB@@) zeS$q-G<`xLat8DT`7Z%~$U@iv`hYC>0L}r@fzwotzm2`-fEy1?4!{;H98g})5c$pdmDe&Bzvn%)_%dT2evJ!6#TzxcG<|{@AL_Lw zFYAjQc?0PaoHZqDO~F}X*7m^5nu2K$WFFCs5AoW{8-|Mfo|X;BK^&;?&#>{&>ks=s z>vHkKYzXjIB5i@YJ+OH|{JC~0@wa_{Cda)!_E~d~1rDe>MA^~~D1i;o95C&{)1j4u z|L5;S#((jSg}*xo-0gt}4+a|cK;{kH;zPuVCKr@Fkhx?pxg%Gfpw^aDoak1M>Sdl_ zt}B@_B5eWlhKnHiumgFB1#*!io{t!Sa{%H$4SqWxvD_}=K0C%1Zya#72MgZ-{#f&y zg4mCFgqfV*5mVv|+amD?2e>~$)+EaJ_`YurV9yd`#7e;**h~B+2g=I>+b1~lMav#| z_#fk|P2Xc`kRQS)t_>}m=mrMNT zDEw9H@PIbKiVZ9tScS4?O0JW{il}PMrArd0@tfPQ3x}XRU#(H?aJInMX9&7~S(n zMXy@;7mx$C4^a5e0$yo|*%bb}=MsM<-gw~H1BpNK{)`{f4g9&jz#OxMJ2;?UTQ!OE zUpOfbDh2;9-;0X>^1Vp0o&xNZC|e-yfgK;p_`segn6ZJ33v|vP!pbA+T(UD)Fl~Y9 z6HXK(de$Xd>&#AVvR!+`I(5bbO5A+{@K+q54PXqg05QNk%mHQrt2FrB{5LrMfjjYs z_~rp)1j`TPy;(<0LhL_H;*Wd+eLsD?!XKZ{+9O$$j5;KT2jB+&k5`{y#Ripv|5t-7 z{K)}#9=P}flLMS9_?j5MrTVTfq$Q5voV9pb~a==&K;Dq(4DmL)#6BYx1N+Cqz z4;zp}{1F3Y0*C3qe-Ui?_ZauYU5Vs^X$y30NS|=IQ23|8_h&HngY9NsQH^~Icg#2S z-bI@a+8(%az}UxHIrzUH6%P)GF9%upTReb2FzkU(Ti}BS<~%{hh|(4Sdn0#rQXY7j zFDhH0=Lr?aAr`*|{2{af^Z}d)}$7pp!c+s5Bxn_5Fb_w{u_w@`%!`%_=+5mJOCfwvt<3dR%{^S z126HR`<(HFv4PGX(GGa#4NQAr&J*-p0XbwdK6K}S+`nk%kL>u6egWrNSonhj1>itF zd_WF-Ko(-a+0gwAh5uY&PyCe_wm|v=`UWFD%pX`+;y)d}pZGKO%OaMv`@|mhg~EL* zo_kg7GY<5gb`={)9#j(kk@4VwpjaHRTICNcpI~snh!1_m1||pent~Z4da(y)Y+&XL ze8mQ4e5iS#bIEF+;N*^Qwu$BdeLy~JK(3Ad9N?9Xaa-^v>_73(GVoVCaI*<2K3oL+ zQxN-m#hs2XKy6J7|bH2l9FY~k;f2ZlXZ51ZgEJ~VmY zkwf&greJfxS!cHFL3wy!)*_ym2hJP;=bMOP$YSuI5H?^D@Lvf0=L3&97^e#VAAs|Z zSyzGsl#}yd(OY#zD(8NfKX5Hk`hJdmj(cKn3+s_(Et(e&II#iwK))dEK&9Xh?Bj{Q z63qd3d%ze$`vf2J1Rwb$kF_N)w!mxsky>Xq@`$EiI5`jO9HOj64wG{O`hg<)0OF4r zAR95@T4tTK#1#j1t zYlmDz%H+I_V^@uR8~Z%8swSDOvI8gL0k}{pv#A)`%C#IRJ8ih`S5ls^ft_IUt3+ z@Zu9B{)qk48T;cim`@=7tTW=cS9K>o_bB+b2bF|>bUZj9Hd27UI}bJ(w!qZS=MPaX6iNEa+Y+F!}P)|(Z+#mjf_;XEh0ewF4w`-2_(aQZQ;99x%Gh6XtrQrX~ zhZg?s9Pr?QX$y?l!14*6xg*H~!ya&+=ss68bBHJP30`tXzIfnmeNmllvJ`fJHlPS` z0P$CIz*+Fy5`Wr$g}-VIf8g#D3W5Jr8-LCt<};?J-&fd!U#vUO`<3`Jc%bb8Un`&B zY6~g{|HSC{Z$69?|DnJJNFLaBK-&W^@u9Q@Ew=w>S^@8S*6Z1gDhQxmw z=l<~h3jZ9&`otf&tMjhRT13qSlLvSP%>!$WP$~FtBL0a{f*g=MusPt33wn;=?h`Z* z6bC&0f=e#h;DP3X$|s+2eNojLIQb)!2WH;Dod+xW+4zG4OTdA}hy#g#u8n`D!XIOP zkHnuGfG8Vaw#px%EquqppYsT=DY3SI>kGtL-SBKPny^ z5ER7$cOFzUHgL@)yRI$y;(j*WjV@TYj;0quch6D)gB z^lp8T#<{ zwm{Am>=@BI2bec-@V9Ki337;bd|>(nIae@!f=dq3nKL>yXs)%0s|JMQd>hyR$a2^K z#sJ>%|B;xx;O}V*91b)WMeh-RtRW+Q$U@xDd;;@|a_mdYE$oZ%n){VJ_bgfd!Hf%R zzfdXofA>*zU*KORIUsouCGCJ?3tZy@kJ!NA!Pj`L?12jpE^_sG0+;OXMCEC9XbUVL&DP`R=2r2fiB?{VVZTqU?af z0Z&`tiw7nLq)#yO1};2s?19U=lEDFUT}kpl%@ODieEI}~14bVClQ+U~zKz8J+5q~1 z#qa^dKL_@C4zOEd04_xiR;z1Vvvlaff?dSRe*BLGBx%Q0j!+gW! zf%XR;JdiQL&`N+m;JaZ_bs<~80r4%xD-RrhK)+!61d|8mJi+t{zIgx+Xuse#Pk;~b z79)E21YbOmwFWAOXzgPs2UbBO{;&bWe-ZM4#D6aFe-Gn7_ZmU`P1)ma4~)2A@t_7` z2Il?>f37LBwm|xOj(dDQg|+EsefmkxIyqF(GxWB~z@Oi-d06C=!2b|AAbDVLK>7t4 z8`3W*9>6D%2L=~ZzQ8>`GN#fGXi?SU^In0`Uc z6;5NCEya6pViA1_r^}9Rp`oRwbwHnnixW(kBLav5AxN3fnuq*Oj4r_*W z=4QY?hO(r0gly%{uZ71TCWrwKWQ#cA(#5ZY)hT>6{JhFV-v4b%1AFtY>9TK8i=+GU zTZny%11>xuC*1r(?$u|-{a;E4f8`cq-ok$o@P}wSZ~_isj^M}tEFldrcfp?=kOF(4 zxnTMP&Jh>-@jpx857sZ2Sva3h=-h`vwQd3vCB% zpRgzI8bAJL4gM{=>?_3hFSPNOJb(`F9|g}tu+z>oh~fmy$ux!EJMgH-B zwlF~AzxXP|6+x|Y8@WPxWM!Ye*CK}`adme zUGKosHZhQ92bQ*Oc3_DYDQ?|tKV|WCls=GS5`S_)^T5X6JuZ+uXpx9{VKYWjN5^p@f zd*$T80dKazi#<5mJVD~G=8aDNXvh9V&1;;|O0Pl>5A1I}xU%g}Xa&V9540_yO=wdw z9=LNs%@54hv@%0#;wbz=$10@4Gx|{uuDqcWqzvNVUmhOVw!p58S&*?1{e;(-x2m?ta0=9(eN$p0R=Afy+EW z`h;@K7Zn%OTEe0h@l{BLXY`{STGg)0!BqzKiUZOf++g_w%>l**W=!9O7^L z3tGN%$`tSy|DZ#k+|V92U=KI|8(<22g1bEc?k@9$6Y>CjfIV=H4~@9Mum{o>xZ49| z161qekB*?`5mE*9$2yj?UL3I)#7z=>tgr=OBSPDeBENKCucyOIZ)Kt*Y5y_vdkcUiY6>ud7^p zIrJV2iHB4RXpFz{CszLL|I4odzXtpo@N2-Y0lx-LlLq#Vi3lhiUpH#&_fz6yEVy{v32g>7NUI#j{0-8P|K%WV_t??vB*lyUV0bReJuOUBj_TOrVaB_E^xxRyZw1@s`$e@jNz z5YU6zJc1H^06J(_!AChQ|GhN1LDIJ51_C;;#MZ;s-=l|-(1q4R^o-Nep$dL!>BI(^ z5CJ`iZOOI{s0*)pu({xc53XF0dMK*kqnwuiUOK5^CPb7@q?|+#9%I5D7si;7nqtdu|a*Hp+L8L$n8eYE@p#>HO(|LrM_Gq$HR64ZgK9{wWzPeuPz8w=bYZG!`gme!}$bl^A2I(4_kli&bVg3uDQnH>8O_=wbC3Bw*O_=jc zNJ8e*Aqg2zgd|Mq9GsB!aL_wnj;OzJ$CSSbsRKg~UyZ0&GUC3#cP2a-l#udBaKh9_ zgA=B8w1lsx;62EjsSgL=Gr8jh74`?qdxu}Jv`_fzrMMq%3B|a#N8Z=N`?}PfUA*g! zV&B~;@A0+o@P!TpbReJuk<$(L%t4?7k&XLepa%gRh%DS42R(?nxI=RGGq^|k$q+HE zONf~8NU&HvxUOLTrLh0D4%U27SB$tqRELkCizgWsToo)tCv zxGTLCkfkfZy*(vGwps@aGln z|BAj5u@JHR^$6S-4pBN#T=1p`d552Km!r$Q&eVf-r?Y& zaX-=u$a19z=)ly2=7PG%${Z8Wg*hhVy~Z{dT=Za!3F=_p^VS%c{zQnF1U|3*u)f%t z*2I!&O|%}?eppY8eK1H&hK{DO-;V{0bSWXwgC&X!7#9`pKkf^TUDY4=M4|su57dF7 z2d`rSdN9X?yw}kj6R;1y#sqBx$3qr$Fb8&E25i7&;JP*u{hxjb#MS|HK`wlX_mdt9 z5-HHpboTr4V37gNP|`7WDAWUW0I6{QaYt6{C%7X^-J!0y;EV}!!Lkk7K6)Dy;Dlux z3>#_N2K$b4p={&=-klB|%!N%%hYd&puAdIAFLupf|823k!1u>J4BH1C&0xQu2o^KJ z87YPyY%Wx||EuF8V^`yzFz4=I-XCpqf#X7P0r!WQW5VYhjKCukoGKcVjWmU@tW z0(Zwk2jsv^*nm`ExbC9{Vpsa5&;iBK1K%G{+Xsx(+3zQV#Vl|}imeBO4;AkJ+BYL( z)&1&H58#6219hPE;4&r*KLHzgV%uPFfj(3D3EaP$gFDpbg9Ed0pY9akxNaEwpK+O` z149p=;r$7;eb7+``whNiO2Iv>XsHLq2k4=~{r_}eL@acGdjol&v~icTuQ8$c;LBf@ z$2Pz|=0XSA;6NsP;Z)$bZdgO{{Y>s=*_eQBQ1_o|8!7!I$Asl8$b*HrgL45m zFdH^t8lIp1{C-wb=m4U1aGCgQL_?8G+Xo%ZLf;uTSi%^>(!p%%z~VxM`;U9%V%7b! zUiI*MZG)R0Oxr+znTPuWbHIT)umNd!_RmK&65nTD?&!eQ!{;L#ib=G6&`~D(&e(CD z6vmO34wN3Cg9`T_ck0EeyA^q#rn*yet$p7*$Alag)Pp%D6dzn{1L8*`e)44-3UFs? z{!5`E7aW)i8!#QXem=61_<{YGI&k#x`KU%>68%28&we9rVjQhv>3PtB*2B}G74ARo z8H`nT5374dr4IC%_&v74&;xy?@|U)4;C->YGkPJ$!93W28Nl_6QH{k9vtuBa8+vFe zz8KwDOs1bF_t|g6O^lyZ9I5m`9n5{E;{C^co3ZlFP2RVv?qXMWFWWk>Yy<40x?9z4 zOnA2q-eYOn2Hum*JCpO^6S80f(t#`c`NN!M5bD6u1K&@f?I-tPE9f)id;+c11Lsu` z&M6=j#vk`i#^N4IK^=J0gSHLo4tjS#p~i(Te<|k_@R`Q^l6M4C2l=oA^AQhZ;Mv!I z{5P?CF8WW=I*5_)r_#>@-+92DK7+A?HNUiUVd$a4{r~Fys94^~`sE<&PF|@4`(AEo z7jXZodEct!g7Ounzl0ui40$r!AZ?>H2D0G`X9BNUt?uV_(ZdOBgZ2|@T)5c=9YY#=U>uE{lPJVE$bk*W1g>8uT`Yc_eknyACABuP%F>C=`#Oe$uhDYrdhv z{m1>ivCx5_xaa|Qc5_@v+ki2lY^2r$?Sirm7!NvbC{HZi7jr4hr;1?{7s3zD0j?X^ z{{`qjb)fVBE_^k<3H&2$A9R$9zA|oL{>?`YuEPDtz1FenZgW!)>JDqA14|Fiz4hw8 zdY`s|_HBI)G>$T!sE$B4)t$(@!#9VC=}b zrJP@)m3qMY%r{_6RJi}R<2jahedBItq3-r}=YnY)zND|9jVy=1bZmnWL)v~~1$3|! z9LR?aoCjRLo^T2Jf3?)X9_qm6!Unvb4%-r{j z?>+9gKA|2=+raUl^k9w&#Rtz=+SUPlro5NDKgIw!P=I(S3)p>~jQ*>;#tl7eNWN5L z!1mKmGG1Wph`YlfMqXOx;G`bDt7!i3yN{ykY=b!_ z)VQDyv~7TG^cG8-wt@a~HFU6Q0LB0~P>5JyKJeQ(@lql0TjxEih917g`!i|#$$j9? zxQX$T6-OeLH1*IkY+gnC&;O5m(4U76_CSQwYEFGFwDypPgX`|fzB+qvzPg9qxp#Z#ysMVI z^}j*&#yu8N8-B9pqF2Idp#RaxzeTeJ52B%iDC8P0{5^fID!+p}12TATfWB{%T(IsR z|I^q1s)7!1r%Hx-53A&YkWkqqY^O6TrL=;5!?f9tF~*Sk2abJPDC{a<_? z&kEFc&^cUac~RMIJ=MmY z641eM#0(Fdj{a2iJ8|~r6z856^Q=|l41VKWU472F(g9jyOz8W%;V-i)`Yfm8|Km*R zO!J-!=e`=}oLPO|uzAMx$+=K;I{H)5@5DK*Gp+NPo%47-bpTydd`z4X_7UgNzAn!u zR%ex~`zqAg^y+>Bbw`QTgMIe6PutM)?TTV?I{rV-Y7WFXy+fgcZy+V$0_27gj0sCt zv@HQ2N?;#L;3I6Y@9-AyEkjO6fBfI+*MMIGehr*y8u$YT z7aR`=xRAeI(N+WmgvqZxE`J>#aDvu4a3KK4+{iy?Y^(ZVwbqFkC+fFUtfiNV>R0`L zspFIV#d9LAfjkD$=R{nBAN+s(8t`ktuYq!C0Q=a3u#deh_Aa-_9`5$opVuCH6We2d zUVH4%Yro}V$mm*9uy4D4$w*3#_Sm!C9{aUxpUyq&*k>7meU_W#UQ6sZmHV%a{kB`i z7<+Baz31F>E%%()II?+obo+9s=}-AD*drM0vQJX)pH_S6jeYdSeqnR}Ja9N|rv_k; z-_3HLpT|B&>s$bRCII(-tNq`e{Yd;%lv|Du#UAEMu$T9c)dy>jp1n^|@9THj)9>C7 z$*G!;m*cDcl>f4QQo{i3uj>FAj6Nhvnb;r^`wTPmKI{n^i?tZri5T07z#;*3TpdO7IY0uLCtFl>O50W>zaZ(*A&$IreGgH3ic4DU~f$7 zyq;0{djF)ohje*D?XSl^5R{62lPOa>2B%=3TnhFJO2K}?5vdOcl`HZ`z1|&=-^{&% zF7+33zl&Ylk2(dr7RjSVk#)Of-7;(0xu0Vy>bqxki*VWd$Ni5518RzK*!#tOk801O z+Uv%BkLW{Dc?K!=@buuGF7EHs_35f6+uq;E`h2~AiSP^)Z4`AJsf78wpo*lT0D*oy~oeQ!X6v$ zoRWK(fWb`Er^5cY>|5d${ri67gT$YxCbrkl_+cPk=lcWJ!nf3>WEa>Cb{nleN_8wjQvLC(m(2i z<8%$2T{F%aINcBS!PnTJowCP<%YG`<4^!xtx<_%_dZ}B(8>=QhzxL@`#xxE zmESO8k#ar%#vxI0dVhoNgR#%W+|xiTOgv0G>)M-e%U|a}NUdU@Stc zscOzuKUO6+6qy*aIjp@#A61>X?#GMedw$f=#_4)$d!Ges>RsyU?V5UNr+~+a?5!Fb z+(*C~dhVepK&;9A17_{~Cqo;G+2Fq1H^Bcx;T~M#1wlW`rGL}|_wZH^?ZPR|EAL~& z;gqu%fHmN(f#)88Ld2S~?%Sw+U;R-dF$dhw13p&WyH)e9d^q}1uIER6cP#3fkE_~l zjfGj;4m>ocu*X5~0W-%2cxCou^&8=`hIS2w^p8r0`5cDAtSR`&58kLCJ^hAt}M2w9@V37zuC87_Bu(ye@w~6o@ zi5MG+;8Y@fcp^BJ2)~htv5^QLo`{$*5jE&T^Ii=bwscUv*|PrJsyP;WP=~&L+$Eo7 zb_*Sz_j1@!)SV|H4oSrPH4!m-BIX)z6ulf)vpmmV8UJVBqH8;#Hn41OzEeYvKAe*I zd!;;oL5mKkaV%pExK#%(>%Y&K=igu0ssp4<)^HcJwED2<+B4_*7hl%_^+aW?!FB2k zTU5E{KZHBaQ6qI9YNV1;FPI`_N$V8U(B`?+Ocu(1Yyci9`wCj5fKw?L827>b!nIEv!(ru(IyasDX8iu8j9kvv#wrUcU$Hsf!KD#pBL+xM) zWEBK`XlM0-wUoreol~r#wDB-F^#ibISsBmj>pKpux$z?4a2X^9eTV@LmaJ$SgE0|< zu`LDTBIdvnO6wSm?-=wU23$e_by^?aSGWA{pG6w5>WBh(GZ+4xs4c@k^50R0RIXO+ zzsdSMuWbo+cvCZy?NI!>$Dm}Vj;RtD;z)g|C}`%KpoBbsH16$ znui#i?;V3R_86?O$6$>;2It(zpl$|IBL?**e@e{^*84M^IvCcE*fkfdw@`O3SamPQ zao0lIQ>}QMh5t3ryjIV!jdvli7RRjnaGv9_Q~mv@;~0ze_G5U4W2hTAhUX~beFSz5 z%5Qj%W5DAW@Yq)}y5?1<`uq8Lc!m%>LnzKc55;qAL>-3G$Fp0K>V)F^DHr@1-|haH zSo7YX>JPw;&hG#IXa9_|k2i4rT|UF4h86mLtX;Lm+EqUC6UA63DaLwkG4e#k$PpDI z&sB`vX)(^{Eynqq#mM~@BM)DUv$KkkgD=J!bTQ5sE#8#W@Mm@IZuYBD|C#h~a52_s zrC_~zG1i;oeCYsZ`;6n6CTfjbt&ejZlj|HZ-^O)Va}5@`MV?*7vw(TN<$uOD(re&c z4@|+if6iIA@{HRbeSJUHERyBgs=WrL)`r!3s>+#hUE9nfGY`(QXnDTkH{%-1HDIp) zX1yFGa5l5cS*ti-bf2&9M@}-Cxm7%eJ~LCTCjt|>uB+DAnSW#sRXzvu@mv$(8uX^| zf3wfNY$DgQxUO!T?Z~rEeSSaAZ%pPIC)c9n8jiiTsn%!Jd7WHCv(}a!Ot`MW^X2}V ze6e1GUC^tBn1N^F8NFQZv(K6I`TfYLC98EYxhBT-Nn=e)4}zaRO%WW6S&))>_~sd^4C+)!&+vyi9%F69#I z>^YpnxUg?cF^g*_);bT)9F%7b`uu+6OOv@ih3Amxg)vXcbt$#(tk%`kd8&#V94B0Z znhg$Yo^q*PL(A(|OU%YIk)QTj4bS}Z`TfXyCUcERuP@;_xF(}8(cFM8SW988C0XOO z5c%i1;K1gom&r9Gp24pTsSUV|*uPw5e`vx~y_h8p<`22q4fs@r53D2pq*4wOHJkRx0 z+>n^?Ic#oF7hFTg#(3N^<8poWQqjQLVga7XT=U0x_4)nCNhj;PI@UN`*EWoEVeA~b zI&YQZmFK|ZU>t1CXr|9VT8!F(96S^GDeVUS9d^U#_aisn1-bEKdYuBfeRF++=N5V6 z2G3$yiFJsD;J~(7SLm}>im`UibqC|DnKGO^uU9$*&>Ea zg)b<<+G`2?atY#s62vAYsK+Tm9cM{V|C)PP1DyVB*bdaomSE1Z!u);2qw5&=aE`*b zi*c~5gM**vxw?x{L%=&2W<4J+>m*SldBpsE#188iH!#NMS*Dz0aDKtL1!MW8s8?j{ zI;VStJfj=6elEWczqgJt8GXMz0}rtW=S+;vS(~up-8wS$in{Eb)qef>VxKJJFyEP>73BW-qJs~zxLn;;E*{f_xQZ19cn0}Eh( rbKnbe;0JSHbLZh%YMB4;kGy6MxeOLuiAcm<<@ni`@Za_S#qa(DhTvwMGTloS}jlni&an_;bnMAfD}TB*?wPkZ!)>eCO6s1W_I`go%7F~ zd-uM+-*;zrW_L0xgiFKG#IRwT+{$;|C7t_W-}jYDBM#t8>O( z5F)1Uz<%EzHtUlMhc8VzK3+5^`1tIt<9@XvCvL;Dt*0k-N*dKaIVmM6v-OB$5B{^! z1@~QVC3k-1#Qq;;UA(qzgXs9o!r!|;JJF*Pb*E)H3EADY*IR#S<;hQHUC%r@XX%v} zb`Nd8^!(A{LkqWTD!RX9?wQu(Mvi@M%u~bf*_Ji$yVD0tWF7S+Wut4o)5&S zl$=)cA5ZNvd)K~3J2!tk?WcRQ_i^Eb^UI2tpG-|#RCsrKOy&aSfbGFuwc>kUa4yADrH&pYw&7w*Yj{d}((`Ej?WOd1fAnRR%;)uZ=KJKOZ4`^Byo z8;r`@yW0CiQd@Jo($2OVI{41uk^fDd@!GcrAK19{p$6GT>`f!QdT!{Bsi~7rd%qF; z^z62?ehg#uXCIkNzXZpE>N_19Og zPS|t3_(gfE~jR!|B zy>Z)?wDJ4%Qyw*@w{!1&d&&H!7hUIj7k$w+_nSukpTA#tCB>5(U$A8NjFQ}0v!8kB z*LTet`SVlj_H&&7(Q)UzQJ=rNChbJ#v6Xo}*UwwN*0pP*@!Oa43rAl)J$K{cCZk?E ze(%Vb%pNU@+N|p|cG;8eO-Cm@vhd|iEgqyWaF}~+dn0Xo))xTqZKzLPgM=D{A@ z(>3=>acXXdlK;7{r7hasJ9pNOj(yurUfVpS%4MB1*(>_A8@Qrm?j6Ip^1$z;_uJTK z+|$XlZEykYa=cIa%q3bj5vB4MAOQgo009sH0T2KI5C8!X009sH0T2KI5C8!X009sH z0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI5C8!X009sH0T2KI z5C8!X009sH0T2KI5C8$E5SU35@%oiT>GLFhEKYNhuJxdb+z+=uOp^W4Cd}ak%<-3T zlPRx-ewECh*NHjavYkvTX^NK|LZGtv%Q*6W{T0)EhtqatahL5(O|a=u0y^>Mcz#ae zy04IAe5*>SD$L;o`1mg4`Y+n9DyCJv&c})c{yr&zg&6@p&hvWEIljxaz~>44o&bw1 z0(^eQ$9)-RHRXMs&;4PMOMs6DR__aZjDST40gko0??;E{@RA82{?WY-5P!rU$N%VE z1K9s-9(!gNZc@F~iNE|Dsk*+ZV?|nCJ#L0WUX6iH{H^Nf_^OT-X?Yz6POGEFz$&&n zb#(kv`-!x?4g;svQDcDkt3>qkPK&M1d{plcf0c-SUgga!!_9Q!uj7+l{pgJ4lsbri zc_a{j-?d;lk?`2ED{gl66CTujv&8;i9xcS*djDrGp;CD?^tbGan_d0r&%Ewy>g@k& zo!ZRTgos^nv#Xz)_)u4E)L1eD)zmt*nODcw$=ek-yZX_Yvs3D*u|)hU-b>w7d=j zr`1toU=>@PIy!!-{X|+`hk?`Ts4+nNRU-O%r^QxhKB{+!ze+?u&+NiYs&_i^$Nzt+ z)FLOZ6aUEZ7M`dC5Py|ObmbBM=!&=ME#j{diLN~2A6@Y_d&|!O=jZ&X*NyyaKv-lG z;A^_do&(Cy0yaMvIYUfha|mv4J}$^Hkb(dRfB*=900@8p2!H?xfB*=9 z00@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p z2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2t*kH zFAM}M2;^ksWtfX|+(yNGtf-h5mFJ5^Lvwdtui>tk&#BOz*PB=I{}1M{?zrRtVead(xftc4gJm4 zyt+TQmHNv5WbO;wAW&BXl7$c+l0kBbMEXnS5u#-ipGx!i0|Fob0w4eaAOHd&00JNY z0w4eaAOHfPBQS=Bnnv=F>XTH9r-JX1__w?~q)0RVT`~Eaf}hd0L268DO_Mv|`^ zv>j>oJ90?<9p-~nc9tal=5!y4*Gie8R~^0_f5M~!|#Zd|Ll99@#@O|7inO_MtP_& zHY@*mZ5Sr;*pdfrhScP^JkQ!NEC1DTbn2*W?8>YD^LrG}r@9I>A06Lx>ICXP*mBi> zgF2LD)ky=*L&rCrI)VBRwp{wib6_(_vaC8Ox3w}I-*oC&^=(I)^b!91Xd0AACe=v; z#X={xI&}i|A8fhwQN};okAK1PRNL#sR;P~IuU&Z=|7bt|ksRzw4S#^FV(X;y-$2(P z!Ip>1^^aZqQJ{XT;vcAPB$h|J|Myc+kj$TV^Jl>P-2i_F5UFPM z`S&q$_A*JXgB!FRsh@wF-`n`}?ggagBwi1Ej={c54hC&Un(_Od{Qir-_fd^m@b_PH zNFEXl1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;sw7ZX&nGaCJAb|}XZRl_Bhx&$ zue>P3pZXGS5vN5$G~#D{+>}yLF_#;z>ZP(>fPQ&M5?fiCQJVG2dCGaqRQlzs<;=hQ zoQUqEaip^6M0CP)A_xZz1V8`;KmY_l00e5AKua26Dd`DPH&Q(k+m}dVNtqa9vNI2RCnl#Tpl$Jz;@x55VXoP>l=J|ikqR)x`dUhrr>WrBMqc#2sndi^< z9;tn1`|H`6c>LpJP?}gnwW4-x=K04_KG82ew(`AowK@OE)IVDn5|3Avtd1+@`Ey^= z5@_QvDHQWRO5=DnyL*W)h)S(i()ww1wME_2?|D^7k5LhqUnxxu(V`*e)pUWl@*bC0m8$Jz zUiRuGW)&Kx#;On6#P1 zw~2c?C zdX)56QmEd4Xeby6fB*=D9|8LCpbB%*>#X;@#iCJ$Pw!J|mam-a`08?fJ>$ a(26Nlf)IIhWm2kj<=b8=FRLT#Qu=@ED6NG6 From c576bb611d2d4efeb3a44ad10d944bca5c893e5d Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 15 Oct 2020 13:19:50 -0700 Subject: [PATCH 11/65] LEGO: check in for master to temporary branch. (#7305) Co-authored-by: Clint Rutkas --- .../Strings/en-us/Resources.resw.lcl | 33 ++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 39 +++++++++++++++++++ .../keyboardmanager/dll/Resources.resx.lcl | 8 +++- .../powerpreview/Resources.resx.lcl | 18 +++++++++ .../powerpreview/Resources.resx.lcl | 3 ++ 7 files changed, 136 insertions(+), 1 deletion(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 817ed9ec41..d895a16088 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,12 @@ + + + + + + @@ -460,6 +466,15 @@ + + + + + + + + + @@ -496,6 +511,18 @@ + + + + + + + + + + + + @@ -928,6 +955,12 @@ + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index d465f998fa..f8ab54440c 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/ja/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/ko/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/ko/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 01aa40d1c6..a5ddf1b730 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/ko/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/ko/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index be2829d13d..8f665c5b63 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,12 @@ + + + + + + @@ -460,6 +466,15 @@ + + + + + + + + + @@ -496,6 +511,24 @@ + + + + + + + + + + + + + + + + + + @@ -928,6 +961,12 @@ + + + + + + diff --git a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl index 47d4174e99..e1d40a93b7 100644 --- a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + 키를 누르고 "Ctrl+C"를 사용하려는 경우 "A" 키는 "키" 열이 되고, 바로 가기 "Ctrl+C"는 "매핑 대상" 열이 됩니다.]]> + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/previewpane/powerpreview/loc/nl/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/nl/src/modules/previewpane/powerpreview/Resources.resx.lcl index d6f36b9682..2730b8931f 100644 --- a/src/modules/previewpane/powerpreview/loc/nl/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/nl/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl index a5e466a760..bb57b7d0c4 100644 --- a/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/pt-BR/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -40,6 +40,9 @@ + + + From 4634c74f9eb5eaaa07df76c188bc9bfbf9151ea7 Mon Sep 17 00:00:00 2001 From: Mykhailo Pylyp Date: Fri, 16 Oct 2020 14:09:57 +0300 Subject: [PATCH 12/65] Remove Drop Down from combo box name as it is redundant (#7307) --- src/modules/keyboardmanager/dll/Resources.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/keyboardmanager/dll/Resources.resx b/src/modules/keyboardmanager/dll/Resources.resx index 7bb610b383..af410acd59 100644 --- a/src/modules/keyboardmanager/dll/Resources.resx +++ b/src/modules/keyboardmanager/dll/Resources.resx @@ -265,7 +265,7 @@ Unexpected error - Key Drop Down + Key Add Key Remap From 36bcbe9d95799b030bf0e83cc1fe278452cf51d8 Mon Sep 17 00:00:00 2001 From: stefansjfw <57057282+stefansjfw@users.noreply.github.com> Date: Fri, 16 Oct 2020 15:25:30 +0200 Subject: [PATCH 13/65] [FancyZones] Minor refactoring of ZoneSet class (#7274) * Minor refactoring of ZoneSet class * Remove comment --- src/modules/fancyzones/lib/ZoneSet.cpp | 173 +++++++++++-------------- src/modules/fancyzones/lib/ZoneSet.h | 92 +++++++------ 2 files changed, 127 insertions(+), 138 deletions(-) diff --git a/src/modules/fancyzones/lib/ZoneSet.cpp b/src/modules/fancyzones/lib/ZoneSet.cpp index 70c0d93469..05ce569518 100644 --- a/src/modules/fancyzones/lib/ZoneSet.cpp +++ b/src/modules/fancyzones/lib/ZoneSet.cpp @@ -1,10 +1,12 @@ #include "pch.h" -#include "util.h" -#include "lib/ZoneSet.h" -#include "Settings.h" +#include "ZoneSet.h" + #include "FancyZonesData.h" #include "FancyZonesDataTypes.h" +#include "Settings.h" +#include "Zone.h" +#include "util.h" #include @@ -15,19 +17,7 @@ using namespace FancyZonesUtils; namespace { constexpr int C_MULTIPLIER = 10000; - constexpr int MAX_ZONE_COUNT = 50; - /* - struct GridLayoutInfo { - int rows; - int columns; - int rowsPercents[MAX_ZONE_COUNT]; - int columnsPercents[MAX_ZONE_COUNT]; - int cellChildMap[MAX_ZONE_COUNT][MAX_ZONE_COUNT]; - }; - */ - - auto l = FancyZonesDataTypes::GridLayoutInfo(FancyZonesDataTypes::GridLayoutInfo::Minimal{ .rows = 1, .columns = 1 }); // PriorityGrid layout is unique for zoneCount <= 11. For zoneCount > 11 PriorityGrid is same as Grid FancyZonesDataTypes::GridLayoutInfo predefinedPriorityGridLayouts[11] = { /* 1 */ @@ -108,6 +98,11 @@ namespace .columnsPercents = { 2500, 2500, 2500, 2500 }, .cellChildMap = { { 0, 1, 2, 3 }, { 4, 1, 5, 6 }, { 7, 8, 9, 10 } } }), }; + + inline void StampWindow(HWND window, size_t bitmask) noexcept + { + SetProp(window, ZonedWindowProperties::PropertyMultipleZoneID, reinterpret_cast(bitmask)); + } } struct ZoneSet : winrt::implements @@ -125,34 +120,34 @@ public: } IFACEMETHODIMP_(GUID) - Id() noexcept { return m_config.Id; } + Id() const noexcept { return m_config.Id; } IFACEMETHODIMP_(FancyZonesDataTypes::ZoneSetLayoutType) - LayoutType() noexcept { return m_config.LayoutType; } + LayoutType() const noexcept { return m_config.LayoutType; } IFACEMETHODIMP AddZone(winrt::com_ptr zone) noexcept; IFACEMETHODIMP_(std::vector) - ZonesFromPoint(POINT pt) noexcept; + ZonesFromPoint(POINT pt) const noexcept; IFACEMETHODIMP_(std::vector) - GetZoneIndexSetFromWindow(HWND window) noexcept; + GetZoneIndexSetFromWindow(HWND window) const noexcept; IFACEMETHODIMP_(std::vector>) - GetZones() noexcept { return m_zones; } + GetZones() const noexcept { return m_zones; } IFACEMETHODIMP_(void) - MoveWindowIntoZoneByIndex(HWND window, HWND zoneWindow, size_t index) noexcept; + MoveWindowIntoZoneByIndex(HWND window, HWND workAreaWindow, size_t index) noexcept; IFACEMETHODIMP_(void) - MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::vector& indexSet) noexcept; + MoveWindowIntoZoneByIndexSet(HWND window, HWND workAreaWindow, const std::vector& indexSet) noexcept; IFACEMETHODIMP_(bool) - MoveWindowIntoZoneByDirectionAndIndex(HWND window, HWND zoneWindow, DWORD vkCode, bool cycle) noexcept; + MoveWindowIntoZoneByDirectionAndIndex(HWND window, HWND workAreaWindow, DWORD vkCode, bool cycle) noexcept; IFACEMETHODIMP_(bool) - MoveWindowIntoZoneByDirectionAndPosition(HWND window, HWND zoneWindow, DWORD vkCode, bool cycle) noexcept; + MoveWindowIntoZoneByDirectionAndPosition(HWND window, HWND workAreaWindow, DWORD vkCode, bool cycle) noexcept; IFACEMETHODIMP_(bool) - ExtendWindowByDirectionAndPosition(HWND window, HWND windowZone, DWORD vkCode) noexcept; + ExtendWindowByDirectionAndPosition(HWND window, HWND workAreaWindow, DWORD vkCode) noexcept; IFACEMETHODIMP_(void) - MoveWindowIntoZoneByPoint(HWND window, HWND zoneWindow, POINT ptClient) noexcept; + MoveWindowIntoZoneByPoint(HWND window, HWND workAreaWindow, POINT ptClient) noexcept; IFACEMETHODIMP_(bool) CalculateZones(RECT workArea, int zoneCount, int spacing) noexcept; IFACEMETHODIMP_(bool) - IsZoneEmpty(int zoneIndex) noexcept; + IsZoneEmpty(int zoneIndex) const noexcept; IFACEMETHODIMP_(std::vector) - GetCombinedZoneRange(const std::vector& initialZones, const std::vector& finalZones) noexcept; + GetCombinedZoneRange(const std::vector& initialZones, const std::vector& finalZones) const noexcept; private: bool CalculateFocusLayout(Rect workArea, int zoneCount) noexcept; @@ -161,7 +156,6 @@ private: bool CalculateUniquePriorityGridLayout(Rect workArea, int zoneCount, int spacing) noexcept; bool CalculateCustomLayout(Rect workArea, int spacing) noexcept; bool CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutInfo gridLayoutInfo, int spacing); - void StampWindow(HWND window, size_t bitmask) noexcept; std::vector> m_zones; std::map> m_windowIndexSet; @@ -182,28 +176,23 @@ IFACEMETHODIMP ZoneSet::AddZone(winrt::com_ptr zone) noexcept } IFACEMETHODIMP_(std::vector) -ZoneSet::ZonesFromPoint(POINT pt) noexcept +ZoneSet::ZonesFromPoint(POINT pt) const noexcept { - int sensitivityRadius = m_config.SensitivityRadius; std::vector capturedZones; std::vector strictlyCapturedZones; for (size_t i = 0; i < m_zones.size(); i++) { - auto zone = m_zones[i]; - RECT newZoneRect = zone->GetZoneRect(); - if (newZoneRect.left < newZoneRect.right && newZoneRect.top < newZoneRect.bottom) // proper zone + const RECT& zoneRect = m_zones[i]->GetZoneRect(); + if (zoneRect.left - m_config.SensitivityRadius <= pt.x && pt.x <= zoneRect.right + m_config.SensitivityRadius && + zoneRect.top - m_config.SensitivityRadius <= pt.y && pt.y <= zoneRect.bottom + m_config.SensitivityRadius) { - if (newZoneRect.left - sensitivityRadius <= pt.x && pt.x <= newZoneRect.right + sensitivityRadius && - newZoneRect.top - sensitivityRadius <= pt.y && pt.y <= newZoneRect.bottom + sensitivityRadius) - { - capturedZones.emplace_back(i); - } + capturedZones.emplace_back(i); + } - if (newZoneRect.left <= pt.x && pt.x < newZoneRect.right && - newZoneRect.top <= pt.y && pt.y < newZoneRect.bottom) - { - strictlyCapturedZones.emplace_back(i); - } + if (zoneRect.left <= pt.x && pt.x < zoneRect.right && + zoneRect.top <= pt.y && pt.y < zoneRect.bottom) + { + strictlyCapturedZones.emplace_back(i); } } @@ -216,22 +205,24 @@ ZoneSet::ZonesFromPoint(POINT pt) noexcept // 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) + sensitivityRadius < min(rectI.bottom, rectJ.bottom) && - max(rectI.left, rectJ.left) + sensitivityRadius < min(rectI.right, rectJ.right)) + const auto& rectI = m_zones[capturedZones[i]]->GetZoneRect(); + const auto& rectJ = m_zones[capturedZones[j]]->GetZoneRect(); + if (max(rectI.top, rectJ.top) + m_config.SensitivityRadius < min(rectI.bottom, rectJ.bottom) && + max(rectI.left, rectJ.left) + m_config.SensitivityRadius < min(rectI.right, rectJ.right)) { overlap = true; - i = capturedZones.size() - 1; break; } } + if (overlap) + { + break; + } } if (overlap) @@ -239,8 +230,8 @@ ZoneSet::ZonesFromPoint(POINT pt) noexcept 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(); + const auto& rectS = m_zones[capturedZones[smallestIdx]]->GetZoneRect(); + const 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); @@ -256,7 +247,7 @@ ZoneSet::ZonesFromPoint(POINT pt) noexcept return capturedZones; } -std::vector ZoneSet::GetZoneIndexSetFromWindow(HWND window) noexcept +std::vector ZoneSet::GetZoneIndexSetFromWindow(HWND window) const noexcept { auto it = m_windowIndexSet.find(window); if (it == m_windowIndexSet.end()) @@ -270,13 +261,13 @@ std::vector ZoneSet::GetZoneIndexSetFromWindow(HWND window) noexcept } IFACEMETHODIMP_(void) -ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, size_t index) noexcept +ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND workAreaWindow, size_t index) noexcept { - MoveWindowIntoZoneByIndexSet(window, windowZone, { index }); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, { index }); } IFACEMETHODIMP_(void) -ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::vector& indexSet) noexcept +ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND workAreaWindow, const std::vector& indexSet) noexcept { if (m_zones.empty()) { @@ -294,14 +285,13 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::v bool sizeEmpty = true; size_t bitmask = 0; - auto& storedIndexSet = m_windowIndexSet[window]; - storedIndexSet = {}; + m_windowIndexSet[window] = {}; for (size_t index : indexSet) { if (index < m_zones.size()) { - RECT newSize = m_zones.at(index)->ComputeActualZoneRect(window, windowZone); + RECT newSize = m_zones.at(index)->ComputeActualZoneRect(window, workAreaWindow); if (!sizeEmpty) { size.left = min(size.left, newSize.left); @@ -315,7 +305,7 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::v sizeEmpty = false; } - storedIndexSet.push_back(index); + m_windowIndexSet[window].push_back(index); } if (index < std::numeric_limits::digits) @@ -333,7 +323,7 @@ ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::v } IFACEMETHODIMP_(bool) -ZoneSet::MoveWindowIntoZoneByDirectionAndIndex(HWND window, HWND windowZone, DWORD vkCode, bool cycle) noexcept +ZoneSet::MoveWindowIntoZoneByDirectionAndIndex(HWND window, HWND workAreaWindow, DWORD vkCode, bool cycle) noexcept { if (m_zones.empty()) { @@ -346,7 +336,7 @@ ZoneSet::MoveWindowIntoZoneByDirectionAndIndex(HWND window, HWND windowZone, DWO // The window was not assigned to any zone here if (indexSet.size() == 0) { - MoveWindowIntoZoneByIndexSet(window, windowZone, { vkCode == VK_LEFT ? numZones - 1 : 0 }); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, { vkCode == VK_LEFT ? numZones - 1 : 0 }); return true; } @@ -357,12 +347,12 @@ ZoneSet::MoveWindowIntoZoneByDirectionAndIndex(HWND window, HWND windowZone, DWO { if (!cycle) { - MoveWindowIntoZoneByIndexSet(window, windowZone, {}); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, {}); return false; } else { - MoveWindowIntoZoneByIndexSet(window, windowZone, { vkCode == VK_LEFT ? numZones - 1 : 0 }); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, { vkCode == VK_LEFT ? numZones - 1 : 0 }); return true; } } @@ -370,25 +360,24 @@ ZoneSet::MoveWindowIntoZoneByDirectionAndIndex(HWND window, HWND windowZone, DWO // We didn't reach the edge if (vkCode == VK_LEFT) { - MoveWindowIntoZoneByIndexSet(window, windowZone, { oldIndex - 1 }); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, { oldIndex - 1 }); } else { - MoveWindowIntoZoneByIndexSet(window, windowZone, { oldIndex + 1 }); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, { oldIndex + 1 }); } return true; } IFACEMETHODIMP_(bool) -ZoneSet::MoveWindowIntoZoneByDirectionAndPosition(HWND window, HWND windowZone, DWORD vkCode, bool cycle) noexcept +ZoneSet::MoveWindowIntoZoneByDirectionAndPosition(HWND window, HWND workAreaWindow, DWORD vkCode, bool cycle) noexcept { if (m_zones.empty()) { return false; } - auto zoneObjects = GetZones(); - std::vector usedZoneIndices(zoneObjects.size(), false); + std::vector usedZoneIndices(m_zones.size(), false); for (size_t idx : GetZoneIndexSetFromWindow(window)) { usedZoneIndices[idx] = true; @@ -397,17 +386,17 @@ ZoneSet::MoveWindowIntoZoneByDirectionAndPosition(HWND window, HWND windowZone, std::vector zoneRects; std::vector freeZoneIndices; - for (size_t i = 0; i < zoneObjects.size(); i++) + for (size_t i = 0; i < m_zones.size(); i++) { if (!usedZoneIndices[i]) { - zoneRects.emplace_back(zoneObjects[i]->GetZoneRect()); + zoneRects.emplace_back(m_zones[i]->GetZoneRect()); freeZoneIndices.emplace_back(i); } } RECT windowRect, windowZoneRect; - if (GetWindowRect(window, &windowRect) && GetWindowRect(windowZone, &windowZoneRect)) + if (GetWindowRect(window, &windowRect) && GetWindowRect(workAreaWindow, &windowZoneRect)) { // Move to coordinates relative to windowZone windowRect.top -= windowZoneRect.top; @@ -418,21 +407,21 @@ ZoneSet::MoveWindowIntoZoneByDirectionAndPosition(HWND window, HWND windowZone, size_t result = FancyZonesUtils::ChooseNextZoneByPosition(vkCode, windowRect, zoneRects); if (result < zoneRects.size()) { - MoveWindowIntoZoneByIndex(window, windowZone, freeZoneIndices[result]); + MoveWindowIntoZoneByIndex(window, workAreaWindow, freeZoneIndices[result]); return true; } else if (cycle) { // Try again from the position off the screen in the opposite direction to vkCode // Consider all zones as available - zoneRects.resize(zoneObjects.size()); - std::transform(zoneObjects.begin(), zoneObjects.end(), zoneRects.begin(), [](auto zone) { return zone->GetZoneRect(); }); + zoneRects.resize(m_zones.size()); + std::transform(m_zones.begin(), m_zones.end(), zoneRects.begin(), [](auto zone) { return zone->GetZoneRect(); }); windowRect = FancyZonesUtils::PrepareRectForCycling(windowRect, windowZoneRect, vkCode); result = FancyZonesUtils::ChooseNextZoneByPosition(vkCode, windowRect, zoneRects); if (result < zoneRects.size()) { - MoveWindowIntoZoneByIndex(window, windowZone, result); + MoveWindowIntoZoneByIndex(window, workAreaWindow, result); return true; } } @@ -442,7 +431,7 @@ ZoneSet::MoveWindowIntoZoneByDirectionAndPosition(HWND window, HWND windowZone, } IFACEMETHODIMP_(bool) -ZoneSet::ExtendWindowByDirectionAndPosition(HWND window, HWND windowZone, DWORD vkCode) noexcept +ZoneSet::ExtendWindowByDirectionAndPosition(HWND window, HWND workAreaWindow, DWORD vkCode) noexcept { if (m_zones.empty()) { @@ -450,11 +439,10 @@ ZoneSet::ExtendWindowByDirectionAndPosition(HWND window, HWND windowZone, DWORD } RECT windowRect, windowZoneRect; - if (GetWindowRect(window, &windowRect) && GetWindowRect(windowZone, &windowZoneRect)) + if (GetWindowRect(window, &windowRect) && GetWindowRect(workAreaWindow, &windowZoneRect)) { - auto zoneObjects = GetZones(); auto oldZones = GetZoneIndexSetFromWindow(window); - std::vector usedZoneIndices(zoneObjects.size(), false); + std::vector usedZoneIndices(m_zones.size(), false); std::vector zoneRects; std::vector freeZoneIndices; @@ -464,7 +452,7 @@ ZoneSet::ExtendWindowByDirectionAndPosition(HWND window, HWND windowZone, DWORD if (finalIndexIt != m_windowFinalIndex.end()) { usedZoneIndices[finalIndexIt->second] = true; - windowRect = zoneObjects[finalIndexIt->second]->GetZoneRect(); + windowRect = m_zones[finalIndexIt->second]->GetZoneRect(); } else { @@ -479,11 +467,11 @@ ZoneSet::ExtendWindowByDirectionAndPosition(HWND window, HWND windowZone, DWORD windowRect.right -= windowZoneRect.left; } - for (size_t i = 0; i < zoneObjects.size(); i++) + for (size_t i = 0; i < m_zones.size(); i++) { if (!usedZoneIndices[i]) { - zoneRects.emplace_back(zoneObjects[i]->GetZoneRect()); + zoneRects.emplace_back(m_zones[i]->GetZoneRect()); freeZoneIndices.emplace_back(i); } } @@ -519,7 +507,7 @@ ZoneSet::ExtendWindowByDirectionAndPosition(HWND window, HWND windowZone, DWORD } m_inExtendWindow = true; - MoveWindowIntoZoneByIndexSet(window, windowZone, resultIndexSet); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, resultIndexSet); m_inExtendWindow = false; return true; } @@ -529,10 +517,10 @@ ZoneSet::ExtendWindowByDirectionAndPosition(HWND window, HWND windowZone, DWORD } IFACEMETHODIMP_(void) -ZoneSet::MoveWindowIntoZoneByPoint(HWND window, HWND zoneWindow, POINT ptClient) noexcept +ZoneSet::MoveWindowIntoZoneByPoint(HWND window, HWND workAreaWindow, POINT ptClient) noexcept { - auto zones = ZonesFromPoint(ptClient); - MoveWindowIntoZoneByIndexSet(window, zoneWindow, zones); + const auto& zones = ZonesFromPoint(ptClient); + MoveWindowIntoZoneByIndexSet(window, workAreaWindow, zones); } IFACEMETHODIMP_(bool) @@ -573,7 +561,7 @@ ZoneSet::CalculateZones(RECT workAreaRect, int zoneCount, int spacing) noexcept return success; } -bool ZoneSet::IsZoneEmpty(int zoneIndex) noexcept +bool ZoneSet::IsZoneEmpty(int zoneIndex) const noexcept { for (auto& [window, zones] : m_windowIndexSet) { @@ -878,12 +866,7 @@ bool ZoneSet::CalculateGridZones(Rect workArea, FancyZonesDataTypes::GridLayoutI return true; } -void ZoneSet::StampWindow(HWND window, size_t bitmask) noexcept -{ - SetProp(window, ZonedWindowProperties::PropertyMultipleZoneID, reinterpret_cast(bitmask)); -} - -std::vector ZoneSet::GetCombinedZoneRange(const std::vector& initialZones, const std::vector& finalZones) noexcept +std::vector ZoneSet::GetCombinedZoneRange(const std::vector& initialZones, const std::vector& finalZones) const noexcept { std::vector combinedZones, result; std::set_union(begin(initialZones), end(initialZones), begin(finalZones), end(finalZones), std::back_inserter(combinedZones)); @@ -894,7 +877,7 @@ std::vector ZoneSet::GetCombinedZoneRange(const std::vector& ini for (size_t zoneId : combinedZones) { - RECT rect = zones[zoneId]->GetZoneRect(); + const RECT& rect = zones[zoneId]->GetZoneRect(); if (boundingRectEmpty) { boundingRect = rect; diff --git a/src/modules/fancyzones/lib/ZoneSet.h b/src/modules/fancyzones/lib/ZoneSet.h index d62c9f0b2b..cc99cac07c 100644 --- a/src/modules/fancyzones/lib/ZoneSet.h +++ b/src/modules/fancyzones/lib/ZoneSet.h @@ -16,11 +16,11 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet : /** * @returns Unique identifier of zone layout. */ - IFACEMETHOD_(GUID, Id)() = 0; + IFACEMETHOD_(GUID, Id)() const = 0; /** * @returns Type of the zone layout. Layout type can be focus, columns, rows, grid, priority grid or custom. */ - IFACEMETHOD_(FancyZonesDataTypes::ZoneSetLayoutType, LayoutType)() = 0; + IFACEMETHOD_(FancyZonesDataTypes::ZoneSetLayoutType, LayoutType)() const = 0; /** * Add zone to the zone layout. * @@ -33,89 +33,95 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet : * @param pt Cursor coordinates. * @returns Vector of indices, corresponding to the current set of zones - the zones considered active. */ - IFACEMETHOD_(std::vector, ZonesFromPoint)(POINT pt) = 0; + IFACEMETHOD_(std::vector, ZonesFromPoint)(POINT pt) const = 0; /** * Get index set of the zones to which the window was assigned. * * @param window Handle of the window. - * @returns A vector of size_t, 0-based, the index set. + * @returns A vector of size_t, 0-based index set. */ - IFACEMETHOD_(std::vector, GetZoneIndexSetFromWindow)(HWND window) = 0; + IFACEMETHOD_(std::vector, GetZoneIndexSetFromWindow) + (HWND window) const = 0; /** * @returns Array of zone objects (defining coordinates of the zone) inside this zone layout. */ - IFACEMETHOD_(std::vector>, GetZones)() = 0; + IFACEMETHOD_(std::vector>, GetZones)() const = 0; /** * Assign window to the zone based on zone index 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 index Zone index within zone layout. + * @param window Handle of window which should be assigned to zone. + * @param workAreaWindow The m_window of a ZoneWindow, it's a hidden window representing the + * current monitor desktop work area. + * @param index Zone index within zone layout. */ - IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, HWND zoneWindow, size_t index) = 0; + IFACEMETHOD_(void, MoveWindowIntoZoneByIndex) + (HWND window, HWND workAreaWindow, size_t 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 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 window Handle of window which should be assigned to zone. + * @param workAreaWindow 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. */ - IFACEMETHOD_(void, MoveWindowIntoZoneByIndexSet)(HWND window, HWND zoneWindow, const std::vector& indexSet) = 0; + IFACEMETHOD_(void, MoveWindowIntoZoneByIndexSet) + (HWND window, HWND workAreaWindow, const std::vector& indexSet) = 0; /** * Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow), based on zone index numbers, * not their on-screen position. * - * @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 vkCode Pressed arrow key. - * @param cycle Whether we should move window to the first zone if we reached last zone in layout. + * @param window Handle of window which should be assigned to zone. + * @param workAreaWindow The m_window of a ZoneWindow, it's a hidden window representing the + * current monitor desktop work area. + * @param vkCode Pressed arrow key. + * @param cycle Whether we should move window to the first zone if we reached last zone in layout. * * @returns Boolean which is always true if cycle argument is set, otherwise indicating if there is more * zones left in the zone layout in which window can move. */ - IFACEMETHOD_(bool, MoveWindowIntoZoneByDirectionAndIndex)(HWND window, HWND zoneWindow, DWORD vkCode, bool cycle) = 0; + IFACEMETHOD_(bool, MoveWindowIntoZoneByDirectionAndIndex) + (HWND window, HWND workAreaWindow, DWORD vkCode, bool cycle) = 0; /** * Assign window to the zone based on direction (using WIN + LEFT/RIGHT/UP/DOWN arrow), based on * their on-screen position. * - * @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 vkCode Pressed arrow key. - * @param cycle Whether we should move window to the first zone if we reached last zone in layout. + * @param window Handle of window which should be assigned to zone. + * @param workAreaWindow The m_window of a ZoneWindow, it's a hidden window representing the + * current monitor desktop work area. + * @param vkCode Pressed arrow key. + * @param cycle Whether we should move window to the first zone if we reached last zone in layout. * * @returns Boolean which is always true if cycle argument is set, otherwise indicating if there is more * zones left in the zone layout in which window can move. */ - IFACEMETHOD_(bool, MoveWindowIntoZoneByDirectionAndPosition)(HWND window, HWND zoneWindow, DWORD vkCode, bool cycle) = 0; + IFACEMETHOD_(bool, MoveWindowIntoZoneByDirectionAndPosition) + (HWND window, HWND workAreaWindow, DWORD vkCode, bool cycle) = 0; /** * Extend or shrink the window to an adjacent zone based on direction (using CTRL+WIN+ALT + LEFT/RIGHT/UP/DOWN arrow), based on * their on-screen position. * - * @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 vkCode Pressed arrow key. + * @param window Handle of window which should be assigned to zone. + * @param workAreaWindow The m_window of a ZoneWindow, it's a hidden window representing the + * current monitor desktop work area. + * @param vkCode Pressed arrow key. * * @returns Boolean indicating whether the window was rezoned. False could be returned when there are no more * zones available in the given direction. */ - IFACEMETHOD_(bool, ExtendWindowByDirectionAndPosition)(HWND window, HWND zoneWindow, DWORD vkCode) = 0; + IFACEMETHOD_(bool, ExtendWindowByDirectionAndPosition) + (HWND window, HWND workAreaWindow, DWORD vkCode) = 0; /** * Assign window to the zone based on cursor coordinates. * - * @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 pt Cursor coordinates. + * @param window Handle of window which should be assigned to zone. + * @param workAreaWindow The m_window of a ZoneWindow, it's a hidden window representing the + * current monitor desktop work area. + * @param pt Cursor coordinates. */ - IFACEMETHOD_(void, MoveWindowIntoZoneByPoint)(HWND window, HWND zoneWindow, POINT ptClient) = 0; + IFACEMETHOD_(void, MoveWindowIntoZoneByPoint) + (HWND window, HWND workAreaWindow, POINT ptClient) = 0; /** - * Calculate zone coordinates within zone layout based on number of zones and spacing. Used for one of - * the predefined layouts (focus, columns, rows, grid, priority grid) or for custom layout. + * Calculate zone coordinates within zone layout based on number of zones and spacing. * * @param workAreaRect The rectangular area on the screen on which the zone layout is applied. * @param zoneCount Number of zones inside zone layout. @@ -125,13 +131,13 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet : */ IFACEMETHOD_(bool, CalculateZones)(RECT workAreaRect, int zoneCount, int spacing) = 0; /** - * Check if the zone with the specified index is empty. Returns true if the zone does not exist. + * Check if the zone with the specified index is empty. Returns true if the zone with passed zoneIndex does not exist. * * @param zoneIndex The index of of the zone within this zone set. * * @returns Boolean indicating whether the zone is empty. */ - IFACEMETHOD_(bool, IsZoneEmpty)(int zoneIndex) = 0; + IFACEMETHOD_(bool, IsZoneEmpty)(int zoneIndex) const = 0; /** * Returns all zones spanned by the minimum bounding rectangle containing the two given zone index sets. * @@ -140,7 +146,7 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet : * * @returns A vector indicating describing the chosen zone index set. */ - IFACEMETHOD_(std::vector, GetCombinedZoneRange)(const std::vector& initialZones, const std::vector& finalZones) = 0; + IFACEMETHOD_(std::vector, GetCombinedZoneRange)(const std::vector& initialZones, const std::vector& finalZones) const = 0; }; struct ZoneSetConfig From c34c96312136001229a42996a6e082de0216177a Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Wed, 14 Oct 2020 17:36:03 +0300 Subject: [PATCH 14/65] bootstrapper: implement logging support - add cxxopts and spdlog libraries - implement cmd flag for severity - add debug and error messages --- .gitmodules | 7 + PowerToys.sln | 7 + deps/cxxopts | 1 + deps/cxxopts.props | 7 + deps/spdlog | 1 + deps/spdlog.props | 8 + .../PowerToysBootstrapper.sln | 6 + .../bootstrapper/bootstrapper.cpp | 178 ++++++++++++------ .../bootstrapper/bootstrapper.vcxproj | 9 +- .../PowerToysBootstrapper/bootstrapper/pch.h | 7 + src/logging/logging.vcxproj | 178 ++++++++++++++++++ src/logging/logging.vcxproj.filters | 122 ++++++++++++ 12 files changed, 473 insertions(+), 58 deletions(-) create mode 100644 .gitmodules create mode 160000 deps/cxxopts create mode 100644 deps/cxxopts.props create mode 160000 deps/spdlog create mode 100644 deps/spdlog.props create mode 100644 src/logging/logging.vcxproj create mode 100644 src/logging/logging.vcxproj.filters diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..5a6991232f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,7 @@ +[submodule "deps/spdlog"] + path = deps/spdlog + url = https://github.com/gabime/spdlog.git + +[submodule "deps/cxxopts"] + path = deps/cxxopts + url = https://github.com/jarro2783/cxxopts.git diff --git a/PowerToys.sln b/PowerToys.sln index ce3c636352..c44829d472 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -269,6 +269,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Calculator EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Folder.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Folder.UnitTests\Microsoft.Plugin.Folder.UnitTests.csproj", "{4FA206A5-F69F-4193-BF8F-F6EEB496734C}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logging", "src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -543,6 +545,10 @@ Global {4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Debug|x64.Build.0 = Debug|x64 {4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.ActiveCfg = Release|x64 {4FA206A5-F69F-4193-BF8F-F6EEB496734C}.Release|x64.Build.0 = Release|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.Build.0 = Debug|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.ActiveCfg = Release|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -621,6 +627,7 @@ Global {0F85E674-34AE-443D-954C-8321EB8B93B1} = {C3081D9A-1586-441A-B5F4-ED815B3719C1} {632BBE62-5421-49EA-835A-7FFA4F499BD6} = {4AFC9975-2456-4C70-94A4-84073C1CED93} {4FA206A5-F69F-4193-BF8F-F6EEB496734C} = {4AFC9975-2456-4C70-94A4-84073C1CED93} + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} = {1AFB6476-670D-4E80-A464-657E01DFF482} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} diff --git a/deps/cxxopts b/deps/cxxopts new file mode 160000 index 0000000000..12e496da3d --- /dev/null +++ b/deps/cxxopts @@ -0,0 +1 @@ +Subproject commit 12e496da3d486b87fa9df43edea65232ed852510 diff --git a/deps/cxxopts.props b/deps/cxxopts.props new file mode 100644 index 0000000000..25cc72b199 --- /dev/null +++ b/deps/cxxopts.props @@ -0,0 +1,7 @@ + + + + $(MSBuildThisFileDirectory)cxxopts\include;%(AdditionalIncludeDirectories) + + + diff --git a/deps/spdlog b/deps/spdlog new file mode 160000 index 0000000000..cbe9448650 --- /dev/null +++ b/deps/spdlog @@ -0,0 +1 @@ +Subproject commit cbe9448650176797739dbab13961ef4c07f4290f diff --git a/deps/spdlog.props b/deps/spdlog.props new file mode 100644 index 0000000000..2689f24231 --- /dev/null +++ b/deps/spdlog.props @@ -0,0 +1,8 @@ + + + + $(MSBuildThisFileDirectory)spdlog\include;%(AdditionalIncludeDirectories) + SPDLOG_WCHAR_TO_UTF8_SUPPORT;SPDLOG_COMPILED_LIB;%(PreprocessorDefinitions) + + + diff --git a/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln b/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln index f935a035e8..119aa75d00 100644 --- a/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln +++ b/installer/PowerToysBootstrapper/PowerToysBootstrapper.sln @@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\..\src\common\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bootstrapper", "bootstrapper\bootstrapper.vcxproj", "{D194E3AA-F824-4CA9-9A58-034DD6B7D022}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logging", "..\..\src\logging\logging.vcxproj", "{7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -27,6 +29,10 @@ Global {D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Debug|x64.Build.0 = Debug|x64 {D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Release|x64.ActiveCfg = Release|x64 {D194E3AA-F824-4CA9-9A58-034DD6B7D022}.Release|x64.Build.0 = Release|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.ActiveCfg = Debug|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Debug|x64.Build.0 = Debug|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.ActiveCfg = Release|x64 + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp index cc22f38b3d..2cbc5184ab 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp +++ b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp @@ -10,16 +10,22 @@ #include #include - #include extern "C" IMAGE_DOS_HEADER __ImageBase; +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) namespace { const wchar_t APPLICATION_ID[] = L"PowerToysInstaller"; const wchar_t TOAST_TAG[] = L"PowerToysInstallerProgress"; + const char LOG_FILENAME[] = "powertoys-bootstrapper-" STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_REVISION) ".log"; + const char MSI_LOG_FILENAME[] = "powertoys-bootstrapper-msi-" STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_REVISION) ".log"; + } +#undef STR +#undef STR_HELPER namespace localized_strings { @@ -59,63 +65,89 @@ std::optional extractIcon() return iconRes->saveAsFile(icoPath) ? std::make_optional(std::move(icoPath)) : std::nullopt; } -enum class CmdArgs +void setup_log(const spdlog::level::level_enum severity) { - silent, - noFullUI, - noStartPT, - skipDotnetInstall, - showHelp -}; - -namespace -{ - const std::unordered_map knownArgs = { - { L"--help", CmdArgs::showHelp }, - { L"--no_full_ui", CmdArgs::noFullUI }, - { L"--silent", CmdArgs::silent }, - { L"--no_start_pt", CmdArgs::noStartPT }, - { L"--skip_dotnet_install", CmdArgs::skipDotnetInstall } - }; -} - -std::unordered_set parseCmdArgs(const int nCmdArgs, LPWSTR* argList) -{ - std::unordered_set result; - for (size_t i = 1; i < nCmdArgs; ++i) + try { - if (auto it = knownArgs.find(argList[i]); it != end(knownArgs)) + std::shared_ptr logger; + if (severity != spdlog::level::off) { - result.emplace(it->second); + logger = spdlog::basic_logger_mt("file", LOG_FILENAME); + + std::error_code _; + const DWORD msiSev = severity == spdlog::level::debug ? INSTALLLOGMODE_VERBOSE : INSTALLLOGMODE_ERROR; + const auto msiLogPath = fs::current_path(_) / MSI_LOG_FILENAME; + MsiEnableLogW(msiSev, msiLogPath.c_str(), INSTALLLOGATTRIBUTES_APPEND); } + else + { + logger = spdlog::null_logger_mt("null"); + } + logger->set_pattern("[%L][%d-%m-%C-%T] %v"); + logger->set_level(severity); + spdlog::set_default_logger(std::move(logger)); + spdlog::set_level(severity); + spdlog::flush_every(std::chrono::seconds(5)); + } + catch (...) + { } - return result; } int bootstrapper() { using namespace localized_strings; winrt::init_apartment(); - - int nCmdArgs = 0; - LPWSTR* argList = CommandLineToArgvW(GetCommandLineW(), &nCmdArgs); - const auto cmdArgs = parseCmdArgs(nCmdArgs, argList); - std::wostringstream oss; - if (cmdArgs.contains(CmdArgs::showHelp)) + cxxopts::Options options{ "PowerToysBootstrapper" }; + // clang-format off + options.add_options() + ("h,help", "Show help") + ("no_full_ui", "Use reduced UI for MSI") + ("s,silent", "Suppress MSI UI and notifications") + ("no_start_pt", "Do not launch PowerToys after the installation is complete") + ("skip_dotnet_install", "Skip dotnet 3.X installation even if it's not detected") + ("log_level", "Log level. Possible values: off|debug|error", cxxopts::value()->default_value("off")); + // clang-format on + cxxopts::ParseResult cmdArgs; + options.allow_unrecognised_options(); + try { - oss << "Supported arguments:\n\n"; - for (auto [arg, _] : knownArgs) - { - oss << arg << '\n'; - } - MessageBoxW(nullptr, oss.str().c_str(), L"Help", MB_OK | MB_ICONINFORMATION); + cmdArgs = options.parse(__argc, const_cast(__argv)); + } + catch (...) + { + } + const bool showHelp = cmdArgs["help"].as(); + const bool noFullUI = cmdArgs["no_full_ui"].as(); + const bool silent = cmdArgs["silent"].as(); + const bool skipDotnetInstall = cmdArgs["skip_dotnet_install"].as(); + const bool noStartPT = cmdArgs["no_start_pt"].as(); + const auto logLevel = cmdArgs["log_level"].as(); + spdlog::level::level_enum severity = spdlog::level::off; + + if (logLevel == "debug") + { + severity = spdlog::level::debug; + } + else if (logLevel == "error") + { + severity = spdlog::level::err; + } + setup_log(severity); + if (showHelp) + { + std::ostringstream helpMsg; + helpMsg << options.help(); + MessageBoxA(nullptr, helpMsg.str().c_str(), "Help", MB_OK | MB_ICONINFORMATION); return 0; } - if (!cmdArgs.contains(CmdArgs::noFullUI)) + spdlog::debug("PowerToys Bootstrapper is launched!\nnoFullUI: {}\nsilent: {}\nno_start_pt: {}\nskip_dotnet_install: {}\nlog_level: {}", noFullUI, silent, noStartPT, skipDotnetInstall, logLevel); + + if (!noFullUI) { MsiSetInternalUI(INSTALLUILEVEL_FULL, nullptr); } - if (cmdArgs.contains(CmdArgs::silent)) + if (silent) { if (is_process_elevated()) { @@ -123,8 +155,12 @@ int bootstrapper() } else { - // MSI fails to run in silent mode due to a suppressed UAC w/o elevation, so we restart elevated + spdlog::debug("MSI doesn't support silent mode without elevation => restarting elevated"); + // MSI fails to run in silent mode due to a suppressed UAC w/o elevation, + // so we restart ourselves elevated with the same args std::wstring params; + int nCmdArgs = 0; + LPWSTR* argList = CommandLineToArgvW(GetCommandLineW(), &nCmdArgs); for (int i = 1; i < nCmdArgs; ++i) { params += argList[i]; @@ -136,6 +172,7 @@ int bootstrapper() const auto processHandle = run_elevated(argList[0], params.c_str()); if (!processHandle) { + spdlog::error("Couldn't restart elevated to enable silent mode! ({})", GetLastError()); return 1; } if (WaitForSingleObject(processHandle, 3600000) == WAIT_OBJECT_0) @@ -146,6 +183,7 @@ int bootstrapper() } else { + spdlog::error("Elevated setup process timed out after 60m => using basic MSI UI ({})", GetLastError()); // Couldn't install using the completely silent mode in an hour, use basic UI. TerminateProcess(processHandle, 0); MsiSetInternalUI(INSTALLUILEVEL_BASIC, nullptr); @@ -163,16 +201,17 @@ int bootstrapper() auto instanceMutex = createAppMutex(POWERTOYS_BOOTSTRAPPER_MUTEX_NAME); if (!instanceMutex) { + spdlog::error("Couldn't acquire PowerToys global mutex. That means setup couldn't kill PowerToys.exe process"); return 1; } notifications::override_application_id(APPLICATION_ID); - + spdlog::debug("Extracting icon for toast notifications"); fs::path iconPath{ L"C:\\" }; if (auto extractedIcon = extractIcon()) { iconPath = std::move(*extractedIcon); } - + spdlog::debug("Registering app id for toast notifications"); notifications::register_application_id(TOAST_TITLE, iconPath.c_str()); auto removeShortcut = wil::scope_exit([&] { @@ -186,6 +225,7 @@ int bootstrapper() auto msi_path = updating::get_msi_package_path(); if (!msi_path.empty()) { + spdlog::error(L"Detected a newer {} version => launching its installer", installedVersion->toWstring()); MsiInstallProductW(msi_path.c_str(), nullptr); return 0; } @@ -196,19 +236,22 @@ int bootstrapper() progressParams.progress = 0.0f; progressParams.progress_title = EXTRACTING_INSTALLER; notifications::toast_params params{ TOAST_TAG, false, std::move(progressParams) }; - if (!cmdArgs.contains(CmdArgs::silent)) + if (!silent) { + spdlog::debug("Launching progress toast notification"); notifications::show_toast_with_activations({}, TOAST_TITLE, {}, {}, std::move(params)); } auto processToasts = wil::scope_exit([&] { + spdlog::debug("Processing HWND messages for 2s so toast have time to show up"); run_message_loop(true, 2); }); - if (!cmdArgs.contains(CmdArgs::silent)) + if (!silent) { // Worker thread to periodically increase progress and keep the progress toast from losing focus std::thread{ [&] { + spdlog::debug("Started worker thread for progress bar update"); for (;; Sleep(3000)) { std::scoped_lock lock{ progressLock }; @@ -223,7 +266,7 @@ int bootstrapper() } auto updateProgressBar = [&](const float value, const wchar_t* title) { - if (cmdArgs.contains(CmdArgs::silent)) + if (silent) { return; } @@ -233,13 +276,15 @@ int bootstrapper() notifications::update_progress_bar_toast(TOAST_TAG, progressParams); }; + spdlog::debug("Extracting embedded MSI installer"); const auto installerPath = extractEmbeddedInstaller(); if (!installerPath) { - if (!cmdArgs.contains(CmdArgs::silent)) + if (!silent) { notifications::show_toast(INSTALLER_EXTRACT_ERROR, TOAST_TITLE); } + spdlog::error("Couldn't install the MSI installer ({})", GetLastError()); return 1; } auto removeExtractedInstaller = wil::scope_exit([&] { @@ -248,12 +293,22 @@ int bootstrapper() }); updateProgressBar(.25f, UNINSTALLING_PREVIOUS_VERSION); + spdlog::debug("Acquiring existing MSI package path"); const auto package_path = updating::get_msi_package_path(); - if (!package_path.empty() && !updating::uninstall_msi_version(package_path) && !cmdArgs.contains(CmdArgs::silent)) + if (!package_path.empty()) { + spdlog::debug(L"Existing MSI package path: {}", package_path); + } + else + { + spdlog::debug("Existing MSI package path not found"); + } + if (!package_path.empty() && !updating::uninstall_msi_version(package_path) && !silent) + { + spdlog::error("Couldn't install the existing MSI package ({})", GetLastError()); notifications::show_toast(UNINSTALL_PREVIOUS_VERSION_ERROR, TOAST_TITLE); } - const bool installDotnet = !cmdArgs.contains(CmdArgs::skipDotnetInstall); + const bool installDotnet = !skipDotnetInstall; if (installDotnet) { updateProgressBar(.5f, INSTALLING_DOTNET); @@ -261,16 +316,22 @@ int bootstrapper() try { - if (installDotnet && - !updating::dotnet_is_installed() && - !updating::install_dotnet(cmdArgs.contains(CmdArgs::silent)) && - !cmdArgs.contains(CmdArgs::silent)) + if (installDotnet) { - notifications::show_toast(DOTNET_INSTALL_ERROR, TOAST_TITLE); + spdlog::debug("Detecting if dotnet is installed"); + const bool dotnetInstalled = updating::dotnet_is_installed(); + spdlog::debug("Dotnet is installed: {}", dotnetInstalled); + if (!dotnetInstalled && + !updating::install_dotnet(silent) && + !silent) + { + notifications::show_toast(DOTNET_INSTALL_ERROR, TOAST_TITLE); + } } } catch (...) { + spdlog::error("Unknown exception during dotnet installation"); MessageBoxW(nullptr, L".NET Core installation", L"Unknown exception encountered!", MB_OK | MB_ICONERROR); } @@ -278,18 +339,23 @@ int bootstrapper() // Always skip dotnet install, because we should've installed it from here earlier std::wstring msiProps = L"SKIPDOTNETINSTALL=1 "; + spdlog::debug("Launching MSI installation for new package {}", installerPath->string()); const bool installationDone = MsiInstallProductW(installerPath->c_str(), msiProps.c_str()) == ERROR_SUCCESS; updateProgressBar(1.f, installationDone ? NEW_VERSION_INSTALLATION_DONE : NEW_VERSION_INSTALLATION_ERROR); if (!installationDone) { + spdlog::error("Couldn't install new MSI package ({})", GetLastError()); return 1; } + spdlog::debug("Installation completed"); - if (!cmdArgs.contains(CmdArgs::noStartPT) && !cmdArgs.contains(CmdArgs::silent)) + if (!noStartPT && !silent) { + spdlog::debug("Starting the newly installed PowerToys.exe"); auto newPTPath = updating::get_msi_package_installed_path(); if (!newPTPath) { + spdlog::error("Couldn't determine new MSI package install location ({})", GetLastError()); return 1; } *newPTPath += L"\\PowerToys.exe"; diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj index 3966dac233..4691001006 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj +++ b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj @@ -28,6 +28,8 @@ bootstrapper + + Application true @@ -78,7 +80,7 @@ true MultiThreaded true - ../../../src/ + ../../../src/;%(AdditionalIncludeDirectories) Use pch.h @@ -99,7 +101,7 @@ true MultiThreadedDebug true - ../../../src/ + ../../../src/;%(AdditionalIncludeDirectories) Use pch.h @@ -137,6 +139,9 @@ {17da04df-e393-4397-9cf0-84dabe11032e} + + {7e1e3f13-2bd6-3f75-a6a7-873a2b55c60f} + diff --git a/installer/PowerToysBootstrapper/bootstrapper/pch.h b/installer/PowerToysBootstrapper/bootstrapper/pch.h index 11dc82b4f6..b9367228c1 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/pch.h +++ b/installer/PowerToysBootstrapper/bootstrapper/pch.h @@ -14,3 +14,10 @@ #include #include #include + +#include +#include +#include +#include + +#include diff --git a/src/logging/logging.vcxproj b/src/logging/logging.vcxproj new file mode 100644 index 0000000000..6649b4e2b9 --- /dev/null +++ b/src/logging/logging.vcxproj @@ -0,0 +1,178 @@ + + + + x64 + + + + Debug + x64 + + + Release + x64 + + + + {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} + 10.0.19041.0 + Win32Proj + x64 + logging + NoUpgrade + + + + + StaticLibrary + MultiByte + v142 + + + StaticLibrary + MultiByte + v142 + + + + + + + + + + true + $(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\ + + + + MultiThreadedDebug + + + + + MaxSpeed + + + + + $(IntDir) + Default + CompileAsCpp + None + Sync + AnySuitable + NotUsing + true + false + Level4 + WIN32;_WINDOWS;SPDLOG_COMPILED_LIB;%(PreprocessorDefinitions) + $(IntDir) + true + true + true + true + MultiThreaded + + + %(AdditionalOptions) /machine:x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/logging/logging.vcxproj.filters b/src/logging/logging.vcxproj.filters new file mode 100644 index 0000000000..937fae1a25 --- /dev/null +++ b/src/logging/logging.vcxproj.filters @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {CDF4BA23-560C-3A6F-8D1C-2F5ACA434329} + + + {EFFE8123-D806-3145-8ABC-B48562A6C8F2} + + + {C546A431-88F1-390F-B0F0-D9CAC274B7F5} + + + {08320F28-6D0D-3217-B0B3-A98758C02C97} + + + {C856528D-4506-3A62-B279-CBB4558CB61D} + + + {A5EE33C4-AB64-38F0-BF4A-CCD02FFAB715} + + + {8B480F42-A230-3344-A387-2D050CFF7D9C} + + + \ No newline at end of file From 6f5cdb46743176a5045d3f77f4f4da44812f4002 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 16 Oct 2020 08:59:49 -0700 Subject: [PATCH 15/65] LEGO: check in for master to temporary branch. (#7319) --- .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 6 +++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 6 +++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 18 +++++++++ .../Strings/en-us/Resources.resw.lcl | 39 +++++++++++++++++++ .../keyboardmanager/dll/Resources.resx.lcl | 6 +++ .../keyboardmanager/dll/Resources.resx.lcl | 8 +++- .../keyboardmanager/dll/Resources.resx.lcl | 8 +++- .../keyboardmanager/dll/Resources.resx.lcl | 6 +++ .../keyboardmanager/dll/Resources.resx.lcl | 6 +++ .../keyboardmanager/dll/Resources.resx.lcl | 8 +++- .../keyboardmanager/dll/Resources.resx.lcl | 2 +- .../keyboardmanager/dll/Resources.resx.lcl | 10 ++++- .../keyboardmanager/dll/Resources.resx.lcl | 10 ++++- .../keyboardmanager/dll/Resources.resx.lcl | 6 +++ .../keyboardmanager/dll/Resources.resx.lcl | 10 ++++- .../powerpreview/Resources.resx.lcl | 18 +++++++++ .../powerpreview/Resources.resx.lcl | 18 +++++++++ 24 files changed, 301 insertions(+), 10 deletions(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index dd1997cd68..04bddd934b 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/cs/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/de/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/de/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index dc2805c425..fc0e36b767 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/de/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/de/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 243b60665b..4d155ec7f9 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/es/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 8661aba18d..9942579f7f 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/fr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index d895a16088..64a7e46c68 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -514,12 +514,18 @@ + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index a4a1bad506..88a868e2c7 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/it/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 8f665c5b63..d844760a62 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/nl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -283,6 +283,9 @@ + + + @@ -964,6 +967,9 @@ + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/pl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/pl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index b9e57c510e..fd1426833b 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/pl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/pl/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 3e44099134..1f1f2ef4bb 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-PT/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/sv/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/sv/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 018c9b34af..5815b90b28 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/sv/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/sv/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 39d62186cc..b642d7d444 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,12 @@ + + + + + + @@ -460,6 +466,15 @@ + + + + + + + + + @@ -496,6 +511,24 @@ + + + + + + + + + + + + + + + + + + @@ -928,6 +961,12 @@ + + + + + + diff --git a/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl index 0a0a06ad4b..2a27ea3f46 100644 --- a/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -106,6 +106,9 @@ + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl index ee32c9c112..6b7f958c4b 100644 --- a/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl index 6e0943237a..a7c6e9f4f9 100644 --- a/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -106,6 +106,9 @@ + + + @@ -176,8 +179,11 @@ - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl index 6ce4a30903..3900d0c4c8 100644 --- a/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -106,6 +106,9 @@ + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl index 26ceee6b61..02d2da764b 100644 --- a/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -106,6 +106,9 @@ + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl index 8e07cb2ea9..f5c407da43 100644 --- a/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -106,6 +106,9 @@ + + + @@ -176,8 +179,11 @@ - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl index e1d40a93b7..2b1689e37c 100644 --- a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,7 +104,7 @@ - 키를 누르고 "Ctrl+C"를 사용하려는 경우 "A" 키는 "키" 열이 되고, 바로 가기 "Ctrl+C"는 "매핑 대상" 열이 됩니다.]]> + diff --git a/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl index 5a8d9fa496..02a230d943 100644 --- a/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + + + + @@ -176,8 +179,11 @@ - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl index 386a4cfa1c..663af6f515 100644 --- a/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + + + + @@ -176,8 +179,11 @@ - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl index f165e5e2fd..aba46cf6f3 100644 --- a/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -106,6 +106,9 @@ + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl index 8106738860..f7f459571c 100644 --- a/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + + + + @@ -176,8 +179,11 @@ - + + + + diff --git a/src/modules/previewpane/powerpreview/loc/hu/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/hu/src/modules/previewpane/powerpreview/Resources.resx.lcl index b100303ed9..78db1b4b8a 100644 --- a/src/modules/previewpane/powerpreview/loc/hu/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/hu/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/modules/previewpane/powerpreview/loc/tr/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/tr/src/modules/previewpane/powerpreview/Resources.resx.lcl index 0d33070040..4778fe4ebc 100644 --- a/src/modules/previewpane/powerpreview/loc/tr/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/tr/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + From 36dd29c05631a54b7c327f52b9bcbcb9ae954e5c Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 16 Oct 2020 11:03:43 -0700 Subject: [PATCH 16/65] LEGO: check in for master to temporary branch. (#7327) --- .../Strings/en-us/Resources.resw.lcl | 36 +++++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 18 ++++++++++ .../keyboardmanager/dll/Resources.resx.lcl | 8 ++++- .../powerpreview/Resources.resx.lcl | 18 ++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 866d0cf492..5ff1b586c1 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -460,6 +469,12 @@ + + + + + + @@ -496,6 +511,18 @@ + + + + + + + + + + + + @@ -928,6 +955,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index c19e754145..75cc42ff01 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hant/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl index c3b4d28a86..73f0f52bfc 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -103,9 +103,12 @@ - + + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/previewpane/powerpreview/loc/zh-Hans/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/zh-Hans/src/modules/previewpane/powerpreview/Resources.resx.lcl index edfe994119..44703e6ab9 100644 --- a/src/modules/previewpane/powerpreview/loc/zh-Hans/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/zh-Hans/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + From b80578b1b9a4b24c9945bddac33c771204280107 Mon Sep 17 00:00:00 2001 From: Davide Giacometti Date: Sat, 17 Oct 2020 01:30:11 +0200 Subject: [PATCH 17/65] [PT Run] Open folder using shell instead of explorer.exe (#7292) * pt run not using explorer.exe for opening path (#4622) * updated explorer action name (#4622) --- .../{IExplorerAction.cs => IShellAction.cs} | 2 +- .../Result/CreateOpenCurrentFolderResult.cs | 13 ++++++------- .../Sources/Result/FileItemResult.cs | 4 ++-- .../Sources/Result/FolderItemResult.cs | 4 ++-- .../{ExplorerAction.cs => ShellAction.cs} | 18 ++++++++++-------- .../UserFolderResult.cs | 4 ++-- 6 files changed, 23 insertions(+), 22 deletions(-) rename src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/{IExplorerAction.cs => IShellAction.cs} (91%) rename src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/{ExplorerAction.cs => ShellAction.cs} (78%) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IExplorerAction.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IShellAction.cs similarity index 91% rename from src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IExplorerAction.cs rename to src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IShellAction.cs index 5617256d75..27946bd096 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IExplorerAction.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IShellAction.cs @@ -6,7 +6,7 @@ using Wox.Plugin; namespace Microsoft.Plugin.Folder.Sources { - public interface IExplorerAction + public interface IShellAction { bool Execute(string sanitizedPath, IPublicAPI contextApi); diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/CreateOpenCurrentFolderResult.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/CreateOpenCurrentFolderResult.cs index 86c60b0cec..3e323fae5d 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/CreateOpenCurrentFolderResult.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/CreateOpenCurrentFolderResult.cs @@ -2,26 +2,25 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Globalization; using Wox.Plugin; namespace Microsoft.Plugin.Folder.Sources.Result { public class CreateOpenCurrentFolderResult : IItemResult { - private readonly IExplorerAction _explorerAction; + private readonly IShellAction _shellAction; - public string Search { get; set; } + public string Search { get; set; } public CreateOpenCurrentFolderResult(string search) - : this(search, new ExplorerAction()) + : this(search, new ShellAction()) { } - public CreateOpenCurrentFolderResult(string search, IExplorerAction explorerAction) + public CreateOpenCurrentFolderResult(string search, IShellAction shellAction) { Search = search; - _explorerAction = explorerAction; + _shellAction = shellAction; } public Wox.Plugin.Result Create(IPublicAPI contextApi) @@ -33,7 +32,7 @@ namespace Microsoft.Plugin.Folder.Sources.Result SubTitle = Properties.Resources.wox_plugin_folder_select_folder_first_result_subtitle, IcoPath = Search, Score = 500, - Action = c => _explorerAction.ExecuteSanitized(Search, contextApi), + Action = c => _shellAction.ExecuteSanitized(Search, contextApi), }; } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FileItemResult.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FileItemResult.cs index 84a35e1396..67ce726808 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FileItemResult.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FileItemResult.cs @@ -11,7 +11,7 @@ namespace Microsoft.Plugin.Folder.Sources.Result { public class FileItemResult : IItemResult { - private static readonly IExplorerAction ExplorerAction = new ExplorerAction(); + private static readonly IShellAction ShellAction = new ShellAction(); public string FilePath { get; set; } @@ -27,7 +27,7 @@ namespace Microsoft.Plugin.Folder.Sources.Result SubTitle = string.Format(CultureInfo.CurrentCulture, Properties.Resources.wox_plugin_folder_select_file_result_subtitle, FilePath), IcoPath = FilePath, TitleHighlightData = StringMatcher.FuzzySearch(Search, Path.GetFileName(FilePath)).MatchData, - Action = c => ExplorerAction.Execute(FilePath, contextApi), + Action = c => ShellAction.Execute(FilePath, contextApi), ContextData = new SearchResult { Type = ResultType.File, FullPath = FilePath }, }; return result; diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FolderItemResult.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FolderItemResult.cs index ad5f1e7f5e..dd295f9413 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FolderItemResult.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Result/FolderItemResult.cs @@ -10,7 +10,7 @@ namespace Microsoft.Plugin.Folder.Sources.Result { public class FolderItemResult : IItemResult { - private static readonly IExplorerAction ExplorerAction = new ExplorerAction(); + private static readonly IShellAction ShellAction = new ShellAction(); public FolderItemResult() { @@ -41,7 +41,7 @@ namespace Microsoft.Plugin.Folder.Sources.Result QueryTextDisplay = Path, TitleHighlightData = StringMatcher.FuzzySearch(Search, Title).MatchData, ContextData = new SearchResult { Type = ResultType.Folder, FullPath = Path }, - Action = c => ExplorerAction.Execute(Path, contextApi), + Action = c => ShellAction.Execute(Path, contextApi), }; } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/ExplorerAction.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/ShellAction.cs similarity index 78% rename from src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/ExplorerAction.cs rename to src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/ShellAction.cs index 69c2562eab..d82ff91459 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/ExplorerAction.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/ShellAction.cs @@ -7,16 +7,13 @@ using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Text.RegularExpressions; -using System.Windows; using Wox.Infrastructure.Logger; using Wox.Plugin; namespace Microsoft.Plugin.Folder.Sources { - public class ExplorerAction : IExplorerAction + public class ShellAction : IShellAction { - private const string FileExplorerProgramName = "explorer"; - public bool Execute(string path, IPublicAPI contextApi) { if (contextApi == null) @@ -24,7 +21,7 @@ namespace Microsoft.Plugin.Folder.Sources throw new ArgumentNullException(nameof(contextApi)); } - return OpenFileOrFolder(FileExplorerProgramName, path, contextApi); + return OpenFileOrFolder(path, contextApi); } public bool ExecuteSanitized(string search, IPublicAPI contextApi) @@ -51,16 +48,21 @@ namespace Microsoft.Plugin.Folder.Sources } [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive and instead inform the user of the error")] - private static bool OpenFileOrFolder(string program, string path, IPublicAPI contextApi) + private static bool OpenFileOrFolder(string path, IPublicAPI contextApi) { try { - Process.Start(program, path); + using (var process = new Process()) + { + process.StartInfo.FileName = path; + process.StartInfo.UseShellExecute = true; + process.Start(); + } } catch (Exception e) { string messageBoxTitle = string.Format(CultureInfo.InvariantCulture, "{0} {1}", Properties.Resources.wox_plugin_folder_select_folder_OpenFileOrFolder_error_message, path); - Log.Exception($"Failed to open {path} in {FileExplorerProgramName}, {e.Message}", e, MethodBase.GetCurrentMethod().DeclaringType); + Log.Exception($"Failed to open {path}, {e.Message}", e, MethodBase.GetCurrentMethod().DeclaringType); contextApi.ShowMsg(messageBoxTitle, e.Message); } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/UserFolderResult.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/UserFolderResult.cs index 01ccb56bee..f8bb9ce1eb 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/UserFolderResult.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/UserFolderResult.cs @@ -12,7 +12,7 @@ namespace Microsoft.Plugin.Folder { public class UserFolderResult : IItemResult { - private readonly IExplorerAction _explorerAction = new ExplorerAction(); + private readonly IShellAction _shellAction = new ShellAction(); public string Search { get; set; } @@ -32,7 +32,7 @@ namespace Microsoft.Plugin.Folder QueryTextDisplay = Path, TitleHighlightData = StringMatcher.FuzzySearch(Search, Title).MatchData, ContextData = new SearchResult { Type = ResultType.Folder, FullPath = Path }, - Action = c => _explorerAction.Execute(Path, contextApi), + Action = c => _shellAction.Execute(Path, contextApi), }; } } From 7e0574cba29c15d8c44df81d4bf9db97d08b7ac1 Mon Sep 17 00:00:00 2001 From: Mykhailo Pylyp Date: Mon, 19 Oct 2020 12:27:47 +0300 Subject: [PATCH 18/65] Get rid of indexes in dropdowns (#7278) --- src/common/keyboard_layout.cpp | 12 +- src/common/keyboard_layout.h | 2 +- src/common/keyboard_layout_impl.h | 4 +- .../keyboardmanager/common/Helpers.cpp | 62 +- src/modules/keyboardmanager/common/Helpers.h | 9 +- .../keyboardmanager/common/Shortcut.cpp | 9 +- src/modules/keyboardmanager/common/Shortcut.h | 4 +- .../dll/KeyboardEventHandlers.cpp | 2 +- .../test/BufferValidationTests.cpp | 728 ++++++++---------- .../test/KeyboardManagerHelperTests.cpp | 43 +- .../keyboardmanager/test/ShortcutTests.cpp | 26 +- .../keyboardmanager/test/TestHelpers.cpp | 6 - .../ui/BufferValidationHelpers.cpp | 50 +- .../ui/BufferValidationHelpers.h | 4 +- .../keyboardmanager/ui/KeyDropDownControl.cpp | 83 +- .../keyboardmanager/ui/KeyDropDownControl.h | 21 +- .../keyboardmanager/ui/ShortcutControl.cpp | 12 +- .../ui/SingleKeyRemapControl.cpp | 20 +- 18 files changed, 469 insertions(+), 628 deletions(-) diff --git a/src/common/keyboard_layout.cpp b/src/common/keyboard_layout.cpp index 2084aba8e1..0bce4a96a7 100644 --- a/src/common/keyboard_layout.cpp +++ b/src/common/keyboard_layout.cpp @@ -27,7 +27,7 @@ std::vector LayoutMap::GetKeyCodeList(const bool isShortcut) return impl->GetKeyCodeList(isShortcut); } -std::vector LayoutMap::GetKeyNameList(const bool isShortcut) +std::vector> LayoutMap::GetKeyNameList(const bool isShortcut) { return impl->GetKeyNameList(isShortcut); } @@ -305,25 +305,25 @@ std::vector LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcu return keyCodes; } -std::vector LayoutMap::LayoutMapImpl::GetKeyNameList(const bool isShortcut) +std::vector> LayoutMap::LayoutMapImpl::GetKeyNameList(const bool isShortcut) { - std::vector keyNames; + std::vector> keyNames; std::vector keyCodes = GetKeyCodeList(isShortcut); std::lock_guard lock(keyboardLayoutMap_mutex); // If it is a key list for the shortcut control then we add a "None" key at the start if (isShortcut) { - keyNames.push_back(L"None"); + keyNames.push_back({ 0, L"None" }); for (int i = 1; i < keyCodes.size(); i++) { - keyNames.push_back(keyboardLayoutMap[keyCodes[i]]); + keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] }); } } else { for (int i = 0; i < keyCodes.size(); i++) { - keyNames.push_back(keyboardLayoutMap[keyCodes[i]]); + keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] }); } } diff --git a/src/common/keyboard_layout.h b/src/common/keyboard_layout.h index 58fe9f5280..4b1504c466 100644 --- a/src/common/keyboard_layout.h +++ b/src/common/keyboard_layout.h @@ -12,7 +12,7 @@ public: void UpdateLayout(); std::wstring GetKeyName(DWORD key); std::vector GetKeyCodeList(const bool isShortcut = false); - std::vector GetKeyNameList(const bool isShortcut = false); + std::vector> GetKeyNameList(const bool isShortcut = false); private: class LayoutMapImpl; diff --git a/src/common/keyboard_layout_impl.h b/src/common/keyboard_layout_impl.h index 9a1b07f2a8..dc1802e537 100644 --- a/src/common/keyboard_layout_impl.h +++ b/src/common/keyboard_layout_impl.h @@ -46,6 +46,6 @@ public: // Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist std::vector GetKeyCodeList(const bool isShortcut); - // Function to return the list of key name in the order for the drop down based on the key codes - std::vector GetKeyNameList(const bool isShortcut); + // Function to return the list of key name pairs in the order for the drop down based on the key codes + std::vector> GetKeyNameList(const bool isShortcut); }; \ No newline at end of file diff --git a/src/modules/keyboardmanager/common/Helpers.cpp b/src/modules/keyboardmanager/common/Helpers.cpp index 3cbb1a9ba2..3d82ccd95d 100644 --- a/src/modules/keyboardmanager/common/Helpers.cpp +++ b/src/modules/keyboardmanager/common/Helpers.cpp @@ -97,12 +97,15 @@ namespace KeyboardManagerHelper } } - Collections::IVector ToBoxValue(const std::vector& list) + Collections::IVector ToBoxValue(const std::vector>& list) { Collections::IVector boxList = single_threaded_vector(); for (auto& val : list) { - boxList.Append(winrt::box_value(val)); + auto comboBox = ComboBoxItem(); + comboBox.DataContext(winrt::box_value(std::to_wstring(val.first))); + comboBox.Content(winrt::box_value(val.second)); + boxList.Append(winrt::box_value(comboBox)); } return boxList; @@ -324,7 +327,7 @@ namespace KeyboardManagerHelper } // Function to filter the key codes for artificial key codes - DWORD FilterArtificialKeys(const DWORD& key) + int32_t FilterArtificialKeys(const int32_t& key) { switch (key) { @@ -345,57 +348,16 @@ namespace KeyboardManagerHelper } // Function to check if a modifier has been repeated in the previous drop downs - bool CheckRepeatedModifier(std::vector& currentKeys, int selectedKeyIndex, const std::vector& keyCodeList) + bool CheckRepeatedModifier(const std::vector& currentKeys, int selectedKeyCode) { - // check if modifier has already been added before in a previous drop down - int currentDropDownIndex = -1; - - // Find the key index of the current drop down selection so that we skip that index while searching for repeated modifiers + // Count the number of keys that are equal to 'selectedKeyCode' + int numberOfSameType = 0; for (int i = 0; i < currentKeys.size(); i++) { - if (currentKeys[i] == keyCodeList[selectedKeyIndex]) - { - currentDropDownIndex = i; - break; - } + numberOfSameType += KeyboardManagerHelper::GetKeyType(selectedKeyCode) == KeyboardManagerHelper::GetKeyType(currentKeys[i]); } - bool matchPreviousModifier = false; - for (int i = 0; i < currentKeys.size(); i++) - { - // Skip the current drop down - if (i != currentDropDownIndex) - { - // If the key type for the newly added key matches any of the existing keys in the shortcut - if (KeyboardManagerHelper::GetKeyType(keyCodeList[selectedKeyIndex]) == KeyboardManagerHelper::GetKeyType(currentKeys[i])) - { - matchPreviousModifier = true; - break; - } - } - } - - return matchPreviousModifier; - } - - // Function to get the selected key codes from the list of selected indices - std::vector GetKeyCodesFromSelectedIndices(const std::vector& selectedIndices, const std::vector& keyCodeList) - { - std::vector keys; - - for (int i = 0; i < selectedIndices.size(); i++) - { - int selectedKeyIndex = selectedIndices[i]; - if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex) - { - // If None is not the selected key - if (keyCodeList[selectedKeyIndex] != 0) - { - keys.push_back(keyCodeList[selectedKeyIndex]); - } - } - } - - return keys; + // If we have at least two keys equal to 'selectedKeyCode' than modifier was repeated + return numberOfSameType > 1; } } diff --git a/src/modules/keyboardmanager/common/Helpers.h b/src/modules/keyboardmanager/common/Helpers.h index 927f765f6f..202b3a3af4 100644 --- a/src/modules/keyboardmanager/common/Helpers.h +++ b/src/modules/keyboardmanager/common/Helpers.h @@ -82,7 +82,7 @@ namespace KeyboardManagerHelper winrt::hstring GetErrorMessage(ErrorType errorType); // Function to return the list of key name in the order for the drop down based on the key codes - winrt::Windows::Foundation::Collections::IVector ToBoxValue(const std::vector& list); + winrt::Windows::Foundation::Collections::IVector ToBoxValue(const std::vector>& list); // Function to set the value of a key event based on the arguments void SetKeyEvent(LPINPUT keyEventArray, int index, DWORD inputType, WORD keyCode, DWORD flags, ULONG_PTR extraInfo); @@ -100,14 +100,11 @@ namespace KeyboardManagerHelper void SetModifierKeyEvents(const Shortcut& shortcutToBeSent, const ModifierKey& winKeyInvoked, LPINPUT keyEventArray, int& index, bool isKeyDown, ULONG_PTR extraInfoFlag, const Shortcut& shortcutToCompare = Shortcut(), const DWORD& keyToBeReleased = NULL); // Function to filter the key codes for artificial key codes - DWORD FilterArtificialKeys(const DWORD& key); + int32_t FilterArtificialKeys(const int32_t& key); // Function to sort a vector of shortcuts based on it's size void SortShortcutVectorBasedOnSize(std::vector& shortcutVector); // Function to check if a modifier has been repeated in the previous drop downs - bool CheckRepeatedModifier(std::vector& currentKeys, int selectedKeyIndex, const std::vector& keyCodeList); - - // Function to get the selected key codes from the list of selected indices - std::vector GetKeyCodesFromSelectedIndices(const std::vector& selectedIndices, const std::vector& keyCodeList); + bool CheckRepeatedModifier(const std::vector& currentKeys, int selectedKeyCodes); } \ No newline at end of file diff --git a/src/modules/keyboardmanager/common/Shortcut.cpp b/src/modules/keyboardmanager/common/Shortcut.cpp index 8ebed5f337..f0f2ad78f6 100644 --- a/src/modules/keyboardmanager/common/Shortcut.cpp +++ b/src/modules/keyboardmanager/common/Shortcut.cpp @@ -18,7 +18,7 @@ Shortcut::Shortcut(const std::wstring& shortcutVK) : } // Constructor to initialize shortcut from a list of keys -Shortcut::Shortcut(const std::vector& keys) +Shortcut::Shortcut(const std::vector& keys) { SetKeyCodes(keys); } @@ -505,12 +505,15 @@ std::vector Shortcut::GetKeyCodes() } // Function to set a shortcut from a vector of key codes -void Shortcut::SetKeyCodes(const std::vector& keys) +void Shortcut::SetKeyCodes(const std::vector& keys) { Reset(); for (int i = 0; i < keys.size(); i++) { - SetKey(keys[i]); + if (keys[i] != -1 && keys[i] != 0) + { + SetKey(keys[i]); + } } } diff --git a/src/modules/keyboardmanager/common/Shortcut.h b/src/modules/keyboardmanager/common/Shortcut.h index a86628c4c2..c4ae23ea0f 100644 --- a/src/modules/keyboardmanager/common/Shortcut.h +++ b/src/modules/keyboardmanager/common/Shortcut.h @@ -28,7 +28,7 @@ public: Shortcut(const std::wstring& shortcutVK); // Constructor to initialize shortcut from a list of keys - Shortcut(const std::vector& keys); + Shortcut(const std::vector& keys); // == operator inline bool operator==(const Shortcut& sc) const @@ -153,7 +153,7 @@ public: std::vector GetKeyCodes(); // Function to set a shortcut from a vector of key codes - void SetKeyCodes(const std::vector& keys); + void SetKeyCodes(const std::vector& keys); // Function to check if all the modifiers in the shortcut have been pressed down bool CheckModifiersKeyboardState(InputInterface& ii) const; diff --git a/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp b/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp index ca33018b8a..3b767e1f01 100644 --- a/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp +++ b/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp @@ -481,7 +481,7 @@ namespace KeyboardEventHandlers else { // Check if the keyboard state is clear apart from the target remap key (by creating a temp Shortcut object with the target key) - bool isKeyboardStateClear = Shortcut(std::vector({ KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut)) })).IsKeyboardStateClearExceptShortcut(ii); + bool isKeyboardStateClear = Shortcut(std::vector({ KeyboardManagerHelper::FilterArtificialKeys(std::get(it->second.targetShortcut)) })).IsKeyboardStateClearExceptShortcut(ii); // If the keyboard state is clear, we release the target key but do not reset the remap state if (isKeyboardStateClear) { diff --git a/src/modules/keyboardmanager/test/BufferValidationTests.cpp b/src/modules/keyboardmanager/test/BufferValidationTests.cpp index 161cf8f8bb..05e841c1d5 100644 --- a/src/modules/keyboardmanager/test/BufferValidationTests.cpp +++ b/src/modules/keyboardmanager/test/BufferValidationTests.cpp @@ -22,7 +22,7 @@ namespace RemappingUITests { int elementRowIndex; int elementColIndex; - int selectedIndexFromDropDown; + int selectedCodeFromDropDown; }; struct ValidateShortcutBufferElementArgs @@ -30,7 +30,7 @@ namespace RemappingUITests int elementRowIndex; int elementColIndex; uint32_t indexOfDropDownLastModified; - std::vector selectedIndicesOnDropDowns; + std::vector selectedCodesOnDropDowns; std::wstring targetAppNameInTextBox; bool isHybridColumn; RemapBufferRow bufferRow; @@ -60,7 +60,7 @@ namespace RemappingUITests // Validate and update the element when -1 i.e. null selection is made on an empty row. ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, -1 }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is validated and buffer is updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::NoError); @@ -79,9 +79,8 @@ namespace RemappingUITests remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, NULL }), std::wstring())); // Validate and update the element when selecting B on an empty row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, GetDropDownIndexFromDropDownList(0x42, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, 0x42 }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is validated and buffer is updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::NoError); @@ -98,9 +97,8 @@ namespace RemappingUITests remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, 0x41 }), std::wstring())); // Validate and update the element when selecting B on a row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, GetDropDownIndexFromDropDownList(0x42, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, 0x42 }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is validated and buffer is updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::NoError); @@ -114,17 +112,16 @@ namespace RemappingUITests RemapBuffer remapBuffer; // Add a row with Ctrl+A as the target - remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, Shortcut(std::vector{ VK_CONTROL, 0x41 }) }), std::wstring())); + remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, Shortcut(std::vector{ VK_CONTROL, 0x41 }) }), std::wstring())); // Validate and update the element when selecting B on a row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, GetDropDownIndexFromDropDownList(0x42, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, 0x42 }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is validated and buffer is updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::NoError); Assert::AreEqual((DWORD)0x42, std::get(remapBuffer[0].first[0])); - Assert::AreEqual(true, Shortcut(std::vector{ VK_CONTROL, 0x41 }) == std::get(remapBuffer[0].first[1])); + Assert::AreEqual(true, Shortcut(std::vector{ VK_CONTROL, 0x41 }) == std::get(remapBuffer[0].first[1])); } // Test if the ValidateAndUpdateKeyBufferElement method is unsuccessful when setting first column to the same value as the right column @@ -136,9 +133,8 @@ namespace RemappingUITests remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, 0x41 }), std::wstring())); // Validate and update the element when selecting A on a row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, GetDropDownIndexFromDropDownList(0x41, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 0, 0, 0x41 }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is invalid and buffer is not updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::MapToSameKey); @@ -156,9 +152,8 @@ namespace RemappingUITests remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, 0x43 }), std::wstring())); // Validate and update the element when selecting A on second row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, GetDropDownIndexFromDropDownList(0x41, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, 0x41 }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is invalid and buffer is not updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::SameKeyPreviouslyMapped); @@ -173,17 +168,16 @@ namespace RemappingUITests // Add a row from A->B and a row with Ctrl+A as target remapBuffer.push_back(std::make_pair(RemapBufferItem({ 0x41, 0x42 }), std::wstring())); - remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, Shortcut(std::vector{ VK_CONTROL, 0x41 }) }), std::wstring())); + remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, Shortcut(std::vector{ VK_CONTROL, 0x41 }) }), std::wstring())); // Validate and update the element when selecting A on second row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, GetDropDownIndexFromDropDownList(0x41, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, 0x41 }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is invalid and buffer is not updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::SameKeyPreviouslyMapped); Assert::AreEqual((DWORD)NULL, std::get(remapBuffer[1].first[0])); - Assert::AreEqual(true, Shortcut(std::vector{ VK_CONTROL, 0x41 }) == std::get(remapBuffer[1].first[1])); + Assert::AreEqual(true, Shortcut(std::vector{ VK_CONTROL, 0x41 }) == std::get(remapBuffer[1].first[1])); } // Test if the ValidateAndUpdateKeyBufferElement method is unsuccessful when setting first column of a key to key row to a conflicting modifier with another row @@ -196,9 +190,8 @@ namespace RemappingUITests remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, 0x43 }), std::wstring())); // Validate and update the element when selecting LCtrl on second row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, VK_LCONTROL }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is invalid and buffer is not updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::ConflictingModifierKey); @@ -213,24 +206,21 @@ namespace RemappingUITests // Add a row from Ctrl->B and a row with Ctrl+A as target remapBuffer.push_back(std::make_pair(RemapBufferItem({ VK_CONTROL, 0x42 }), std::wstring())); - remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, Shortcut(std::vector{ VK_CONTROL, 0x41 }) }), std::wstring())); + remapBuffer.push_back(std::make_pair(RemapBufferItem({ NULL, Shortcut(std::vector{ VK_CONTROL, 0x41 }) }), std::wstring())); // Validate and update the element when selecting LCtrl on second row - std::vector keyList = keyboardLayout.GetKeyCodeList(false); - ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList) }; - KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedIndexFromDropDown, keyboardLayout.GetKeyCodeList(false), remapBuffer); + ValidateAndUpdateKeyBufferElementArgs args = { 1, 0, VK_LCONTROL }; + KeyboardManagerHelper::ErrorType error = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(args.elementRowIndex, args.elementColIndex, args.selectedCodeFromDropDown, remapBuffer); // Assert that the element is invalid and buffer is not updated Assert::AreEqual(true, error == KeyboardManagerHelper::ErrorType::ConflictingModifierKey); Assert::AreEqual((DWORD)NULL, std::get(remapBuffer[1].first[0])); - Assert::AreEqual(true, Shortcut(std::vector{ VK_CONTROL, 0x41 }) == std::get(remapBuffer[1].first[1])); + Assert::AreEqual(true, Shortcut(std::vector{ VK_CONTROL, 0x41 }) == std::get(remapBuffer[1].first[1])); } // Test if the ValidateShortcutBufferElement method is successful and no drop down action is required on setting a column to null in a new or valid row TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndNoAction_OnSettingColumnToNullInANewOrValidRow) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when making null-selection (-1 index) on first column of empty shortcut to shortcut row testCases.push_back({ 0, 0, 0, std::vector{ -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); @@ -241,43 +231,43 @@ namespace RemappingUITests // Case 4: Validate the element when making null-selection (-1 index) on second column of empty shortcut to key row testCases.push_back({ 0, 1, 0, std::vector{ -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), NULL }, std::wstring()) }); // Case 5: Validate the element when making null-selection (-1 index) on first dropdown of first column of valid shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector({ -1, GetDropDownIndexFromDropDownList(0x43, keyList) }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector({ -1, 0x43 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 6: Validate the element when making null-selection (-1 index) on first dropdown of second column of valid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector({ -1, GetDropDownIndexFromDropDownList(0x41, keyList) }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector({ -1, 0x41 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 7: Validate the element when making null-selection (-1 index) on first dropdown of second column of valid hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector({ -1, GetDropDownIndexFromDropDownList(0x41, keyList) }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector({ -1, 0x41 }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 8: Validate the element when making null-selection (-1 index) on second dropdown of first column of valid shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector({ VK_CONTROL, -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 9: Validate the element when making null-selection (-1 index) on second dropdown of second column of valid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector({ VK_CONTROL, -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 10: Validate the element when making null-selection (-1 index) on second dropdown of second column of valid hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1 }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector({ VK_CONTROL, -1 }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 11: Validate the element when making null-selection (-1 index) on first dropdown of first column of valid 3 key shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector({ -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x44, keyList) }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector({ -1, VK_SHIFT, 0x44 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 12: Validate the element when making null-selection (-1 index) on first dropdown of second column of valid 3 key shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector({ -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector({ -1, VK_SHIFT, 0x42 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 13: Validate the element when making null-selection (-1 index) on first dropdown of second column of valid hybrid 3 key shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector({ -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector({ -1, VK_SHIFT, 0x42 }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 14: Validate the element when making null-selection (-1 index) on second dropdown of first column of valid 3 key shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x44, keyList) }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector({ VK_CONTROL, -1, 0x44 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 15: Validate the element when making null-selection (-1 index) on second dropdown of second column of valid 3 key shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x42, keyList) }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector({ VK_CONTROL, -1, 0x42 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 16: Validate the element when making null-selection (-1 index) on second dropdown of second column of valid hybrid 3 key shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x42, keyList) }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector({ VK_CONTROL, -1, 0x42 }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 17: Validate the element when making null-selection (-1 index) on third dropdown of first column of valid 3 key shortcut to shortcut row - testCases.push_back({ 0, 0, 2, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector({ VK_CONTROL, VK_SHIFT, -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 18: Validate the element when making null-selection (-1 index) on third dropdown of second column of valid 3 key shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector({ VK_CONTROL, VK_SHIFT, -1 }), std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 19: Validate the element when making null-selection (-1 index) on third dropdown of second column of valid hybrid 3 key shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector({ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), -1 }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector({ VK_CONTROL, VK_SHIFT, -1 }), std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x44 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and no drop down action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -288,25 +278,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutStartWithModifier error and no drop down action is required on setting first drop down to an action key on a non-hybrid control column TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutStartWithModifierErrorAndNoAction_OnSettingFirstDropDownToActionKeyOnANonHybridColumn) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on first dropdown of first column of empty shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ 0x41 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting A (0x41) on first dropdown of second column of empty shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0x41 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 3: Validate the element when selecting A (0x41) on first dropdown of first column of empty shortcut to key row - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), NULL }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ 0x41 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), NULL }, std::wstring()) }); // Case 4: Validate the element when selecting A (0x41) on first dropdown of first column of valid shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ 0x41, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no drop down action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutStartWithModifier); @@ -317,21 +305,19 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and no drop down action is required on setting first drop down to an action key on an empty hybrid control column TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndNoAction_OnSettingFirstDropDownToActionKeyOnAnEmptyHybridColumn) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on first dropdown of second column of empty shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting A (0x41) on first dropdown of second column of empty shortcut to key row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), NULL }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), NULL }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and no drop down action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -342,21 +328,19 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutNotMoreThanOneActionKey error and no drop down action is required on setting first drop down to an action key on a hybrid control column with full shortcut TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutNotMoreThanOneActionKeyAndNoAction_OnSettingNonLastDropDownToActionKeyOnAHybridColumnWithFullShortcut) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on first dropdown of second column of hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0x41, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 2: Validate the element when selecting A (0x41) on second dropdown of second column of hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x41, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no drop down action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutNotMoreThanOneActionKey); @@ -367,21 +351,19 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutNotMoreThanOneActionKey error and no drop down action is required on setting non first non last drop down to an action key on a non hybrid control column with full shortcut TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutNotMoreThanOneActionKeyAndNoAction_OnSettingNonFirstNonLastDropDownToActionKeyOnANonHybridColumnWithFullShortcut) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on second dropdown of first column of shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0x41, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting A (0x41)on second dropdown of second column of shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x41, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no drop down action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutNotMoreThanOneActionKey); @@ -392,29 +374,27 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and no drop down action is required on setting last drop down to an action key on a column with atleast two drop downs TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndNoAction_OnSettingLastDropDownToActionKeyOnAColumnWithAtleastTwoDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on last dropdown of first column of three key shortcut to shortcut row - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x41 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting A (0x41) on last dropdown of second column of three key shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x41 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting A (0x41) on last dropdown of hybrid second column of three key shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting A (0x41) on last dropdown of first column of two key shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0x41 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 5: Validate the element when selecting A (0x41) on last dropdown of second column of two key shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x41 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 6: Validate the element when selecting A (0x41) on last dropdown of hybrid second column of two key shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and no drop down action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -425,29 +405,27 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and ClearUnusedDropDowns action is required on setting non first drop down to an action key on a column if all the drop downs after it are empty TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndClearUnusedDropDownsAction_OnSettingNonFirstDropDownToActionKeyOnAColumnIfAllTheDropDownsAfterItAreEmpty) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on second dropdown of first column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0x41, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting A (0x41) on second dropdown of second column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x41, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting A (0x41) on second dropdown of second column of 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x41, keyList), -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x41, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting A (0x41) on second dropdown of first column of empty 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(0x41, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ -1, 0x41, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 5: Validate the element when selecting A (0x41) on second dropdown of second column of empty 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(0x41, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ -1, 0x41, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 6: Validate the element when selecting A (0x41) on second dropdown of second column of empty 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(0x41, keyList), -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ -1, 0x41, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and ClearUnusedDropDowns action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -458,19 +436,17 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and ClearUnusedDropDowns action is required on setting first drop down to an action key on a hybrid column if all the drop downs after it are empty TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndClearUnusedDropDownsAction_OnSettingFirstDropDownToActionKeyOnAHybridColumnIfAllTheDropDownsAfterItAreEmpty) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on first dropdown of second column of empty 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList), -1, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0x41, -1, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and ClearUnusedDropDowns action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -481,31 +457,31 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and AddDropDown action is required on setting last drop down to a non-repeated modifier key on a column there are less than 3 drop downs TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndAddDropDownAction_OnSettingLastDropDownToNonRepeatedModifierKeyOnAColumnIfThereAreLessThan3DropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); + std::vector testCases; // Case 1: Validate the element when selecting Shift (VK_SHIFT) on second dropdown of first column of 2 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting Shift (VK_SHIFT) on second dropdown of second column of 2 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting Shift (VK_SHIFT) on second dropdown of second column of 2 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_SHIFT }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of first column of 1 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 5: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column of 1 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 6: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column of 1 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_SHIFT }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 7: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column of 1 dropdown hybrid shortcut to key row with an action key selected - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), 0x44 }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_SHIFT }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), 0x44 }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and AddDropDown action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -516,23 +492,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutCannotHaveRepeatedModifier error and no action is required on setting last drop down to a repeated modifier key on a column there are less than 3 drop downs TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutCannotHaveRepeatedModifierErrorAndNoAction_OnSettingLastDropDownToRepeatedModifierKeyOnAColumnIfThereAreLessThan3DropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); + std::vector testCases; // Case 1: Validate the element when selecting LCtrl (VK_LCONTROL) on second dropdown of first column of 2 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, VK_LCONTROL }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting LCtrl (VK_LCONTROL) on second dropdown of second column of 2 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_LCONTROL }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting LCtrl (VK_LCONTROL) on second dropdown of second column of 2 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_LCONTROL }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutCannotHaveRepeatedModifier); @@ -543,35 +519,33 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutMaxShortcutSizeOneActionKey error and no action is required on setting last drop down to a non repeated modifier key on a column there 3 or more drop downs TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutMaxShortcutSizeOneActionKeyErrorAndNoAction_OnSettingLastDropDownToNonRepeatedModifierKeyOnAColumnIfThereAre3OrMoreDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of first column of 3 dropdown shortcut to shortcut row with middle empty - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, -1, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of second column of 3 dropdown shortcut to shortcut row with middle empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, -1, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of second column of 3 dropdown hybrid shortcut to shortcut row with middle empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, -1, VK_SHIFT }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of first column of 3 dropdown shortcut to shortcut row with first two empty - testCases.push_back({ 0, 0, 2, std::vector{ -1, -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ -1, -1, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 5: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of second column of 3 dropdown shortcut to shortcut row with first two empty - testCases.push_back({ 0, 1, 2, std::vector{ -1, -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ -1, -1, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 6: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of second column of 3 dropdown hybrid shortcut to shortcut row with first two empty - testCases.push_back({ 0, 1, 2, std::vector{ -1, -1, GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ -1, -1, VK_SHIFT }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 7: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of first column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, VK_MENU, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 8: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of second column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 9: Validate the element when selecting Shift (VK_SHIFT) on last dropdown of second column of 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, VK_SHIFT }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutMaxShortcutSizeOneActionKey); @@ -582,29 +556,27 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutMaxShortcutSizeOneActionKey error and no action is required on setting last drop down to a repeated modifier key on a column there 3 or more drop downs TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutMaxShortcutSizeOneActionKeyErrorAndNoAction_OnSettingLastDropDownToRepeatedModifierKeyOnAColumnIfThereAre3OrMoreDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting Ctrl (VK_CONTROL) on last dropdown of first column of 3 dropdown shortcut to shortcut row with middle empty - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, -1, VK_CONTROL }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting Ctrl (VK_CONTROL) on last dropdown of second column of 3 dropdown shortcut to shortcut row with middle empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, -1, VK_CONTROL }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting Ctrl (VK_CONTROL) on last dropdown of second column of 3 dropdown hybrid shortcut to shortcut row with middle empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, -1, VK_CONTROL }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting Ctrl (VK_CONTROL) on last dropdown of first column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, VK_MENU, VK_CONTROL }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 5: Validate the element when selecting Ctrl (VK_CONTROL) on last dropdown of second column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, VK_CONTROL }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 6: Validate the element when selecting Ctrl (VK_CONTROL) on last dropdown of second column of 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, VK_CONTROL }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutMaxShortcutSizeOneActionKey); @@ -615,35 +587,33 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and no action is required on setting non-last drop down to a non repeated modifier key on a column TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndNoAction_OnSettingNonLastDropDownToNonRepeatedModifierKeyOnAColumn) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of first column of 2 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_CONTROL, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column of 2 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_CONTROL, VK_SHIFT }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column of 2 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_CONTROL, VK_SHIFT }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of first column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_SHIFT, VK_MENU, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 5: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_SHIFT, VK_MENU, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 6: Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column of 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_SHIFT, VK_MENU, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 7: Validate the element when selecting Shift (VK_SHIFT) on second dropdown of first column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 8: Validate the element when selecting Shift (VK_SHIFT) on second dropdown of second column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 9: Validate the element when selecting Shift (VK_SHIFT) on second dropdown of second column of 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -654,35 +624,33 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutCannotHaveRepeatedModifier error and no action is required on setting non-last drop down to a repeated modifier key on a column TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutCannotHaveRepeatedModifierErrorAndNoAction_OnSettingNonLastDropDownToRepeatedModifierKeyOnAColumn) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of first column of 3 dropdown shortcut to shortcut row with first empty - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_CONTROL, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 2: Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of second column of 3 dropdown shortcut to shortcut row with first empty - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_CONTROL, VK_CONTROL, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 3: Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of second column of 3 dropdown hybrid shortcut to shortcut row with first empty - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_CONTROL, VK_CONTROL, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting Alt (VK_MENU) on first dropdown of first column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_MENU, VK_MENU, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 5: Validate the element when selecting Alt (VK_MENU) on first dropdown of second column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_MENU, VK_MENU, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 6: Validate the element when selecting Alt (VK_MENU) on first dropdown of second column of 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_MENU, VK_MENU, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 7: Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of first column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 8: Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of second column of 3 dropdown shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_CONTROL, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 9: Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of second column of 3 dropdown hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_CONTROL, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutCannotHaveRepeatedModifier); @@ -693,21 +661,19 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutStartWithModifier error and no action is required on setting first drop down to None on a non-hybrid column with one drop down TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutStartWithModifierErrorAndNoAction_OnSettingFirstDropDownToNoneOnNonHybridColumnWithOneDropDown) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting None (0) on first dropdown of first column of 1 dropdown shortcut to shortcut row testCases.push_back({ 0, 0, 0, std::vector{ 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting None (0) on first dropdown of second column of 1 dropdown shortcut to shortcut row testCases.push_back({ 0, 1, 0, std::vector{ 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutStartWithModifier); @@ -718,19 +684,17 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutOneActionKey error and no action is required on setting first drop down to None on a hybrid column with one drop down TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutOneActionKeyErrorAndNoAction_OnSettingFirstDropDownToNoneOnHybridColumnWithOneDropDown) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting None (0) on first dropdown of first column of 1 dropdown hybrid shortcut to shortcut row testCases.push_back({ 0, 1, 0, std::vector{ 0 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutOneActionKey); @@ -741,25 +705,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutAtleast2Keys error and no action is required on setting first drop down to None on a non-hybrid column with two drop down TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutAtleast2KeysAndNoAction_OnSettingFirstDropDownToNoneOnNonHybridColumnWithTwoDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting None (0) on first dropdown of first column of 2 dropdown empty shortcut to shortcut row testCases.push_back({ 0, 0, 0, std::vector{ 0, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting None (0) on first dropdown of second column of 2 dropdown empty shortcut to shortcut row testCases.push_back({ 0, 1, 0, std::vector{ 0, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 3: Validate the element when selecting None (0) on first dropdown of second column of 2 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ 0, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting None (0) on first dropdown of second column of 2 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutAtleast2Keys); @@ -770,25 +732,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutOneActionKey error and no action is required on setting second drop down to None on a non-hybrid column with two drop down TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutOneActionKeyAndNoAction_OnSettingSecondDropDownToNoneOnNonHybridColumnWithTwoDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting None (0) on second dropdown of first column of 2 dropdown empty shortcut to shortcut row testCases.push_back({ 0, 0, 1, std::vector{ -1, 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting None (0) on second dropdown of second column of 2 dropdown empty shortcut to shortcut row testCases.push_back({ 0, 1, 1, std::vector{ -1, 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 3: Validate the element when selecting None (0) on second dropdown of second column of 2 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting None (0) on second dropdown of second column of 2 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutOneActionKey); @@ -799,25 +759,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and DeleteDropDown action is required on setting drop down to None on a hybrid column with two drop down TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndDeleteDropDownAction_OnSettingDropDownToNoneOnHybridColumnWithTwoDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting None (0) on first dropdown of second column of 2 dropdown empty hybrid shortcut to shortcut row testCases.push_back({ 0, 1, 0, std::vector{ 0, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting None (0) on second dropdown of second column of 2 dropdown empty hybrid shortcut to shortcut row testCases.push_back({ 0, 1, 1, std::vector{ -1, 0 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 3: Validate the element when selecting None (0) on first dropdown of second column of 2 dropdown valid hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0, VK_CONTROL }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); // Case 4: Validate the element when selecting None (0) on second dropdown of second column of 2 dropdown valid hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and DeleteDropDown action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -828,8 +786,6 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error and DeleteDropDown action is required on setting non last drop down to None on a column with three drop down TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoErrorAndDeleteDropDownAction_OnSettingNonLastDropDownToNoneOnColumnWithThreeDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting None (0) on first dropdown of first column of 3 dropdown empty shortcut to shortcut row testCases.push_back({ 0, 0, 0, std::vector{ 0, -1, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); @@ -844,25 +800,25 @@ namespace RemappingUITests // Case 6: Validate the element when selecting None (0) on second dropdown of second column of 3 dropdown empty hybrid shortcut to shortcut row testCases.push_back({ 0, 1, 1, std::vector{ -1, 0, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 7: Validate the element when selecting None (0) on first dropdown of first column of 3 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 0, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ 0, VK_MENU, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 8: Validate the element when selecting None (0) on first dropdown of second column of 3 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0, VK_MENU, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 9: Validate the element when selecting None (0) on first dropdown of second column of 3 dropdown valid hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0, VK_MENU, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 10: Validate the element when selecting None (0) on first dropdown of first column of 3 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 11: Validate the element when selecting None (0) on first dropdown of second column of 3 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0, 0x42 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 12: Validate the element when selecting None (0) on first dropdown of second column of 3 dropdown valid hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x42, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0, 0x42 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid and DeleteDropDown action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -873,8 +829,6 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ShortcutOneActionKey error and no action is required on setting last drop down to None on a column with three drop down TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnShortcutOneActionKeyErrorAndNoAction_OnSettingLastDropDownToNoneOnColumnWithThreeDropDowns) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting None (0) on first dropdown of first column of 3 dropdown empty shortcut to shortcut row testCases.push_back({ 0, 0, 2, std::vector{ -1, -1, 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); @@ -883,19 +837,19 @@ namespace RemappingUITests // Case 3: Validate the element when selecting None (0) on first dropdown of second column of 3 dropdown empty hybrid shortcut to shortcut row testCases.push_back({ 0, 1, 2, std::vector{ -1, -1, 0 }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), Shortcut() }, std::wstring()) }); // Case 4: Validate the element when selecting None (0) on first dropdown of first column of 3 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, VK_MENU, 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 5: Validate the element when selecting None (0) on first dropdown of second column of 3 dropdown valid shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, 0 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); // Case 6: Validate the element when selecting None (0) on first dropdown of second column of 3 dropdown valid hybrid shortcut to shortcut row - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), 0 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, 0 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU, 0x43 }, std::vector{ VK_CONTROL, VK_MENU, 0x42 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid and no action is required Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutOneActionKey); @@ -906,35 +860,35 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns WinL error on setting a drop down to Win or L on a column resulting in Win+L TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnWinLError_OnSettingDropDownToWinOrLOnColumnResultingInWinL) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); + std::vector testCases; // Case 1: Validate the element when selecting L (0x4C) on second dropdown of first column of LWin+Empty shortcut - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LWIN }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_LWIN, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LWIN }, Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting L (0x4C) on second dropdown of second column of LWin+Empty shortcut - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_LWIN, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN } }, std::wstring()) }); // Case 3: Validate the element when selecting L (0x4C) on second dropdown of second column of hybrid LWin+Empty shortcut - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_LWIN, 0x4C }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN } }, std::wstring()) }); // Case 4: Validate the element when selecting L (0x4C) on second dropdown of first column of Win+Empty shortcut - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(CommonSharedConstants::VK_WIN_BOTH, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ CommonSharedConstants::VK_WIN_BOTH }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ CommonSharedConstants::VK_WIN_BOTH, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ CommonSharedConstants::VK_WIN_BOTH }, Shortcut() }, std::wstring()) }); // Case 5: Validate the element when selecting L (0x4C) on second dropdown of second column of Win+Empty shortcut - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(CommonSharedConstants::VK_WIN_BOTH, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ CommonSharedConstants::VK_WIN_BOTH } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ CommonSharedConstants::VK_WIN_BOTH, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ CommonSharedConstants::VK_WIN_BOTH } }, std::wstring()) }); // Case 6: Validate the element when selecting L (0x4C) on second dropdown of second column of hybrid Win+Empty shortcut - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(CommonSharedConstants::VK_WIN_BOTH, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ CommonSharedConstants::VK_WIN_BOTH } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ CommonSharedConstants::VK_WIN_BOTH, 0x4C }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ CommonSharedConstants::VK_WIN_BOTH } }, std::wstring()) }); // Case 7: Validate the element when selecting LWin (VK_LWIN) on first dropdown of first column of Empty+L shortcut - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x4C }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_LWIN, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x4C }, Shortcut() }, std::wstring()) }); // Case 8: Validate the element when selecting LWin (VK_LWIN) on first dropdown of second column of Empty+L shortcut - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ 0x4C } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_LWIN, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ 0x4C } }, std::wstring()) }); // Case 9: Validate the element when selecting LWin (VK_LWIN) on first dropdown of second column of hybrid Empty+L shortcut - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ 0x4C } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_LWIN, 0x4C }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ 0x4C } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::WinL); @@ -944,29 +898,29 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns WinL error on setting a drop down to null or none on a column resulting in Win+L TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnWinLError_OnSettingDropDownToNullOrNoneOnColumnResultingInWinL) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); + std::vector testCases; // Case 1: Validate the element when selecting Null (-1) on second dropdown of first column of LWin + Ctrl + L shortcut - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), -1, GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LWIN, VK_CONTROL, 0x4C }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_LWIN, -1, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LWIN, VK_CONTROL, 0x4C }, Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting Null (-1) on second dropdown of second column of LWin + Ctrl + L shortcut - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), -1, GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_LWIN, -1, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); // Case 3: Validate the element when selecting Null (-1) on second dropdown of second column of hybrid LWin + Ctrl + L shortcut - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), -1, GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_LWIN, -1, 0x4C }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); // Case 4: Validate the element when selecting None (0) on second dropdown of first column of LWin + Ctrl + L shortcut - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), 0, GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LWIN, VK_CONTROL, 0x4C }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_LWIN, 0, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LWIN, VK_CONTROL, 0x4C }, Shortcut() }, std::wstring()) }); // Case 5: Validate the element when selecting None (0) on second dropdown of second column of LWin + Ctrl + L shortcut - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), 0, GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_LWIN, 0, 0x4C }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); // Case 6: Validate the element when selecting None (0) on second dropdown of second column of hybrid LWin + Ctrl + L shortcut - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LWIN, keyList), 0, GetDropDownIndexFromDropDownList(0x4C, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_LWIN, 0, 0x4C }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_LWIN, VK_CONTROL, 0x4C } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::WinL); @@ -976,29 +930,29 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns CtrlAltDel error on setting a drop down to Ctrl, Alt or Del on a column resulting in Ctrl+Alt+Del TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnCtrlAltDelError_OnSettingDropDownToCtrlAltOrDelOnColumnResultingInCtrlAltDel) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); + std::vector testCases; // Case 1: Validate the element when selecting Del (VK_DELETE) on third dropdown of first column of Ctrl+Alt+Empty shortcut - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_DELETE, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, VK_MENU, VK_DELETE }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_MENU }, Shortcut() }, std::wstring()) }); // Case 2: Validate the element when selecting Del (VK_DELETE) on third dropdown of second column of Ctrl+Alt+Empty shortcut - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_DELETE, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_MENU } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, VK_DELETE }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_MENU } }, std::wstring()) }); // Case 3: Validate the element when selecting Del (VK_DELETE) on third dropdown of second column of hybrid Ctrl+Alt+Empty shortcut - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_DELETE, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_MENU } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_MENU, VK_DELETE }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_MENU } }, std::wstring()) }); // Case 4: Validate the element when selecting Alt (VK_MENU) on second dropdown of first column of Ctrl+Empty+Del shortcut - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_DELETE, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_DELETE }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, VK_MENU, VK_DELETE }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_DELETE }, Shortcut() }, std::wstring()) }); // Case 5: Validate the element when selecting Alt (VK_MENU) on second dropdown of second column of Ctrl+Empty+Del shortcut - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_DELETE, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_DELETE } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_MENU, VK_DELETE }, std::wstring(), false, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_DELETE } }, std::wstring()) }); // Case 6: Validate the element when selecting Alt (VK_MENU) on second dropdown of second column of hybrid Ctrl+Empty+Del shortcut - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_MENU, keyList), GetDropDownIndexFromDropDownList(VK_DELETE, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_DELETE } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_MENU, VK_DELETE }, std::wstring(), true, std::make_pair(RemapBufferItem{ Shortcut(), std::vector{ VK_CONTROL, VK_DELETE } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::CtrlAltDel); @@ -1008,33 +962,31 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns MapToSameKey error on setting hybrid second column to match first column in a remap keys table TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnMapToSameKeyError_OnSettingHybridSecondColumnToFirstColumnInKeyTable) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1: Validate the element when selecting A (0x41) on first dropdown of empty hybrid second column - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList), -1, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, NULL }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0x41, -1, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, NULL }, std::wstring()) }); // Case 2: Validate the element when selecting A (0x41) on second dropdown of empty hybrid second column - testCases.push_back({ 0, 1, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(0x41, keyList), -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, NULL }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ -1, 0x41, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, NULL }, std::wstring()) }); // Case 3: Validate the element when selecting A (0x41) on third dropdown of empty hybrid second column - testCases.push_back({ 0, 1, 2, std::vector{ -1, -1, GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, NULL }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ -1, -1, 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, NULL }, std::wstring()) }); // Case 4: Validate the element when selecting A (0x41) on first dropdown of hybrid second column with key - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, 0x43 }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, 0x43 }, std::wstring()) }); // Case 5: Validate the element when selecting Null (-1) on first dropdown of hybrid second column with shortcut - testCases.push_back({ 0, 1, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ -1, 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 6: Validate the element when selecting None (0) on first dropdown of hybrid second column with shortcut - testCases.push_back({ 0, 1, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(0x41, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0, 0x41 }, std::wstring(), true, std::make_pair(RemapBufferItem{ 0x41, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 7: Validate the element when selecting Null (-1) on second dropdown of hybrid second column with shortcut - testCases.push_back({ 0, 1, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ VK_CONTROL, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ -1, VK_CONTROL }, std::wstring(), true, std::make_pair(RemapBufferItem{ VK_CONTROL, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 8: Validate the element when selecting None (0) on second dropdown of hybrid second column with shortcut - testCases.push_back({ 0, 1, 1, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ VK_CONTROL, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ 0, VK_CONTROL }, std::wstring(), true, std::make_pair(RemapBufferItem{ VK_CONTROL, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::MapToSameKey); @@ -1044,35 +996,35 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns MapToSameShortcut error on setting one column to match the other and both are valid 3 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnMapToSameShortcutError_OnSettingOneColumnToTheOtherAndBothAreValid3KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); + std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on third dropdown of first column with Ctrl+Shift+Empty - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); // Case 2 : Validate the element when selecting C (0x43) on third dropdown of second column with Ctrl+Shift+Empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT } }, std::wstring()) }); // Case 3 : Validate the element when selecting C (0x43) on third dropdown of second column with hybrid Ctrl+Shift+Empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT } }, std::wstring()) }); // Case 4 : Validate the element when selecting Shift (VK_SHIFT) on second dropdown of first column with Ctrl+Empty+C - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); // Case 5 : Validate the element when selecting Shift (VK_SHIFT) on second dropdown of second column with Ctrl+Empty+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 6 : Validate the element when selecting Shift (VK_SHIFT) on second dropdown of second column with hybrid Ctrl+Empty+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 7 : Validate the element when selecting Shift (VK_SHIFT) on first dropdown of first column with Empty+Ctrl+C - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); // Case 8 : Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column with Empty+Ctrl+C - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 9 : Validate the element when selecting Shift (VK_SHIFT) on first dropdown of second column with hybrid Empty+Ctrl+C - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::MapToSameShortcut); @@ -1082,77 +1034,75 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns MapToSameShortcut error on setting one column to match the other and both are valid 2 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnMapToSameShortcutError_OnSettingOneColumnToTheOtherAndBothAreValid2KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on third dropdown of first column with Ctrl+Empty+Empty - testCases.push_back({ 0, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 2, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 2 : Validate the element when selecting C (0x43) on third dropdown of second column with Ctrl+Empty+Empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); // Case 3 : Validate the element when selecting C (0x43) on third dropdown of second column with hybrid Ctrl+Empty+Empty - testCases.push_back({ 0, 1, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); + testCases.push_back({ 0, 1, 2, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); // Case 4 : Validate the element when selecting C (0x43) on second dropdown of first column with Ctrl+Empty+Empty - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0x43, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 5 : Validate the element when selecting C (0x43) on second dropdown of second column with Ctrl+Empty+Empty - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x43, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); // Case 6 : Validate the element when selecting C (0x43) on second dropdown of second column with hybrid Ctrl+Empty+Empty - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList), -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x43, -1 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL } }, std::wstring()) }); // Case 7 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of first column with Empty+Empty+C - testCases.push_back({ 0, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 8 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of second column with Empty+Empty+C - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); // Case 9 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of second column with hybrid Empty+Empty+C - testCases.push_back({ 0, 1, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); // Case 10 : Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of first column with Empty+Empty+C - testCases.push_back({ 0, 0, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 11 : Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of second column with Empty+Empty+C - testCases.push_back({ 0, 1, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); // Case 12 : Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of second column with hybrid Empty+Empty+C - testCases.push_back({ 0, 1, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ 0x43 } }, std::wstring()) }); // Case 13 : Validate the element when selecting C (0x43) on second dropdown of first column with Ctrl+A - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x41 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x41 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 14 : Validate the element when selecting C (0x43) on second dropdown of second column with Ctrl+A - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 15 : Validate the element when selecting C (0x43) on second dropdown of second column with hybrid Ctrl+A - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x41 } }, std::wstring()) }); // Case 16 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of first column with Alt+C - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_MENU, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_MENU, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 17 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of second column with Alt+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_MENU, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_MENU, 0x43 } }, std::wstring()) }); // Case 18 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of second column with hybrid Alt+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_MENU, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_MENU, 0x43 } }, std::wstring()) }); // Case 19 : Validate the element when selecting Null (-1) on second dropdown of first column with Ctrl+Shift+C - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 20 : Validate the element when selecting Null (-1) on second dropdown of second column with Ctrl+Shift+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); // Case 21 : Validate the element when selecting Null (-1) on second dropdown of second column with hybrid Ctrl+Shift+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); // Case 22 : Validate the element when selecting None (0) on second dropdown of first column with Ctrl+Shift+C - testCases.push_back({ 0, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 1, std::vector{ VK_CONTROL, 0, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 23 : Validate the element when selecting None (0) on second dropdown of second column with Ctrl+Shift+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); // Case 24 : Validate the element when selecting None (0) on second dropdown of second column with hybrid Ctrl+Shift+C - testCases.push_back({ 0, 1, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 1, std::vector{ VK_CONTROL, 0, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 } }, std::wstring()) }); // Case 25 : Validate the element when selecting Null (-1) on first dropdown of first column with Shift+Ctrl+C - testCases.push_back({ 0, 0, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 26 : Validate the element when selecting Null (-1) on first dropdown of second column with Shift+Ctrl+C - testCases.push_back({ 0, 1, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 27 : Validate the element when selecting Null (-1) on first dropdown of second column with hybrid Shift+Ctrl+C - testCases.push_back({ 0, 1, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 28 : Validate the element when selecting None (0) on first dropdown of first column with Shift+Ctrl+C - testCases.push_back({ 0, 0, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 0, 0, std::vector{ 0, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::vector{ VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 29 : Validate the element when selecting None (0) on first dropdown of second column with Shift+Ctrl+C - testCases.push_back({ 0, 1, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); // Case 30 : Validate the element when selecting None (0) on first dropdown of second column with hybrid Shift+Ctrl+C - testCases.push_back({ 0, 1, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); + testCases.push_back({ 0, 1, 0, std::vector{ 0, VK_CONTROL, 0x43 }, std::wstring(), true, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 } }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::MapToSameShortcut); @@ -1162,25 +1112,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns SameShortcutPreviouslyMapped error on setting first column to match first column in another row with same target app and both are valid 3 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnSameShortcutPreviouslyMappedError_OnSettingFirstColumnToFirstColumnInAnotherRowWithSameTargetAppAndBothAreValid3KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on third dropdown of first column with Ctrl+Shift+Empty - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT }, Shortcut() }, std::wstring()) }); // Case 2 : Validate the element when selecting Shift (VK_SHIFT) on second dropdown of first column with Ctrl+Empty+C - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); // Case 3 : Validate the element when selecting Shift (VK_SHIFT) on first dropdown of first column with Empty+Ctrl+C - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+Shift+C remapped - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring())); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring())); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::SameShortcutPreviouslyMapped); @@ -1190,25 +1138,25 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error on setting first column to match first column in another row with different target app and both are valid 3 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoError_OnSettingFirstColumnToFirstColumnInAnotherRowWithDifferentTargetAppAndBothAreValid3KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); + std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on third dropdown of first column with Ctrl+Shift+Empty for testApp2 - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT }, Shortcut() }, testApp2) }); // Case 2 : Validate the element when selecting Shift (VK_SHIFT) on second dropdown of first column with Ctrl+Empty+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); // Case 3 : Validate the element when selecting Shift (VK_SHIFT) on first dropdown of first column with Empty+Ctrl+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+Shift+C remapped for testApp1 - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp1)); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp1)); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -1218,25 +1166,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ConflictingModifierShortcut error on setting first column to conflict with first column in another row with same target app and both are valid 3 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnConflictingModifierShortcutError_OnSettingFirstColumnToConflictWithFirstColumnInAnotherRowWithSameTargetAppAndBothAreValid3KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on third dropdown of first column with LCtrl+Shift+Empty - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT }, Shortcut() }, std::wstring()) }); // Case 2 : Validate the element when selecting Shift (VK_SHIFT) on second dropdown of first column with LCtrl+Empty+C - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, 0x43 }, Shortcut() }, std::wstring()) }); // Case 3 : Validate the element when selecting LShift (VK_LSHIFT) on first dropdown of first column with Empty+Ctrl+C - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LSHIFT, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_LSHIFT, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+Shift+C remapped - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring())); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring())); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut); @@ -1246,25 +1192,23 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error on setting first column to conflict with first column in another row with different target app and both are valid 3 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoError_OnSettingFirstColumnToConflictWithFirstColumnInAnotherRowWithDifferentTargetAppAndBothAreValid3KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on third dropdown of first column with LCtrl+Shift+Empty for testApp2 - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT }, Shortcut() }, testApp2) }); // Case 2 : Validate the element when selecting Shift (VK_SHIFT) on second dropdown of first column with LCtrl+Empty+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, 0x43 }, Shortcut() }, testApp2) }); // Case 3 : Validate the element when selecting LShift (VK_LSHIFT) on first dropdown of first column with Empty+Ctrl+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LSHIFT, keyList), GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_LSHIFT, VK_CONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+Shift+C remapped for testApp1 - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp1)); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp1)); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -1274,39 +1218,37 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns SameShortcutPreviouslyMapped error on setting first column to match first column in another row with same target app and both are valid 2 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnSameShortcutPreviouslyMappedError_OnSettingFirstColumnToFirstColumnInAnotherRowWithSameTargetAppAndBothAreValid2KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on second dropdown of first column with Ctrl+Empty - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, std::wstring()) }); // Case 2 : Validate the element when selecting C (0x43) on third dropdown of first column with Ctrl+Empty+Empty - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, std::wstring()) }); // Case 3 : Validate the element when selecting C (0x43) on second dropdown of first column with Ctrl+Empty+Empty - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, 0x43, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, std::wstring()) }); // Case 4 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of first column with Empty+C - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); // Case 5 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of first column with Empty+Empty+C - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); // Case 6 : Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of first column with Empty+Empty+C - testCases.push_back({ 1, 0, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); // Case 7 : Validate the element when selecting Null (-1) on second dropdown of first column with Ctrl+Shift+C - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); // Case 8 : Validate the element when selecting Null (-1) on first dropdown of first column with Shift+Ctrl+C - testCases.push_back({ 1, 0, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ -1, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); // Case 9 : Validate the element when selecting None (0) on second dropdown of first column with Ctrl+Shift+C - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, 0, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); // Case 10 : Validate the element when selecting None (0) on first dropdown of first column with Shift+Ctrl+C - testCases.push_back({ 1, 0, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ 0, VK_CONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+C remapped - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring())); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring())); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::SameShortcutPreviouslyMapped); @@ -1316,39 +1258,37 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error on setting first column to match first column in another row with different target app and both are valid 2 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoError_OnSettingFirstColumnToFirstColumnInAnotherRowWithDifferentTargetAppAndBothAreValid2KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on second dropdown of first column with Ctrl+Empty for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, testApp2) }); // Case 2 : Validate the element when selecting C (0x43) on third dropdown of first column with Ctrl+Empty+Empty for testApp2 - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_CONTROL, -1, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, testApp2) }); // Case 3 : Validate the element when selecting C (0x43) on second dropdown of first column with Ctrl+Empty+Empty for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList), -1 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, 0x43, -1 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL }, Shortcut() }, testApp2) }); // Case 4 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of first column with Empty+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_CONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); // Case 5 : Validate the element when selecting Ctrl (VK_CONTROL) on first dropdown of first column with Empty+Empty+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_CONTROL, -1, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); // Case 6 : Validate the element when selecting Ctrl (VK_CONTROL) on second dropdown of first column with Empty+Empty+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ -1, VK_CONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); // Case 7 : Validate the element when selecting Null (-1) on second dropdown of first column with Ctrl+Shift+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, -1, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); // Case 8 : Validate the element when selecting Null (-1) on first dropdown of first column with Shift+Ctrl+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ -1, VK_CONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); // Case 9 : Validate the element when selecting None (0) on second dropdown of first column with Ctrl+Shift+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_CONTROL, 0, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); // Case 10 : Validate the element when selecting None (0) on first dropdown of first column with Shift+Ctrl+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ 0, VK_CONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_CONTROL, 0x43 }, Shortcut() }, testApp2) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+C remapped for testApp1 - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp1)); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp1)); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -1358,39 +1298,37 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns ConflictingModifierShortcut error on setting first column to conflict with first column in another row with same target app and both are valid 2 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnConflictingModifierShortcutError_OnSettingFirstColumnToConflictWithFirstColumnInAnotherRowWithSameTargetAppAndBothAreValid2KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on second dropdown of first column with LCtrl+Empty - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, std::wstring()) }); // Case 2 : Validate the element when selecting C (0x43) on third dropdown of first column with LCtrl+Empty+Empty - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_LCONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, std::wstring()) }); // Case 3 : Validate the element when selecting C (0x43) on second dropdown of first column with LCtrl+Empty+Empty - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList), -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, 0x43, -1 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, std::wstring()) }); // Case 4 : Validate the element when selecting LCtrl (VK_LCONTROL) on first dropdown of first column with Empty+C - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_LCONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); // Case 5 : Validate the element when selecting LCtrl (VK_LCONTROL) on first dropdown of first column with Empty+Empty+C - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_LCONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); // Case 6 : Validate the element when selecting LCtrl (VK_LCONTROL) on second dropdown of first column with Empty+Empty+C - testCases.push_back({ 1, 0, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ -1, VK_LCONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, std::wstring()) }); // Case 7 : Validate the element when selecting Null (-1) on second dropdown of first column with LCtrl+Shift+C - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, -1, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); // Case 8 : Validate the element when selecting Null (-1) on first dropdown of first column with Shift+LCtrl+C - testCases.push_back({ 1, 0, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ -1, VK_LCONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, std::wstring()) }); // Case 9 : Validate the element when selecting None (0) on second dropdown of first column with LCtrl+Shift+C - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, 0, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, std::wstring()) }); // Case 10 : Validate the element when selecting None (0) on first dropdown of first column with Shift+LCtrl+C - testCases.push_back({ 1, 0, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, std::wstring()) }); + testCases.push_back({ 1, 0, 0, std::vector{ 0, VK_LCONTROL, 0x43 }, std::wstring(), false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, std::wstring()) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+C remapped - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring())); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, std::wstring())); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is invalid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ConflictingModifierShortcut); @@ -1400,39 +1338,37 @@ namespace RemappingUITests // Test if the ValidateShortcutBufferElement method returns no error on setting first column to conflict with first column in another row with different target app and both are valid 2 key shortcuts TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnNoError_OnSettingFirstColumnToConflictWithFirstColumnInAnotherRowWithDifferentTargetAppAndBothAreValid2KeyShortcuts) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - std::vector testCases; // Case 1 : Validate the element when selecting C (0x43) on second dropdown of first column with LCtrl+Empty for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, testApp2) }); // Case 2 : Validate the element when selecting C (0x43) on third dropdown of first column with LCtrl+Empty+Empty for testApp2 - testCases.push_back({ 1, 0, 2, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 2, std::vector{ VK_LCONTROL, -1, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, testApp2) }); // Case 3 : Validate the element when selecting C (0x43) on second dropdown of first column with LCtrl+Empty+Empty for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList), -1 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, 0x43, -1 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL }, Shortcut() }, testApp2) }); // Case 4 : Validate the element when selecting LCtrl (VK_LCONTROL) on first dropdown of first column with Empty+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_LCONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); // Case 5 : Validate the element when selecting LCtrl (VK_LCONTROL) on first dropdown of first column with Empty+Empty+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ VK_LCONTROL, -1, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); // Case 6 : Validate the element when selecting LCtrl (VK_LCONTROL) on second dropdown of first column with Empty+Empty+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ -1, VK_LCONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ 0x43 }, Shortcut() }, testApp2) }); // Case 7 : Validate the element when selecting Null (-1) on second dropdown of first column with LCtrl+Shift+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), -1, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, -1, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); // Case 8 : Validate the element when selecting Null (-1) on first dropdown of first column with Shift+LCtrl+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ -1, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ -1, VK_LCONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, testApp2) }); // Case 9 : Validate the element when selecting None (0) on second dropdown of first column with LCtrl+Shift+C for testApp2 - testCases.push_back({ 1, 0, 1, std::vector{ GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), 0, GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 1, std::vector{ VK_LCONTROL, 0, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_LCONTROL, VK_SHIFT, 0x43 }, Shortcut() }, testApp2) }); // Case 10 : Validate the element when selecting None (0) on first dropdown of first column with Shift+LCtrl+C for testApp2 - testCases.push_back({ 1, 0, 0, std::vector{ 0, GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), GetDropDownIndexFromDropDownList(0x43, keyList) }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, testApp2) }); + testCases.push_back({ 1, 0, 0, std::vector{ 0, VK_LCONTROL, 0x43 }, testApp2, false, std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, VK_LCONTROL, 0x43 }, Shortcut() }, testApp2) }); - RunTestCases(testCases, [this, &keyList](const ValidateShortcutBufferElementArgs& testCase) { + RunTestCases(testCases, [this](const ValidateShortcutBufferElementArgs& testCase) { // Arrange RemapBuffer remapBuffer; // Ctrl+C remapped for testApp1 - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp1)); + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_CONTROL, 0x43 }, Shortcut() }, testApp1)); remapBuffer.push_back(testCase.bufferRow); // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedIndicesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(testCase.elementRowIndex, testCase.elementColIndex, testCase.indexOfDropDownLastModified, testCase.selectedCodesOnDropDowns, testCase.targetAppNameInTextBox, testCase.isHybridColumn, remapBuffer, true); // Assert that the element is valid Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::NoError); @@ -1442,18 +1378,16 @@ namespace RemappingUITests // Return error on Disable as second modifier key or action key TEST_METHOD (ValidateShortcutBufferElement_ShouldReturnDisableAsActionKeyError_OnSettingSecondDropdownAsDisable) { - std::vector keyList = keyboardLayout.GetKeyCodeList(true); - keyList.insert(keyList.begin(), CommonSharedConstants::VK_DISABLED); // Arrange RemapBuffer remapBuffer; - remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, CommonSharedConstants::VK_DISABLED }, Shortcut() }, testApp1)); - std::vector selectedIndices = { - GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), - GetDropDownIndexFromDropDownList(CommonSharedConstants::VK_DISABLED, keyList) + remapBuffer.push_back(std::make_pair(RemapBufferItem{ std::vector{ VK_SHIFT, CommonSharedConstants::VK_DISABLED }, Shortcut() }, testApp1)); + std::vector selectedCodes = { + VK_SHIFT, + CommonSharedConstants::VK_DISABLED }; // Act - std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(0, 1, 1, selectedIndices, testApp1, true, keyList, remapBuffer, true); + std::pair result = BufferValidationHelpers::ValidateShortcutBufferElement(0, 1, 1, selectedCodes, testApp1, true, remapBuffer, true); // Assert Assert::AreEqual(true, result.first == KeyboardManagerHelper::ErrorType::ShortcutDisableAsActionKey); diff --git a/src/modules/keyboardmanager/test/KeyboardManagerHelperTests.cpp b/src/modules/keyboardmanager/test/KeyboardManagerHelperTests.cpp index c52ce7151c..468962731d 100644 --- a/src/modules/keyboardmanager/test/KeyboardManagerHelperTests.cpp +++ b/src/modules/keyboardmanager/test/KeyboardManagerHelperTests.cpp @@ -104,11 +104,10 @@ namespace KeyboardManagerCommonTests TEST_METHOD (CheckRepeatedModifier_ShouldReturnTrue_OnPassingSameModifierRepeated) { // Arrange - std::vector keyList = LayoutMap().GetKeyCodeList(true); - std::vector keys = { VK_CONTROL, VK_CONTROL, 0x41 }; + std::vector keys = { VK_CONTROL, VK_CONTROL, 0x41 }; // Act - bool result = KeyboardManagerHelper::CheckRepeatedModifier(keys, TestHelpers::GetDropDownIndexFromDropDownList(VK_CONTROL, keyList), keyList); + bool result = KeyboardManagerHelper::CheckRepeatedModifier(keys, VK_CONTROL); // Assert Assert::IsTrue(result); @@ -118,11 +117,10 @@ namespace KeyboardManagerCommonTests TEST_METHOD (CheckRepeatedModifier_ShouldReturnTrue_OnPassingConflictingModifierRepeated) { // Arrange - std::vector keyList = LayoutMap().GetKeyCodeList(true); - std::vector keys = { VK_CONTROL, VK_LCONTROL, 0x41 }; + std::vector keys = { VK_CONTROL, VK_LCONTROL, 0x41 }; // Act - bool result = KeyboardManagerHelper::CheckRepeatedModifier(keys, TestHelpers::GetDropDownIndexFromDropDownList(VK_LCONTROL, keyList), keyList); + bool result = KeyboardManagerHelper::CheckRepeatedModifier(keys, VK_LCONTROL); // Assert Assert::IsTrue(result); @@ -132,42 +130,13 @@ namespace KeyboardManagerCommonTests TEST_METHOD (CheckRepeatedModifier_ShouldReturnFalse_OnPassingDifferentModifiers) { // Arrange - std::vector keyList = LayoutMap().GetKeyCodeList(true); - std::vector keys = { VK_CONTROL, VK_SHIFT, 0x41 }; + std::vector keys = { VK_CONTROL, VK_SHIFT, 0x41 }; // Act - bool result = KeyboardManagerHelper::CheckRepeatedModifier(keys, TestHelpers::GetDropDownIndexFromDropDownList(VK_SHIFT, keyList), keyList); + bool result = KeyboardManagerHelper::CheckRepeatedModifier(keys, VK_SHIFT); // Assert Assert::IsFalse(result); } - - // Test if the GetKeyCodesFromSelectedIndices method ignores -1 and 0 from argument in return value - TEST_METHOD (GetKeyCodesFromSelectedIndices_ShouldIgnoreMinus1And0_OnPassingArgumentWithMinus1Or0) - { - // Arrange - std::vector keyList = LayoutMap().GetKeyCodeList(true); - std::vector indices = { -1, 0, -1, 0 }; - - // Act - auto result = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(indices, keyList); - - // Assert - Assert::IsTrue(result.empty()); - } - - // Test if the GetKeyCodesFromSelectedIndices method returns vector with key codes from vector with indices as per key code list - TEST_METHOD (GetKeyCodesFromSelectedIndices_ShouldReturnVectorWithKeyCodes_OnPassingVectorWithIndicesAsPerKeyCodeList) - { - // Arrange - std::vector keyList = LayoutMap().GetKeyCodeList(true); - std::vector indices = { TestHelpers::GetDropDownIndexFromDropDownList(0x41, keyList), TestHelpers::GetDropDownIndexFromDropDownList(0x42, keyList) }; - - // Act - auto result = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(indices, keyList); - - // Assert - Assert::IsTrue(result == std::vector{ 0x41, 0x42 }); - } }; } diff --git a/src/modules/keyboardmanager/test/ShortcutTests.cpp b/src/modules/keyboardmanager/test/ShortcutTests.cpp index c82763436c..591d3aa444 100644 --- a/src/modules/keyboardmanager/test/ShortcutTests.cpp +++ b/src/modules/keyboardmanager/test/ShortcutTests.cpp @@ -79,8 +79,8 @@ namespace KeyboardManagerCommonTests TEST_METHOD (DoKeysOverlap_ShouldReturnNoError_OnPassingInvalidShortcutForOneOfTheArguments) { // Arrange - Shortcut s1(std::vector{ NULL }); - Shortcut s2(std::vector{ VK_CONTROL, 0x41 }); + Shortcut s1(std::vector{ NULL }); + Shortcut s2(std::vector{ VK_CONTROL, 0x41 }); // Act auto result = Shortcut::DoKeysOverlap(s1, s2); @@ -93,7 +93,7 @@ namespace KeyboardManagerCommonTests TEST_METHOD (DoKeysOverlap_ShouldReturnSameShortcutPreviouslyMapped_OnPassingSameShortcutForBothArguments) { // Arrange - Shortcut s1(std::vector{ VK_CONTROL, 0x41 }); + Shortcut s1(std::vector{ VK_CONTROL, 0x41 }); Shortcut s2 = s1; // Act @@ -107,8 +107,8 @@ namespace KeyboardManagerCommonTests TEST_METHOD (DoKeysOverlap_ShouldReturnNoError_OnPassingShortcutsWithDifferentActionKeys) { // Arrange - Shortcut s1(std::vector{ VK_CONTROL, 0x42 }); - Shortcut s2(std::vector{ VK_CONTROL, 0x41 }); + Shortcut s1(std::vector{ VK_CONTROL, 0x42 }); + Shortcut s2(std::vector{ VK_CONTROL, 0x41 }); // Act auto result = Shortcut::DoKeysOverlap(s1, s2); @@ -121,8 +121,8 @@ namespace KeyboardManagerCommonTests TEST_METHOD (DoKeysOverlap_ShouldReturnNoError_OnPassingShortcutsWithDifferentModifiers) { // Arrange - Shortcut s1(std::vector{ VK_CONTROL, 0x42 }); - Shortcut s2(std::vector{ VK_SHIFT, 0x42 }); + Shortcut s1(std::vector{ VK_CONTROL, 0x42 }); + Shortcut s2(std::vector{ VK_SHIFT, 0x42 }); // Act auto result = Shortcut::DoKeysOverlap(s1, s2); @@ -135,8 +135,8 @@ namespace KeyboardManagerCommonTests TEST_METHOD (DoKeysOverlap_ShouldReturnConflictingModifierShortcut_OnPassingShortcutsWithLeftModifierAndCommonModifierOfSameType) { // Arrange - Shortcut s1(std::vector{ VK_LCONTROL, 0x42 }); - Shortcut s2(std::vector{ VK_CONTROL, 0x42 }); + Shortcut s1(std::vector{ VK_LCONTROL, 0x42 }); + Shortcut s2(std::vector{ VK_CONTROL, 0x42 }); // Act auto result = Shortcut::DoKeysOverlap(s1, s2); @@ -149,8 +149,8 @@ namespace KeyboardManagerCommonTests TEST_METHOD (DoKeysOverlap_ShouldReturnConflictingModifierShortcut_OnPassingShortcutsWithRightModifierAndCommonModifierOfSameType) { // Arrange - Shortcut s1(std::vector{ VK_RCONTROL, 0x42 }); - Shortcut s2(std::vector{ VK_CONTROL, 0x42 }); + Shortcut s1(std::vector{ VK_RCONTROL, 0x42 }); + Shortcut s2(std::vector{ VK_CONTROL, 0x42 }); // Act auto result = Shortcut::DoKeysOverlap(s1, s2); @@ -163,8 +163,8 @@ namespace KeyboardManagerCommonTests TEST_METHOD (DoKeysOverlap_ShouldReturnConflictingModifierShortcut_OnPassingShortcutsWithLeftModifierAndRightModifierOfSameType) { // Arrange - Shortcut s1(std::vector{ VK_LCONTROL, 0x42 }); - Shortcut s2(std::vector{ VK_RCONTROL, 0x42 }); + Shortcut s1(std::vector{ VK_LCONTROL, 0x42 }); + Shortcut s2(std::vector{ VK_RCONTROL, 0x42 }); // Act auto result = Shortcut::DoKeysOverlap(s1, s2); diff --git a/src/modules/keyboardmanager/test/TestHelpers.cpp b/src/modules/keyboardmanager/test/TestHelpers.cpp index 6d42906b58..501280be59 100644 --- a/src/modules/keyboardmanager/test/TestHelpers.cpp +++ b/src/modules/keyboardmanager/test/TestHelpers.cpp @@ -22,10 +22,4 @@ namespace TestHelpers state.SetActivatedApp(maxLengthString); state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp); } - - // Function to return the index of the given key code from the drop down key list - int GetDropDownIndexFromDropDownList(DWORD key, const std::vector& keyList) - { - return (int)std::distance(keyList.begin(), std::find(keyList.begin(), keyList.end(), key)); - } } diff --git a/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp b/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp index 34d600e691..ab73775195 100644 --- a/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp +++ b/src/modules/keyboardmanager/ui/BufferValidationHelpers.cpp @@ -2,21 +2,22 @@ #include "BufferValidationHelpers.h" #include #include +#include namespace BufferValidationHelpers { // Function to validate and update an element of the key remap buffer when the selection has changed - KeyboardManagerHelper::ErrorType ValidateAndUpdateKeyBufferElement(int rowIndex, int colIndex, int selectedKeyIndex, const std::vector& keyCodeList, RemapBuffer& remapBuffer) + KeyboardManagerHelper::ErrorType ValidateAndUpdateKeyBufferElement(int rowIndex, int colIndex, int selectedKeyCode, RemapBuffer& remapBuffer) { KeyboardManagerHelper::ErrorType errorType = KeyboardManagerHelper::ErrorType::NoError; // Check if the element was not found or the index exceeds the known keys - if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex) + if (selectedKeyCode != -1) { // Check if the value being set is the same as the other column if (remapBuffer[rowIndex].first[std::abs(int(colIndex) - 1)].index() == 0) { - if (std::get(remapBuffer[rowIndex].first[std::abs(int(colIndex) - 1)]) == keyCodeList[selectedKeyIndex]) + if (std::get(remapBuffer[rowIndex].first[std::abs(int(colIndex) - 1)]) == selectedKeyCode) { errorType = KeyboardManagerHelper::ErrorType::MapToSameKey; } @@ -33,7 +34,7 @@ namespace BufferValidationHelpers { if (remapBuffer[i].first[colIndex].index() == 0) { - KeyboardManagerHelper::ErrorType result = KeyboardManagerHelper::DoKeysOverlap(std::get(remapBuffer[i].first[colIndex]), keyCodeList[selectedKeyIndex]); + KeyboardManagerHelper::ErrorType result = KeyboardManagerHelper::DoKeysOverlap(std::get(remapBuffer[i].first[colIndex]), selectedKeyCode); if (result != KeyboardManagerHelper::ErrorType::NoError) { errorType = result; @@ -49,7 +50,7 @@ namespace BufferValidationHelpers // If there is no error, set the buffer if (errorType == KeyboardManagerHelper::ErrorType::NoError) { - remapBuffer[rowIndex].first[colIndex] = keyCodeList[selectedKeyIndex]; + remapBuffer[rowIndex].first[colIndex] = selectedKeyCode; } else { @@ -66,18 +67,17 @@ namespace BufferValidationHelpers } // Function to validate an element of the shortcut remap buffer when the selection has changed - std::pair ValidateShortcutBufferElement(int rowIndex, int colIndex, uint32_t dropDownIndex, const std::vector& selectedIndices, std::wstring appName, bool isHybridControl, const std::vector& keyCodeList, const RemapBuffer& remapBuffer, bool dropDownFound) + std::pair ValidateShortcutBufferElement(int rowIndex, int colIndex, uint32_t dropDownIndex, const std::vector& selectedCodes, std::wstring appName, bool isHybridControl, const RemapBuffer& remapBuffer, bool dropDownFound) { BufferValidationHelpers::DropDownAction dropDownAction = BufferValidationHelpers::DropDownAction::NoAction; KeyboardManagerHelper::ErrorType errorType = KeyboardManagerHelper::ErrorType::NoError; - size_t dropDownCount = selectedIndices.size(); - std::vector selectedKeyCodes = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(selectedIndices, keyCodeList); - int selectedKeyIndex = dropDownFound ? selectedIndices[dropDownIndex] : -1; + size_t dropDownCount = selectedCodes.size(); + DWORD selectedKeyCode = dropDownFound ? selectedCodes[dropDownIndex] : -1; - if (selectedKeyIndex != -1 && keyCodeList.size() > selectedKeyIndex && dropDownFound) + if (selectedKeyCode != -1 && dropDownFound) { // If only 1 drop down and action key is chosen: Warn that a modifier must be chosen (if the drop down is not for a hybrid scenario) - if (dropDownCount == 1 && !KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && !isHybridControl) + if (dropDownCount == 1 && !KeyboardManagerHelper::IsModifierKey(selectedKeyCode) && !isHybridControl) { // warn and reset the drop down errorType = KeyboardManagerHelper::ErrorType::ShortcutStartWithModifier; @@ -86,10 +86,10 @@ namespace BufferValidationHelpers else if (dropDownIndex == dropDownCount - 1) { // If last drop down and a modifier is selected: add a new drop down (max drop down count should be enforced) - if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && dropDownCount < KeyboardManagerConstants::MaxShortcutSize) + if (KeyboardManagerHelper::IsModifierKey(selectedKeyCode) && dropDownCount < KeyboardManagerConstants::MaxShortcutSize) { // If it matched any of the previous modifiers then reset that drop down - if (KeyboardManagerHelper::CheckRepeatedModifier(selectedKeyCodes, selectedKeyIndex, keyCodeList)) + if (KeyboardManagerHelper::CheckRepeatedModifier(selectedCodes, selectedKeyCode)) { // warn and reset the drop down errorType = KeyboardManagerHelper::ErrorType::ShortcutCannotHaveRepeatedModifier; @@ -101,13 +101,13 @@ namespace BufferValidationHelpers } } // If last drop down and a modifier is selected but there are already max drop downs: warn the user - else if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex]) && dropDownCount >= KeyboardManagerConstants::MaxShortcutSize) + else if (KeyboardManagerHelper::IsModifierKey(selectedKeyCode) && dropDownCount >= KeyboardManagerConstants::MaxShortcutSize) { // warn and reset the drop down errorType = KeyboardManagerHelper::ErrorType::ShortcutMaxShortcutSizeOneActionKey; } // If None is selected but it's the last index: warn - else if (keyCodeList[selectedKeyIndex] == 0) + else if (selectedKeyCode == 0) { // If it is a hybrid control and there are 2 drop downs then deletion is allowed if (isHybridControl && dropDownCount == KeyboardManagerConstants::MinShortcutSize) @@ -123,7 +123,7 @@ namespace BufferValidationHelpers } } // Disable can not be selected if one modifier key has already been selected - else if (keyCodeList[selectedKeyIndex] == CommonSharedConstants::VK_DISABLED && dropDownIndex) + else if (selectedKeyCode == CommonSharedConstants::VK_DISABLED && dropDownIndex) { errorType = KeyboardManagerHelper::ErrorType::ShortcutDisableAsActionKey; } @@ -132,10 +132,10 @@ namespace BufferValidationHelpers // If it is not the last drop down else { - if (KeyboardManagerHelper::IsModifierKey(keyCodeList[selectedKeyIndex])) + if (KeyboardManagerHelper::IsModifierKey(selectedKeyCode)) { // If it matched any of the previous modifiers then reset that drop down - if (KeyboardManagerHelper::CheckRepeatedModifier(selectedKeyCodes, selectedKeyIndex, keyCodeList)) + if (KeyboardManagerHelper::CheckRepeatedModifier(selectedCodes, selectedKeyCode)) { // warn and reset the drop down errorType = KeyboardManagerHelper::ErrorType::ShortcutCannotHaveRepeatedModifier; @@ -143,13 +143,13 @@ namespace BufferValidationHelpers // If not, the modifier key will be set } // If None is selected and there are more than 2 drop downs - else if (keyCodeList[selectedKeyIndex] == 0 && dropDownCount > KeyboardManagerConstants::MinShortcutSize) + else if (selectedKeyCode == 0 && dropDownCount > KeyboardManagerConstants::MinShortcutSize) { // set delete drop down flag dropDownAction = BufferValidationHelpers::DropDownAction::DeleteDropDown; // do not delete the drop down now since there may be some other error which would cause the drop down to be invalid after removal } - else if (keyCodeList[selectedKeyIndex] == 0 && dropDownCount <= KeyboardManagerConstants::MinShortcutSize) + else if (selectedKeyCode == 0 && dropDownCount <= KeyboardManagerConstants::MinShortcutSize) { // If it is a hybrid control and there are 2 drop downs then deletion is allowed if (isHybridControl && dropDownCount == KeyboardManagerConstants::MinShortcutSize) @@ -165,7 +165,7 @@ namespace BufferValidationHelpers } } // Allow selection of VK_DISABLE only in first dropdown - else if (keyCodeList[selectedKeyIndex] == CommonSharedConstants::VK_DISABLED && dropDownIndex) + else if (selectedKeyCode == CommonSharedConstants::VK_DISABLED && dropDownIndex) { errorType = KeyboardManagerHelper::ErrorType::ShortcutDisableAsActionKey; } @@ -175,7 +175,7 @@ namespace BufferValidationHelpers bool isClear = true; for (int i = dropDownIndex + 1; i < (int)dropDownCount; i++) { - if (selectedIndices[i] != -1) + if (selectedCodes[i] != -1) { isClear = false; break; @@ -205,14 +205,14 @@ namespace BufferValidationHelpers if (errorType == KeyboardManagerHelper::ErrorType::NoError) { KeyShortcutUnion tempShortcut; - if (isHybridControl && selectedKeyCodes.size() == 1) + if (isHybridControl && KeyDropDownControl::GetNumberOfSelectedKeys(selectedCodes) == 1) { - tempShortcut = selectedKeyCodes[0]; + tempShortcut = *std::find_if(selectedCodes.begin(), selectedCodes.end(), [](int32_t a) { return a != -1 && a != 0; }); } else { tempShortcut = Shortcut(); - std::get(tempShortcut).SetKeyCodes(selectedKeyCodes); + std::get(tempShortcut).SetKeyCodes(selectedCodes); } // Convert app name to lower case diff --git a/src/modules/keyboardmanager/ui/BufferValidationHelpers.h b/src/modules/keyboardmanager/ui/BufferValidationHelpers.h index c8f5cae450..3c28a292ee 100644 --- a/src/modules/keyboardmanager/ui/BufferValidationHelpers.h +++ b/src/modules/keyboardmanager/ui/BufferValidationHelpers.h @@ -15,8 +15,8 @@ namespace BufferValidationHelpers }; // Function to validate and update an element of the key remap buffer when the selection has changed - KeyboardManagerHelper::ErrorType ValidateAndUpdateKeyBufferElement(int rowIndex, int colIndex, int selectedKeyIndex, const std::vector& keyCodeList, RemapBuffer& remapBuffer); + KeyboardManagerHelper::ErrorType ValidateAndUpdateKeyBufferElement(int rowIndex, int colIndex, int selectedKeyCode, RemapBuffer& remapBuffer); // Function to validate an element of the shortcut remap buffer when the selection has changed - std::pair ValidateShortcutBufferElement(int rowIndex, int colIndex, uint32_t dropDownIndex, const std::vector& selectedIndices, std::wstring appName, bool isHybridControl, const std::vector& keyCodeList, const RemapBuffer& remapBuffer, bool dropDownFound); + std::pair ValidateShortcutBufferElement(int rowIndex, int colIndex, uint32_t dropDownIndex, const std::vector& selectedCodes, std::wstring appName, bool isHybridControl, const RemapBuffer& remapBuffer, bool dropDownFound); } diff --git a/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp b/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp index ff4eae2260..971271778e 100644 --- a/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp +++ b/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp @@ -5,29 +5,34 @@ #include "BufferValidationHelpers.h" #include #include +#include // Initialized to null KeyboardManagerState* KeyDropDownControl::keyboardManagerState = nullptr; -// Get keys code list depending if Disable is in dropdown -std::vector KeyDropDownControl::GetKeyCodeList(bool isShortcut, bool renderDisable) +// Get selected value of dropdown or -1 if nothing is selected +DWORD KeyDropDownControl::GetSelectedValue(ComboBox comboBox) { - auto list = keyboardManagerState->keyboardMap.GetKeyCodeList(isShortcut); - if (renderDisable) - { - list.insert(list.begin(), CommonSharedConstants::VK_DISABLED); - } + auto dataContext = comboBox.SelectedValue(); + if (!dataContext) + return -1; - return list; + auto value = winrt::unbox_value(dataContext); + return stoi(std::wstring(value)); +} + +void KeyDropDownControl::SetSelectedValue(std::wstring value) +{ + this->dropDown.as().SelectedValue(winrt::box_value(value)); } // Get keys name list depending if Disable is in dropdown -std::vector KeyDropDownControl::GetKeyNameList(bool isShortcut, bool renderDisable) +std::vector> KeyDropDownControl::GetKeyList(bool isShortcut, bool renderDisable) { auto list = keyboardManagerState->keyboardMap.GetKeyNameList(isShortcut); if (renderDisable) { - list.insert(list.begin(), keyboardManagerState->keyboardMap.GetKeyName(CommonSharedConstants::VK_DISABLED)); + list.insert(list.begin(), { CommonSharedConstants::VK_DISABLED, keyboardManagerState->keyboardMap.GetKeyName(CommonSharedConstants::VK_DISABLED) }); } return list; @@ -51,8 +56,9 @@ void KeyDropDownControl::SetDefaultProperties(bool isShortcut, bool renderDisabl dropDown.as().MaxDropDownHeight(KeyboardManagerConstants::TableDropDownHeight); // Initialise layout attribute previousLayout = GetKeyboardLayout(0); - keyCodeList = GetKeyCodeList(isShortcut, renderDisable); - dropDown.as().ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyNameList(isShortcut, renderDisable))); + dropDown.as().SelectedValuePath(L"DataContext"); + dropDown.as().ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyList(isShortcut, renderDisable))); + // drop down open handler - to reload the items with the latest layout dropDown.as().DropDownOpened([&, isShortcut](winrt::Windows::Foundation::IInspectable const& sender, auto args) { ComboBox currentDropDown = sender.as(); @@ -82,8 +88,7 @@ void KeyDropDownControl::CheckAndUpdateKeyboardLayout(ComboBox currentDropDown, // Check if the layout has changed if (previousLayout != layout) { - keyCodeList = GetKeyCodeList(isShortcut, renderDisable); - currentDropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyNameList(isShortcut, renderDisable))); + currentDropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(GetKeyList(isShortcut, renderDisable))); previousLayout = layout; } } @@ -94,7 +99,8 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel singleKeyCo // drop down selection handler auto onSelectionChange = [&, table, singleKeyControl, colIndex](winrt::Windows::Foundation::IInspectable const& sender) { ComboBox currentDropDown = sender.as(); - int selectedKeyIndex = currentDropDown.SelectedIndex(); + int selectedKeyCode = GetSelectedValue(currentDropDown); + // Get row index of the single key control uint32_t controlIndex; bool indexFound = table.Children().IndexOf(singleKeyControl, controlIndex); @@ -104,7 +110,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel singleKeyCo int rowIndex = table.GetRow(singleKeyControl) - 1; // Validate current remap selection - KeyboardManagerHelper::ErrorType errorType = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(rowIndex, colIndex, selectedKeyIndex, keyCodeList, singleKeyRemapBuffer); + KeyboardManagerHelper::ErrorType errorType = BufferValidationHelpers::ValidateAndUpdateKeyBufferElement(rowIndex, colIndex, selectedKeyCode, singleKeyRemapBuffer); // If there is an error set the warning flyout if (errorType != KeyboardManagerHelper::ErrorType::NoError) @@ -132,7 +138,6 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel singleKeyCo std::pair KeyDropDownControl::ValidateShortcutSelection(Grid table, StackPanel shortcutControl, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow) { ComboBox currentDropDown = dropDown.as(); - int selectedKeyIndex = currentDropDown.SelectedIndex(); uint32_t dropDownIndex = -1; bool dropDownFound = parent.Children().IndexOf(currentDropDown, dropDownIndex); // Get row index of the single key control @@ -146,7 +151,7 @@ std::pair KeyDropDownControl::ValidateSho // GetRow will give the row index including the table header rowIndex = table.GetRow(shortcutControl) - 1; - std::vector selectedIndices = GetSelectedIndicesFromStackPanel(parent); + std::vector selectedCodes = GetSelectedCodesFromStackPanel(parent); std::wstring appName; if (targetApp != nullptr) @@ -155,7 +160,7 @@ std::pair KeyDropDownControl::ValidateSho } // Validate shortcut element - validationResult = BufferValidationHelpers::ValidateShortcutBufferElement(rowIndex, colIndex, dropDownIndex, selectedIndices, appName, isHybridControl, keyCodeList, shortcutRemapBuffer, dropDownFound); + validationResult = BufferValidationHelpers::ValidateShortcutBufferElement(rowIndex, colIndex, dropDownIndex, selectedCodes, appName, isHybridControl, shortcutRemapBuffer, dropDownFound); // Add or clear unused drop downs if (validationResult.second == BufferValidationHelpers::DropDownAction::AddDropDown) @@ -229,7 +234,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutCon } // Reset the buffer based on the new selected drop down items. Use static key code list since the KeyDropDownControl object might be deleted - std::vector selectedKeyCodes = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(GetSelectedIndicesFromStackPanel(parent), GetKeyCodeList(true, colIndex == 1)); + std::vector selectedKeyCodes = GetSelectedCodesFromStackPanel(parent); if (!isHybridControl) { std::get(shortcutRemapBuffer[validationResult.second].first[colIndex]).SetKeyCodes(selectedKeyCodes); @@ -237,7 +242,7 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutCon else { // If exactly one key is selected consider it to be a key remap - if (selectedKeyCodes.size() == 1) + if (GetNumberOfSelectedKeys(selectedKeyCodes) == 1) { shortcutRemapBuffer[validationResult.second].first[colIndex] = selectedKeyCodes[0]; } @@ -294,12 +299,6 @@ void KeyDropDownControl::SetSelectionHandler(Grid& table, StackPanel shortcutCon }); } -// Function to set the selected index of the drop down -void KeyDropDownControl::SetSelectedIndex(int32_t index) -{ - dropDown.as().SelectedIndex(index); -} - // Function to return the combo box element of the drop down ComboBox KeyDropDownControl::GetComboBox() { @@ -319,18 +318,18 @@ void KeyDropDownControl::AddDropDown(Grid table, StackPanel shortcutControl, Sta } // Function to get the list of key codes from the shortcut combo box stack panel -std::vector KeyDropDownControl::GetSelectedIndicesFromStackPanel(StackPanel parent) +std::vector KeyDropDownControl::GetSelectedCodesFromStackPanel(StackPanel parent) { - std::vector selectedIndices; + std::vector selectedKeyCodes; // Get selected indices for each drop down for (int i = 0; i < (int)parent.Children().Size(); i++) { ComboBox ItDropDown = parent.Children().GetAt(i).as(); - selectedIndices.push_back(ItDropDown.SelectedIndex()); + selectedKeyCodes.push_back(GetSelectedValue(ItDropDown)); } - return selectedIndices; + return selectedKeyCodes; } // Function for validating the selection of shortcuts for all the associated drop downs @@ -340,9 +339,9 @@ void KeyDropDownControl::ValidateShortcutFromDropDownList(Grid table, StackPanel for (int i = 0; i < keyDropDownControlObjects.size(); i++) { // Check for errors only if the current selection is a valid shortcut - std::vector selectedKeyCodes = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(keyDropDownControlObjects[i]->GetSelectedIndicesFromStackPanel(parent), GetKeyCodeList(true, colIndex == 1)); + std::vector selectedKeyCodes = GetSelectedCodesFromStackPanel(parent); KeyShortcutUnion currentShortcut; - if (selectedKeyCodes.size() == 1 && isHybridControl) + if (GetNumberOfSelectedKeys(selectedKeyCodes) == 1 && isHybridControl) { currentShortcut = selectedKeyCodes[0]; } @@ -354,7 +353,7 @@ void KeyDropDownControl::ValidateShortcutFromDropDownList(Grid table, StackPanel } // If the key/shortcut is valid and that drop down is not empty - if (((currentShortcut.index() == 0 && std::get(currentShortcut) != NULL) || (currentShortcut.index() == 1 && std::get(currentShortcut).IsValidShortcut())) && keyDropDownControlObjects[i]->GetComboBox().SelectedIndex() != -1) + if (((currentShortcut.index() == 0 && std::get(currentShortcut) != NULL) || (currentShortcut.index() == 1 && std::get(currentShortcut).IsValidShortcut())) && GetSelectedValue(keyDropDownControlObjects[i]->GetComboBox()) != -1) { keyDropDownControlObjects[i]->ValidateShortcutSelection(table, shortcutControl, parent, colIndex, shortcutRemapBuffer, keyDropDownControlObjects, targetApp, isHybridControl, isSingleKeyWindow); } @@ -376,9 +375,7 @@ void KeyDropDownControl::AddShortcutToControl(Shortcut shortcut, Grid table, Sta parent.Children().Clear(); // Remove references to the old drop down objects to destroy them keyDropDownControlObjects.clear(); - std::vector shortcutKeyCodes = shortcut.GetKeyCodes(); - std::vector keyCodeList = GetKeyCodeList(true, colIndex == 1); if (shortcutKeyCodes.size() != 0) { bool ignoreWarning = false; @@ -393,17 +390,19 @@ void KeyDropDownControl::AddShortcutToControl(Shortcut shortcut, Grid table, Sta for (int i = 0; i < shortcutKeyCodes.size(); i++) { - // New drop down gets added automatically when the SelectedIndex is set + // New drop down gets added automatically when the SelectedValue(key code) is set if (i < (int)parent.Children().Size()) { ComboBox currentDropDown = parent.Children().GetAt(i).as(); - auto it = std::find(keyCodeList.begin(), keyCodeList.end(), shortcutKeyCodes[i]); - if (it != keyCodeList.end()) - { - currentDropDown.SelectedIndex((int32_t)std::distance(keyCodeList.begin(), it)); - } + currentDropDown.SelectedValue(winrt::box_value(std::to_wstring(shortcutKeyCodes[i]))); } } } parent.UpdateLayout(); } + +// Get number of selected keys. Do not count -1 and 0 values as they stand for Not selected and None +int KeyDropDownControl::GetNumberOfSelectedKeys(std::vector keyCodes) +{ + return (int)std::count_if(keyCodes.begin(), keyCodes.end(), [](int32_t a) { return a != -1 && a != 0; }); +} \ No newline at end of file diff --git a/src/modules/keyboardmanager/ui/KeyDropDownControl.h b/src/modules/keyboardmanager/ui/KeyDropDownControl.h index c7a9b24fba..03b9d2f1b7 100644 --- a/src/modules/keyboardmanager/ui/KeyDropDownControl.h +++ b/src/modules/keyboardmanager/ui/KeyDropDownControl.h @@ -33,8 +33,6 @@ private: winrt::Windows::Foundation::IInspectable dropDown; // Stores the previous layout HKL previousLayout = 0; - // Stores the key code list - std::vector keyCodeList; // Stores the flyout warning message winrt::Windows::Foundation::IInspectable warningMessage; // Stores the flyout attached to the current drop down @@ -48,6 +46,9 @@ private: // Function to check if the layout has changed and accordingly update the drop down list void CheckAndUpdateKeyboardLayout(ComboBox currentDropDown, bool isShortcut, bool renderDisable); + // Get selected value of dropdown or -1 if nothing is selected + static DWORD GetSelectedValue(ComboBox comboBox); + // Function to set accessible name for combobox static void SetAccessibleNameForComboBox(ComboBox dropDown, int index); public: @@ -70,9 +71,6 @@ public: // Function to set selection handler for shortcut drop down. Needs to be called after the constructor since the shortcutControl StackPanel is null if called in the constructor void SetSelectionHandler(winrt::Windows::UI::Xaml::Controls::Grid& table, winrt::Windows::UI::Xaml::Controls::StackPanel shortcutControl, winrt::Windows::UI::Xaml::Controls::StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox& targetApp, bool isHybridControl, bool isSingleKeyWindow); - // Function to set the selected index of the drop down - void SetSelectedIndex(int32_t index); - // Function to return the combo box element of the drop down ComboBox GetComboBox(); @@ -80,7 +78,7 @@ public: static void AddDropDown(winrt::Windows::UI::Xaml::Controls::Grid table, winrt::Windows::UI::Xaml::Controls::StackPanel shortcutControl, winrt::Windows::UI::Xaml::Controls::StackPanel parent, const int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector>& keyDropDownControlObjects, winrt::Windows::UI::Xaml::Controls::TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow, bool ignoreWarning = false); // Function to get the list of key codes from the shortcut combo box stack panel - static std::vector GetSelectedIndicesFromStackPanel(StackPanel parent); + static std::vector GetSelectedCodesFromStackPanel(StackPanel parent); // Function for validating the selection of shortcuts for all the associated drop downs static void ValidateShortcutFromDropDownList(Grid table, StackPanel shortcutControl, StackPanel parent, int colIndex, RemapBuffer& shortcutRemapBuffer, std::vector>& keyDropDownControlObjects, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow); @@ -88,12 +86,15 @@ public: // Function to set the warning message void SetDropDownError(winrt::Windows::UI::Xaml::Controls::ComboBox currentDropDown, winrt::hstring message); + // Set selected Value + void SetSelectedValue(std::wstring value); + // Function to add a shortcut to the UI control as combo boxes static void AddShortcutToControl(Shortcut shortcut, Grid table, StackPanel parent, KeyboardManagerState& keyboardManagerState, const int colIndex, std::vector>& keyDropDownControlObjects, RemapBuffer& remapBuffer, StackPanel controlLayout, TextBox targetApp, bool isHybridControl, bool isSingleKeyWindow); - // Get keys code list depending if Disable is in dropdown - static std::vector GetKeyCodeList(bool isShortcut, bool renderDisable); - // Get keys name list depending if Disable is in dropdown - static std::vector GetKeyNameList(bool isShortcut, bool renderDisable); + static std::vector> GetKeyList(bool isShortcut, bool renderDisable); + + // Get number of selected keys. Do not count -1 and 0 values as they stand for Not selected and None + static int GetNumberOfSelectedKeys(std::vector keys); }; diff --git a/src/modules/keyboardmanager/ui/ShortcutControl.cpp b/src/modules/keyboardmanager/ui/ShortcutControl.cpp index b4782752fd..ca2e18ccec 100644 --- a/src/modules/keyboardmanager/ui/ShortcutControl.cpp +++ b/src/modules/keyboardmanager/ui/ShortcutControl.cpp @@ -133,9 +133,10 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vectorgetShortcutControl(), keyboardRemapControlObjects[rowIndex][1]->shortcutDropDownStackPanel.as(), 1, ShortcutControl::shortcutRemapBuffer, keyboardRemapControlObjects[rowIndex][1]->keyDropDownControlObjects, targetAppTextBox, true, false); // Reset the buffer based on the selected drop down items - std::get(shortcutRemapBuffer[rowIndex].first[0]).SetKeyCodes(KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(KeyDropDownControl::GetSelectedIndicesFromStackPanel(keyboardRemapControlObjects[rowIndex][0]->shortcutDropDownStackPanel.as()), KeyDropDownControl::GetKeyCodeList(true, false))); + std::get(shortcutRemapBuffer[rowIndex].first[0]).SetKeyCodes(KeyDropDownControl::GetSelectedCodesFromStackPanel(keyboardRemapControlObjects[rowIndex][0]->shortcutDropDownStackPanel.as())); // second column is a hybrid column - std::vector selectedKeyCodes = KeyboardManagerHelper::GetKeyCodesFromSelectedIndices(KeyDropDownControl::GetSelectedIndicesFromStackPanel(keyboardRemapControlObjects[rowIndex][1]->shortcutDropDownStackPanel.as()), KeyDropDownControl::GetKeyCodeList(true, true)); + + std::vector selectedKeyCodes = KeyDropDownControl::GetSelectedCodesFromStackPanel(keyboardRemapControlObjects[rowIndex][1]->shortcutDropDownStackPanel.as()); // If exactly one key is selected consider it to be a key remap if (selectedKeyCodes.size() == 1) @@ -244,12 +245,7 @@ void ShortcutControl::AddNewShortcutControlRow(Grid& parent, std::vector shortcutListKeyCodes = KeyDropDownControl::GetKeyCodeList(true, true); - auto it = std::find(shortcutListKeyCodes.begin(), shortcutListKeyCodes.end(), std::get(newKeys)); - if (it != shortcutListKeyCodes.end()) - { - keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects[0]->SetSelectedIndex((int32_t)std::distance(shortcutListKeyCodes.begin(), it)); - } + keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects[0]->SetSelectedValue(std::to_wstring(std::get(newKeys))); } else { diff --git a/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp b/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp index 2cdf31d201..30cf8acb22 100644 --- a/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp +++ b/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp @@ -106,20 +106,10 @@ void SingleKeyRemapControl::AddNewControlKeyRemapRow(Grid& parent, std::vector(newKey) == NULL) && !(newKey.index() == 1 && !std::get(newKey).IsValidShortcut())) { singleKeyRemapBuffer.push_back(std::make_pair(RemapBufferItem{ originalKey, newKey }, L"")); - std::vector keyCodes = keyboardManagerState->keyboardMap.GetKeyCodeList(); - std::vector shortcutListKeyCodes = KeyDropDownControl::GetKeyCodeList(true, true); - auto it = std::find(keyCodes.begin(), keyCodes.end(), originalKey); - if (it != keyCodes.end()) - { - keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->keyDropDownControlObjects[0]->SetSelectedIndex((int32_t)std::distance(keyCodes.begin(), it)); - } + keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][0]->keyDropDownControlObjects[0]->SetSelectedValue(std::to_wstring(originalKey)); if (newKey.index() == 0) { - it = std::find(shortcutListKeyCodes.begin(), shortcutListKeyCodes.end(), std::get(newKey)); - if (it != shortcutListKeyCodes.end()) - { - keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects[0]->SetSelectedIndex((int32_t)std::distance(shortcutListKeyCodes.begin(), it)); - } + keyboardRemapControlObjects[keyboardRemapControlObjects.size() - 1][1]->keyDropDownControlObjects[0]->SetSelectedValue(std::to_wstring(std::get(newKey))); } else { @@ -234,11 +224,7 @@ void SingleKeyRemapControl::createDetectKeyWindow(winrt::Windows::Foundation::II std::vector keyCodeList = keyboardManagerState.keyboardMap.GetKeyCodeList(); // Update the drop down list with the new language to ensure that the correct key is displayed linkedRemapDropDown.ItemsSource(KeyboardManagerHelper::ToBoxValue(keyboardManagerState.keyboardMap.GetKeyNameList())); - auto it = std::find(keyCodeList.begin(), keyCodeList.end(), detectedKey); - if (it != keyCodeList.end()) - { - linkedRemapDropDown.SelectedIndex((int32_t)std::distance(keyCodeList.begin(), it)); - } + linkedRemapDropDown.SelectedValue(winrt::box_value(std::to_wstring(detectedKey))); } // Hide the type key UI detectRemapKeyBox.Hide(); From 06de5ffa0708e3d8f490c084d61b2ebb4c9c6c3c Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 19 Oct 2020 10:22:30 -0700 Subject: [PATCH 19/65] LEGO: check in for master to temporary branch. (#7338) --- .../Strings/en-us/Resources.resw.lcl | 6 ++++++ .../Strings/en-us/Resources.resw.lcl | 18 ++++++++++++++++++ .../Strings/en-us/Resources.resw.lcl | 6 ++++++ .../Strings/en-us/Resources.resw.lcl | 9 +++++++++ .../keyboardmanager/dll/Resources.resx.lcl | 10 ++++++++-- .../keyboardmanager/dll/Resources.resx.lcl | 10 ++++++++-- .../keyboardmanager/dll/Resources.resx.lcl | 6 ++++++ .../keyboardmanager/dll/Resources.resx.lcl | 2 +- .../keyboardmanager/dll/Resources.resx.lcl | 10 ++++++++-- 9 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 64a7e46c68..d03c54b940 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/hu/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -283,6 +283,9 @@ + + + @@ -964,6 +967,9 @@ + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index eb6c4600bb..129d7de1bf 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/pt-BR/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -955,6 +964,15 @@ + + + + + + + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index b642d7d444..fdfe13e3e7 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/tr/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -283,6 +283,9 @@ + + + @@ -964,6 +967,9 @@ + + + diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 5ff1b586c1..dd2f9f54ac 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/zh-Hans/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -472,6 +472,9 @@ + + + @@ -514,12 +517,18 @@ + + + + + + diff --git a/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl index af0471f9e3..a2469ba540 100644 --- a/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + + + + @@ -176,8 +179,11 @@ - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl index bd687d2d07..8199c5a966 100644 --- a/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + + + + @@ -176,8 +179,11 @@ - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl index 975c423038..96f95faf98 100644 --- a/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -106,6 +106,9 @@ + + + @@ -178,6 +181,9 @@ + + + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl index 73f0f52bfc..ba9c396b3c 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -103,7 +103,7 @@ - + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl index b1bb91cb98..cea31af58e 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -104,8 +104,11 @@ - + + + + @@ -176,8 +179,11 @@ - + + + + From 12a84c01b132b42bc70440dcfc50475b48e7a64f Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 19 Oct 2020 10:23:15 -0700 Subject: [PATCH 20/65] LEGO: check in for master to temporary branch. (#7346) --- .../src/modules/imageresizer/ui/Properties/Resources.resx.lcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/imageresizer/ui/loc/hu/src/modules/imageresizer/ui/Properties/Resources.resx.lcl b/src/modules/imageresizer/ui/loc/hu/src/modules/imageresizer/ui/Properties/Resources.resx.lcl index deaac2d508..b7a790b7e0 100644 --- a/src/modules/imageresizer/ui/loc/hu/src/modules/imageresizer/ui/Properties/Resources.resx.lcl +++ b/src/modules/imageresizer/ui/loc/hu/src/modules/imageresizer/ui/Properties/Resources.resx.lcl @@ -68,7 +68,7 @@ - + From 4660dd49708c8a53868f487878a36719d4a58db6 Mon Sep 17 00:00:00 2001 From: Gordon Watts Date: Mon, 19 Oct 2020 10:42:01 -0700 Subject: [PATCH 21/65] Add action keywords for each plugin (#6129) * Add action keywords for each plugin - Added keywords for each plug-in - Change window walker search to use Query, not RawQuery (to get rid of action keyword) - Make sure plug-ins that have action keywords as well as are in global list don't get added twice All tests passed that passed before I started Addressing issue #5823 * Fix bad formatting from the merge * Do not add global plug-ins if we have an action keyword Note side effect: you will not not be able to search for things that start with one of the plug-in keywords. * Missed merge conflict repair! * Revert "Do not add global plug-ins if we have an action keyword" This reverts commit e3b0ecd708455c28b4ebf1a590ab5bdb1990f21a. * Adjust keywords to suggested ones * No need to ubild a query if we aren't going to use it Didn't quite get the if statement right the first time I put it in. * Do not add global plugins if we have an action keyword This means, especially without a space, that global plugins do not become part of the search. Which really narrows down the search results, nicely. * Update keywords as requested in the PR --- .../Microsoft.Plugin.Calculator/plugin.json | 2 +- .../Microsoft.Plugin.Folder/plugin.json | 2 +- .../Microsoft.Plugin.Indexer/plugin.json | 2 +- .../Microsoft.Plugin.Program/plugin.json | 2 +- .../Plugins/Microsoft.Plugin.Uri/plugin.json | 2 +- .../Microsoft.Plugin.WindowWalker/Main.cs | 2 +- .../Microsoft.Plugin.WindowWalker/plugin.json | 2 +- .../launcher/Wox.Core/Plugin/QueryBuilder.cs | 18 +++++++++++++----- 8 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/plugin.json index 8a4629ef93..2bfa6343b5 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/plugin.json @@ -1,6 +1,6 @@ { "ID":"CEA0FDFC6D3B4085823D60DC76F28855", - "ActionKeyword":"*", + "ActionKeywords": [ "*", "=" ], "Name":"Calculator", "Description":"Provide mathematical calculations.(Try 5*3-2 in PowerToys)", "Author":"cxfksword", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json index 8d1bce3e96..686f8566af 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/plugin.json @@ -1,6 +1,6 @@ { "ID":"B4D3B69656E14D44865C8D818EAE47C4", - "ActionKeyword":"*", + "ActionKeyword": "*", "Name":"Folder", "Description":"Searcn and open folders", "Author":"qianlifeng", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json index 147e81d886..8c9dd6772f 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/plugin.json @@ -1,6 +1,6 @@ { "ID": "2140FC9819AD43A3A616E2735815C27C", - "ActionKeyword": "*", + "ActionKeywords": [ "*", "?" ], "Name": "Windows Indexer", "Description": "Search for files and folders", "Author": "Microsoft", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json index 97d23aa4a8..25a917f2ce 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/plugin.json @@ -1,6 +1,6 @@ { "ID":"791FC278BA414111B8D1886DFE447410", - "ActionKeyword":"*", + "ActionKeywords": [ "*", "."], "Name":"Program", "Description":"Search for programs", "Author":"qianlifeng", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json index 38347f46b0..836f3fa317 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/plugin.json @@ -1,6 +1,6 @@ { "ID": "03276A39D4E9417C8FFD200B0EE5E871", - "ActionKeyword": "*", + "ActionKeywords": [ "*", "//" ], "Name": "Windows Uri Handler", "Description": "Handles urls", "Author": "Microsoft", diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs index 4e7cbca161..3056e3df87 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs @@ -32,7 +32,7 @@ namespace Microsoft.Plugin.WindowWalker } OpenWindows.Instance.UpdateOpenWindowsList(); - SearchController.Instance.UpdateSearchText(query.RawQuery).Wait(); + SearchController.Instance.UpdateSearchText(query.Search).Wait(); return _results.Select(x => new Result() { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json index 3293c76320..c8f54664dc 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/plugin.json @@ -1,6 +1,6 @@ { "ID":"F737A9223560B3C6833B5FFB8CDF78E5", - "ActionKeyword":"*", + "ActionKeywords": [ "*", "<"], "Name":"Window Walker", "Description":"Alt-Tab alternative enabling searching through your windows.", "Author":"betadele", diff --git a/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs b/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs index d9976e4752..a915fef3ee 100644 --- a/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs +++ b/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs @@ -59,12 +59,20 @@ namespace Wox.Core.Plugin } } - var globalplugins = PluginManager.GlobalPlugins; - - foreach (PluginPair globalPlugin in PluginManager.GlobalPlugins) + // If the user has specified a matching action keyword, then do not + // add the global plugins to the list. + if (pluginQueryPair.Count == 0) { - var query = new Query(rawQuery, rawQuery, terms, string.Empty); - pluginQueryPair.Add(globalPlugin, query); + var globalplugins = PluginManager.GlobalPlugins; + + foreach (PluginPair globalPlugin in PluginManager.GlobalPlugins) + { + if (!pluginQueryPair.ContainsKey(globalPlugin)) + { + var query = new Query(rawQuery, rawQuery, terms, string.Empty); + pluginQueryPair.Add(globalPlugin, query); + } + } } return pluginQueryPair; From 03509e7f36afff02bb9cac2b7b1e37dd9df2a995 Mon Sep 17 00:00:00 2001 From: Andrey Nekrasov Date: Mon, 19 Oct 2020 20:54:39 +0300 Subject: [PATCH 22/65] Logging improvements (#7377) * bootstrapper: fix Windows SDK version * devdocs: add spdlog usage readme --- doc/devdocs/logging.md | 9 +++++++++ src/logging/logging.vcxproj | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 doc/devdocs/logging.md diff --git a/doc/devdocs/logging.md b/doc/devdocs/logging.md new file mode 100644 index 0000000000..ba3a50dd2c --- /dev/null +++ b/doc/devdocs/logging.md @@ -0,0 +1,9 @@ +# How to use + +We use the awesome [spdlog](https://github.com/gabime/spdlog) library for logging as a git submodule under the `deps` directory. To use it in your project, just include [spdlog.props](../../deps/spdlog.props) in a .vcxproj like this: + +```xml + +``` +It'll add the required include dirs and link the library binary itself. +You can see many example usage of the library in its repository or in the [bootstrapper project](../../installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp). diff --git a/src/logging/logging.vcxproj b/src/logging/logging.vcxproj index 6649b4e2b9..6c283eab81 100644 --- a/src/logging/logging.vcxproj +++ b/src/logging/logging.vcxproj @@ -15,7 +15,7 @@ {7E1E3F13-2BD6-3F75-A6A7-873A2B55C60F} - 10.0.19041.0 + 10.0.17134.0 Win32Proj x64 logging From 688f1340519085370e444a205c4853a317b2e4db Mon Sep 17 00:00:00 2001 From: Luthfi Mawarid Date: Mon, 19 Oct 2020 13:32:05 -0700 Subject: [PATCH 23/65] [fxcop] Settings UI library (part 2) (#7257) * Suppress warnings for read-only collection properties (see code comments) * Call ConfigureAwait on tasks * Add CultureInfo and StringComparison policy for certain string operations * Add checks and exceptions for null arguments to public methods * Rename RaisePropertyChanged to NotifyPropertyChanged * Suppress CA1000 warning on SettingsRepository class * Implement Disposable pattern in HotkeySettingsControlHook * Modify null argument handling in KeyboardManagerViewModel::CombineShortcutLists --- .../AppSpecificKeysDataModel.cs | 11 ++- .../ColorPickerSettings.cs | 6 ++ .../CustomAction/SendCustomAction.cs | 3 +- .../HotkeySettingsControlHook.cs | 21 ++++- .../ImageSize.cs | 6 ++ .../ImageresizerSizes.cs | 5 ++ .../PowerLauncherSettings.cs | 6 ++ .../PowerRenameSettings.cs | 6 ++ .../RemapKeysDataModel.cs | 5 ++ .../SettingsRepository`1.cs | 4 + .../ShortcutsKeyDataModel.cs | 7 ++ .../Utilities/Helper.cs | 9 ++ .../ViewModels/ColorPickerViewModel.cs | 13 ++- .../ViewModels/FancyZonesViewModel.cs | 86 ++++++++++++------- .../ViewModels/GeneralViewModel.cs | 39 ++++++--- .../ViewModels/ImageResizerViewModel.cs | 10 +++ .../ViewModels/KeyboardManagerViewModel.cs | 33 +++++-- .../ViewModels/PowerLauncherViewModel.cs | 13 ++- .../ViewModels/PowerPreviewViewModel.cs | 10 +++ .../ViewModels/PowerRenameViewModel.cs | 5 ++ .../ViewModels/ShortcutGuideViewModel.cs | 22 +++-- .../ViewModelTests/KeyboardManager.cs | 63 ++++++++++++++ .../Views/GeneralPage.xaml.cs | 8 +- 23 files changed, 326 insertions(+), 65 deletions(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/AppSpecificKeysDataModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/AppSpecificKeysDataModel.cs index 3b849a7473..e3bedd2eb3 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/AppSpecificKeysDataModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/AppSpecificKeysDataModel.cs @@ -2,6 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Text.Json.Serialization; @@ -24,7 +25,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib public bool Compare(AppSpecificKeysDataModel arg) { - return OriginalKeys.Equals(arg.OriginalKeys) && NewRemapKeys.Equals(arg.NewRemapKeys) && TargetApp.Equals(arg.TargetApp); + if (arg == null) + { + throw new ArgumentNullException(nameof(arg)); + } + + // Using Ordinal comparison for internal text + return OriginalKeys.Equals(arg.OriginalKeys, StringComparison.Ordinal) && + NewRemapKeys.Equals(arg.NewRemapKeys, StringComparison.Ordinal) && + TargetApp.Equals(arg.TargetApp, StringComparison.Ordinal); } } } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ColorPickerSettings.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ColorPickerSettings.cs index 849bae1909..42de1632d2 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ColorPickerSettings.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ColorPickerSettings.cs @@ -2,6 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.PowerToys.Settings.UI.Lib.Interface; @@ -30,6 +31,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib WriteIndented = true, }; + if (settingsUtils == null) + { + throw new ArgumentNullException(nameof(settingsUtils)); + } + settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName); } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/CustomAction/SendCustomAction.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/CustomAction/SendCustomAction.cs index 515be86b6e..81c8b7ef26 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/CustomAction/SendCustomAction.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/CustomAction/SendCustomAction.cs @@ -25,7 +25,8 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.CustomAction { PropertyNamingPolicy = new CustomNamePolicy((propertyName) => { - return propertyName.Equals("ModuleAction") ? moduleName : propertyName; + // Using Ordinal as this is an internal property name + return propertyName.Equals("ModuleAction", System.StringComparison.Ordinal) ? moduleName : propertyName; }), }; diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/HotkeySettingsControlHook.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/HotkeySettingsControlHook.cs index 1b7cfc48d2..26231e7553 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/HotkeySettingsControlHook.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/HotkeySettingsControlHook.cs @@ -13,7 +13,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib public delegate bool FilterAccessibleKeyboardEvents(int key, UIntPtr extraInfo); - public class HotkeySettingsControlHook + public class HotkeySettingsControlHook : IDisposable { private const int WmKeyDown = 0x100; private const int WmKeyUp = 0x101; @@ -24,6 +24,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib private KeyEvent _keyDown; private KeyEvent _keyUp; private IsActive _isActive; + private bool disposedValue; private FilterAccessibleKeyboardEvents _filterKeyboardEvent; @@ -62,10 +63,24 @@ namespace Microsoft.PowerToys.Settings.UI.Lib return _filterKeyboardEvent(ev.key, (UIntPtr)ev.dwExtraInfo); } + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // Dispose the KeyboardHook object to terminate the hook threads + _hook.Dispose(); + } + + disposedValue = true; + } + } + public void Dispose() { - // Dispose the KeyboardHook object to terminate the hook threads - _hook.Dispose(); + Dispose(disposing: true); + GC.SuppressFinalize(this); } } } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageSize.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageSize.cs index a5d2d4aea1..cd268add57 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageSize.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageSize.cs @@ -2,6 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Text.Json; @@ -222,6 +223,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib public void Update(ImageSize modifiedSize) { + if (modifiedSize == null) + { + throw new ArgumentNullException(nameof(modifiedSize)); + } + Id = modifiedSize.Id; Name = modifiedSize.Name; Fit = modifiedSize.Fit; diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageresizerSizes.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageresizerSizes.cs index 38ae835af1..36d79b2d03 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageresizerSizes.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ImageresizerSizes.cs @@ -10,8 +10,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib { public class ImageResizerSizes { + // Suppressing this warning because removing the setter breaks + // deserialization with System.Text.Json. This affects the UI display. + // See: https://github.com/dotnet/runtime/issues/30258 [JsonPropertyName("value")] +#pragma warning disable CA2227 // Collection properties should be read only public ObservableCollection Value { get; set; } +#pragma warning restore CA2227 // Collection properties should be read only public ImageResizerSizes() { diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerLauncherSettings.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerLauncherSettings.cs index 124657664c..72aaedd9e0 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerLauncherSettings.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerLauncherSettings.cs @@ -2,6 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.PowerToys.Settings.UI.Lib.Interface; @@ -30,6 +31,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib WriteIndented = true, }; + if (settingsUtils == null) + { + throw new ArgumentNullException(nameof(settingsUtils)); + } + settingsUtils.SaveSettings(JsonSerializer.Serialize(this, options), ModuleName); } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerRenameSettings.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerRenameSettings.cs index 0d7dc58a98..9b89e38f88 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerRenameSettings.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/PowerRenameSettings.cs @@ -2,6 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Text.Json.Serialization; using Microsoft.PowerToys.Settings.UI.Lib.Interface; @@ -23,6 +24,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib public PowerRenameSettings(PowerRenameLocalProperties localProperties) { + if (localProperties == null) + { + throw new ArgumentNullException(nameof(localProperties)); + } + Properties = new PowerRenameProperties(); Properties.PersistState.Value = localProperties.PersistState; Properties.MRUEnabled.Value = localProperties.MRUEnabled; diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs index 873d5d7d64..894d97483d 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/RemapKeysDataModel.cs @@ -10,8 +10,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib { public class RemapKeysDataModel { + // Suppressing this warning because removing the setter breaks + // deserialization with System.Text.Json. This affects the UI display. + // See: https://github.com/dotnet/runtime/issues/30258 [JsonPropertyName("inProcess")] +#pragma warning disable CA2227 // Collection properties should be read only public List InProcessRemapKeys { get; set; } +#pragma warning restore CA2227 // Collection properties should be read only public RemapKeysDataModel() { diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsRepository`1.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsRepository`1.cs index 3bb7df8518..8930bf23d4 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsRepository`1.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsRepository`1.cs @@ -20,7 +20,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib private T settingsConfig; + // Suppressing the warning as this is a singleton class and this method is + // necessarily static +#pragma warning disable CA1000 // Do not declare static members on generic types public static SettingsRepository GetInstance(ISettingsUtils settingsUtils) +#pragma warning restore CA1000 // Do not declare static members on generic types { // To ensure that only one instance of Settings Repository is created in a multi-threaded environment. lock (_SettingsRepoLock) diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs index 5195c6c1e9..91db9695db 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ShortcutsKeyDataModel.cs @@ -10,11 +10,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib { public class ShortcutsKeyDataModel { + // Suppressing these warnings because removing the setter breaks + // deserialization with System.Text.Json. This affects the UI display. + // See: https://github.com/dotnet/runtime/issues/30258 [JsonPropertyName("global")] +#pragma warning disable CA2227 // Collection properties should be read only public List GlobalRemapShortcuts { get; set; } +#pragma warning restore CA2227 // Collection properties should be read only [JsonPropertyName("appSpecific")] +#pragma warning disable CA2227 // Collection properties should be read only public List AppSpecificRemapShortcuts { get; set; } +#pragma warning restore CA2227 // Collection properties should be read only public ShortcutsKeyDataModel() { diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/Utilities/Helper.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/Utilities/Helper.cs index 71b3e47929..e6b5d723d4 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/Utilities/Helper.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/Utilities/Helper.cs @@ -92,6 +92,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.Utilities { // Split up the version strings into int[] // Example: v10.0.2 -> {10, 0, 2}; + if (version1 == null) + { + throw new ArgumentNullException(nameof(version1)); + } + else if (version2 == null) + { + throw new ArgumentNullException(nameof(version2)); + } + var v1 = version1.Substring(1).Split('.').Select(int.Parse).ToArray(); var v2 = version2.Substring(1).Split('.').Select(int.Parse).ToArray(); diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ColorPickerViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ColorPickerViewModel.cs index 5df080b77d..a56ae1c537 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ColorPickerViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ColorPickerViewModel.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Globalization; using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Lib.Helpers; using Microsoft.PowerToys.Settings.UI.Lib.Interface; @@ -24,6 +25,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels public ColorPickerViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc) { // Obtain the general PowerToy settings configurations + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; _settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils)); @@ -121,8 +127,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels private void NotifySettingsChanged() { + // Using InvariantCulture as this is an IPC message SendConfigMSG( - string.Format("{{ \"powertoys\": {{ \"{0}\": {1} }} }}", ColorPickerSettings.ModuleName, JsonSerializer.Serialize(_colorPickerSettings))); + string.Format( + CultureInfo.InvariantCulture, + "{{ \"powertoys\": {{ \"{0}\": {1} }} }}", + ColorPickerSettings.ModuleName, + JsonSerializer.Serialize(_colorPickerSettings))); } } } diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/FancyZonesViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/FancyZonesViewModel.cs index bf773a2649..86acc34cc8 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/FancyZonesViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/FancyZonesViewModel.cs @@ -4,6 +4,7 @@ using System; using System.Drawing; +using System.Globalization; using System.Runtime.CompilerServices; using Microsoft.PowerToys.Settings.UI.Lib.Helpers; using Microsoft.PowerToys.Settings.UI.Lib.Interface; @@ -28,10 +29,20 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels public FancyZonesViewModel(ISettingsRepository settingsRepository, ISettingsRepository moduleSettingsRepository, Func ipcMSGCallBackFunc, string configFileSubfolder = "") { // To obtain the general settings configurations of PowerToys Settings. + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; settingsConfigFileFolder = configFileSubfolder; // To obtain the settings configurations of Fancy zones. + if (moduleSettingsRepository == null) + { + throw new ArgumentNullException(nameof(moduleSettingsRepository)); + } + Settings = moduleSettingsRepository.SettingsConfig; LaunchEditorEventHandler = new ButtonClickCommand(LaunchEditor); @@ -137,7 +148,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _shiftDrag = value; Settings.Properties.FancyzonesShiftDrag.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -155,7 +166,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _mouseSwitch = value; Settings.Properties.FancyzonesMouseSwitch.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -178,7 +189,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _overrideSnapHotkeys = value; Settings.Properties.FancyzonesOverrideSnapHotkeys.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); OnPropertyChanged(nameof(SnapHotkeysCategoryEnabled)); } } @@ -197,7 +208,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _moveWindowsAcrossMonitors = value; Settings.Properties.FancyzonesMoveWindowsAcrossMonitors.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -215,7 +226,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _moveWindowsBasedOnPosition = value; Settings.Properties.FancyzonesMoveWindowsBasedOnPosition.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -233,7 +244,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _displayChangemoveWindows = value; Settings.Properties.FancyzonesDisplayChangeMoveWindows.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -251,7 +262,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _zoneSetChangeMoveWindows = value; Settings.Properties.FancyzonesZoneSetChangeMoveWindows.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -269,7 +280,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _appLastZoneMoveWindows = value; Settings.Properties.FancyzonesAppLastZoneMoveWindows.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -287,7 +298,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _openWindowOnActiveMonitor = value; Settings.Properties.FancyzonesOpenWindowOnActiveMonitor.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -305,7 +316,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _restoreSize = value; Settings.Properties.FancyzonesRestoreSize.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -323,7 +334,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _useCursorPosEditorStartupScreen = value; Settings.Properties.UseCursorposEditorStartupscreen.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -341,7 +352,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _showOnAllMonitors = value; Settings.Properties.FancyzonesShowOnAllMonitors.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -359,7 +370,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _spanZonesAcrossMonitors = value; Settings.Properties.FancyzonesSpanZonesAcrossMonitors.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -377,11 +388,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _makeDraggedWindowTransparent = value; Settings.Properties.FancyzonesMakeDraggedWindowTransparent.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } + // For the following setters we use OrdinalIgnoreCase string comparison since + // we expect value to be a hex code. public string ZoneHighlightColor { get @@ -391,12 +404,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels set { - value = ToRGBHex(value); - if (!value.Equals(_zoneHighlightColor)) + // The fallback value is based on ToRGBHex's behavior, which returns + // #FFFFFF if any exceptions are encountered, e.g. from passing in a null value. + // This extra handling is added here to deal with FxCop warnings. + value = (value != null) ? ToRGBHex(value) : "#FFFFFF"; + if (!value.Equals(_zoneHighlightColor, StringComparison.OrdinalIgnoreCase)) { _zoneHighlightColor = value; Settings.Properties.FancyzonesZoneHighlightColor.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -410,12 +426,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels set { - value = ToRGBHex(value); + // The fallback value is based on ToRGBHex's behavior, which returns + // #FFFFFF if any exceptions are encountered, e.g. from passing in a null value. + // This extra handling is added here to deal with FxCop warnings. + value = (value != null) ? ToRGBHex(value) : "#FFFFFF"; if (!value.Equals(_zoneBorderColor, StringComparison.OrdinalIgnoreCase)) { _zoneBorderColor = value; Settings.Properties.FancyzonesBorderColor.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -429,12 +448,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels set { - value = ToRGBHex(value); - if (!value.Equals(_zoneInActiveColor)) + // The fallback value is based on ToRGBHex's behavior, which returns + // #FFFFFF if any exceptions are encountered, e.g. from passing in a null value. + // This extra handling is added here to deal with FxCop warnings. + value = (value != null) ? ToRGBHex(value) : "#FFFFFF"; + if (!value.Equals(_zoneInActiveColor, StringComparison.OrdinalIgnoreCase)) { _zoneInActiveColor = value; Settings.Properties.FancyzonesInActiveColor.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -452,7 +474,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _highlightOpacity = value; Settings.Properties.FancyzonesHighlightOpacity.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -468,7 +490,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { if (value != _editorHotkey) { - if (value.IsEmpty()) + if (value == null || value.IsEmpty()) { _editorHotkey = FZConfigProperties.DefaultHotkeyValue; } @@ -478,7 +500,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels } Settings.Properties.FancyzonesEditorHotkey.Value = _editorHotkey; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -496,7 +518,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _excludedApps = value; Settings.Properties.FancyzonesExcludedApps.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -507,7 +529,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels SendConfigMSG("{\"action\":{\"FancyZones\":{\"action_name\":\"ToggledFZEditor\", \"value\":\"\"}}}"); } - public void RaisePropertyChanged([CallerMemberName] string propertyName = null) + public void NotifyPropertyChanged([CallerMemberName] string propertyName = null) { OnPropertyChanged(propertyName); if (SendConfigMSG != null) @@ -522,9 +544,15 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { try { - int argb = int.Parse(color.Replace("#", string.Empty), System.Globalization.NumberStyles.HexNumber); + // Using InvariantCulture as these are expected to be hex codes. + int argb = int.Parse( + color.Replace("#", string.Empty), + System.Globalization.NumberStyles.HexNumber, + CultureInfo.InvariantCulture); Color clr = Color.FromArgb(argb); - return "#" + clr.R.ToString("X2") + clr.G.ToString("X2") + clr.B.ToString("X2"); + return "#" + clr.R.ToString("X2", CultureInfo.InvariantCulture) + + clr.G.ToString("X2", CultureInfo.InvariantCulture) + + clr.B.ToString("X2", CultureInfo.InvariantCulture); } catch (Exception) { diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/GeneralViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/GeneralViewModel.cs index df15756f79..fe6a83c0fc 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/GeneralViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/GeneralViewModel.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Globalization; using System.Runtime.CompilerServices; using Microsoft.PowerToys.Settings.UI.Lib.Helpers; using Microsoft.PowerToys.Settings.UI.Lib.Interface; @@ -39,6 +40,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels RestartElevatedButtonEventHandler = new ButtonClickCommand(RestartElevated); // To obtain the general settings configuration of PowerToys if it exists, else to create a new file and return the default configurations. + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; // set the callback functions value to hangle outgoing IPC message. @@ -48,20 +54,25 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels // set the callback function value to update the UI theme. UpdateUIThemeCallBack = updateTheme; - UpdateUIThemeCallBack(GeneralSettingsConfig.Theme.ToLower()); + + UpdateUIThemeCallBack(GeneralSettingsConfig.Theme); // Update Settings file folder: _settingsConfigFileFolder = configFileSubfolder; - switch (GeneralSettingsConfig.Theme.ToLower()) + // Using Invariant here as these are internal strings and fxcop + // expects strings to be normalized to uppercase. While the theme names + // are represented in lowercase everywhere else, we'll use uppercase + // normalization for switch statements + switch (GeneralSettingsConfig.Theme.ToUpperInvariant()) { - case "light": + case "LIGHT": _isLightThemeRadioButtonChecked = true; break; - case "dark": + case "DARK": _isDarkThemeRadioButtonChecked = true; break; - case "system": + case "SYSTEM": _isSystemThemeRadioButtonChecked = true; break; } @@ -102,7 +113,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels if (_packaged != value) { _packaged = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -121,7 +132,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _startup = value; GeneralSettingsConfig.Startup = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -193,7 +204,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _runElevated = value; GeneralSettingsConfig.RunElevated = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -220,7 +231,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _autoDownloadUpdates = value; GeneralSettingsConfig.AutoDownloadUpdates = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -246,7 +257,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { } - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -272,7 +283,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { } - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -298,7 +309,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { } - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -329,12 +340,12 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels if (_latestAvailableVersion != value) { _latestAvailableVersion = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } - public void RaisePropertyChanged([CallerMemberName] string propertyName = null) + public void NotifyPropertyChanged([CallerMemberName] string propertyName = null) { // Notify UI of property change OnPropertyChanged(propertyName); diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ImageResizerViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ImageResizerViewModel.cs index 44e564ad3b..e86b59c9ad 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ImageResizerViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ImageResizerViewModel.cs @@ -28,6 +28,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels _settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils)); // To obtain the general settings configurations of PowerToys. + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; try @@ -92,13 +97,18 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels } } +#pragma warning disable CA2227 // Collection properties should be read only public ObservableCollection Sizes +#pragma warning restore CA2227 // Collection properties should be read only { get { return _advancedSizes; } + // FxCop demands collection properties to be read-only, but this + // setter is used in autogenerated files (ImageResizerPage.g.cs) + // and replacing the setter with its own method will break the file set { SavesImageSizes(value); diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/KeyboardManagerViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/KeyboardManagerViewModel.cs index 0e6d36f519..ba50ea8d05 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/KeyboardManagerViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/KeyboardManagerViewModel.cs @@ -43,6 +43,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels public KeyboardManagerViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc, Func, int> filterRemapKeysList) { + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; // set the callback functions value to hangle outgoing IPC message. @@ -107,7 +112,22 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels public static List CombineShortcutLists(List globalShortcutList, List appSpecificShortcutList) { - return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).Concat(appSpecificShortcutList).ToList(); + if (globalShortcutList == null && appSpecificShortcutList == null) + { + return new List(); + } + else if (globalShortcutList == null) + { + return appSpecificShortcutList; + } + else if (appSpecificShortcutList == null) + { + return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).ToList(); + } + else + { + return globalShortcutList.ConvertAll(x => new AppSpecificKeysDataModel { OriginalKeys = x.OriginalKeys, NewRemapKeys = x.NewRemapKeys, TargetApp = "All Apps" }).Concat(appSpecificShortcutList).ToList(); + } } public List RemapShortcuts @@ -129,28 +149,31 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels public ICommand EditShortcutCommand => _editShortcutCommand ?? (_editShortcutCommand = new RelayCommand(OnEditShortcut)); + // Note: FxCop suggests calling ConfigureAwait() for the following methods, + // and calling ConfigureAwait(true) has the same behavior as not explicitly + // calling it (continuations are scheduled on the task-creating thread) private async void OnRemapKeyboard() { - await Task.Run(() => OnRemapKeyboardBackground()); + await Task.Run(() => OnRemapKeyboardBackground()).ConfigureAwait(true); } private async void OnEditShortcut() { - await Task.Run(() => OnEditShortcutBackground()); + await Task.Run(() => OnEditShortcutBackground()).ConfigureAwait(true); } private async Task OnRemapKeyboardBackground() { Helper.AllowRunnerToForeground(); SendConfigMSG(Helper.GetSerializedCustomAction(PowerToyName, RemapKeyboardActionName, RemapKeyboardActionValue)); - await Task.CompletedTask; + await Task.CompletedTask.ConfigureAwait(true); } private async Task OnEditShortcutBackground() { Helper.AllowRunnerToForeground(); SendConfigMSG(Helper.GetSerializedCustomAction(PowerToyName, EditShortcutActionName, EditShortcutActionValue)); - await Task.CompletedTask; + await Task.CompletedTask.ConfigureAwait(true); } public void NotifyFileChanged() diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerLauncherViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerLauncherViewModel.cs index 82af7c1b5d..2fac0e69ec 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerLauncherViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerLauncherViewModel.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Globalization; using System.Runtime.CompilerServices; using System.Text.Json; using Microsoft.PowerToys.Settings.UI.Lib.Helpers; @@ -29,6 +30,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels _settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils)); // To obtain the general Settings configurations of PowerToys + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; // set the callback functions value to hangle outgoing IPC message. @@ -36,8 +42,13 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels callback = (PowerLauncherSettings settings) => { // Propagate changes to Power Launcher through IPC + // Using InvariantCulture as this is an IPC message SendConfigMSG( - string.Format("{{ \"powertoys\": {{ \"{0}\": {1} }} }}", PowerLauncherSettings.ModuleName, JsonSerializer.Serialize(settings))); + string.Format( + CultureInfo.InvariantCulture, + "{{ \"powertoys\": {{ \"{0}\": {1} }} }}", + PowerLauncherSettings.ModuleName, + JsonSerializer.Serialize(settings))); }; if (_settingsUtils.SettingsExists(PowerLauncherSettings.ModuleName)) diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerPreviewViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerPreviewViewModel.cs index 981cb81406..5282a0e48c 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerPreviewViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerPreviewViewModel.cs @@ -27,10 +27,20 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels _settingsConfigFileFolder = configFileSubfolder; // To obtain the general Settings configurations of PowerToys + if (generalSettingsRepository == null) + { + throw new ArgumentNullException(nameof(generalSettingsRepository)); + } + GeneralSettingsConfig = generalSettingsRepository.SettingsConfig; // To obtain the PowerPreview settings if it exists. // If the file does not exist, to create a new one and return the default settings configurations. + if (moduleSettingsRepository == null) + { + throw new ArgumentNullException(nameof(moduleSettingsRepository)); + } + Settings = moduleSettingsRepository.SettingsConfig; // set the callback functions value to hangle outgoing IPC message. diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerRenameViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerRenameViewModel.cs index e5b464c034..fae8014c6a 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerRenameViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/PowerRenameViewModel.cs @@ -29,6 +29,11 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels _settingsConfigFileFolder = configFileSubfolder; _settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils)); + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; try diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ShortcutGuideViewModel.cs b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ShortcutGuideViewModel.cs index 8be635dfa4..bcde5576b7 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ShortcutGuideViewModel.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/ShortcutGuideViewModel.cs @@ -27,10 +27,20 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels _settingsConfigFileFolder = configFileSubfolder; // To obtain the general PowerToys settings. + if (settingsRepository == null) + { + throw new ArgumentNullException(nameof(settingsRepository)); + } + GeneralSettingsConfig = settingsRepository.SettingsConfig; // To obtain the shortcut guide settings, if the file exists. // If not, to create a file with the default settings and to return the default configurations. + if (moduleSettingsRepository == null) + { + throw new ArgumentNullException(nameof(moduleSettingsRepository)); + } + Settings = moduleSettingsRepository.SettingsConfig; // set the callback functions value to hangle outgoing IPC message. @@ -102,7 +112,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels // set theme to dark. Settings.Properties.Theme.Value = "dark"; _themeIndex = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } if (value == 1) @@ -110,7 +120,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels // set theme to light. Settings.Properties.Theme.Value = "light"; _themeIndex = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } if (value == 2) @@ -118,7 +128,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels // set theme to system default. Settings.Properties.Theme.Value = "system"; _themeIndex = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -137,7 +147,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _pressTime = value; Settings.Properties.PressTime.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -155,7 +165,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels { _opacity = value; Settings.Properties.OverlayOpacity.Value = value; - RaisePropertyChanged(); + NotifyPropertyChanged(); } } } @@ -165,7 +175,7 @@ namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels return _settingsConfigFileFolder + "\\" + ModuleName; } - public void RaisePropertyChanged([CallerMemberName] string propertyName = null) + public void NotifyPropertyChanged([CallerMemberName] string propertyName = null) { OnPropertyChanged(propertyName); SndShortcutGuideSettings outsettings = new SndShortcutGuideSettings(Settings); diff --git a/src/core/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs b/src/core/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs index f1888cbc41..75ee9479ea 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/KeyboardManager.cs @@ -41,6 +41,69 @@ namespace ViewModelTests Assert.AreEqual(expectedResult.Count, result.Count); } + [TestMethod] + public void CombineShortcutListsShouldReturnEmptyListWhenBothArgumentsAreNull() + { + // act + var result = KeyboardManagerViewModel.CombineShortcutLists(null, null); + + // Assert + var expectedResult = new List(); + + Assert.AreEqual(expectedResult.Count, result.Count); + } + + [TestMethod] + public void CombineShortcutListsShouldReturnListWithOneAppSpecificEntryWhenFirstArgumentIsNullAndSecondArgumentHasOneEntry() + { + // arrange + var secondList = new List(); + var entry = new AppSpecificKeysDataModel(); + entry.OriginalKeys = "17;65"; + entry.NewRemapKeys = "17;86"; + entry.TargetApp = "msedge"; + secondList.Add(entry); + + // act + var result = KeyboardManagerViewModel.CombineShortcutLists(null, secondList); + + // Assert + var expectedResult = new List(); + var expectedEntry = new AppSpecificKeysDataModel(); + expectedEntry.OriginalKeys = entry.OriginalKeys; + expectedEntry.NewRemapKeys = entry.NewRemapKeys; + expectedEntry.TargetApp = entry.TargetApp; + expectedResult.Add(expectedEntry); + + Assert.AreEqual(expectedResult.Count, result.Count); + Assert.IsTrue(expectedResult[0].Compare(result[0])); + } + + [TestMethod] + public void CombineShortcutListsShouldReturnListWithOneAllAppsEntryWhenFirstArgumentHasOneEntryAndSecondArgumentIsNull() + { + // arrange + var firstList = new List(); + var entry = new KeysDataModel(); + entry.OriginalKeys = "17;65"; + entry.NewRemapKeys = "17;86"; + firstList.Add(entry); + + // act + var result = KeyboardManagerViewModel.CombineShortcutLists(firstList, null); + + // Assert + var expectedResult = new List(); + var expectedEntry = new AppSpecificKeysDataModel(); + expectedEntry.OriginalKeys = entry.OriginalKeys; + expectedEntry.NewRemapKeys = entry.NewRemapKeys; + expectedEntry.TargetApp = "All Apps"; + expectedResult.Add(expectedEntry); + + Assert.AreEqual(expectedResult.Count, result.Count); + Assert.IsTrue(expectedResult[0].Compare(result[0])); + } + [TestMethod] public void CombineShortcutListsShouldReturnListWithOneAllAppsEntryWhenFirstArgumentHasOneEntryAndSecondArgumentIsEmpty() { diff --git a/src/core/Microsoft.PowerToys.Settings.UI/Views/GeneralPage.xaml.cs b/src/core/Microsoft.PowerToys.Settings.UI/Views/GeneralPage.xaml.cs index 739bafc106..a96ad730b4 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/Views/GeneralPage.xaml.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI/Views/GeneralPage.xaml.cs @@ -79,15 +79,15 @@ namespace Microsoft.PowerToys.Settings.UI.Views public int UpdateUIThemeMethod(string themeName) { - switch (themeName) + switch (themeName.ToUpperInvariant()) { - case "light": + case "LIGHT": ShellPage.ShellHandler.RequestedTheme = ElementTheme.Light; break; - case "dark": + case "DARK": ShellPage.ShellHandler.RequestedTheme = ElementTheme.Dark; break; - case "system": + case "SYSTEM": ShellPage.ShellHandler.RequestedTheme = ElementTheme.Default; break; } From 0aae53598630ff633a16672d8baf92edbb56060f Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Mon, 19 Oct 2020 20:49:17 +0300 Subject: [PATCH 24/65] fix low-level kb hook disabling macro --- src/modules/fancyzones/lib/GenericKeyHook.h | 1 + src/runner/centralized_kb_hook.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/fancyzones/lib/GenericKeyHook.h b/src/modules/fancyzones/lib/GenericKeyHook.h index 77d08c0b8c..361d77060e 100644 --- a/src/modules/fancyzones/lib/GenericKeyHook.h +++ b/src/modules/fancyzones/lib/GenericKeyHook.h @@ -2,6 +2,7 @@ #include "pch.h" #include +#include template class GenericKeyHook diff --git a/src/runner/centralized_kb_hook.cpp b/src/runner/centralized_kb_hook.cpp index a9c2409b63..f0945afc28 100644 --- a/src/runner/centralized_kb_hook.cpp +++ b/src/runner/centralized_kb_hook.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "centralized_kb_hook.h" -#include "common/common.h" +#include +#include namespace CentralizedKeyboardHook { From 8b759094f7177e2bb01123a5b241152f31677fc2 Mon Sep 17 00:00:00 2001 From: Avneet Kaur <72103212+avneet-kr@users.noreply.github.com> Date: Mon, 19 Oct 2020 15:46:56 -0700 Subject: [PATCH 25/65] FxCopAnalyzer fixes for Wox.Core (#7209) * FxCop Fixes- added InvarientCulture info, suppressed warnings for general exception types * Used IsNullOrEmpty to test for empty strings (CA1820: Test for empty strings using string length) * Check if arguments are null and throw ArgumentNullException * Removed unused function argument from PluginsLoader.cs * Addressing comments- Using attributes to suppress errors for general exception types * Addressing comments- Using attributes to suppress errors * Addressed comments and changed InvariantCulture to CurrentCulture/Ordinal where appropriate * Addressing comments - catching and logging specific exception in FontHelper.cs --- .../launcher/Wox.Core/Plugin/PluginConfig.cs | 2 ++ .../Wox.Core/Plugin/PluginInstaller.cs | 26 ++++++++------- .../launcher/Wox.Core/Plugin/PluginManager.cs | 33 ++++++++++++++++--- .../launcher/Wox.Core/Plugin/PluginsLoader.cs | 7 ++-- .../launcher/Wox.Core/Plugin/QueryBuilder.cs | 13 +++++++- .../launcher/Wox.Core/Resource/FontHelper.cs | 22 +++++++++++-- 6 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs b/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs index 0727fae26e..11094c0a4e 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginConfig.cs @@ -32,6 +32,7 @@ namespace Wox.Core.Plugin return PluginMetadatas; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] private static void ParsePluginConfigs(IEnumerable directories) { // todo use linq when diable plugin is implemented since parallel.foreach + list is not thread saft @@ -59,6 +60,7 @@ namespace Wox.Core.Plugin } } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] private static PluginMetadata GetPluginMetadata(string pluginDirectory) { string configPath = Path.Combine(pluginDirectory, PluginConfigName); diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs b/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs index 1c1a316066..38f74320ee 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs @@ -41,15 +41,16 @@ namespace Wox.Core.Plugin string pluginFolderPath = Infrastructure.Constant.PluginsDirectory; + // Using Ordinal since this is part of a path string newPluginName = plugin.Name - .Replace("/", "_") - .Replace("\\", "_") - .Replace(":", "_") - .Replace("<", "_") - .Replace(">", "_") - .Replace("?", "_") - .Replace("*", "_") - .Replace("|", "_") + .Replace("/", "_", StringComparison.Ordinal) + .Replace("\\", "_", StringComparison.Ordinal) + .Replace(":", "_", StringComparison.Ordinal) + .Replace("<", "_", StringComparison.Ordinal) + .Replace(">", "_", StringComparison.Ordinal) + .Replace("?", "_", StringComparison.Ordinal) + .Replace("*", "_", StringComparison.Ordinal) + .Replace("|", "_", StringComparison.Ordinal) + "-" + Guid.NewGuid(); string newPluginPath = Path.Combine(pluginFolderPath, newPluginName); string content = $"Do you want to install following plugin?{Environment.NewLine}{Environment.NewLine}" + @@ -157,12 +158,13 @@ namespace Wox.Core.Plugin /// overwrite private static void UnZip(string zippedFile, string strDirectory, bool overWrite) { - if (strDirectory == string.Empty) + if (string.IsNullOrEmpty(strDirectory)) { strDirectory = Directory.GetCurrentDirectory(); } - if (!strDirectory.EndsWith("\\")) + // Using Ordinal since this is a path + if (!strDirectory.EndsWith("\\", StringComparison.Ordinal)) { strDirectory += "\\"; } @@ -177,7 +179,7 @@ namespace Wox.Core.Plugin string pathToZip = string.Empty; pathToZip = theEntry.Name; - if (pathToZip != string.Empty) + if (!string.IsNullOrEmpty(pathToZip)) { directoryName = Path.GetDirectoryName(pathToZip) + "\\"; } @@ -186,7 +188,7 @@ namespace Wox.Core.Plugin Directory.CreateDirectory(strDirectory + directoryName); - if (fileName != string.Empty) + if (!string.IsNullOrEmpty(fileName)) { if ((File.Exists(strDirectory + directoryName + fileName) && overWrite) || (!File.Exists(strDirectory + directoryName + fileName))) { diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs b/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs index 53c2bbf663..d225090f3d 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Reflection; @@ -79,17 +80,18 @@ namespace Wox.Core.Plugin public static void LoadPlugins(PluginSettings settings) { _metadatas = PluginConfig.Parse(Directories); - Settings = settings; + Settings = settings ?? throw new ArgumentNullException(nameof(settings)); Settings.UpdatePluginSettings(_metadatas); - AllPlugins = PluginsLoader.Plugins(_metadatas, Settings); + AllPlugins = PluginsLoader.Plugins(_metadatas); } /// /// Call initialize for all plugins /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] public static void InitializePlugins(IPublicAPI api) { - API = api; + API = api ?? throw new ArgumentNullException(nameof(api)); var failedPlugins = new ConcurrentQueue(); Parallel.ForEach(AllPlugins, pair => { @@ -142,6 +144,11 @@ namespace Wox.Core.Plugin public static List ValidPluginsForQuery(Query query) { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + if (NonGlobalPlugins.ContainsKey(query.ActionKeyword)) { var plugin = NonGlobalPlugins[query.ActionKeyword]; @@ -153,8 +160,14 @@ namespace Wox.Core.Plugin } } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] public static List QueryForPlugin(PluginPair pair, Query query, bool delayedExecution = false) { + if (pair == null) + { + throw new ArgumentNullException(nameof(pair)); + } + try { List results = null; @@ -201,7 +214,8 @@ namespace Wox.Core.Plugin if (!string.IsNullOrEmpty(query.ActionKeyword)) { - result.QueryTextDisplay = string.Format("{0} {1}", query.ActionKeyword, result.QueryTextDisplay); + // Using CurrentCulture since this is user facing + result.QueryTextDisplay = string.Format(CultureInfo.CurrentCulture, "{0} {1}", query.ActionKeyword, result.QueryTextDisplay); } } @@ -210,6 +224,16 @@ namespace Wox.Core.Plugin public static void UpdatePluginMetadata(List results, PluginMetadata metadata, Query query) { + if (results == null) + { + throw new ArgumentNullException(nameof(results)); + } + + if (metadata == null) + { + throw new ArgumentNullException(nameof(metadata)); + } + foreach (var r in results) { r.PluginDirectory = metadata.PluginDirectory; @@ -239,6 +263,7 @@ namespace Wox.Core.Plugin return AllPlugins.Where(p => p.Plugin is T); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] public static List GetContextMenusForPlugin(Result result) { var pluginPair = _contextMenuPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs b/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs index 35456e480d..61b209d80e 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs @@ -17,7 +17,7 @@ namespace Wox.Core.Plugin { public const string PATH = "PATH"; - public static List Plugins(List metadatas, PluginSettings settings) + public static List Plugins(List metadatas) { var csharpPlugins = CSharpPlugins(metadatas).ToList(); var executablePlugins = ExecutablePlugins(metadatas); @@ -25,10 +25,11 @@ namespace Wox.Core.Plugin return plugins; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] public static IEnumerable CSharpPlugins(List source) { var plugins = new List(); - var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.CSharp); + var metadatas = source.Where(o => o.Language.ToUpperInvariant() == AllowedLanguage.CSharp); foreach (var metadata in metadatas) { @@ -89,7 +90,7 @@ namespace Wox.Core.Plugin public static IEnumerable ExecutablePlugins(IEnumerable source) { - var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.Executable); + var metadatas = source.Where(o => o.Language.ToUpperInvariant() == AllowedLanguage.Executable); var plugins = metadatas.Select(metadata => new PluginPair { diff --git a/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs b/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs index a915fef3ee..6db5def1c5 100644 --- a/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs +++ b/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs @@ -13,6 +13,16 @@ namespace Wox.Core.Plugin { public static Dictionary Build(ref string text, Dictionary nonGlobalPlugins) { + if (text == null) + { + throw new ArgumentNullException(nameof(text)); + } + + if (nonGlobalPlugins == null) + { + throw new ArgumentNullException(nameof(nonGlobalPlugins)); + } + // replace multiple white spaces with one white space var terms = text.Split(new[] { Query.TermSeparator }, StringSplitOptions.RemoveEmptyEntries); if (terms.Length == 0) @@ -32,7 +42,8 @@ namespace Wox.Core.Plugin foreach (string pluginActionKeyword in nonGlobalPlugins.Keys) { - if (possibleActionKeyword.StartsWith(pluginActionKeyword)) + // Using Ordinal since this is used internally + if (possibleActionKeyword.StartsWith(pluginActionKeyword, StringComparison.Ordinal)) { if (nonGlobalPlugins.TryGetValue(pluginActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled) { diff --git a/src/modules/launcher/Wox.Core/Resource/FontHelper.cs b/src/modules/launcher/Wox.Core/Resource/FontHelper.cs index 191cf8daad..90f6931fef 100644 --- a/src/modules/launcher/Wox.Core/Resource/FontHelper.cs +++ b/src/modules/launcher/Wox.Core/Resource/FontHelper.cs @@ -3,9 +3,12 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics; using System.Linq; +using System.Reflection; using System.Windows; using System.Windows.Media; +using Wox.Infrastructure.Logger; namespace Wox.Core.Resource { @@ -24,8 +27,9 @@ namespace Wox.Core.Resource { return (FontWeight)_fontWeightConverter.ConvertFromInvariantString(value); } - catch + catch (NotSupportedException e) { + Log.Exception($"Can't convert {value} to FontWeight", e, MethodBase.GetCurrentMethod().DeclaringType); return FontWeights.Normal; } } @@ -43,8 +47,9 @@ namespace Wox.Core.Resource { return (FontStyle)_fontStyleConverter.ConvertFromInvariantString(value); } - catch + catch (NotSupportedException e) { + Log.Exception($"Can't convert {value} to FontStyle", e, MethodBase.GetCurrentMethod().DeclaringType); return FontStyles.Normal; } } @@ -62,14 +67,20 @@ namespace Wox.Core.Resource { return (FontStretch)_fontStretchConverter.ConvertFromInvariantString(value); } - catch + catch (NotSupportedException e) { + Log.Exception($"Can't convert {value} to FontStretch", e, MethodBase.GetCurrentMethod().DeclaringType); return FontStretches.Normal; } } public static FamilyTypeface ChooseRegularFamilyTypeface(this FontFamily family) { + if (family == null) + { + throw new ArgumentNullException(nameof(family)); + } + return family.FamilyTypefaces.OrderBy(o => { return (Math.Abs(o.Stretch.ToOpenTypeStretch() - FontStretches.Normal.ToOpenTypeStretch()) * 100) + @@ -80,6 +91,11 @@ namespace Wox.Core.Resource public static FamilyTypeface ConvertFromInvariantStringsOrNormal(this FontFamily family, string style, string weight, string stretch) { + if (family == null) + { + throw new ArgumentNullException(nameof(family)); + } + var styleObj = GetFontStyleFromInvariantStringOrNormal(style); var weightObj = GetFontWeightFromInvariantStringOrNormal(weight); var stretchObj = GetFontStretchFromInvariantStringOrNormal(stretch); From 280d1907d831ad08b18efcc72498f3144951f13d Mon Sep 17 00:00:00 2001 From: Divyansh Srivastava Date: Mon, 19 Oct 2020 16:07:02 -0700 Subject: [PATCH 26/65] Non localized module name (#7170) * Added get_key to powertoysmodule interface * Replace get_name with get_key * Implement get_key function in modules * Make key global constant in each module * Update settings v1 to use key to load and save files * Fixed fancyzones and preview pane unit tests * Removed setings unit test as the case is not covered anymore * Add constant files for modules and use it to reference module key * Add constant string files to colorpicker, launcher and shortcut guide * correct sunction signature in settings helper * Fix powerpreview merge conflicts * nit fix with include statement location * add check for fields in from_json_string * Updated preview pane tests with correct from_json_string signature * Correct Image resizer naming * Roll back changes for adding check for property and version * Fix image resizer not working --- .../UnitTests-CommonLib/Settings.Tests.cpp | 43 ++++++++-------- src/common/settings_helpers.cpp | 16 +++--- src/common/settings_objects.cpp | 23 ++++++--- src/common/settings_objects.h | 8 +-- .../ColorPicker/ColorPicker.vcxproj | 1 + .../ColorPicker/ColorPickerConstants.h | 8 +++ .../colorPicker/ColorPicker/dllmain.cpp | 15 +++++- src/modules/fancyzones/dll/dllmain.cpp | 14 +++++- src/modules/fancyzones/lib/Settings.cpp | 18 ++++--- src/modules/fancyzones/lib/Settings.h | 2 +- .../tests/UnitTests/FancyZones.Spec.cpp | 17 ++++--- .../UnitTests/FancyZonesSettings.Spec.cpp | 49 ++++++++++--------- .../imageresizer/dll/ImageResizerConstants.h | 11 +++++ .../imageresizer/dll/ImageResizerExt.vcxproj | 1 + src/modules/imageresizer/dll/Settings.cpp | 3 +- src/modules/imageresizer/dll/dllmain.cpp | 12 ++++- .../interface/powertoy_module_interface.h | 6 ++- src/modules/keyboardmanager/dll/dllmain.cpp | 15 ++++-- .../Microsoft.Launcher/LauncherConstants.h | 8 +++ .../Microsoft.Launcher.vcxproj | 1 + .../launcher/Microsoft.Launcher/dllmain.cpp | 17 +++++-- .../powerrename/dll/PowerRenameConstants.h | 8 +++ .../powerrename/dll/PowerRenameExt.vcxproj | 1 + src/modules/powerrename/dll/dllmain.cpp | 14 +++++- src/modules/powerrename/lib/Settings.cpp | 5 +- .../previewpane/powerpreview/powerpreview.cpp | 13 +++-- .../previewpane/powerpreview/powerpreview.h | 4 ++ .../powerpreview/powerpreview.vcxproj | 1 + .../powerpreview/powerpreviewConstants.h | 8 +++ .../FileExplorerPreviewSettingsTest.cpp | 28 +++++------ .../shortcut_guide/ShortcutGuideConstants.h | 8 +++ src/modules/shortcut_guide/shortcut_guide.cpp | 13 ++++- src/modules/shortcut_guide/shortcut_guide.h | 3 ++ .../shortcut_guide/shortcut_guide.vcxproj | 1 + src/runner/main.cpp | 2 +- src/runner/powertoy_module.cpp | 4 +- .../ModuleTemplate/dllmain.cpp | 12 +++-- 37 files changed, 290 insertions(+), 123 deletions(-) create mode 100644 src/modules/colorPicker/ColorPicker/ColorPickerConstants.h create mode 100644 src/modules/imageresizer/dll/ImageResizerConstants.h create mode 100644 src/modules/launcher/Microsoft.Launcher/LauncherConstants.h create mode 100644 src/modules/powerrename/dll/PowerRenameConstants.h create mode 100644 src/modules/previewpane/powerpreview/powerpreviewConstants.h create mode 100644 src/modules/shortcut_guide/ShortcutGuideConstants.h diff --git a/src/common/UnitTests-CommonLib/Settings.Tests.cpp b/src/common/UnitTests-CommonLib/Settings.Tests.cpp index dbc848186b..6d9148817c 100644 --- a/src/common/UnitTests-CommonLib/Settings.Tests.cpp +++ b/src/common/UnitTests-CommonLib/Settings.Tests.cpp @@ -53,11 +53,12 @@ namespace UnitTestsCommonLib private: const std::wstring m_json = L"{\"name\":\"Module Name\",\"properties\" : {\"bool_toggle_true\":{\"value\":true},\"bool_toggle_false\":{\"value\":false},\"color_picker\" : {\"value\":\"#ff8d12\"},\"int_spinner\" : {\"value\":10},\"string_text\" : {\"value\":\"a quick fox\"}},\"version\" : \"1.0\" }"; const std::wstring m_moduleName = L"Module Name"; + const std::wstring m_moduleKey = L"Module Key"; public: TEST_METHOD (LoadFromJsonBoolTrue) { - PowerToyValues values = PowerToyValues::from_json_string(m_json); + PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey); auto value = values.get_bool_value(L"bool_toggle_true"); Assert::IsTrue(value.has_value()); Assert::AreEqual(true, *value); @@ -65,7 +66,7 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromJsonBoolFalse) { - PowerToyValues values = PowerToyValues::from_json_string(m_json); + PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey); auto value = values.get_bool_value(L"bool_toggle_false"); Assert::IsTrue(value.has_value()); Assert::AreEqual(false, *value); @@ -73,7 +74,7 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromJsonInt) { - PowerToyValues values = PowerToyValues::from_json_string(m_json); + PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey); auto value = values.get_int_value(L"int_spinner"); Assert::IsTrue(value.has_value()); Assert::AreEqual(10, *value); @@ -81,7 +82,7 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromJsonString) { - PowerToyValues values = PowerToyValues::from_json_string(m_json); + PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey); auto value = values.get_string_value(L"string_text"); Assert::IsTrue(value.has_value()); @@ -91,7 +92,7 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromJsonColorPicker) { - PowerToyValues values = PowerToyValues::from_json_string(m_json); + PowerToyValues values = PowerToyValues::from_json_string(m_json, m_moduleKey); auto value = values.get_string_value(L"color_picker"); Assert::IsTrue(value.has_value()); @@ -101,19 +102,19 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromEmptyString) { - auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L""); }; + auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L"", L"Module Key"); }; Assert::ExpectException(func); } TEST_METHOD (LoadFromInvalidString_NameMissed) { - auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L"{\"properties\" : {\"bool_toggle_true\":{\"value\":true},\"bool_toggle_false\":{\"value\":false},\"color_picker\" : {\"value\":\"#ff8d12\"},\"int_spinner\" : {\"value\":10},\"string_text\" : {\"value\":\"a quick fox\"}},\"version\" : \"1.0\" }"); }; + auto func = [] { PowerToyValues values = PowerToyValues::from_json_string(L"{\"properties\" : {\"bool_toggle_true\":{\"value\":true},\"bool_toggle_false\":{\"value\":false},\"color_picker\" : {\"value\":\"#ff8d12\"},\"int_spinner\" : {\"value\":10},\"string_text\" : {\"value\":\"a quick fox\"}},\"version\" : \"1.0\" }", L"Module Key"); }; Assert::ExpectException(func); } TEST_METHOD (LoadFromInvalidString_VersionMissed) { - PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}}"); + PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}}", L"Module Key"); const std::wstring expectedStr = L"{\"name\" : \"Module Name\", \"properties\" : {},\"version\" : \"1.0\"}"; const auto expected = json::JsonObject::Parse(expectedStr); const auto actual = json::JsonObject::Parse(values.serialize()); @@ -123,7 +124,7 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromInvalidString_PropertiesMissed) { - PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"version\" : \"1.0\" }"); + PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"version\" : \"1.0\" }", L"Module Key"); const std::wstring expectedStr = L"{\"name\":\"Module Name\",\"version\" : \"1.0\" }"; const auto expected = json::JsonObject::Parse(expectedStr); const auto actual = json::JsonObject::Parse(values.serialize()); @@ -133,7 +134,7 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromValidString_EmptyProperties) { - PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}, \"version\" : \"1.0\" }"); + PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {}, \"version\" : \"1.0\" }", L"Module Key"); const std::wstring expectedStr = L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"1.0\" }"; const auto expected = json::JsonObject::Parse(expectedStr); const auto actual = json::JsonObject::Parse(values.serialize()); @@ -143,7 +144,7 @@ namespace UnitTestsCommonLib TEST_METHOD (LoadFromValidString_ChangedVersion) { - PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"2.0\"}"); + PowerToyValues values = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"2.0\"}", L"Module Key"); const std::wstring expectedStr = L"{\"name\" : \"Module Name\", \"properties\" : {},\"version\" : \"1.0\"}"; //version from input json is ignored const auto expected = json::JsonObject::Parse(expectedStr); @@ -154,7 +155,7 @@ namespace UnitTestsCommonLib TEST_METHOD (CreateWithName) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const std::wstring expectedStr = L"{\"name\":\"Module Name\",\"properties\" : {},\"version\" : \"1.0\" }"; const auto expected = json::JsonObject::Parse(expectedStr); @@ -165,7 +166,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyBoolPositive) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"positive_bool_value", true); auto value = values.get_bool_value(L"positive_bool_value"); @@ -175,7 +176,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyBoolNegative) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"negative_bool_value", false); auto value = values.get_bool_value(L"negative_bool_value"); @@ -185,7 +186,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyIntPositive) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const int intVal = 4392854; values.add_property(L"integer", intVal); @@ -196,7 +197,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyIntNegative) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const int intVal = -4392854; values.add_property(L"integer", intVal); @@ -207,7 +208,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyIntZero) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const int intVal = 0; values.add_property(L"integer", intVal); @@ -218,7 +219,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyStringEmpty) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const std::wstring stringVal = L""; values.add_property(L"stringval", stringVal); @@ -229,7 +230,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyString) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const std::wstring stringVal = L"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; values.add_property(L"stringval", stringVal); @@ -240,7 +241,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyJsonEmpty) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const auto json = json::JsonObject(); values.add_property(L"jsonval", json); @@ -251,7 +252,7 @@ namespace UnitTestsCommonLib TEST_METHOD (AddPropertyJsonObject) { - PowerToyValues values(m_moduleName); + PowerToyValues values(m_moduleName, m_moduleKey); const auto json = json::JsonObject::Parse(m_json); values.add_property(L"jsonval", json); diff --git a/src/common/settings_helpers.cpp b/src/common/settings_helpers.cpp index 88bf018ff4..35fe5827de 100644 --- a/src/common/settings_helpers.cpp +++ b/src/common/settings_helpers.cpp @@ -23,11 +23,11 @@ namespace PTSettingsHelper return result; } - std::wstring get_module_save_folder_location(std::wstring_view powertoy_name) + std::wstring get_module_save_folder_location(std::wstring_view powertoy_key) { std::wstring result = get_root_save_folder_location(); result += L"\\"; - result += powertoy_name; + result += powertoy_key; std::filesystem::path save_path(result); if (!std::filesystem::exists(save_path)) { @@ -36,9 +36,9 @@ namespace PTSettingsHelper return result; } - std::wstring get_module_save_file_location(std::wstring_view powertoy_name) + std::wstring get_module_save_file_location(std::wstring_view powertoy_key) { - return get_module_save_folder_location(powertoy_name) + settings_filename; + return get_module_save_folder_location(powertoy_key) + settings_filename; } std::wstring get_powertoys_general_save_file_location() @@ -46,15 +46,15 @@ namespace PTSettingsHelper return get_root_save_folder_location() + settings_filename; } - void save_module_settings(std::wstring_view powertoy_name, json::JsonObject& settings) + void save_module_settings(std::wstring_view powertoy_key, json::JsonObject& settings) { - const std::wstring save_file_location = get_module_save_file_location(powertoy_name); + const std::wstring save_file_location = get_module_save_file_location(powertoy_key); json::to_file(save_file_location, settings); } - json::JsonObject load_module_settings(std::wstring_view powertoy_name) + json::JsonObject load_module_settings(std::wstring_view powertoy_key) { - const std::wstring save_file_location = get_module_save_file_location(powertoy_name); + const std::wstring save_file_location = get_module_save_file_location(powertoy_key); auto saved_settings = json::from_file(save_file_location); return saved_settings.has_value() ? std::move(*saved_settings) : json::JsonObject{}; } diff --git a/src/common/settings_objects.cpp b/src/common/settings_objects.cpp index 2bd2e8ca68..b92da8933b 100644 --- a/src/common/settings_objects.cpp +++ b/src/common/settings_objects.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "settings_objects.h" #include "settings_helpers.h" +#include namespace PowerToysSettings { @@ -277,27 +278,33 @@ namespace PowerToysSettings return L"RESOURCE ID NOT FOUND: " + std::to_wstring(resource_id); } - PowerToyValues::PowerToyValues(std::wstring_view powertoy_name) + PowerToyValues::PowerToyValues(std::wstring_view powertoy_name, std::wstring_view powertoy_key) { - _name = powertoy_name; + _key = powertoy_key; set_version(); m_json.SetNamedValue(L"name", json::value(powertoy_name)); m_json.SetNamedValue(L"properties", json::JsonObject{}); } - PowerToyValues PowerToyValues::from_json_string(std::wstring_view json) + PowerToyValues PowerToyValues::from_json_string(std::wstring_view json, std::wstring_view powertoy_key) { PowerToyValues result = PowerToyValues(); + json::JsonObject jsonObject = json::JsonValue::Parse(json).GetObjectW(); + if (!jsonObject.HasKey(L"name")) + { + throw winrt::hresult_error(E_NOT_SET, L"name field not set"); + } + result.m_json = json::JsonValue::Parse(json).GetObjectW(); - result._name = result.m_json.GetNamedString(L"name"); + result._key = powertoy_key; return result; } - PowerToyValues PowerToyValues::load_from_settings_file(std::wstring_view powertoy_name) + PowerToyValues PowerToyValues::load_from_settings_file(std::wstring_view powertoy_key) { PowerToyValues result = PowerToyValues(); - result.m_json = PTSettingsHelper::load_module_settings(powertoy_name); - result._name = powertoy_name; + result.m_json = PTSettingsHelper::load_module_settings(powertoy_key); + result._key = powertoy_key; return result; } @@ -357,7 +364,7 @@ namespace PowerToysSettings void PowerToyValues::save_to_settings_file() { set_version(); - PTSettingsHelper::save_module_settings(_name, m_json); + PTSettingsHelper::save_module_settings(_key, m_json); } void PowerToyValues::set_version() diff --git a/src/common/settings_objects.h b/src/common/settings_objects.h index 3f2a212eb6..e27e2973ed 100644 --- a/src/common/settings_objects.h +++ b/src/common/settings_objects.h @@ -67,9 +67,9 @@ namespace PowerToysSettings class PowerToyValues { public: - PowerToyValues(std::wstring_view powertoy_name); - static PowerToyValues from_json_string(std::wstring_view json); - static PowerToyValues load_from_settings_file(std::wstring_view powertoy_name); + PowerToyValues(std::wstring_view powertoy_name, std::wstring_view powertoy_key); + static PowerToyValues from_json_string(std::wstring_view json, std::wstring_view powertoy_key); + static PowerToyValues load_from_settings_file(std::wstring_view powertoy_key); template inline void add_property(std::wstring_view name, T value) @@ -92,7 +92,7 @@ namespace PowerToysSettings const std::wstring m_version = L"1.0"; void set_version(); json::JsonObject m_json; - std::wstring _name; + std::wstring _key; PowerToyValues() {} }; diff --git a/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj b/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj index 4f0c2f7fb3..f809dfdc90 100644 --- a/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj +++ b/src/modules/colorPicker/ColorPicker/ColorPicker.vcxproj @@ -103,6 +103,7 @@ + diff --git a/src/modules/colorPicker/ColorPicker/ColorPickerConstants.h b/src/modules/colorPicker/ColorPicker/ColorPickerConstants.h new file mode 100644 index 0000000000..f14ce690c9 --- /dev/null +++ b/src/modules/colorPicker/ColorPicker/ColorPickerConstants.h @@ -0,0 +1,8 @@ +#pragma once +#include + +namespace ColorPickerConstants +{ + // Name of the powertoy module. + inline const std::wstring ModuleKey = L"ColorPicker"; +} \ No newline at end of file diff --git a/src/modules/colorPicker/ColorPicker/dllmain.cpp b/src/modules/colorPicker/ColorPicker/dllmain.cpp index de5bae10d9..804844f79b 100644 --- a/src/modules/colorPicker/ColorPicker/dllmain.cpp +++ b/src/modules/colorPicker/ColorPicker/dllmain.cpp @@ -6,6 +6,7 @@ #include "Generated Files/resource.h" #include #include +#include extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -38,6 +39,9 @@ private: std::wstring app_name; + //contains the non localized key of the powertoy + std::wstring app_key; + HANDLE m_hProcess; // Time to wait for process to close after sending WM_CLOSE signal @@ -47,6 +51,7 @@ public: ColorPicker() { app_name = GET_RESOURCE_STRING(IDS_COLORPICKER_NAME); + app_key = ColorPickerConstants::ModuleKey; } ~ColorPicker() @@ -63,12 +68,18 @@ public: delete this; } - // Return the display name of the powertoy, this will be cached by the runner + // Return the localized display name of the powertoy virtual const wchar_t* get_name() override { return app_name.c_str(); } + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return app_key.c_str(); + } + virtual bool get_config(wchar_t* buffer, int* buffer_size) override { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); @@ -92,7 +103,7 @@ public: { // Parse the input JSON string. PowerToysSettings::PowerToyValues values = - PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); // If you don't need to do any custom processing of the settings, proceed // to persists the values calling: diff --git a/src/modules/fancyzones/dll/dllmain.cpp b/src/modules/fancyzones/dll/dllmain.cpp index d988a9796c..473eae6287 100644 --- a/src/modules/fancyzones/dll/dllmain.cpp +++ b/src/modules/fancyzones/dll/dllmain.cpp @@ -12,6 +12,7 @@ #include #include #include +#include extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -37,12 +38,18 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv class FancyZonesModule : public PowertoyModuleIface { public: - // Return the display name of the powertoy, this will be cached + // Return the localized display name of the powertoy virtual PCWSTR get_name() override { return app_name.c_str(); } + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return app_key.c_str(); + } + // Return JSON with the configuration options. // These are the settings shown on the settings page along with their current values. virtual bool get_config(_Out_ PWSTR buffer, _Out_ int* buffer_size) override @@ -142,7 +149,8 @@ public: FancyZonesModule() { app_name = GET_RESOURCE_STRING(IDS_FANCYZONES); - m_settings = MakeFancyZonesSettings(reinterpret_cast(&__ImageBase), FancyZonesModule::get_name()); + app_key = NonLocalizable::FancyZonesStr; + m_settings = MakeFancyZonesSettings(reinterpret_cast(&__ImageBase), FancyZonesModule::get_name(), FancyZonesModule::get_key()); FancyZonesDataInstance().LoadFancyZonesData(); s_instance = this; } @@ -190,6 +198,8 @@ private: winrt::com_ptr m_app; winrt::com_ptr m_settings; std::wstring app_name; + //contains the non localized key of the powertoy + std::wstring app_key; static inline FancyZonesModule* s_instance; static inline HHOOK s_llKeyboardHook; diff --git a/src/modules/fancyzones/lib/Settings.cpp b/src/modules/fancyzones/lib/Settings.cpp index bca90ba4f2..c696b263d3 100644 --- a/src/modules/fancyzones/lib/Settings.cpp +++ b/src/modules/fancyzones/lib/Settings.cpp @@ -43,9 +43,10 @@ namespace NonLocalizable struct FancyZonesSettings : winrt::implements { public: - FancyZonesSettings(HINSTANCE hinstance, PCWSTR name) - : m_hinstance(hinstance) - , m_moduleName(name) + FancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) + : m_hinstance(hinstance), + m_moduleName(name), + m_moduleKey(key) { LoadSettings(name, true); } @@ -64,6 +65,7 @@ private: IFancyZonesCallback* m_callback{}; const HINSTANCE m_hinstance; PCWSTR m_moduleName{}; + PCWSTR m_moduleKey{}; Settings m_settings; @@ -171,8 +173,8 @@ void FancyZonesSettings::LoadSettings(PCWSTR config, bool fromFile) noexcept try { PowerToysSettings::PowerToyValues values = fromFile ? - PowerToysSettings::PowerToyValues::load_from_settings_file(m_moduleName) : - PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues::load_from_settings_file(m_moduleKey) : + PowerToysSettings::PowerToyValues::from_json_string(config, m_moduleKey); for (auto const& setting : m_configBools) { @@ -244,7 +246,7 @@ void FancyZonesSettings::SaveSettings() noexcept { try { - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); for (auto const& setting : m_configBools) { @@ -271,7 +273,7 @@ void FancyZonesSettings::SaveSettings() noexcept } } -winrt::com_ptr MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR name) noexcept +winrt::com_ptr MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) noexcept { - return winrt::make_self(hinstance, name); + return winrt::make_self(hinstance, name, key); } diff --git a/src/modules/fancyzones/lib/Settings.h b/src/modules/fancyzones/lib/Settings.h index f5a7b173c0..973348ad5a 100644 --- a/src/modules/fancyzones/lib/Settings.h +++ b/src/modules/fancyzones/lib/Settings.h @@ -49,4 +49,4 @@ interface __declspec(uuid("{BA4E77C4-6F44-4C5D-93D3-CBDE880495C2}")) IFancyZones IFACEMETHOD_(const Settings*, GetSettings)() const = 0; }; -winrt::com_ptr MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR config) noexcept; \ No newline at end of file +winrt::com_ptr MakeFancyZonesSettings(HINSTANCE hinstance, PCWSTR name, PCWSTR key) noexcept; \ No newline at end of file diff --git a/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp index ce5df79dbc..d52eabb245 100644 --- a/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/FancyZones.Spec.cpp @@ -17,11 +17,12 @@ namespace FancyZonesUnitTests HINSTANCE m_hInst; winrt::com_ptr m_settings; const std::wstring_view m_moduleName = L"FancyZonesUnitTests"; + const std::wstring_view m_modulekey = L"FancyZonesUnitTests"; TEST_METHOD_INITIALIZE(Init) { m_hInst = (HINSTANCE)GetModuleHandleW(nullptr); - m_settings = MakeFancyZonesSettings(m_hInst, m_moduleName.data()); + m_settings = MakeFancyZonesSettings(m_hInst, m_moduleName.data(), m_modulekey.data()); Assert::IsTrue(m_settings != nullptr); } @@ -57,7 +58,8 @@ namespace FancyZonesUnitTests TEST_CLASS (FancyZonesIZoneWindowHostUnitTests) { HINSTANCE m_hInst{}; - std::wstring m_settingsLocation = L"FancyZonesUnitTests"; + std::wstring m_moduleName = L"FancyZonesUnitTests"; + std::wstring m_moduleKey = L"FancyZonesUnitTests"; winrt::com_ptr m_settings = nullptr; winrt::com_ptr m_zoneWindowHost = nullptr; @@ -92,7 +94,7 @@ namespace FancyZonesUnitTests TEST_METHOD_INITIALIZE(Init) { m_hInst = (HINSTANCE)GetModuleHandleW(nullptr); - m_settings = MakeFancyZonesSettings(m_hInst, m_settingsLocation.c_str()); + m_settings = MakeFancyZonesSettings(m_hInst, m_moduleName.c_str(), m_moduleKey.c_str()); Assert::IsTrue(m_settings != nullptr); auto fancyZones = MakeFancyZones(m_hInst, m_settings, nullptr); @@ -104,7 +106,7 @@ namespace FancyZonesUnitTests TEST_METHOD_CLEANUP(Cleanup) { - auto settingsFolder = PTSettingsHelper::get_module_save_folder_location(m_settingsLocation); + auto settingsFolder = PTSettingsHelper::get_module_save_folder_location(m_moduleName); const auto settingsFile = settingsFolder + L"\\settings.json"; std::filesystem::remove(settingsFile); std::filesystem::remove(settingsFolder); @@ -279,7 +281,8 @@ namespace FancyZonesUnitTests TEST_CLASS (FancyZonesIFancyZonesCallbackUnitTests) { HINSTANCE m_hInst{}; - std::wstring m_settingsLocation = L"FancyZonesUnitTests"; + std::wstring m_moduleName = L"FancyZonesUnitTests"; + std::wstring m_moduleKey = L"FancyZonesUnitTests"; winrt::com_ptr m_settings = nullptr; winrt::com_ptr m_fzCallback = nullptr; @@ -328,7 +331,7 @@ namespace FancyZonesUnitTests TEST_METHOD_INITIALIZE(Init) { m_hInst = (HINSTANCE)GetModuleHandleW(nullptr); - m_settings = MakeFancyZonesSettings(m_hInst, m_settingsLocation.c_str()); + m_settings = MakeFancyZonesSettings(m_hInst, m_moduleName.c_str(), m_moduleKey.c_str()); Assert::IsTrue(m_settings != nullptr); auto fancyZones = MakeFancyZones(m_hInst, m_settings, nullptr); @@ -346,7 +349,7 @@ namespace FancyZonesUnitTests sendKeyboardInput(VK_LWIN, true); sendKeyboardInput(VK_CONTROL, true); - auto settingsFolder = PTSettingsHelper::get_module_save_folder_location(m_settingsLocation); + auto settingsFolder = PTSettingsHelper::get_module_save_folder_location(m_moduleName); const auto settingsFile = settingsFolder + L"\\settings.json"; std::filesystem::remove(settingsFile); std::filesystem::remove(settingsFolder); diff --git a/src/modules/fancyzones/tests/UnitTests/FancyZonesSettings.Spec.cpp b/src/modules/fancyzones/tests/UnitTests/FancyZonesSettings.Spec.cpp index 9582c27785..dd814732b3 100644 --- a/src/modules/fancyzones/tests/UnitTests/FancyZonesSettings.Spec.cpp +++ b/src/modules/fancyzones/tests/UnitTests/FancyZonesSettings.Spec.cpp @@ -59,6 +59,7 @@ namespace FancyZonesUnitTests { HINSTANCE m_hInst; PCWSTR m_moduleName = L"FancyZonesUnitTests"; + PCWSTR m_moduleKey = L"FancyZonesUnitTests"; std::wstring m_tmpName; const PowerToysSettings::HotkeyObject m_defaultHotkeyObject = PowerToysSettings::HotkeyObject::from_settings(true, false, false, false, VK_OEM_3); @@ -76,7 +77,7 @@ namespace FancyZonesUnitTests TEST_METHOD (CreateWithHinstanceDefault) { - auto actual = MakeFancyZonesSettings({}, m_moduleName); + auto actual = MakeFancyZonesSettings({}, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -85,7 +86,7 @@ namespace FancyZonesUnitTests TEST_METHOD (CreateWithHinstanceNullptr) { - auto actual = MakeFancyZonesSettings(nullptr, m_moduleName); + auto actual = MakeFancyZonesSettings(nullptr, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -94,7 +95,7 @@ namespace FancyZonesUnitTests TEST_METHOD (CreateWithNameEmpty) { - auto actual = MakeFancyZonesSettings(m_hInst, L""); + auto actual = MakeFancyZonesSettings(m_hInst, L"", m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -106,7 +107,7 @@ namespace FancyZonesUnitTests //prepare data const Settings expected; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag); values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch); values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows); @@ -131,7 +132,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -146,7 +147,7 @@ namespace FancyZonesUnitTests .excludedAppsArray = { L"APP", L"APP1", L"APP2", L"ANOTHER APP" }, }; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag); values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch); values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows); @@ -171,7 +172,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -205,7 +206,7 @@ namespace FancyZonesUnitTests .excludedAppsArray = { L"APP" }, }; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_zoneColor", expected.zoneColor); values.add_property(L"fancyzones_zoneBorderColor", expected.zoneBorderColor); values.add_property(L"fancyzones_zoneHighlightColor", expected.zoneHighlightColor); @@ -215,7 +216,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -227,7 +228,7 @@ namespace FancyZonesUnitTests //prepare data const Settings expected; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag); values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch); values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows); @@ -249,7 +250,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -261,7 +262,7 @@ namespace FancyZonesUnitTests //prepare data const Settings expected; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag); values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch); values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows); @@ -284,7 +285,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -296,7 +297,7 @@ namespace FancyZonesUnitTests //prepare data const Settings expected; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag); values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch); values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows); @@ -320,7 +321,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -332,7 +333,7 @@ namespace FancyZonesUnitTests //prepare data const Settings expected; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag); values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch); values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows); @@ -356,7 +357,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -366,7 +367,7 @@ namespace FancyZonesUnitTests TEST_METHOD (CreateWithEmptyJson) { json::to_file(m_tmpName, json::JsonObject()); - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -377,7 +378,7 @@ namespace FancyZonesUnitTests { std::wofstream{ m_tmpName.data(), std::ios::binary } << L"{ \"version\": \"1.0\", \"name\": \""; - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -387,7 +388,7 @@ namespace FancyZonesUnitTests TEST_METHOD (CreateWithCyrillicSymbolsInJson) { std::wofstream{ m_tmpName.data(), std::ios::binary } << L"{ \"version\": \"1.0\", \"name\": \"ФансиЗонс\"}"; - auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName); + auto actual = MakeFancyZonesSettings(m_hInst, m_moduleName, m_moduleKey); Assert::IsTrue(actual != nullptr); auto actualSettings = actual->GetSettings(); @@ -399,6 +400,7 @@ namespace FancyZonesUnitTests { winrt::com_ptr m_settings = nullptr; PCWSTR m_moduleName = L"FancyZonesUnitTests"; + PCWSTR m_moduleKey = L"FancyZonesUnitTests"; struct FZCallback : public winrt::implements { @@ -474,7 +476,7 @@ namespace FancyZonesUnitTests .excludedAppsArray = { L"APP" }, }; - PowerToysSettings::PowerToyValues values(m_moduleName); + PowerToysSettings::PowerToyValues values(m_moduleName, m_moduleKey); values.add_property(L"fancyzones_shiftDrag", expected.shiftDrag); values.add_property(L"fancyzones_mouseSwitch", expected.mouseSwitch); values.add_property(L"fancyzones_displayChange_moveWindows", expected.displayChange_moveWindows); @@ -499,7 +501,7 @@ namespace FancyZonesUnitTests values.save_to_settings_file(); - m_settings = MakeFancyZonesSettings(hInst, m_moduleName); + m_settings = MakeFancyZonesSettings(hInst, m_moduleName, m_moduleKey); Assert::IsTrue(m_settings != nullptr); } @@ -579,6 +581,7 @@ namespace FancyZonesUnitTests { winrt::com_ptr m_settings = nullptr; PCWSTR m_moduleName = L"FancyZonesUnitTests"; + PCWSTR m_moduleKey = L"FancyZonesUnitTests"; std::wstring serializedPowerToySettings(const Settings& settings) { @@ -622,7 +625,7 @@ namespace FancyZonesUnitTests { HINSTANCE hInst = (HINSTANCE)GetModuleHandleW(nullptr); - m_settings = MakeFancyZonesSettings(hInst, m_moduleName); + m_settings = MakeFancyZonesSettings(hInst, m_moduleName, m_moduleKey); Assert::IsTrue(m_settings != nullptr); } diff --git a/src/modules/imageresizer/dll/ImageResizerConstants.h b/src/modules/imageresizer/dll/ImageResizerConstants.h new file mode 100644 index 0000000000..849b8a6d6a --- /dev/null +++ b/src/modules/imageresizer/dll/ImageResizerConstants.h @@ -0,0 +1,11 @@ +#pragma once +#include + +namespace ImageResizerConstants +{ + // Name of the powertoy module. + inline const std::wstring ModuleKey = L"Image Resizer"; + + // Name of the ImageResizer save folder. + inline const std::wstring ModuleSaveFolderKey = L"ImageResizer"; +} diff --git a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj index 25f36c19d1..d699514424 100644 --- a/src/modules/imageresizer/dll/ImageResizerExt.vcxproj +++ b/src/modules/imageresizer/dll/ImageResizerExt.vcxproj @@ -162,6 +162,7 @@ + diff --git a/src/modules/imageresizer/dll/Settings.cpp b/src/modules/imageresizer/dll/Settings.cpp index bdfcc91aa9..634e3965ce 100644 --- a/src/modules/imageresizer/dll/Settings.cpp +++ b/src/modules/imageresizer/dll/Settings.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace { @@ -44,7 +45,7 @@ namespace CSettings::CSettings() { - std::wstring result = PTSettingsHelper::get_module_save_folder_location(L"ImageResizer"); + std::wstring result = PTSettingsHelper::get_module_save_folder_location(ImageResizerConstants::ModuleSaveFolderKey); jsonFilePath = result + std::wstring(c_imageResizerDataFilePath); Load(); } diff --git a/src/modules/imageresizer/dll/dllmain.cpp b/src/modules/imageresizer/dll/dllmain.cpp index 93f30e4a02..f7ea349167 100644 --- a/src/modules/imageresizer/dll/dllmain.cpp +++ b/src/modules/imageresizer/dll/dllmain.cpp @@ -7,6 +7,7 @@ #include "Settings.h" #include "trace.h" #include +#include CImageResizerExtModule _AtlModule; HINSTANCE g_hInst_imageResizer = 0; @@ -32,6 +33,8 @@ private: // Enabled by default bool m_enabled = true; std::wstring app_name; + //contains the non localized key of the powertoy + std::wstring app_key; public: // Constructor @@ -39,6 +42,7 @@ public: { m_enabled = CSettingsInstance().GetEnabled(); app_name = GET_RESOURCE_STRING(IDS_IMAGERESIZER); + app_key = ImageResizerConstants::ModuleKey; }; // Destroy the powertoy and free memory @@ -47,12 +51,18 @@ public: delete this; } - // Return the display name of the powertoy, this will be cached by the runner + // Return the localized display name of the powertoy virtual const wchar_t* get_name() override { return app_name.c_str(); } + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return app_key.c_str(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { diff --git a/src/modules/interface/powertoy_module_interface.h b/src/modules/interface/powertoy_module_interface.h index 3a7e45709e..f5ed6ef794 100644 --- a/src/modules/interface/powertoy_module_interface.h +++ b/src/modules/interface/powertoy_module_interface.h @@ -13,7 +13,7 @@ - call powertoy_create() to create the PowerToy. On the received object, the runner will call: - - get_name() to get the name of the PowerToy, + - get_key() to get the non localized ID of the PowerToy, - enable() to initialize the PowerToy. - get_hotkeys() to register the hotkeys the PowerToy uses. @@ -48,8 +48,10 @@ public: std::strong_ordering operator<=>(const Hotkey&) const = default; }; - /* Returns the name of the PowerToy, this will be cached by the runner. */ + /* Returns the localized name of the PowerToy*/ virtual const wchar_t* get_name() = 0; + /* Returns non localized name of the PowerToy, this will be cached by the runner. */ + virtual const wchar_t* get_key() = 0; /* Fills a buffer with the available configuration settings. * If 'buffer' is a null ptr or the buffer size is not large enough * sets the required buffer size in 'buffer_size' and return false. diff --git a/src/modules/keyboardmanager/dll/dllmain.cpp b/src/modules/keyboardmanager/dll/dllmain.cpp index 554f5ff3cd..b7937ecddf 100644 --- a/src/modules/keyboardmanager/dll/dllmain.cpp +++ b/src/modules/keyboardmanager/dll/dllmain.cpp @@ -45,6 +45,9 @@ private: // The PowerToy name that will be shown in the settings. const std::wstring app_name = GET_RESOURCE_STRING(IDS_KEYBOARDMANAGER); + //contains the non localized key of the powertoy + std::wstring app_key = KeyboardManagerConstants::ModuleName; + // Low level hook handles static HHOOK hook_handle; @@ -77,7 +80,7 @@ public: try { PowerToysSettings::PowerToyValues settings = - PowerToysSettings::PowerToyValues::load_from_settings_file(get_name()); + PowerToysSettings::PowerToyValues::load_from_settings_file(get_key()); auto current_config = settings.get_string_value(KeyboardManagerConstants::ActiveConfigurationSettingName); if (current_config) @@ -227,12 +230,18 @@ public: delete this; } - // Return the display name of the powertoy, this will be cached by the runner + // Return the localized display name of the powertoy virtual const wchar_t* get_name() override { return app_name.c_str(); } + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return app_key.c_str(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { @@ -286,7 +295,7 @@ public: { // Parse the input JSON string. PowerToysSettings::PowerToyValues values = - PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); // If you don't need to do any custom processing of the settings, proceed // to persists the values calling: diff --git a/src/modules/launcher/Microsoft.Launcher/LauncherConstants.h b/src/modules/launcher/Microsoft.Launcher/LauncherConstants.h new file mode 100644 index 0000000000..ea3463c071 --- /dev/null +++ b/src/modules/launcher/Microsoft.Launcher/LauncherConstants.h @@ -0,0 +1,8 @@ +#pragma once +#include + +namespace LauncherConstants +{ + // Name of the powertoy module. + inline const std::wstring ModuleKey = L"PowerToys Run"; +} \ No newline at end of file diff --git a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj index 003464bd7c..2b36ca613f 100644 --- a/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj +++ b/src/modules/launcher/Microsoft.Launcher/Microsoft.Launcher.vcxproj @@ -103,6 +103,7 @@ + diff --git a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp index f4b9f6908b..8bb79a4c2a 100644 --- a/src/modules/launcher/Microsoft.Launcher/dllmain.cpp +++ b/src/modules/launcher/Microsoft.Launcher/dllmain.cpp @@ -6,6 +6,7 @@ #include "trace.h" #include "Generated Files/resource.h" #include +#include extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -59,6 +60,9 @@ private: //contains the name of the powerToys std::wstring app_name; + //contains the non localized key of the powertoy + std::wstring app_key; + // Time to wait for process to close after sending WM_CLOSE signal static const int MAX_WAIT_MILLISEC = 10000; @@ -76,6 +80,7 @@ public: Microsoft_Launcher() { app_name = GET_RESOURCE_STRING(IDS_LAUNCHER_NAME); + app_key = LauncherConstants::ModuleKey; init_settings(); SECURITY_ATTRIBUTES sa; @@ -100,12 +105,18 @@ public: delete this; } - // Return the display name of the powertoy, this will be cached by the runner + // Return the localized display name of the powertoy virtual const wchar_t* get_name() override { return app_name.c_str(); } + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return app_key.c_str(); + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { @@ -143,7 +154,7 @@ public: { // Parse the input JSON string. PowerToysSettings::PowerToyValues values = - PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); parse_hotkey(values); // If you don't need to do any custom processing of the settings, proceed @@ -320,7 +331,7 @@ void Microsoft_Launcher::init_settings() { // Load and parse the settings file for this PowerToy. PowerToysSettings::PowerToyValues settings = - PowerToysSettings::PowerToyValues::load_from_settings_file(get_name()); + PowerToysSettings::PowerToyValues::load_from_settings_file(get_key()); parse_hotkey(settings); } diff --git a/src/modules/powerrename/dll/PowerRenameConstants.h b/src/modules/powerrename/dll/PowerRenameConstants.h new file mode 100644 index 0000000000..fbbcffe02e --- /dev/null +++ b/src/modules/powerrename/dll/PowerRenameConstants.h @@ -0,0 +1,8 @@ +#pragma once +#include + +namespace PowerRenameConstants +{ + // Name of the powertoy module. + inline const std::wstring ModuleKey = L"PowerRename"; +} \ No newline at end of file diff --git a/src/modules/powerrename/dll/PowerRenameExt.vcxproj b/src/modules/powerrename/dll/PowerRenameExt.vcxproj index 4644f17a96..9561fd7aa0 100644 --- a/src/modules/powerrename/dll/PowerRenameExt.vcxproj +++ b/src/modules/powerrename/dll/PowerRenameExt.vcxproj @@ -178,6 +178,7 @@ + diff --git a/src/modules/powerrename/dll/dllmain.cpp b/src/modules/powerrename/dll/dllmain.cpp index 00069bf084..d9aede9323 100644 --- a/src/modules/powerrename/dll/dllmain.cpp +++ b/src/modules/powerrename/dll/dllmain.cpp @@ -7,6 +7,7 @@ #include #include "Generated Files/resource.h" #include +#include std::atomic g_dwModuleRefCount = 0; HINSTANCE g_hInst = 0; @@ -155,14 +156,22 @@ private: // Enabled by default bool m_enabled = true; std::wstring app_name; + //contains the non localized key of the powertoy + std::wstring app_key; public: - // Return the display name of the powertoy, this will be cached + // Return the localized display name of the powertoy virtual PCWSTR get_name() override { return app_name.c_str(); } + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return app_key.c_str(); + } + // Enable the powertoy virtual void enable() { @@ -236,7 +245,7 @@ public: { // Parse the input JSON string. PowerToysSettings::PowerToyValues values = - PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); CSettingsInstance().SetPersistState(values.get_bool_value(L"bool_persist_input").value()); CSettingsInstance().SetMRUEnabled(values.get_bool_value(L"bool_mru_enabled").value()); @@ -282,6 +291,7 @@ public: { init_settings(); app_name = GET_RESOURCE_STRING(IDS_POWERRENAME_APP_NAME); + app_key = PowerRenameConstants::ModuleKey; } ~PowerRenameModule(){}; diff --git a/src/modules/powerrename/lib/Settings.cpp b/src/modules/powerrename/lib/Settings.cpp index 9de15f6b68..b0d9b87b87 100644 --- a/src/modules/powerrename/lib/Settings.cpp +++ b/src/modules/powerrename/lib/Settings.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace { @@ -92,7 +93,7 @@ public: pushIdx(0), nextIdx(1), size(size), - jsonFilePath(PTSettingsHelper::get_module_save_folder_location(L"PowerRename") + filePath), + jsonFilePath(PTSettingsHelper::get_module_save_folder_location(PowerRenameConstants::ModuleKey) + filePath), registryFilePath(regPath) { items.resize(size); @@ -395,7 +396,7 @@ IFACEMETHODIMP CRenameMRU::AddMRUString(_In_ PCWSTR entry) CSettings::CSettings() { - std::wstring result = PTSettingsHelper::get_module_save_folder_location(L"PowerRename"); + std::wstring result = PTSettingsHelper::get_module_save_folder_location(PowerRenameConstants::ModuleKey); jsonFilePath = result + std::wstring(c_powerRenameDataFilePath); UIFlagsFilePath = result + std::wstring(c_powerRenameUIFlagsFilePath); Load(); diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp index 06c27fb217..7c00ee4202 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.cpp +++ b/src/modules/previewpane/powerpreview/powerpreview.cpp @@ -10,6 +10,7 @@ // Constructor PowerPreviewModule::PowerPreviewModule() : m_moduleName(GET_RESOURCE_STRING(IDS_MODULE_NAME)), + app_key(powerpreviewConstants::ModuleKey), m_fileExplorerModules( { // SVG Preview Handler settings object. new PreviewHandlerSettings( @@ -55,12 +56,18 @@ void PowerPreviewModule::destroy() delete this; } -// Return the display name of the powertoy, this will be cached. +// Return the localized display name of the powertoy const wchar_t* PowerPreviewModule::get_name() { return m_moduleName.c_str(); } +// Return the non localized key of the powertoy, this will be cached by the runner +const wchar_t* PowerPreviewModule::get_key() +{ + return app_key.c_str(); +} + // Return JSON with the configuration options. bool PowerPreviewModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size) { @@ -96,7 +103,7 @@ void PowerPreviewModule::set_config(const wchar_t* config) { try { - PowerToysSettings::PowerToyValues settings = PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues settings = PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); bool updateSuccess = true; bool isElevated = is_process_elevated(false); @@ -167,7 +174,7 @@ void PowerPreviewModule::init_settings() { // Load and parse the settings file for this PowerToy. PowerToysSettings::PowerToyValues settings = - PowerToysSettings::PowerToyValues::load_from_settings_file(PowerPreviewModule::get_name()); + PowerToysSettings::PowerToyValues::load_from_settings_file(PowerPreviewModule::get_key()); // Load settings states. for (auto fileExplorerModule : this->m_fileExplorerModules) diff --git a/src/modules/previewpane/powerpreview/powerpreview.h b/src/modules/previewpane/powerpreview/powerpreview.h index 92d7574451..b88387e758 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.h +++ b/src/modules/previewpane/powerpreview/powerpreview.h @@ -6,6 +6,7 @@ #include "thumbnail_provider.h" #include "preview_handler.h" #include "registry_wrapper.h" +#include using namespace PowerPreviewSettings; @@ -18,6 +19,8 @@ private: // The PowerToy state. bool m_enabled = false; std::wstring m_moduleName; + //contains the non localized key of the powertoy + std::wstring app_key; std::vector m_fileExplorerModules; // Function to check if the registry states need to be updated @@ -40,6 +43,7 @@ public: virtual void destroy(); virtual const wchar_t* get_name(); + virtual const wchar_t* get_key(); virtual bool get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_size); virtual void set_config(const wchar_t* config); virtual void enable(); diff --git a/src/modules/previewpane/powerpreview/powerpreview.vcxproj b/src/modules/previewpane/powerpreview/powerpreview.vcxproj index a49a3825af..b8aaea835b 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.vcxproj +++ b/src/modules/previewpane/powerpreview/powerpreview.vcxproj @@ -109,6 +109,7 @@ + diff --git a/src/modules/previewpane/powerpreview/powerpreviewConstants.h b/src/modules/previewpane/powerpreview/powerpreviewConstants.h new file mode 100644 index 0000000000..3f1c2b58a7 --- /dev/null +++ b/src/modules/previewpane/powerpreview/powerpreviewConstants.h @@ -0,0 +1,8 @@ +#pragma once +#include + +namespace powerpreviewConstants +{ + // Name of the powertoy module. + inline const std::wstring ModuleKey = L"File Explorer"; +} \ No newline at end of file diff --git a/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp b/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp index 2e9c784639..fe66476dcd 100644 --- a/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp +++ b/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp @@ -82,7 +82,7 @@ namespace FileExplorerPreviewSettingsTest bool defaultState = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(defaultState, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); // Act previewSettings.LoadState(settings); @@ -97,7 +97,7 @@ namespace FileExplorerPreviewSettingsTest bool defaultState = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(defaultState, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\"}"); + auto settings = PowerToyValues::from_json_string(L"{\"name\":\"Module Name\"}", L"FileExplorerPreviewTests"); // Act previewSettings.LoadState(settings); @@ -113,7 +113,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); previewSettings.UpdateToggleSettingState(true); // Add expected data in registry mockRegistryWrapper->SetMockData(previewSettings.GetRegistryValueData()); @@ -134,7 +134,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); ThumbnailProviderSettings thumbnailSettings = GetThumbnailProviderSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(thumbnailSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(thumbnailSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); thumbnailSettings.UpdateToggleSettingState(true); // Add expected data in registry mockRegistryWrapper->SetMockData(thumbnailSettings.GetCLSID()); @@ -155,7 +155,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); previewSettings.UpdateToggleSettingState(true); // Act @@ -174,7 +174,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = false; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); previewSettings.UpdateToggleSettingState(true); // Act @@ -193,7 +193,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"true")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"true"), L"FileExplorerPreviewTests"); previewSettings.UpdateToggleSettingState(false); // Act @@ -211,7 +211,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"true")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"true"), L"FileExplorerPreviewTests"); previewSettings.UpdateToggleSettingState(false); // Add expected data in registry mockRegistryWrapper->SetMockData(previewSettings.GetRegistryValueData()); @@ -231,7 +231,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); ThumbnailProviderSettings thumbnailSettings = GetThumbnailProviderSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(thumbnailSettings.GetToggleSettingName(), L"true")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(thumbnailSettings.GetToggleSettingName(), L"true"), L"FileExplorerPreviewTests"); thumbnailSettings.UpdateToggleSettingState(false); // Add expected data in registry mockRegistryWrapper->SetMockData(thumbnailSettings.GetCLSID()); @@ -251,7 +251,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = false; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"true")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"true"), L"FileExplorerPreviewTests"); previewSettings.UpdateToggleSettingState(false); // Act @@ -269,7 +269,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); // Act previewSettings.UpdateState(settings, enabled, elevated); @@ -285,7 +285,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = false; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); // Act previewSettings.UpdateState(settings, enabled, elevated); @@ -301,7 +301,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = true; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); // Act previewSettings.UpdateState(settings, enabled, elevated); @@ -319,7 +319,7 @@ namespace FileExplorerPreviewSettingsTest bool elevated = false; RegistryMock* mockRegistryWrapper = new RegistryMock(); PreviewHandlerSettings previewSettings = GetPreviewHandlerSettingsObject(true, mockRegistryWrapper); - auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false")); + auto settings = PowerToyValues::from_json_string(GetJSONSettings(previewSettings.GetToggleSettingName(), L"false"), L"FileExplorerPreviewTests"); // Act previewSettings.UpdateState(settings, enabled, elevated); diff --git a/src/modules/shortcut_guide/ShortcutGuideConstants.h b/src/modules/shortcut_guide/ShortcutGuideConstants.h new file mode 100644 index 0000000000..3d0e434abf --- /dev/null +++ b/src/modules/shortcut_guide/ShortcutGuideConstants.h @@ -0,0 +1,8 @@ +#pragma once +#include + +namespace ShortcutGuideConstants +{ + // Name of the powertoy module. + inline const std::wstring ModuleKey = L"Shortcut Guide"; +} \ No newline at end of file diff --git a/src/modules/shortcut_guide/shortcut_guide.cpp b/src/modules/shortcut_guide/shortcut_guide.cpp index 60c9041f06..d51cfa0090 100644 --- a/src/modules/shortcut_guide/shortcut_guide.cpp +++ b/src/modules/shortcut_guide/shortcut_guide.cpp @@ -7,6 +7,7 @@ #include #include #include +#include extern "C" IMAGE_DOS_HEADER __ImageBase; @@ -94,14 +95,22 @@ namespace OverlayWindow::OverlayWindow() { app_name = GET_RESOURCE_STRING(IDS_SHORTCUT_GUIDE); + app_key = ShortcutGuideConstants::ModuleKey; init_settings(); } +// Return the localized display name of the powertoy const wchar_t* OverlayWindow::get_name() { return app_name.c_str(); } +// Return the non localized key of the powertoy, this will be cached by the runner +const wchar_t* OverlayWindow::get_key() +{ + return app_key.c_str(); +} + bool OverlayWindow::get_config(wchar_t* buffer, int* buffer_size) { HINSTANCE hinstance = reinterpret_cast(&__ImageBase); @@ -142,7 +151,7 @@ void OverlayWindow::set_config(const wchar_t* config) { // save configuration PowerToysSettings::PowerToyValues _values = - PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); _values.save_to_settings_file(); Trace::SettingsChanged(pressTime.value, overlayOpacity.value, theme.value); @@ -331,7 +340,7 @@ void OverlayWindow::init_settings() try { PowerToysSettings::PowerToyValues settings = - PowerToysSettings::PowerToyValues::load_from_settings_file(OverlayWindow::get_name()); + PowerToysSettings::PowerToyValues::load_from_settings_file(OverlayWindow::get_key()); if (const auto val = settings.get_int_value(pressTime.name)) { pressTime.value = *val; diff --git a/src/modules/shortcut_guide/shortcut_guide.h b/src/modules/shortcut_guide/shortcut_guide.h index 1af0b06b51..b34c8353cc 100644 --- a/src/modules/shortcut_guide/shortcut_guide.h +++ b/src/modules/shortcut_guide/shortcut_guide.h @@ -17,6 +17,7 @@ public: OverlayWindow(); virtual const wchar_t* get_name() override; + virtual const wchar_t* get_key() override; virtual bool get_config(wchar_t* buffer, int* buffer_size) override; virtual void set_config(const wchar_t* config) override; @@ -37,6 +38,8 @@ public: private: std::wstring app_name; + //contains the non localized key of the powertoy + std::wstring app_key; std::unique_ptr target_state; std::unique_ptr winkey_popup; bool _enabled = false; diff --git a/src/modules/shortcut_guide/shortcut_guide.vcxproj b/src/modules/shortcut_guide/shortcut_guide.vcxproj index c606c3f689..39047b7830 100644 --- a/src/modules/shortcut_guide/shortcut_guide.vcxproj +++ b/src/modules/shortcut_guide/shortcut_guide.vcxproj @@ -109,6 +109,7 @@ + diff --git a/src/runner/main.cpp b/src/runner/main.cpp index cbc2b69a85..90241bffad 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -136,7 +136,7 @@ int runner(bool isProcessElevated) try { auto module = load_powertoy(moduleSubdir); - modules().emplace(module->get_name(), std::move(module)); + modules().emplace(module->get_key(), std::move(module)); } catch (...) { diff --git a/src/runner/powertoy_module.cpp b/src/runner/powertoy_module.cpp index ef2c45c853..220911b954 100644 --- a/src/runner/powertoy_module.cpp +++ b/src/runner/powertoy_module.cpp @@ -49,7 +49,7 @@ PowertoyModule::PowertoyModule(PowertoyModuleIface* module, HMODULE handle) : void PowertoyModule::update_hotkeys() { - CentralizedKeyboardHook::ClearModuleHotkeys(module->get_name()); + CentralizedKeyboardHook::ClearModuleHotkeys(module->get_key()); size_t hotkeyCount = module->get_hotkeys(nullptr, 0); std::vector hotkeys(hotkeyCount); @@ -59,7 +59,7 @@ void PowertoyModule::update_hotkeys() for (size_t i = 0; i < hotkeyCount; i++) { - CentralizedKeyboardHook::SetHotkeyAction(module->get_name(), hotkeys[i], [modulePtr, i] { + CentralizedKeyboardHook::SetHotkeyAction(module->get_key(), hotkeys[i], [modulePtr, i] { return modulePtr->on_hotkey(i); }); } diff --git a/tools/project_template/ModuleTemplate/dllmain.cpp b/tools/project_template/ModuleTemplate/dllmain.cpp index 7d9c47286c..7d6db190f6 100644 --- a/tools/project_template/ModuleTemplate/dllmain.cpp +++ b/tools/project_template/ModuleTemplate/dllmain.cpp @@ -66,12 +66,18 @@ public: delete this; } - // Return the display name of the powertoy, this will be cached by the runner + // Return the localized display name of the powertoy virtual const wchar_t* get_name() override { return MODULE_NAME; } + // Return the non localized key of the powertoy, this will be cached by the runner + virtual const wchar_t* get_key() override + { + return MODULE_NAME; + } + // Return JSON with the configuration options. virtual bool get_config(wchar_t* buffer, int* buffer_size) override { @@ -158,7 +164,7 @@ public: { // Parse the input JSON string. PowerToysSettings::PowerToyValues values = - PowerToysSettings::PowerToyValues::from_json_string(config); + PowerToysSettings::PowerToyValues::from_json_string(config, get_key()); // Update a bool property. //if (auto v = values.get_bool_value(L"bool_toggle_1")) { @@ -218,7 +224,7 @@ void $safeprojectname$::init_settings() { // Load and parse the settings file for this PowerToy. PowerToysSettings::PowerToyValues settings = - PowerToysSettings::PowerToyValues::load_from_settings_file($safeprojectname$::get_name()); + PowerToysSettings::PowerToyValues::load_from_settings_file($safeprojectname$::get_key()); // Load a bool property. //if (auto v = settings.get_bool_value(L"bool_toggle_1")) { From 701ccfdbccc6d08f484b16d883e583707be6c8bf Mon Sep 17 00:00:00 2001 From: Avneet Kaur <72103212+avneet-kr@users.noreply.github.com> Date: Mon, 19 Oct 2020 19:48:51 -0700 Subject: [PATCH 27/65] FxCopAnalyzer fix for Wox.Core (PR#2of3) - Removing unused JsonRPC files (#7211) * Removed unused JsonRPC related files and references - Files Removed: ExecutablePlugin.cs, JsonRPCClientRequestModel.cs, JsonRPCErrorModel.cs, JsonRPCModelBase.cs, JsonRPCPlugin.cs, JsonRPCQueryResponseModel.cs, JsonRPCRequestModel.cs, JsonRPCResponseModel.cs, JsonRPCResult.cs, JsonRPCServerRequestModel.cs - Modified PluginsLoader.cs: - Removed method ExecutablePlugins - In method Plugins(): Removed call to ExecutablePlugins() * Suppressed warning for catching general exception type * Addressing comments: Replaced in source suppression with attribute and logged exception information --- .../Wox.Core/Plugin/ExecutablePlugin.cs | 60 ----- .../Plugin/JsonRPCClientRequestModel.cs | 34 --- .../Wox.Core/Plugin/JsonRPCErrorModel.cs | 29 --- .../Wox.Core/Plugin/JsonRPCModelBase.cs | 25 -- .../launcher/Wox.Core/Plugin/JsonRPCPlugin.cs | 227 ------------------ .../Plugin/JsonRPCQueryResponseModel.cs | 27 --- .../Wox.Core/Plugin/JsonRPCRequestModel.cs | 78 ------ .../Wox.Core/Plugin/JsonRPCResponseModel.cs | 27 --- .../launcher/Wox.Core/Plugin/JsonRPCResult.cs | 32 --- .../Plugin/JsonRPCServerRequestModel.cs | 32 --- .../Wox.Core/Plugin/PluginInstaller.cs | 6 +- .../launcher/Wox.Core/Plugin/PluginsLoader.cs | 17 +- 12 files changed, 6 insertions(+), 588 deletions(-) delete mode 100644 src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCClientRequestModel.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCErrorModel.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCModelBase.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCQueryResponseModel.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCRequestModel.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCResponseModel.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCResult.cs delete mode 100644 src/modules/launcher/Wox.Core/Plugin/JsonRPCServerRequestModel.cs diff --git a/src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs b/src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs deleted file mode 100644 index 0a595a4202..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/ExecutablePlugin.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using Wox.Plugin; - -namespace Wox.Core.Plugin -{ - internal class ExecutablePlugin : JsonRPCPlugin - { - private readonly ProcessStartInfo _startInfo; - - public override string SupportedLanguage { get; set; } = AllowedLanguage.Executable; - - public ExecutablePlugin(string filename) - { - _startInfo = new ProcessStartInfo - { - FileName = filename, - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - }; - } - - protected override string ExecuteQuery(Query query) - { - JsonRPCServerRequestModel request = new JsonRPCServerRequestModel - { - Method = "query", - Parameters = new object[] { query.Search }, - }; - - _startInfo.Arguments = $"\"{request}\""; - - return Execute(_startInfo); - } - - protected override string ExecuteCallback(JsonRPCRequestModel rpcRequest) - { - _startInfo.Arguments = $"\"{rpcRequest}\""; - return Execute(_startInfo); - } - - protected override string ExecuteContextMenu(Result selectedResult) - { - JsonRPCServerRequestModel request = new JsonRPCServerRequestModel - { - Method = "contextmenu", - Parameters = new object[] { selectedResult.ContextData }, - }; - - _startInfo.Arguments = $"\"{request}\""; - - return Execute(_startInfo); - } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCClientRequestModel.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCClientRequestModel.cs deleted file mode 100644 index 22cdb05b17..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCClientRequestModel.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -namespace Wox.Core.Plugin -{ - /// - /// Json RPC Request(in query response) that client sent to Wox - /// - public class JsonRPCClientRequestModel : JsonRPCRequestModel - { - public bool DontHideAfterAction { get; set; } - - public override string ToString() - { - string rpc = base.ToString(); - return rpc + "}"; - } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCErrorModel.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCErrorModel.cs deleted file mode 100644 index 7130d1e604..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCErrorModel.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -namespace Wox.Core.Plugin -{ - public class JsonRPCErrorModel - { - public int Code { get; set; } - - public string Message { get; set; } - - public string Data { get; set; } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCModelBase.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCModelBase.cs deleted file mode 100644 index 9040a345c1..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCModelBase.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -namespace Wox.Core.Plugin -{ - public class JsonRPCModelBase - { - public int Id { get; set; } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs deleted file mode 100644 index ae0512eea1..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCPlugin.cs +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Windows.Forms; -using Newtonsoft.Json; -using Wox.Infrastructure.Logger; -using Wox.Plugin; - -namespace Wox.Core.Plugin -{ - /// - /// Represent the plugin that using JsonPRC - /// every JsonRPC plugin should has its own plugin instance - /// - internal abstract class JsonRPCPlugin : IPlugin, IContextMenu - { - protected PluginInitContext Context { get; set; } - - public const string JsonRPC = "JsonRPC"; - - /// - /// Gets or sets the language this JsonRPCPlugin support - /// - public abstract string SupportedLanguage { get; set; } - - protected abstract string ExecuteQuery(Query query); - - protected abstract string ExecuteCallback(JsonRPCRequestModel rpcRequest); - - protected abstract string ExecuteContextMenu(Result selectedResult); - - public List Query(Query query) - { - string output = ExecuteQuery(query); - try - { - return DeserializedResult(output); - } - catch (Exception e) - { - Log.Exception($"Exception when query <{query}>", e, GetType()); - return null; - } - } - - public List LoadContextMenus(Result selectedResult) - { - string output = ExecuteContextMenu(selectedResult); - try - { - // This should not hit. If it does it's because Wox shares the same interface for querying context menu items as well as search results. In this case please file a bug. - // To my knowledge we aren't supporting this JSonRPC commands in Launcher, and am not able to repro this, but I will leave this here for the time being in case I'm proven wrong. - // We should remove this, or identify and test officially supported use cases and Deserialize this properly. - // return DeserializedResult(output); - throw new NotImplementedException(); - } - catch (Exception e) - { - Log.Exception($"THIS IS A BUG - Exception on result <{selectedResult}>", e, GetType()); - return null; - } - } - - private List DeserializedResult(string output) - { - if (!string.IsNullOrEmpty(output)) - { - List results = new List(); - - JsonRPCQueryResponseModel queryResponseModel = JsonConvert.DeserializeObject(output); - if (queryResponseModel.Result == null) - { - return null; - } - - foreach (JsonRPCResult result in queryResponseModel.Result) - { - JsonRPCResult result1 = result; - result.Action = c => - { - if (result1.JsonRPCAction == null) - { - return false; - } - - if (!string.IsNullOrEmpty(result1.JsonRPCAction.Method)) - { - if (result1.JsonRPCAction.Method.StartsWith("Wox.")) - { - ExecuteWoxAPI(result1.JsonRPCAction.Method.Substring(4), result1.JsonRPCAction.Parameters); - } - else - { - string actionResponse = ExecuteCallback(result1.JsonRPCAction); - JsonRPCRequestModel jsonRpcRequestModel = JsonConvert.DeserializeObject(actionResponse); - if (jsonRpcRequestModel != null - && !string.IsNullOrEmpty(jsonRpcRequestModel.Method) - && jsonRpcRequestModel.Method.StartsWith("Wox.")) - { - ExecuteWoxAPI(jsonRpcRequestModel.Method.Substring(4), jsonRpcRequestModel.Parameters); - } - } - } - - return !result1.JsonRPCAction.DontHideAfterAction; - }; - results.Add(result); - } - - return results; - } - else - { - return null; - } - } - - private void ExecuteWoxAPI(string method, object[] parameters) - { - MethodInfo methodInfo = PluginManager.API.GetType().GetMethod(method); - if (methodInfo != null) - { - try - { - methodInfo.Invoke(PluginManager.API, parameters); - } - catch (Exception) - { -#if DEBUG - { - throw; - } -#endif - } - } - } - - /// - /// Execute external program and return the output - /// - /// file to execute - /// args to pass in to that exe - /// results - protected string Execute(string fileName, string arguments) - { - ProcessStartInfo start = new ProcessStartInfo - { - FileName = fileName, - Arguments = arguments, - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - }; - - return Execute(start); - } - - protected string Execute(ProcessStartInfo startInfo) - { - try - { - using (var process = Process.Start(startInfo)) - { - if (process != null) - { - using (var standardOutput = process.StandardOutput) - { - var result = standardOutput.ReadToEnd(); - if (string.IsNullOrEmpty(result)) - { - using (var standardError = process.StandardError) - { - var error = standardError.ReadToEnd(); - if (!string.IsNullOrEmpty(error)) - { - Log.Error(error, GetType()); - - return string.Empty; - } - else - { - Log.Error("Empty standard output and standard error.", GetType()); - - return string.Empty; - } - } - } - else if (result.StartsWith("DEBUG:")) - { - MessageBox.Show(new Form { TopMost = true }, result.Substring(6)); - - return string.Empty; - } - else - { - return result; - } - } - } - else - { - Log.Error("Can't start new process", GetType()); - - return string.Empty; - } - } - } - catch (Exception e) - { - Log.Exception($"Exception for filename <{startInfo.FileName}> with argument <{startInfo.Arguments}>", e, GetType()); - - return string.Empty; - } - } - - public void Init(PluginInitContext ctx) - { - Context = ctx; - } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCQueryResponseModel.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCQueryResponseModel.cs deleted file mode 100644 index 9ded1a4fcf..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCQueryResponseModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -using System.Collections.Generic; - -namespace Wox.Core.Plugin -{ - public class JsonRPCQueryResponseModel : JsonRPCResponseModel - { - public new List Result { get; set; } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCRequestModel.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCRequestModel.cs deleted file mode 100644 index 967cd1930b..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCRequestModel.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -using System.Linq; - -namespace Wox.Core.Plugin -{ - public class JsonRPCRequestModel : JsonRPCModelBase - { - public string Method { get; set; } - - public object[] Parameters { get; set; } - - public override string ToString() - { - string rpc = string.Empty; - if (Parameters != null && Parameters.Length > 0) - { - string parameters = Parameters.Aggregate("[", (current, o) => current + (GetParameterByType(o) + ",")); - parameters = parameters.Substring(0, parameters.Length - 1) + "]"; - rpc = string.Format(@"{{\""method\"":\""{0}\"",\""parameters\"":{1}", Method, parameters); - } - else - { - rpc = string.Format(@"{{\""method\"":\""{0}\"",\""parameters\"":[]", Method); - } - - return rpc; - } - - private string GetParameterByType(object parameter) - { - if (parameter == null) - { - return "null"; - } - - if (parameter is string) - { - return string.Format(@"\""{0}\""", ReplaceEscapes(parameter.ToString())); - } - - if (parameter is int || parameter is float || parameter is double) - { - return string.Format(@"{0}", parameter); - } - - if (parameter is bool) - { - return string.Format(@"{0}", parameter.ToString().ToLower()); - } - - return parameter.ToString(); - } - - private string ReplaceEscapes(string str) - { - return str.Replace(@"\", @"\\") // Escapes in ProcessStartInfo - .Replace(@"\", @"\\") // Escapes itself when passed to client - .Replace(@"""", @"\\"""""); - } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCResponseModel.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCResponseModel.cs deleted file mode 100644 index a6b5723a2b..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCResponseModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -namespace Wox.Core.Plugin -{ - public class JsonRPCResponseModel : JsonRPCModelBase - { - public string Result { get; set; } - - public JsonRPCErrorModel Error { get; set; } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCResult.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCResult.cs deleted file mode 100644 index a9eb036957..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCResult.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -using Wox.Plugin; - -namespace Wox.Core.Plugin -{ - /// - /// Represent the json-rpc result item that client send to Wox - /// Typically, we will send back this request model to client after user select the result item - /// But if the request method starts with "Wox.", we will invoke the public APIs we expose. - /// - public class JsonRPCResult : Result - { - public JsonRPCClientRequestModel JsonRPCAction { get; set; } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/JsonRPCServerRequestModel.cs b/src/modules/launcher/Wox.Core/Plugin/JsonRPCServerRequestModel.cs deleted file mode 100644 index a7d7f57b95..0000000000 --- a/src/modules/launcher/Wox.Core/Plugin/JsonRPCServerRequestModel.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/* We basically follow the Json-RPC 2.0 spec (http://www.jsonrpc.org/specification) to invoke methods between Wox and other plugins, - * like python or other self-execute program. But, we added additional infos (proxy and so on) into rpc request. Also, we didn't use the - * "id" and "jsonrpc" in the request, since it's not so useful in our request model. - * - * When execute a query: - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCQueryResponseModel--------- client - * - * When execute a action (which mean user select an item in reulst item): - * Wox -------JsonRPCServerRequestModel--------> client - * Wox <------JsonRPCResponseModel-------------- client - * - */ - -namespace Wox.Core.Plugin -{ - /// - /// Json RPC Request that Wox sent to client - /// - public class JsonRPCServerRequestModel : JsonRPCRequestModel - { - public override string ToString() - { - string rpc = base.ToString(); - return rpc + "}"; - } - } -} diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs b/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs index 38f74320ee..e70745189d 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginInstaller.cs @@ -4,9 +4,11 @@ using System; using System.IO; +using System.Reflection; using System.Windows; using ICSharpCode.SharpZipLib.Zip; using Newtonsoft.Json; +using Wox.Infrastructure.Logger; using Wox.Plugin; namespace Wox.Core.Plugin @@ -96,6 +98,7 @@ namespace Wox.Core.Plugin } } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] private static PluginMetadata GetMetadataFromJson(string pluginDirectory) { string configPath = Path.Combine(pluginDirectory, "plugin.json"); @@ -111,9 +114,10 @@ namespace Wox.Core.Plugin metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); metadata.PluginDirectory = pluginDirectory; } - catch (Exception) + catch (Exception e) { string error = $"Parse plugin config {configPath} failed: json format is not valid"; + Log.Exception(error, e, MethodBase.GetCurrentMethod().DeclaringType); #if DEBUG { throw new Exception(error); diff --git a/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs b/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs index 61b209d80e..d946d7fc14 100644 --- a/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs +++ b/src/modules/launcher/Wox.Core/Plugin/PluginsLoader.cs @@ -20,9 +20,7 @@ namespace Wox.Core.Plugin public static List Plugins(List metadatas) { var csharpPlugins = CSharpPlugins(metadatas).ToList(); - var executablePlugins = ExecutablePlugins(metadatas); - var plugins = csharpPlugins.Concat(executablePlugins).ToList(); - return plugins; + return csharpPlugins; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "All exception information is being logged")] @@ -87,18 +85,5 @@ namespace Wox.Core.Plugin return plugins; } - - public static IEnumerable ExecutablePlugins(IEnumerable source) - { - var metadatas = source.Where(o => o.Language.ToUpperInvariant() == AllowedLanguage.Executable); - - var plugins = metadatas.Select(metadata => new PluginPair - { - Plugin = new ExecutablePlugin(metadata.ExecuteFilePath), - Metadata = metadata, - }); - - return plugins; - } } } From 83872046fa4a8bb5c557434c4c5131ef5753557d Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Tue, 20 Oct 2020 12:35:51 +0300 Subject: [PATCH 28/65] autoupdating: ignore local builds --- src/common/updating/updating.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/updating/updating.cpp b/src/common/updating/updating.cpp index 165cf0a69a..de051f30d3 100644 --- a/src/common/updating/updating.cpp +++ b/src/common/updating/updating.cpp @@ -102,6 +102,11 @@ namespace updating std::future> get_new_github_version_info_async() { + // If the current version starts with 0.0.*, it means we're on a local build from a farm and shouldn't check for updates. + if (VERSION_MAJOR == 0 && VERSION_MINOR == 0) + { + co_return std::nullopt; + } try { http::HttpClient client; From 7c07bc2717d326b61371e0482484784502bd4628 Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Tue, 20 Oct 2020 14:15:09 +0300 Subject: [PATCH 29/65] interop: fix possible crash in keyboardhook also treat warnings as errors --- src/common/interop/KeyboardHook.h | 4 +++- src/common/interop/interop.vcxproj | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/interop/KeyboardHook.h b/src/common/interop/KeyboardHook.h index fc8d9e690b..1b14748e75 100644 --- a/src/common/interop/KeyboardHook.h +++ b/src/common/interop/KeyboardHook.h @@ -1,5 +1,7 @@ #pragma once +#include + using namespace System::Threading; using namespace System::Collections::Generic; @@ -10,7 +12,7 @@ public { WPARAM message; int key; - DWORD dwExtraInfo; + uint64_t dwExtraInfo; }; public diff --git a/src/common/interop/interop.vcxproj b/src/common/interop/interop.vcxproj index fe2dfc7862..d3b0a96b26 100644 --- a/src/common/interop/interop.vcxproj +++ b/src/common/interop/interop.vcxproj @@ -98,6 +98,8 @@ pch.h true true + true + true From 58cf165eb4c9dbcb442139f9940e537fe81dc3c2 Mon Sep 17 00:00:00 2001 From: Avneet Kaur <72103212+avneet-kr@users.noreply.github.com> Date: Tue, 20 Oct 2020 10:36:18 -0700 Subject: [PATCH 30/65] Enabled FxCopAnalyzers for Wox.Core.csproj (#7212) --- src/modules/launcher/Wox.Core/Wox.Core.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/launcher/Wox.Core/Wox.Core.csproj b/src/modules/launcher/Wox.Core/Wox.Core.csproj index 98697616a2..2708128a28 100644 --- a/src/modules/launcher/Wox.Core/Wox.Core.csproj +++ b/src/modules/launcher/Wox.Core/Wox.Core.csproj @@ -65,6 +65,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + all From 14e74376d97bd976b5c8d10469ef5948e29c71be Mon Sep 17 00:00:00 2001 From: Alekhya Date: Tue, 20 Oct 2020 11:13:53 -0700 Subject: [PATCH 31/65] Use task delay instead of thread sleep (#7401) * Use task delay instead of thread.sleep to free up the blocked thread * fix formatting --- .../Storage/ConcurrentQueueEventHandlerTest.cs | 17 +++++++++-------- .../Storage/EventHandler.cs | 6 +++--- .../Storage/Win32ProgramRepository.cs | 7 +++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/ConcurrentQueueEventHandlerTest.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/ConcurrentQueueEventHandlerTest.cs index af484b4d66..fd0e10e05f 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/ConcurrentQueueEventHandlerTest.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Storage/ConcurrentQueueEventHandlerTest.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Concurrent; +using System.Threading.Tasks; using Microsoft.Plugin.Program.Storage; using NUnit.Framework; @@ -12,14 +13,14 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage public class ConcurrentQueueEventHandlerTest { [TestCase] - public void EventHandlerMustReturnEmptyPathForEmptyQueue() + public async Task EventHandlerMustReturnEmptyPathForEmptyQueueAsync() { // Arrange int dequeueDelay = 0; ConcurrentQueue eventHandlingQueue = new ConcurrentQueue(); // Act - string appPath = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay); + string appPath = await EventHandler.GetAppPathFromQueueAsync(eventHandlingQueue, dequeueDelay).ConfigureAwait(false); // Assert Assert.IsEmpty(appPath); @@ -27,7 +28,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage [TestCase(1)] [TestCase(10)] - public void EventHandlerMustReturnPathForConcurrentQueueWithSameFilePaths(int itemCount) + public async Task EventHandlerMustReturnPathForConcurrentQueueWithSameFilePathsAsync(int itemCount) { // Arrange int dequeueDelay = 0; @@ -39,7 +40,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage } // Act - string pathFromQueue = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay); + string pathFromQueue = await EventHandler.GetAppPathFromQueueAsync(eventHandlingQueue, dequeueDelay).ConfigureAwait(false); // Assert Assert.AreEqual(appPath, pathFromQueue); @@ -47,7 +48,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage } [TestCase(5)] - public void EventHandlerMustReturnPathAndRetainDifferentFilePathsInQueue(int itemCount) + public async Task EventHandlerMustReturnPathAndRetainDifferentFilePathsInQueueAsync(int itemCount) { // Arrange int dequeueDelay = 0; @@ -65,7 +66,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage } // Act - string pathFromQueue = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay); + string pathFromQueue = await EventHandler.GetAppPathFromQueueAsync(eventHandlingQueue, dequeueDelay).ConfigureAwait(false); // Assert Assert.AreEqual(firstAppPath, pathFromQueue); @@ -73,7 +74,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage } [TestCase(5)] - public void EventHandlerMustReturnPathAndRetainAllPathsAfterEncounteringADifferentPath(int itemCount) + public async Task EventHandlerMustReturnPathAndRetainAllPathsAfterEncounteringADifferentPathAsync(int itemCount) { // Arrange int dequeueDelay = 0; @@ -96,7 +97,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Storage } // Act - string pathFromQueue = EventHandler.GetAppPathFromQueue(eventHandlingQueue, dequeueDelay); + string pathFromQueue = await EventHandler.GetAppPathFromQueueAsync(eventHandlingQueue, dequeueDelay).ConfigureAwait(false); // Assert Assert.AreEqual(firstAppPath, pathFromQueue); diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/EventHandler.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/EventHandler.cs index 689d581ad0..aee59ba3e7 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/EventHandler.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/EventHandler.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Concurrent; -using System.Threading; +using System.Threading.Tasks; namespace Microsoft.Plugin.Program.Storage { @@ -12,7 +12,7 @@ namespace Microsoft.Plugin.Program.Storage { // To obtain the path of the app when multiple events are added to the Concurrent queue across multiple threads. // On the first occurence of a different file path, the existing app path is to be returned without removing any more elements from the queue. - public static string GetAppPathFromQueue(ConcurrentQueue eventHandlingQueue, int dequeueDelay) + public static async Task GetAppPathFromQueueAsync(ConcurrentQueue eventHandlingQueue, int dequeueDelay) { if (eventHandlingQueue == null) { @@ -36,7 +36,7 @@ namespace Microsoft.Plugin.Program.Storage } // This delay has been added to account for the delay in events being triggered during app installation. - Thread.Sleep(dequeueDelay); + await Task.Delay(dequeueDelay).ConfigureAwait(false); } return previousAppPath; diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs index 5f1aa74f6b..3d2e7d1bf6 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Storage/Win32ProgramRepository.cs @@ -8,7 +8,6 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IO; -using System.Threading; using System.Threading.Tasks; using Wox.Infrastructure.Logger; using Wox.Infrastructure.Storage; @@ -40,15 +39,15 @@ namespace Microsoft.Plugin.Program.Storage InitializeFileSystemWatchers(); // This task would always run in the background trying to dequeue file paths from the queue at regular intervals. - Task.Run(() => + _ = Task.Run(async () => { while (true) { int dequeueDelay = 500; - string appPath = EventHandler.GetAppPathFromQueue(commonEventHandlingQueue, dequeueDelay); + string appPath = await EventHandler.GetAppPathFromQueueAsync(commonEventHandlingQueue, dequeueDelay).ConfigureAwait(false); // To allow for the installation process to finish. - Thread.Sleep(5000); + await Task.Delay(5000).ConfigureAwait(false); if (!string.IsNullOrEmpty(appPath)) { From 334e612bce2b45f2ac1c55d5955bd221672ccbb4 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 20 Oct 2020 11:22:47 -0700 Subject: [PATCH 32/65] LEGO: check in for master to temporary branch. (#7411) --- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 21 +++++++++++++------ .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- .../keyboardmanager/dll/Resources.resx.lcl | 7 +++++-- 17 files changed, 95 insertions(+), 38 deletions(-) diff --git a/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl index 2a27ea3f46..bf66d520df 100644 --- a/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/cs/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl index 6b7f958c4b..a100aaf674 100644 --- a/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/de/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl index a7c6e9f4f9..515bf7aec4 100644 --- a/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/es/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl index 3900d0c4c8..38d4eb9237 100644 --- a/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/fr/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl index a2469ba540..385612b4c8 100644 --- a/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/hu/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl index 02d2da764b..db12d4f8fb 100644 --- a/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/it/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl index f5c407da43..ce3553b373 100644 --- a/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ja/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl index 2b1689e37c..68ffe7f7c0 100644 --- a/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ko/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl index 02a230d943..b51d16390d 100644 --- a/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/nl/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl index 663af6f515..e1074b8166 100644 --- a/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pl/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl index 8199c5a966..fd493716c2 100644 --- a/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pt-BR/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl index aba46cf6f3..d3a528b156 100644 --- a/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/pt-PT/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl index 491cecb7f9..82e830901d 100644 --- a/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -103,9 +103,12 @@ - - + + + + + @@ -175,9 +178,12 @@ - - + + + + + @@ -390,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl index f7f459571c..f3ce0a1fdd 100644 --- a/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/sv/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl index 96f95faf98..7e9d18aad4 100644 --- a/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/tr/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl index ba9c396b3c..c9afbeea5d 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl index cea31af58e..4ea9189d1c 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hant/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -396,10 +396,13 @@ - + - + + + + From 51d6482ec27c4ff4300a8f8e8e2e55ddaa5f8873 Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Tue, 20 Oct 2020 11:58:32 -0700 Subject: [PATCH 33/65] [Localization] Fix Settings resw path on the build farm (#7383) * Added loc debugging statements * Added more debug statements * Check path * Fixed input path for Settings resources on pipeline --- tools/localization/move_uwp_resources.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/localization/move_uwp_resources.ps1 b/tools/localization/move_uwp_resources.ps1 index 03df78c8d8..350f856fca 100644 --- a/tools/localization/move_uwp_resources.ps1 +++ b/tools/localization/move_uwp_resources.ps1 @@ -1,5 +1,5 @@ # List of resource folders -$input_resource_folder_list = @("src\core\Microsoft.PowerToys.Settings.UI\Strings\en-us\") +$input_resource_folder_list = @("src\core\Microsoft.PowerToys.Settings.UI\Strings\") $output_resource_folder_list = @("src\core\Microsoft.PowerToys.Settings.UI\Strings\") # Hash table to get the folder language code from the code used in the file name From 9a9424a975109095d748ad2732b51a9e9e744166 Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Tue, 20 Oct 2020 12:50:04 -0700 Subject: [PATCH 34/65] Add null check for WindowsXamlHost_ChildChanged handler (#7426) --- .../MainWindow.xaml.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs b/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs index ff477163a5..38c02e694a 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs +++ b/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs @@ -30,6 +30,12 @@ namespace Microsoft.PowerToys.Settings.UI.Runner private void WindowsXamlHost_ChildChanged(object sender, EventArgs e) { + // If sender is null, it could lead to a NullReferenceException. This might occur on restarting as admin (check https://github.com/microsoft/PowerToys/issues/7393 for details) + if (sender == null) + { + return; + } + // Hook up x:Bind source. WindowsXamlHost windowsXamlHost = sender as WindowsXamlHost; ShellPage shellPage = windowsXamlHost.GetUwpInternalObject() as ShellPage; From 18eb6b4ffdf1a6ea01b91831a5635f83564485b5 Mon Sep 17 00:00:00 2001 From: Alekhya Date: Tue, 20 Oct 2020 14:28:06 -0700 Subject: [PATCH 35/65] Dev documentation of SettingsV2 (#7335) * created a folder for settings and added an overview, hotkey information * basic structure for communication between settings and runner * Added information about the IPC communication between settings and runner * Added information about the communication between the settings process and modules * Added details on backward compatibility * brief overview on settings utils * added an overview of the viewmodels and anomalies * minor modifications * Settings v2 dev docs (#7334) * Added settings architecture and tech stack dev docs * Added telemetry and updated architecture docs for settings v2 * Fix image link in ui_architecture markdown * Added table of contents for settings v2 * Correct file path for ui architecture image * nit fix in table of contents heading * Add doc for xaml island tweaks Co-authored-by: Divyansh Srivastava --- .../settingsv2/communication-with-modules.md | 15 ++++++ .../compatibility-legacy-settings.md | 12 +++++ doc/devdocs/settingsv2/hotkeycontrol.md | 46 ++++++++++++++++++ doc/devdocs/settingsv2/project-overview.md | 17 +++++++ doc/devdocs/settingsv2/readme.md | 12 +++++ doc/devdocs/settingsv2/runner-ipc.md | 46 ++++++++++++++++++ doc/devdocs/settingsv2/settings-utilities.md | 13 +++++ doc/devdocs/settingsv2/telemetry.md | 8 +++ doc/devdocs/settingsv2/ui-architecture.md | 9 ++++ doc/devdocs/settingsv2/viewmodels.md | 26 ++++++++++ doc/devdocs/settingsv2/xaml-island-tweaks.md | 30 ++++++++++++ .../settingsv2/settingshotkeycontrol.png | Bin 0 -> 2761 bytes doc/images/settingsv2/ui-architecture.png | Bin 0 -> 31648 bytes 13 files changed, 234 insertions(+) create mode 100644 doc/devdocs/settingsv2/communication-with-modules.md create mode 100644 doc/devdocs/settingsv2/compatibility-legacy-settings.md create mode 100644 doc/devdocs/settingsv2/hotkeycontrol.md create mode 100644 doc/devdocs/settingsv2/project-overview.md create mode 100644 doc/devdocs/settingsv2/readme.md create mode 100644 doc/devdocs/settingsv2/runner-ipc.md create mode 100644 doc/devdocs/settingsv2/settings-utilities.md create mode 100644 doc/devdocs/settingsv2/telemetry.md create mode 100644 doc/devdocs/settingsv2/ui-architecture.md create mode 100644 doc/devdocs/settingsv2/viewmodels.md create mode 100644 doc/devdocs/settingsv2/xaml-island-tweaks.md create mode 100644 doc/images/settingsv2/settingshotkeycontrol.png create mode 100644 doc/images/settingsv2/ui-architecture.png diff --git a/doc/devdocs/settingsv2/communication-with-modules.md b/doc/devdocs/settingsv2/communication-with-modules.md new file mode 100644 index 0000000000..d857e36936 --- /dev/null +++ b/doc/devdocs/settingsv2/communication-with-modules.md @@ -0,0 +1,15 @@ +# Communication with modules + +## Through runner +- The settings process communicates changes in the UI to most modules using the runner through delegates. +- More details on this are mentioned in [`runner-ipc.md`](settingsv2/runner-ipc.md). + +## PT Run +- Any changes to the UI are saved by the settings process in the `settings.json` file located within the `/Local/Microsoft/PowerToys/Launcher/` folder. +- PT Run watches for any changes within this file and updates it's general settings or propagates the information to the plugins, depending on the type of information. +Eg: The maximum number of results drop down updates the maximum number of rows in the results list which updates the general settings of PT Run whereas the drive detection checkbox details are dispatched to the indexer plugin. + +## Keyboard Manager +- The Settings process and keyboard manager share access to a common `default.json` file which contains information about the remapped keys and shortcuts. +- To ensure that there is no contention while both processes try to access the common file, there is a named file mutex. +- The settings process expects the keyboard manager process to create the `default.json` file if it does not exist. It does not create the file in case it is not present. \ No newline at end of file diff --git a/doc/devdocs/settingsv2/compatibility-legacy-settings.md b/doc/devdocs/settingsv2/compatibility-legacy-settings.md new file mode 100644 index 0000000000..392591c50c --- /dev/null +++ b/doc/devdocs/settingsv2/compatibility-legacy-settings.md @@ -0,0 +1,12 @@ +# Compatibility with legacy settings and runner +The following must be kept in mind regarding compatibility with settings v1 and runner. + +### 1. Folder Naming structure +- Each of the modules has a folder within the `Local/Microsoft/PowerToys` directory which contains the module configurations within the `settings.json` file. The name of this folder must be the same across settingsv1 and settingsv2. +- The name of the settings folder for each powertoy is the same as the `ModuleName`. It is set within each of the viewModel files. This name must not be changed to ensure that the user configurations for each of the powertoys rolls over on update. + +### 2. Communication with runner +- The status of each of the modules is communicated with the runner in the form of a json object. The names of all the powerToys is set in the [`EnableModules.cs`](src/core/Microsoft.PowerToys.Settings.UI.Lib/EnabledModules.cs) file. The `JsonPropertyName` must not be changed to ensure that the information is dispatched properly to all the modules by the runner. + +### ImageResizer anomaly +All the powertoys have the same folder name as well as JsonPropertyName to communicate information with the runner. However that is not the case with ImageResizer. The folder name is `ImageResizer` whereas the JsonPropertyName is `Image Resizer`(Note the additional space). This should not be changed to ensure backward compatibity as well as proper functioning of the module. \ No newline at end of file diff --git a/doc/devdocs/settingsv2/hotkeycontrol.md b/doc/devdocs/settingsv2/hotkeycontrol.md new file mode 100644 index 0000000000..b6e5e52ff6 --- /dev/null +++ b/doc/devdocs/settingsv2/hotkeycontrol.md @@ -0,0 +1,46 @@ +# Custom HotKey Control + +The Settings project provides a custom hotkey control which consumes key presses. This control can be used to set the hotkey of any PowerToy. + +## HotKey Control in FancyZones +![Image of hotkey control](/doc/images/settingsv2/settingshotkeycontrol.png) + +## Hotkey related files + +#### [`HotkeySettingsControlHook.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Lib/HotkeySettingsControlHook.cs) + +- This function initializes and starts the [`keyboardHook`](src/common/interop/KeyboardHook.cpp) for the hotkey control. + +```csharp + public HotkeySettingsControlHook(KeyEvent keyDown, KeyEvent keyUp, IsActive isActive, FilterAccessibleKeyboardEvents filterAccessibleKeyboardEvents) + { + _keyDown = keyDown; + _keyUp = keyUp; + _isActive = isActive; + _filterKeyboardEvent = filterAccessibleKeyboardEvents; + _hook = new KeyboardHook(HotkeySettingsHookCallback, IsActive, FilterKeyboardEvents); + _hook.Start(); + } + +``` + +#### [`HotkeySettingsControl.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/HotkeySettingsControl.xaml.cs) + +- The function of this class is to update the state of the keys being pressed within the custom control. This information is stored in `internalSettings`. + +- It provides the following callbacks to the `HotKeySettingsControlHook`: + + - `KeyUp`: Resets the key state in `internalSettings` when a key is released. + - `KeyDown`: Updates the user facing text of the hotkey control as soon as a key is pressed. + - `isActive`: Sets the current status of the keyboard hook. + - `FilterAccessibleKeyboardEvents`: This function is used to ignore the `Tab` and `Shift+Tab` key presses to meet the accessibility requirements. + +#### [`HotkeySettings.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Lib/HotkeySettings.cs) + +- Contains the structure of a HotKey where it is represented as a combination of one of the modifier keys (`Alt`, `Shift`, `Win` and `Ctrl`) and a non-modifier key. + +#### Note +- The control displays all key presses to the user (except Tab and Shift+Tab which move focus out of the control). However, when the focus is being lost from the control, the `lastValidHotkeySettings` is set as the user facing text. + + + diff --git a/doc/devdocs/settingsv2/project-overview.md b/doc/devdocs/settingsv2/project-overview.md new file mode 100644 index 0000000000..23baa985da --- /dev/null +++ b/doc/devdocs/settingsv2/project-overview.md @@ -0,0 +1,17 @@ +# Overview +`Settingsv2` is WPF .net core desktop application. It uses the `WindowsXamlHost` control from the Windows Community Toolkit to host UWP controls from `WinUI3` library. More details about WinUI can be found [here](https://microsoft.github.io/microsoft-ui-xaml/about.html#what-is-it). + +## Settings V2 Project structure +The Settings project is a XAML island based project which +follows the [MVVM architectural pattern][MVVM] where the graphical user interface is separated from the view models. + +#### [UI Components:](/src/core/Microsoft.PowerToys.Settings.UI) +The Settings.UI project contains the xaml files for each of the UI components. It also contains the Hotkey logic for the settings control. + +#### [Viewmodels:](/src/core/Microsoft.PowerToys.Settings.UI.Lib) +The Settings.UI.Lib project contains the data that is to be rendered by the UI components. + +#### [Settings Runner:](/src/core/Microsoft.PowerToys.Settings.UI.Runner) +The function of the settings runner project is to communicate all changes that the user makes in the user interface, to the runner so that it can be dispatched and reflected in all the modules. + +[MVVM]: https://docs.microsoft.com/en-us/windows/uwp/data-binding/data-binding-and-mvvm \ No newline at end of file diff --git a/doc/devdocs/settingsv2/readme.md b/doc/devdocs/settingsv2/readme.md new file mode 100644 index 0000000000..c9cb7945be --- /dev/null +++ b/doc/devdocs/settingsv2/readme.md @@ -0,0 +1,12 @@ +# Table of Contents +1. [Settings overview](/doc/devdocs/settingsv2/project-overview.md) +2. [UI Architecture](/doc/devdocs/settingsv2/ui-architecture.md) +3. [ViewModels](/doc/devdocs/settingsv2/viewmodels.md) +4. Data flow + - [Inter-Process Communication with runner](/doc/devdocs/settingsv2/runner-ipc.md) + - [Communication with modules](/doc/devdocs/settingsv2/communication-with-modules.md) +5. [Settings Utilities](/doc/devdocs/settingsv2/settings-utilities.md) +6. [Custom Hotkey control and keyboard hook handling](hotkeycontrol.md) +7. [Compatibility with legacy settings and runner](/doc/devdocs/settingsv2/compatibility-legacy-settings.md) +8. [XAML Island tweaks](/doc/devdocs/settingsv2/xaml-island-tweaks.md) +9. [Telemetry](/doc/devdocs/settingsv2/telemetry.md) diff --git a/doc/devdocs/settingsv2/runner-ipc.md b/doc/devdocs/settingsv2/runner-ipc.md new file mode 100644 index 0000000000..d10dcd7848 --- /dev/null +++ b/doc/devdocs/settingsv2/runner-ipc.md @@ -0,0 +1,46 @@ +# Inter-Process Communication with Runner + +The Settings v2 process uses two way IPC to communicate with the runner process. + +## Initialization +- On the settings' side, the two way IPC delegates are contained with the [`ShellPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml.cs) file. The delegates are static and the views for all the powerToys send the ipc information to the viewmodels as `ShellPage.DefaultSndMSGCallBack`. +- These delegates are initialized within the [`Mainwindow.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml.cs) file in the `Settings.Runner` project. + + +## Types of IPC delegates +- There are three types of delegates for the settings to communicate with the runner: +1. `SendDefaultMessage` - This is used by all the viewmodels to communicate changes in the UI to the runner so that the information can be dispatched to the modules. +2. `RestartAsAdmin` +3. `CheckForUpdates` + +## Sending information to runner +- The settings process communicates with the runner by using the delegates defined within the [`ShellPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml.cs) file. +- Depending on the type of object sending the information, the json is created accordingly. +- If any information has been modified by the user in the GeneralSettings page, then the json file sent to the runner has the name set to `general`, whereas if any information has been modified by the user in any powertoy related settings page, the name of the json file being communicated with the runner is set to `powertoy`. + +## Receiving information from runner +- The `ShellPage`object has a `IPCResponseHandleList` which is a list of functions which handle IPC responses. + +```csharp +// receive IPC Message +Program.IPCMessageReceivedCallback = (string msg) => +{ + if (ShellPage.ShellHandler.IPCResponseHandleList != null) + { + try + { + JsonObject json = JsonObject.Parse(msg); + foreach (Action handle in ShellPage.ShellHandler.IPCResponseHandleList) + { + handle(json); + } + } + catch (Exception) + { + } + } +}; +``` + +- Whenever any information is sent from the runner each of the functions in the handle list perform their action on that json object. +- One example of where information sent from the runner is being processed by the settings is in [`GeneralPage.xaml.cs`](/src/core/Microsoft.PowerToys.Settings.UI/Views/GeneralPage.xaml.cs) when the user clicks the check for updates button. The information displayed after, such as the user has the latest version installed is a result of this handle. diff --git a/doc/devdocs/settingsv2/settings-utilities.md b/doc/devdocs/settingsv2/settings-utilities.md new file mode 100644 index 0000000000..e0f07b62f5 --- /dev/null +++ b/doc/devdocs/settingsv2/settings-utilities.md @@ -0,0 +1,13 @@ +# Settings Utilities + +- Abstractions for each of the file/folder related operations are present in [`SettingsUtils.cs`](src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsUtils.cs). +- To reduce contention between the settings process and runner while trying to access the `settings.json` file of any powertoy, the settings process tries to access the file only when it needs to load the information for the first time. However, there is still no mechanism in place which ensures that both the settings and runner processes do not access the information simultaneously leading to `IOExceptions`. + +## Utilities + +### `GetSettings(powertoy, filename)` + +- The GetSettings function tries to read the file in the powertoy settings folder and creates a new file with default configurations if it does not exist. +- Ideally this function should only be called by the [`SettingsRepository`](src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsRepository`1.cs) which would be accessed only when a powertoy settings object is being loaded for the first time. +- The reason behind ensuring that it is not accessed elsewhere is to avoid contention with the runner during file access. +- Each of the objects which are deserialized using this function must implement the `ISettingsConfig` interface. diff --git a/doc/devdocs/settingsv2/telemetry.md b/doc/devdocs/settingsv2/telemetry.md new file mode 100644 index 0000000000..8ae1070d14 --- /dev/null +++ b/doc/devdocs/settingsv2/telemetry.md @@ -0,0 +1,8 @@ +# Telemetry +## Overview +[`Microsoft.PowerToys.Settings.UI.Lib/Telemetry`](/src/core/Microsoft.PowerToys.Settings.UI.Lib/Telemetry) contains telemetry events generated by `Settingsv2.` These event classes are derived from the [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class and [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class. [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class provides the lowest level abstraction, containing attributes such as privacy tags needed for every telemetry data. [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class provides a higher-level abstraction, having attributes common to all `PowerToys` telemetry events. + +## Events +The following events are generated by `Settingsv2`: +1. [`SettingsBootEvent`](/src/core/Microsoft.PowerToys.Settings.UI.Lib/Telemetry/Events/SettingsBootEvent.cs): This event captures the time taken by `Settingsv2` to initialize `MainWindow` UI control. +2. [`SettingsEnabledEvent.cs`](/src/core/Microsoft.PowerToys.Settings.UI.Lib/Telemetry/Events/SettingsEnabledEvent.cs): This event is generated when a module is enabled or disabled. \ No newline at end of file diff --git a/doc/devdocs/settingsv2/ui-architecture.md b/doc/devdocs/settingsv2/ui-architecture.md new file mode 100644 index 0000000000..ffebc17107 --- /dev/null +++ b/doc/devdocs/settingsv2/ui-architecture.md @@ -0,0 +1,9 @@ +# UI Architecture + + The UI code is distributed between two projects: [`Microsoft.PowerToys.Settings.UI.Runner`](/src/core/Microsoft.PowerToys.Settings.UI.Runner) and [`Microsoft.PowerToys.Settings.UI`](/src/core/Microsoft.PowerToys.Settings.UI.Lib). [`Microsoft.PowerToys.Settings.UI.Runner`](/src/core/Microsoft.PowerToys.Settings.UI.Runner) is a WPF .net core application. It contains the parent display window and corresponding code is present in [`MainWindow.xaml.`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml) [`Microsoft.PowerToys.Settings.UI`](/src/core/Microsoft.PowerToys.Settings.UI.Lib) is UWP applications and contains views for base navigation and modules. Fig 1 provides a description of the UI controls hierarchy and each of the controls have been summarized below : +- [`MainWindow.xaml`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml) is the parent WPF control. +- `WindowsXamlHost` control is used to host UWP control to [`MainWindow.xaml`](/src/core/Microsoft.PowerToys.Settings.UI.Runner/MainWindow.xaml) parent control. +- [`ShellPage.xaml`](/src/core/Microsoft.PowerToys.Settings.UI/Views/ShellPage.xaml) is a UWP control, consisting of a side navigation panel with an icon for each module. Clicking on a module icon loads the corresponding `setting.json` file and displays the data in the UI. + +![Settings UI architecture](/doc/images/settingsv2/ui-architecture.png) +**Fig 1: UI Architecture for settingsv2** diff --git a/doc/devdocs/settingsv2/viewmodels.md b/doc/devdocs/settingsv2/viewmodels.md new file mode 100644 index 0000000000..1f9cd54d95 --- /dev/null +++ b/doc/devdocs/settingsv2/viewmodels.md @@ -0,0 +1,26 @@ +# Viewmodels +The viewmodels are located within the [`Microsoft.PowerToys.Settings.UI.Lib`](/src/core/Microsoft.PowerToys.Settings.UI.Lib) project. + +## Components +- Each viewmodel takes in the general `settingsRepository`, the `moduleSettingsRepository` if it exists and the delegates for IPC communication. +- The general `settingsRepository` contains the general configurations of all powertoys whereas the `moduleSettingsRepository` is spcific to the module. This is to ensure that the configuration details are shared amongst the viewmodels without having to re-open the `settings.json` file. +- Whenever there is a change in the UI, the `OnPropertyChanged` event is invoked and the viewmodel sends a corresponding IPC message to the runner which would perform the designated action such as dispatching the change to the modules or enabling/disabling the powertoy etc. + +#### Difference between viewmodels +- The [`GeneralViewModel`](/src/core/Microsoft.PowerToys.Settings.UI.Lib/ViewModels/GeneralViewModel.cs) is different from the rest of the view models with regard to the IPC communication wherein it sends special IPC messages to the runner to check for updates and to restart as admin. +- Each of the powerToy viewmodels have two types of IPC communications, one for the general status of the powerToy and the other for communication powerToy specific change in properties to the runner. + +## [`SettingsRepository`](src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsRepository`1.cs) +- The [`SettingsRepository`](src/core/Microsoft.PowerToys.Settings.UI.Lib/SettingsRepository`1.cs) is a generic singleton which contains the configurations for each viewmodel. +- As it is a generic singleton, there can only be one instance of the settings repository of a particular type. This ensures that all the viewmodels are modifying a common object and a change made in one locations reflects everywhere. +- The singleton implementation is thread-safe. Unit tests have been added for the same. + +### Settings viewmodel anomalies +- The reason behind using the `SettingsRepository` is to ensure that the settings process does not try to access the `settings.json` files directly but rather does it through this class which encapsulates all the file operations from the viewmodels. +- However, this could not be expanded to all the viewmodels directly for the following reasons. Some refactoring must be done to unify these cases and to bring them under the same model: + - The PowerRename viewodel does not save the settings configurations in the same format as the rest of the powertoys, ie. {name, version, properties}. However, it only stores the properties directly. + - Some viewmodels expect the runner to create the file instead of creating the file themselves, like in keyboard manager. + - The colorpicker powertoy creates the `settings.json` within the module. This must be taken care of when encapsulated within the settingsRepository. +- Currently, all modules use the `SettingsRepository` to access the General Settings config. +- However, only Fancyzones, ShortcutGuide and PowerPreview use the `SettingsRepository` to access the module properties. + diff --git a/doc/devdocs/settingsv2/xaml-island-tweaks.md b/doc/devdocs/settingsv2/xaml-island-tweaks.md new file mode 100644 index 0000000000..e0b134b4f3 --- /dev/null +++ b/doc/devdocs/settingsv2/xaml-island-tweaks.md @@ -0,0 +1,30 @@ +# XAML Island Tweaks +Few tweaks were made to fix issues with Xaml Islands. These tweaks should be removed after migrating to WINUI3. The tweaks are listed below: +1. Workaround to ensure XAML Island application terminates if attempted to close from taskbar while minimized: +``` +private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) +{ + isOpen = false; + + // XAML Islands: If the window is closed while minimized, exit the process. Required to avoid process not terminating issue - https://github.com/microsoft/PowerToys/issues/4430 + if (WindowState == WindowState.Minimized) + { + // Run Environment.Exit on a separate task to avoid performance impact + System.Threading.Tasks.Task.Run(() => { Environment.Exit(0); }); + } +} +``` +2. Workaround to hide the XAML Island blank icon in the taskbar when the XAML Island application is loading: +``` +var coreWindow = Windows.UI.Core.CoreWindow.GetForCurrentThread(); +var coreWindowInterop = Interop.GetInterop(coreWindow); +Interop.ShowWindow(coreWindowInterop.WindowHandle, Interop.SW_HIDE); +``` +3. Workaround to prevent XAML Island failing to render on Nvidia workstation graphics cards: +``` + // XAML Islands: If the window is open, explicity force it to be shown to solve the blank dialog issue https://github.com/microsoft/PowerToys/issues/3384 + if (isOpen) + { + Show(); + } + ``` \ No newline at end of file diff --git a/doc/images/settingsv2/settingshotkeycontrol.png b/doc/images/settingsv2/settingshotkeycontrol.png new file mode 100644 index 0000000000000000000000000000000000000000..efe8d1a9546269132fb61a5da359b52760f094b5 GIT binary patch literal 2761 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 literal 0 HcmV?d00001 From 0314b570cd5b2b5247d445a479b02e88de4b540f Mon Sep 17 00:00:00 2001 From: Alekhya Date: Tue, 20 Oct 2020 14:28:23 -0700 Subject: [PATCH 36/65] Dev Documentation of PowerToys Run (#7333) * Architecture and (#7267) * Added debugging steps for PT Run * Updated architecture markdown for launcher * updated project architecture markdown for launcher * Added telemetry docs for launcher * Added the basic folder structure and files * Added a basic overview of all common functionalities of the plugins * Added information about the functioning of the calculator plugin * update score section of overview * added information about the uri plugin * added info about the indexer plugin * Added the documentation for the indexer plugin * Added information about the program plugin * Added info about the shell plugin * updated some plugin info and added information about the ww plugin * documenting the folder plugin * updated window walker docs * dev docs for the folder plugin * added images to each of the plugins * Added link to pt run documents * fix typos and some minor corrections * Add table of contents for pt run dev docs * Fix image path and project link for Wox.plugin Co-authored-by: Divyansh Srivastava --- doc/devdocs/modules/launcher/architecture.md | 48 ++++++++++++++++++ doc/devdocs/modules/launcher/debugging.md | 20 ++++++++ .../modules/launcher/plugins/calculator.md | 23 +++++++++ .../modules/launcher/plugins/folder.md | 17 +++++++ .../modules/launcher/plugins/indexer.md | 39 ++++++++++++++ .../modules/launcher/plugins/overview.md | 35 +++++++++++++ .../modules/launcher/plugins/program.md | 43 ++++++++++++++++ doc/devdocs/modules/launcher/plugins/shell.md | 14 +++++ doc/devdocs/modules/launcher/plugins/uri.md | 19 +++++++ .../modules/launcher/plugins/windowwalker.md | 18 +++++++ .../modules/launcher/project_structure.md | 24 +++++++++ doc/devdocs/modules/launcher/readme.md | 14 +++++ doc/devdocs/modules/launcher/telemetry.md | 14 +++++ doc/images/launcher/launcher_dependency.PNG | Bin 0 -> 50844 bytes doc/images/launcher/plugins/calculator.png | Bin 0 -> 49069 bytes doc/images/launcher/plugins/folder.png | Bin 0 -> 124917 bytes doc/images/launcher/plugins/indexer.png | Bin 0 -> 124917 bytes doc/images/launcher/plugins/program.png | Bin 0 -> 89835 bytes doc/images/launcher/plugins/shell.png | Bin 0 -> 51291 bytes doc/images/launcher/plugins/uri.png | Bin 0 -> 57477 bytes doc/images/launcher/plugins/windowwalker.png | Bin 0 -> 62294 bytes doc/images/launcher/pt_run_ui.png | Bin 0 -> 465987 bytes doc/images/launcher/ui_vm_interaction.PNG | Bin 0 -> 45518 bytes doc/images/launcher/vm_plugin_interaction.PNG | Bin 0 -> 46241 bytes 24 files changed, 328 insertions(+) create mode 100644 doc/devdocs/modules/launcher/architecture.md create mode 100644 doc/devdocs/modules/launcher/debugging.md create mode 100644 doc/devdocs/modules/launcher/plugins/calculator.md create mode 100644 doc/devdocs/modules/launcher/plugins/folder.md create mode 100644 doc/devdocs/modules/launcher/plugins/indexer.md create mode 100644 doc/devdocs/modules/launcher/plugins/overview.md create mode 100644 doc/devdocs/modules/launcher/plugins/program.md create mode 100644 doc/devdocs/modules/launcher/plugins/shell.md create mode 100644 doc/devdocs/modules/launcher/plugins/uri.md create mode 100644 doc/devdocs/modules/launcher/plugins/windowwalker.md create mode 100644 doc/devdocs/modules/launcher/project_structure.md create mode 100644 doc/devdocs/modules/launcher/readme.md create mode 100644 doc/devdocs/modules/launcher/telemetry.md create mode 100644 doc/images/launcher/launcher_dependency.PNG create mode 100644 doc/images/launcher/plugins/calculator.png create mode 100644 doc/images/launcher/plugins/folder.png create mode 100644 doc/images/launcher/plugins/indexer.png create mode 100644 doc/images/launcher/plugins/program.png create mode 100644 doc/images/launcher/plugins/shell.png create mode 100644 doc/images/launcher/plugins/uri.png create mode 100644 doc/images/launcher/plugins/windowwalker.png create mode 100644 doc/images/launcher/pt_run_ui.png create mode 100644 doc/images/launcher/ui_vm_interaction.PNG create mode 100644 doc/images/launcher/vm_plugin_interaction.PNG diff --git a/doc/devdocs/modules/launcher/architecture.md b/doc/devdocs/modules/launcher/architecture.md new file mode 100644 index 0000000000..f0287f56dc --- /dev/null +++ b/doc/devdocs/modules/launcher/architecture.md @@ -0,0 +1,48 @@ +# Architecture + +## Overview +`PowerToys Run` is a plugin-based .net core desktop application. It is written in WPF using `Model-View-ViewModel (MVVM)` structural design pattern. This article provides an overview of `PowerToys Run` architecture and introduces major components in the data flow. + +Note : We refer to base application without plugins as `PowerLauncher`, which is same as the name of startup WPF project. + +## UI +PowerToys Run UI is written in the WPF framework. The UI code is present in the Powerlauncher project and is spanned across three high-level components: [`MainWindow.xaml`](/src/modules/launcher/PowerLauncher/MainWindow.xaml), [`LauncherControl.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml) and [`ResultList.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml). These components are discussed below. + +![Image of PowerToys Run UI](/doc/images/launcher/pt_run_ui.png) +**Fig 1: PowerToys Run UI architecture** + +1. **[`MainWindow.xaml`](/src/modules/launcher/PowerLauncher/MainWindow.xaml)**: This is the outermost-level UI control. It is composed of lower-level UI components such as [`LauncherControl.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml) and [`ResultList.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml). The corresponding code-behind file implements all the UI related functionalities such as autosuggest, key-bindings, toggling visibility of WPF window and animations. +2. **[`LauncherControl.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml)**: This control implements the UI component for editing query text.(marked in red in Fig 1) It consists of two overlapping WPF controls, `TextBox` and `TextBlock`. The outer `TextBox` is used for editing query whereas the inner `TextBlock` is used to display autosuggest text. +3. **[`ResultList.xaml`](/src/modules/launcher/PowerLauncher/LauncherControl.xaml)**: This control implements the UI component for displaying results (marked in green in Fig 1). It consists of a `ListView` WPF control with a custom `ItemTemplate` to display application logo, name, tooltip text, and context menu. + +## Data flow +The backend code is written using the `Model-View-ViewModel (MVVM)` structural design pattern. Plugins act as `Model` in this project. A detailed overview of the project's structure is given [here](/doc/devdocs/modules/launcher/project_structure.md). + +#### Flow of data between UI(view) and ViewModels +Data flow between View and ViewModel follows typical `MVVM` scheme. Properties in viewModels are bound to WPF controls and when these properties are updated, `INotifyPropertyChanged` handler is invoked, which in turn updates UI. The diagram below provides a rough sketch of the components involved. +![Flow of data between UI(view) and ViewModels](/doc/images/launcher/ui_vm_interaction.PNG) +**Fig 2: Flow of data between UI and ViewModels.** + +#### Flow of data between ViewModels and Plugins(Model) +`PowerLauncher` interact with plugins using [`IPlugin`](/src/modules/launcher/Wox.Plugin/IPlugin.cs) and `IDelayedExecutionPlugin` interface. [`IPlugin`](/src/modules/launcher/Wox.Plugin/IPlugin.cs) is used for initialization and making queries which are fast (typically return results in less than 100ms).[`IDelayedExecutionPlugin`](/src/modules/launcher/Wox.Plugin/IDelayedExecutionPlugin.cs) is used for long-running queries and is implemented only when required. For example, [`IDelayedExecutionPlugin`](/src/modules/launcher/Wox.Plugin/IDelayedExecutionPlugin.cs) is implemented by indexer plugin for searching files with names of form \*abc\*. +``` + public interface IPlugin + { + // Query plugin + List Query(Query query); + + // Initialize plugin + void Init(PluginInitContext context); + } + + public interface IDelayedExecutionPlugin : IFeatures + { + // Query plugin + List Query(Query query, bool delayedExecution); + } +``` +![Flow of data between UI(view) and ViewModels](/doc/images/launcher/vm_plugin_interaction.PNG) +**Fig 3: Flow of data between ViewModels and Plugins.** + +#### Requesting services from powerlauncher +Plugins could use the [`IPublicAPI`](/src/modules/launcher/Wox.Plugin/IPublicAPI.cs) interface to request services such as getting the current theme (for deciding logo background), displaying messages to the user, and toggling the visibility of PowerLauncher. \ No newline at end of file diff --git a/doc/devdocs/modules/launcher/debugging.md b/doc/devdocs/modules/launcher/debugging.md new file mode 100644 index 0000000000..018d36e2c4 --- /dev/null +++ b/doc/devdocs/modules/launcher/debugging.md @@ -0,0 +1,20 @@ +# Debugging +`PowerToys Run` is a single exe file associated with `launcher.exe` process and debugger should be attached to this process. There are two approaches to debug `PowerToys Run`. Both these approaches differ in the compile-time and the range of functionalities that could be debugged. These methods are discussed in detail in the following sections. + + +## Debugging Prerequisite +Setup development environment for PowerToys by following instruction [here.](https://github.com/microsoft/PowerToys/tree/master/doc/devdocs#prerequisites-for-compiling-powertoys) + +## Direct debugging +This approach is used to test UI, plugins, and core `PowerToys Run` functionality. This **cannot** be used to test `PowerToys Run` settings. The approach is significantly faster compared to `Debugging with runner`, as it requires compiling projects relevant to `PowerToys Run`. Please follow the steps below for direct debugging. +1. Right-click on `modules->launcher->PowerLauncher` and select `Set as startup Project`. +2. Press `F5` to start debugging. + +## Debugging with runner +This approach can be used to test UI, plugins, core `PowerToys Run` functionality and `PowerToys Run` settings. This approach **cannot** be used to debugg functions that execute on starting `launcher.exe` process. This requires building runner along with all the other modules on first compile, making it slower than `Direct debugging` approach. The subsequent compilations should be fast. +1. Right-click on `runner` and select `Set as startup Project`. +2. Press `F5` to start debugging. +3. Attach debugger to `launcher.exe` process. + 1. Go to `Debug->Attach to process..` + 2. Filter and select `launcher.exe` process. + 3. Click on `Attach`. \ No newline at end of file diff --git a/doc/devdocs/modules/launcher/plugins/calculator.md b/doc/devdocs/modules/launcher/plugins/calculator.md new file mode 100644 index 0000000000..8d5c44fa2b --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/calculator.md @@ -0,0 +1,23 @@ +# Calculator Plugin +The Calculator plugin as the name suggests is used to perform calculations on the user entered query. + +![Image of Calculator plugin](/doc/images/launcher/plugins/calculator.png) + +### [`CalculateHelper`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateHelper.cs) +- The [`CalculateHelper.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateHelper.cs) class checks to see if the user entered query is a valid input to the calculator and only if the input is valid does it perform the operation. +- It does so by matching the user query to a valid regex. + +### [`CalculateEngine`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateEngine.cs) +- The main computation is done in the [`CalculateEngine.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateEngine.cs) file using the `Mages` library. + +```csharp +var result = CalculateEngine.Interpret(query.Search, CultureInfo.CurrentUICulture); +``` + +### [`CalculateResult`](src/modules/launcher/Plugins/Microsoft.Plugin.Calculator/CalculateResult.cs) +- The class which encapsulates the result of the computation. +- It comprises of the `Result` and `RoundedResult` properties. + +### Score +The score of each result from the calculator plugin is `300`. + diff --git a/doc/devdocs/modules/launcher/plugins/folder.md b/doc/devdocs/modules/launcher/plugins/folder.md new file mode 100644 index 0000000000..2248b16d86 --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/folder.md @@ -0,0 +1,17 @@ +# Folder Plugin +The Folder plugin is used to navigate the directory structure and display the sub-folders and files within a folder. +![Image of Folder plugin](/doc/images/launcher/plugins/folder.png) + +### [`FolderHelper.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/FolderHelper.cs) +- The [`FolderHelper`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/FolderHelper.cs) class leverages the `DriveInformation` and `folderLinks` to get the folder results for a user query. +- The [`DriveInformation`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/DriveInformation.cs) class gets the list of all drives on the system. +- The [`FolderLink`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/FolderLink.cs) object corresponds to a user created link for frequently accessed projects. This was inherited from Wox but is presently not functional as we don't have the UI setup in settings to get this user input. Each folderLink object has a `nickname`, which is the name of the folder and this can be used to directly access that folder instead of entering the entire path. + +### [`IFolderProcessor.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IFolderProcessor.cs) +The `IFolderProcessor` utilizes the `FolderHelper` class to extract the folders and return the results. +There are two types of Folder Processors, based on the type of information they are processing - +1. [`UserFolderProcessor`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/UserFolderProcessor.cs) - This Processor is currently not used in PT Run but it is used to process the user created folder links. +2. [`InternalDirectoryProcessor`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/InternalDirectoryProcessor.cs) - This processor is used to retrieve the files and folders located within the current drive or shared folder. + +### Score +The first result is of score 500 and the following results are scored 10. \ No newline at end of file diff --git a/doc/devdocs/modules/launcher/plugins/indexer.md b/doc/devdocs/modules/launcher/plugins/indexer.md new file mode 100644 index 0000000000..63519a0583 --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/indexer.md @@ -0,0 +1,39 @@ +# Indexer Plugin +The indexer plugin is used to search for files within the indexed locations of the system. + +![Image of Indexer plugin](/doc/images/launcher/plugins/indexer.png) + +### [Drive Detection](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/DriveDetection) +- There are two indexing modes in Windows: + 1. **Classic mode**: Only the desktop and certain customizable locations in the system are indexed. All the systems have the classic mode enabled by default. + 2. **Enhanced Mode**: This mode indexes the entire PC when enabled. The user can exclude certain locations from being indexed in this mode from the Windows Search settings options. +- A drive detection warning is displayed to the users when only the custom mode is enabled on the system informing the user that not all the locations on their PC are indexed as this could lead to some results not showing up. +- The [`IndexerDriveDetection.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/DriveDetection/IndexerDriveDetection.cs) file gets the status of the drive detection checkbox in the settings UI and depending on whether the enhanced mode is enabled or disabled, displays the warning. +- To determine whether the `EnhancedMode` is enabled or not, we check the local machine registry entry for `EnableFindMyFiles`. If it is set to 1, the enhanced mode is enabled. + +### [`OleDBSearch`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs) +- The `Query` function within the [`OleDBSearch.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs) class takes in the query and the connection string to the SystemIndex catalog as arguments and returns a list of results. +- It first opens a [connection][OLEDBConnection] to the Windows Indexer database, creates an [OleDB command][OLEDBCommand] and executes the command to get a list of results. + +### [`WindowsSearchAPI`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/WindowsSearchAPI.cs) +- The [`WindowsSearchAPI`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/WindowsSearchAPI.cs) class leverages the [`OleDBSearch.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs) class to execute the query. +- It initializes the `QueryHelper` in the `InitQueryHelper()` function by creating a catalog manager to the SystemIndex catalog. +- The metadata is initialized within the query helper, such as the number of results to retrive, the type of information to retrieve for each file (currently we retrieve the item URL, the file name and the file attributes). +- The query helper matches results using the name of the file only and they are sorted by the last modified date, ensuring that the recently modified files are ranked higher. +- The File attributes are utilized to filter out hidden files from being displayed. + +### Additional Information +- There are two major types of queries generated by the indexer plugin: + 1. Full Text predicates - eg: [CONTAINS][Contains] + 2. Non-Full Text predicates - eg: [LIKE][Like] +- The Full text predicates are much faster than non-full text predicates as they are based on finding matches rather than comparing the query with each item in the indexer database. Hence, queries which have the `CONTAINS` keyword are much faster than those which contain the `LIKE` keyword. +- To prevent the indexer query from taking a long time and blocking the UI thread, there are two types of indexer queries which are executed. A simplified query and a full query, without and with the `LIKE` keyword respectively. +- The result list is updated with the results of the full query once they are obtained. + +### Score +Each of the indexer plugin results has a score set to 0 so they are present at the bottom of the list. + +[OLEDBCommand]: https://docs.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbcommand?view=dotnet-plat-ext-3.1 +[OLEDBConnection]: https://docs.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbconnection?view=dotnet-plat-ext-3.1 +[Contains]: https://docs.microsoft.com/en-us/windows/win32/search/-search-sql-contains +[Like]: https://docs.microsoft.com/en-us/windows/win32/search/-search-sql-like \ No newline at end of file diff --git a/doc/devdocs/modules/launcher/plugins/overview.md b/doc/devdocs/modules/launcher/plugins/overview.md new file mode 100644 index 0000000000..ea6233c6c4 --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/overview.md @@ -0,0 +1,35 @@ +# Structural Overview +The following basic functions are common to each of the plugins. They perform some rudimentary operations such as initialization of the plugin, executing the query that has been entered, loading context menu icons, updating settings when configurations are altered in the settings UI, and updating the theme of the icons when the theme changed event is triggered. + +## IPlugin Interface +Each plugin implements the `IPlugin` interface which comprises of the `Init()` and `Query()` functions. + +### `Init` +- The `Init()` function initializes the context, storage and settings of each plugin. This is equivalent to a contructor and is the first function to be called in the `Main.cs` file for each plugin. + +### `Query` +- For every query that the user enters into PT Run, the `PluginManager.cs` executes the `Query()` function in the `Main.cs` file corresponding to each Plugin. + +### Context Menu Icons +- The `ContextMenus` are loaded for each result based on the type of the result. +- The various types of `ContextMenu` functionalities are: + - Open containing folder + - Run as Administrator + - Open in console + - Copy path + +### UpdateSettings +- This function updates the settings of each plugin based on the changes made by the user in the settings UI. +- Eg: To disable drive detection in the indexer plugin, when the user checks or unchecks the drive detection check box, the `UpdateSettings()` function dispatches the changes in the check box to the plugin. + +### ThemeChanged +- This function is invoked when there is a change in the theme of PT Run. +- It is used to update the `IconPath` for each plugin based on the theme. + +### Save +- This function saves the configurations of each plugin so that they can be loaded the next time. + +### Score +- The user query is executed against each of the plugins and the result list view is updated with results from each of the plugins. +- The ordering of the results is based on the `Score` of each Result. +- Each plugin assigns a score to a result based on it's relevance. The results with higher scores are displayed higher in the list view and vice versa. \ No newline at end of file diff --git a/doc/devdocs/modules/launcher/plugins/program.md b/doc/devdocs/modules/launcher/plugins/program.md new file mode 100644 index 0000000000..80eb221797 --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/program.md @@ -0,0 +1,43 @@ +# Program Plugin +The program plugin as the name suggests is used to search for programs installed on the system. + +![Image of Program plugin](/doc/images/launcher/plugins/program.png) + +There are broadly two different categories of applications: + +1. Packaged applications +2. Win32 applications + +### [UWP](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWP.cs) +- The logic for indexing Packaged applications is present within the [`UWP.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWP.cs) file. +- There can be multiple applications present within a package. The [`UWPApplication.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs) file encapsulates the properties of a packaged application. +- To index packaged applications, the `PackageManager` retrives all the packages for the current user and indexes all the applications. +- To retrieve the app icon for packaged applications, the assets path is retrieved from the `Application Manifest` file. There are multiple icons corresponding to each scale, target size and theme. The best icon is chosen given the theme of powerToys Run. + +### [Win32Program](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs) +- Win32 programs in the following locations are indexed by PT Run- + 1. Desktop + 2. Public Desktop (Applications present on the desktop of all the users) + 3. Registry (Some programs) + 4. Start Menu + 5. Common start menu (Applications which are common to all users) + 8. Locations pointed to by the PATH environment variable. +- To prevent applications and shortcuts present in multiple locations from showing up as duplicate results, we consider apps with the same name, executable name and full path to be the same. +- The subtitle of the application result is set based on it's application type. It could be one of the following: + 1. Lnk Shortcuts + 2. Appref files + 3. Internet shortcut - steam and epic games + 4. PWAs + 5. Run commands - these are indexed by the PATH environment variable + +### Score +- The score for each application result is based on the how many letters are matched, how close the matched letters are to the actual word and the index of the matched characters. +- There is a threshold score to decide the apps which are to be displayed and applications which have a lower score are not displayed by PT Run. + +### Update Program List in Runtime +- Packaged and Win32 app helpers exist to reflect changes in the list of indexed apps when applications are installed on the system while PT Run is executing. +- Packaged applications trigger events when the package is being installed and uninstalled. PT Run listens to those events to index applications which are newly installed or to delete an app which no longer exists from the database. +- No such events exist for Win32 applications. We therefore use FileSystem Watchers to monitor the locations that we index for newly created, deleted or renamed application files and update the indexed Win32 catalog accordingly. + +### Additional Notes +- Arguments can be provided to the program plugin by entering them after `--` (a double dash). \ No newline at end of file diff --git a/doc/devdocs/modules/launcher/plugins/shell.md b/doc/devdocs/modules/launcher/plugins/shell.md new file mode 100644 index 0000000000..1b9b5b4672 --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/shell.md @@ -0,0 +1,14 @@ +# Shell Plugin +- Shell plugin emulates the Windows Run Prompt (Win+R). +- Shell Plugin is one of the non-global plugins which has an action keyword set to `>`. + +![Image of Shell plugin](/doc/images/launcher/plugins/shell.png) + +### Functionality +- The Shell command expands environment variables, so `>%appdata%` works as expected. +- On inheriting the Shell plugin from Wox, there are three different ways of executing a command, using the command prompt, powershell or the run prompt. To uphold the name of PT Run, the Shell plugin always executes commands as the Run prompt would. +- The Shell plugin has a concept of history where the previously executed commands show up in the drop down list along with the number of times they have been executed. +- The Run prompt has the folder plugin function where we can navigate to different locations and entering the path to a directory displays all the sub-directories. To prevent reimplementing this logic, the shell plugin references the folder plugin to implement this functionality. + +### Score +The Shell plugin results have a very high score of 5000. Hence, they are one of the first results in the list. diff --git a/doc/devdocs/modules/launcher/plugins/uri.md b/doc/devdocs/modules/launcher/plugins/uri.md new file mode 100644 index 0000000000..dec3362729 --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/uri.md @@ -0,0 +1,19 @@ +# URI Plugin +The URI Plugin, as the name suggests is used to dierctly run the URI that has been entered by the user as a query. This is done by parsing the entry and validating the URI, followed by executing it. + +![Image of URI plugin](/doc/images/launcher/plugins/uri.png) + +### [`URI Parser`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/ExtendedUriParser.cs) +- The [`ExtendedUriParser.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/ExtendedUriParser.cs) file tries to parse the user input and returns a `System.Uri` result by using the `UriBuilder`. +- It also captures other cases which the UriBuilder does not handle such as when the input ends with a `:`, `.` or `:/`. + +### [`URI Resolver`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/UriResolver.cs) +- The [`UriResolver.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/UriResolver.cs) file returns true for Valid hosts. +- Currently there is no additional logic for filtering out invalid hosts and it always returns true for a valid Uri that was created by parsing the user query. It can be expanded in the future to filter out certain hosts. + +### Default Browser Icon +- The icon for each uri result is that of the default browser set by the user. +- These details are obtained from the user registry and updated each time the theme of PT Run is changed. + +### Score +- All uri plugin results have a score of 0 which indicates that they would show up after each of the other plugins, other than the indexer plugin which also has a score of 0. diff --git a/doc/devdocs/modules/launcher/plugins/windowwalker.md b/doc/devdocs/modules/launcher/plugins/windowwalker.md new file mode 100644 index 0000000000..401cfa307a --- /dev/null +++ b/doc/devdocs/modules/launcher/plugins/windowwalker.md @@ -0,0 +1,18 @@ +# Window Walker plugin +The window walker plugin matches the user entered query with the open windows on the system. + +![Image of Window Walker plugin](/doc/images/launcher/plugins/windowwalker.png) + +### [`OpenWindows.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs) +- The window walker plugin uses the `EnumWindows` function to enumerate all the open windows in the [`OpenWindows.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs) class. + + +### [`SearchController.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs) +- The [`SearchController`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs) encapsulates the functions needed to search and find matches. +- It is responsible for updating the search text and performing a fuzzy search on all the open windows in an asynchronous manner. + +### [`Window.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) +- The [`Window`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) class represents a specific window and has functions to get the name of the process, the state of the window (whether it is visible or not), and the `SwitchTowindow` function which switches the desktop focus to the selected window. This action is performed when the user clicks on a window walker plugin result. + +### Score +The window walker plugin uses [`FuzzyMatching`](src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/FuzzyMatching.cs) to get the matching indices and calculates the score by creating a 2 dimensional array of the window and the query text. diff --git a/doc/devdocs/modules/launcher/project_structure.md b/doc/devdocs/modules/launcher/project_structure.md new file mode 100644 index 0000000000..b76976d5c5 --- /dev/null +++ b/doc/devdocs/modules/launcher/project_structure.md @@ -0,0 +1,24 @@ +# Project Structure +## Overview +`PowerToys Run` is divided across several projects to keep a logical separation between plugins and core functionality. The following sections provide a brief overview of each project. + +![Image of project dependency](/doc/images/launcher/launcher_dependency.PNG) +Fig 1. Project along with their dependencies in `PowerToys Run` ecosystem. + +## Project Description +#### [`PowerLauncher`](/src/modules/launcher/PowerLauncher) +This is the startup project for the `PowerToys Run.` It is a WPF desktop application and follows the `Model-View-ViewModel (MVVM)` design pattern. Plugins play the role of `Model` and provide data to `ViewModel.` + +#### [`PowerLauncher.Telemetry`](/src/modules/launcher/PowerLauncher.Telemetry) +[`PowerLauncher.Telemetry`](/src/modules/launcher/PowerLauncher.Telemetry) is a .net core project that contains telemetry events generated by `PowerLauncher.` These events have been discussed in detail [here](/doc/devdocs/modules/launcher/telemetry.md). + +#### [`Wox.Core`](/src/modules/launcher/Wox.Core) +[`Wox.Core`](/src/modules/launcher/Wox.Core) is a .net core project that contains helper classes required by the `PowerLauncher` project. Two major functionalities encapsulated in this project are [`PluginManager`](/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs) and [`Query Builder.`](/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs) [`PluginManager`](/src/modules/launcher/Wox.Core/Plugin/PluginManager.cs) provides an interface for managing C# plugins. [`Query Builder.`](/src/modules/launcher/Wox.Core/Plugin/QueryBuilder.cs) decimate user-typed query string and creates a [`Query`](/src/modules/launcher/Wox.Plugin/Query.cs) object. [`Query`](/src/modules/launcher/Wox.Plugin/Query.cs) object contains the action keyword and cleaned query, which is then sent to all plugins. + +#### [`Wox.Infrastructure`](/src/modules/launcher/Wox.Infrastructure) +[`Wox.Infrastructure`](/src/modules/launcher/Wox.Infrastructure) is a .net core project that contains helper classes required for logging, image manipulation, and storage by the `PowerLauncher` project and the plugins. [`ImageLoader.cs`](/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs) class is used to load icons for `Win32` program. It also provides caching functionality to speed up image loading for frequently queried programs. [`Log.cs`](/src/modules/launcher/Wox.Infrastructure/Logger/Log.cs) provides an abstraction for logging error, information, and output to text files. These files are stored at `%userprofile%/appdata/local/microsoft/powertoys/powertoys run/Logs.` + +#### [`Wox.Plugin`](/src/modules/launcher/Wox.Plugin) +[`Wox.Plugin`](/src/modules/launcher/Wox.Plugin) contains interfaces that facilitate communication between `PowerLauncher` and plugins. These interfaces have been discussed in detail [here](/doc/devdocs/modules/launcher/architecture.md#flow-of-data-between-viewmodels-and-pluginsmodel). + + diff --git a/doc/devdocs/modules/launcher/readme.md b/doc/devdocs/modules/launcher/readme.md new file mode 100644 index 0000000000..2267b8b688 --- /dev/null +++ b/doc/devdocs/modules/launcher/readme.md @@ -0,0 +1,14 @@ +# Table of Contents +1. [Architecture](/doc/devdocs/modules/launcher/architecture.md) +2. [Debugging](/doc/devdocs/modules/launcher/debugging.md) +3. [Project Structure](/doc/devdocs/modules/launcher/project_structure.md) +4. [Telemetry](/doc/devdocs/modules/launcher/telemetry.md) +5. Plugins + - [Overview](/doc/devdocs/modules/launcher/plugins/overview.md) + - [Calculator](/doc/devdocs/modules/launcher/plugins/calculator.md) + - [Folder](/doc/devdocs/modules/launcher/plugins/folder.md) + - [Indexer](/doc/devdocs/modules/launcher/plugins/indexer.md) + - [Program](/doc/devdocs/modules/launcher/plugins/program.md) + - [Shell](/doc/devdocs/modules/launcher/plugins/shell.md) + - [Uri](/doc/devdocs/modules/launcher/plugins/uri.md) + - [Window Walker](/doc/devdocs/modules/launcher/plugins/windowwalker.md) \ No newline at end of file diff --git a/doc/devdocs/modules/launcher/telemetry.md b/doc/devdocs/modules/launcher/telemetry.md new file mode 100644 index 0000000000..3e0c233517 --- /dev/null +++ b/doc/devdocs/modules/launcher/telemetry.md @@ -0,0 +1,14 @@ +# Telemetry +## Overview +`PowerLauncher.Telemetry` project contains telemetry events generated by `PowerToys Run.` These event classes are derived from the [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class and [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class. [`IEvent`](/src/common/ManagedTelemetry/Telemetry/Events/IEvent.cs) class provides the lowest level abstraction, containing attributes such as privacy tags needed for every telemetry data. [`EventBase`](/src/common/ManagedTelemetry/Telemetry/Events/EventBase.cs) class provides a higher-level abstraction, having attributes common to all `PowerToys` telemetry events. + +## Events +The following events are generated by `PowerLauncher`: +1. [`LauncherBootEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherBootEvent.cs): This event captures the time taken by `PowerLauncher` to load all plugins, perform cold start, and setup UI environment. +2. [`LauncherHideEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherHideEvent.cs): This event is generated when the `PowerLauncher` window is hidden. +3. [`LauncherColdStateHotkeyEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherColdStateHotkeyEvent.cs): This event logs time from the first Alt+Space press till the `PowerLauncher` window is visible. +4. [`LauncherFirstDeleteEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherFirstDeleteEvent.cs): This event is generated after the first delete is pressed after `PowerLauncher` is visible. +5. [`LauncherQueryEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherQueryEvent.cs): This event is generated for every query that is typed in the searchbox. It logs query time, number of results, and query length. +6. [`LauncherResultActionEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherResultActionEvent.cs): This event is generated when a context menu action is triggered. +7. [`LauncherShowEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherShowEvent.cs): This event is generated when the `PowerLauncher` window is shown. +8. [`LauncherWarmStateHotkeyEvent`](/src/modules/launcher/PowerLauncher.Telemetry/Events/LauncherWarmStateHotkeyEvent.cs): This event logs time from the Alt+Space press until the PT Run window is visible. \ No newline at end of file diff --git a/doc/images/launcher/launcher_dependency.PNG b/doc/images/launcher/launcher_dependency.PNG new file mode 100644 index 0000000000000000000000000000000000000000..dd28b85b0d5f9fab1d386d6419cc83ee34f9202f GIT binary patch literal 50844 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 literal 0 HcmV?d00001 diff --git a/doc/images/launcher/plugins/calculator.png b/doc/images/launcher/plugins/calculator.png new file mode 100644 index 0000000000000000000000000000000000000000..7d8810777455a638bf6550e7e036a7927c608363 GIT binary patch literal 49069 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

cW1twJ8?-(>PM-yFXm+a6>&MD{Rr;}f_KK@Y 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 R^|h;y;w#mc`7eyV{2wa}zGVOa literal 0 HcmV?d00001 diff --git a/doc/images/launcher/plugins/folder.png b/doc/images/launcher/plugins/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..ae707b1e222b5d8d42ed437395f5e95a68991ed9 GIT binary patch literal 124917 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� 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 J; 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 literal 0 HcmV?d00001 diff --git a/doc/images/launcher/plugins/program.png b/doc/images/launcher/plugins/program.png new file mode 100644 index 0000000000000000000000000000000000000000..a7583088b852da1c539a40e266f5861086b39bc6 GIT binary patch literal 89835 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 literal 0 HcmV?d00001 diff --git a/doc/images/launcher/plugins/shell.png b/doc/images/launcher/plugins/shell.png new file mode 100644 index 0000000000000000000000000000000000000000..556e82045a02cfab14afc3906fe58f5443c95894 GIT binary patch literal 51291 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 z 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 Z`+v|*6Dli5n8yGB002ovPDHLkV1h%L0R;d6 literal 0 HcmV?d00001 diff --git a/doc/images/launcher/plugins/windowwalker.png b/doc/images/launcher/plugins/windowwalker.png new file mode 100644 index 0000000000000000000000000000000000000000..cd1368f56a5158307c7e452e4d3e1d56d50d550e GIT binary patch literal 62294 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%0DHrXoXlW7R}Do}-1 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≤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%0A{1B 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�DKsaub<0e6;W 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�IiP1ePqdA3HW`9)KpzHAEC$~Ecwwu>x% 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 literal 0 HcmV?d00001 diff --git a/doc/devdocs/modules/keyboardmanager/keyboardeventhandlers.md b/doc/devdocs/modules/keyboardmanager/keyboardeventhandlers.md new file mode 100644 index 0000000000..8908f450e6 --- /dev/null +++ b/doc/devdocs/modules/keyboardmanager/keyboardeventhandlers.md @@ -0,0 +1,84 @@ +# Keyboard Event Handlers (Remapping Logic) +This file contains documentation for all the methods involved in key/shortcut remapping. + +## Table of Contents: +1. [HandleSingleKeyRemapEvent](#HandleSingleKeyRemapEvent) +2. [HandleShortcutRemapEvent](#HandleShortcutRemapEvent) +3. [HandleOSLevelShortcutRemapEvent](#HandleOSLevelShortcutRemapEvent) +4. [HandleAppSpecificShortcutRemapEvent](#HandleAppSpecificShortcutRemapEvent) +5. [HandleSingleKeyToggleToModEvent (Obsolete))](#HandleSingleKeyToggleToModEvent-(Obsolete---Code-from-PoC-which-is-commented-out)) +6. [Tests](#Tests) + 1. [MockedInput](#MockedInput) + 2. [Tests for single key remaps and shortcut remaps](#Tests-for-single-key-remaps-and-shortcut-remaps) + +## HandleSingleKeyRemapEvent +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L13-L124) is used for handling the key to key and key to shortcut remapping logic. The general logic is as follows: +- Check if the `dwExtraInfo` field contains the `KEYBOARDMANAGER_INJECTED_FLAG` bit set. This bit is used to indicate that the key event was generated by KBM using `SendInput`. This ensures that we don't read events generated by the key or shortcut remap methods. +- Check if the current key is present in the list of remaps. If it isn't, return 0 (i.e. do not suppress the event). +- If it is remapped to Disable, suppress the event. +- If it is remapped to a key, we send the key down/up message for the target key and suppress the current key event. We have a check for filtering artificial keys, such as `VK_WIN` (which is a keycode added by us), so that it is translated to `VK_LWIN` instead. +- If it is remapped to a shortcut, for key down we set the target modifiers first, followed by the target action key, and for key up we release the action key first, followed by the modifiers. +- All the remapped key events that we send above are sent with `KEYBOARDMANAGER_SINGLEKEY_FLAG` on the `dwExtraInfo` field. + +## HandleShortcutRemapEvent +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L178-L739) is used for handling the shortcut to shortcut and shortcut to key remapping logic. The general logic is as follows: +- Check if any shortcut remap is currently invoked. This is required to ensure that two remaps don't occur simultaneously at a time, and we send key up events for the shortcuts only if they are actually invoked and not for artificial key up events. In addition to that, while a remap is in the middle of execution, the keyboard state will not match the physical keys, so we do not want a remap Ctrl+A to Ctrl+V to also trigger the remap from Ctrl+V to Alt+V on pressing Ctrl+A on the keyboard. +- Get the remap table as per the the `activatedApp` argument (i.e. if it is empty, we get the global shortcut remap table and otherwise we get the corresponding app-specific shortcut remap table). +- Iterate over the list of remaps in descending order of number of keys in the shortcut. This is required **for shortcut to key remaps** to ensure that if a user has both Ctrl+A and Ctrl+Shift+A remapped to some keys, and the user presses Ctrl+Shift+A, then we prefer the Ctrl+Shift+A remap. This logic would not be required if there were only shortcut to shortcut remaps, as they are invoked only on exact match. +- If any shortcut was found to be invoked (from the first step), then we skip till we find the matching shortcut remap. If not we check if the modifiers of the original shortcut are pressed down. If they are, we check if the current key event is a key down event and it matches the action key of the original shortcut. For shortcut to shortcut and for disabling a shortcut [we have an additional step](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L208-L212) where we check if any other key is pressed apart from the original shortcut. This is required because for these two features we allow the remaps only if those exact keys are pressed. The method used for this is described in detail [here](keyboardmanagercommon.md#IsKeyboardStateClearExceptShortcut). If a win key was pressed, we store whether it was the left or the right one, in order to determine which key to set for remaps from/to the common Win key code which we added. This is so that pressing and releasing Left Win key results in that Win key getting modified and not the Right Win key. + - If the remap is to a key, we send a dummy key event followed by releasing the original shortcut's modifiers and setting the target key (or doing nothing if it is remapped to disable) and we suppress the event. + - If the remap is to a shortcut, if the modifiers in the original shortcut are present in the target, we only set the additional modifiers and the action key of the target. If it isn't, we send a dummy key event followed by releasing the modifiers which are not common, and setting the remaining ones in the target along with the action key. + - For both cases, we set the `isShortcutInvoked` flag to true, and set the `KeyboardManagerState.activatedApp` if it is an app-specific shortcut remap. +- For the `isShortcutInvoked` is true scenario (i.e. the initial remap keydown section is done) there are several cases depending on the key pressed or released: + - [**Case 1:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L339-L430) If a modifier in the original shortcut is released, we need to reset back to the physical keys pressed. + - For remap to shortcut, we release the target action key if it is currently pressed, and depending on whether all the modifiers of the original shortcut are present in the target, we release the target modifiers that are not common, and set the remaining original shortcut modifiers except the one that was released. We do not need to send the original action key as that will get generate it's own key event if it is held down. + - For remap to key, we release the target key if it is pressed (and it is not remapped to Disable), and we set the original shortcut modifiers. + - For both the cases we send a dummy key event at the end, since we are setting modifiers without any other key after that, and we reset all the remap variables. + - [**Case 2:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L435-L461) If the original shortcut's action key is pressed again, we send the target shortcut's action key or the target key again (or for disable we just suppress the event). + - [**Case 3:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L463-L527) If the original shortcut's action key is released + - For remap to shortcut, we just release the target shortcut's action key + - For remap to disable, we suppress the event + - For remap to key, we check if any other keys are pressed apart from the target key. If not, we just release the target key. If there are, we reset back to the physical keys by releasing the target key and setting the original shortcut's modifiers along with a dummy key, and we reset all the remap variables. This behavior is different from remap to shortcut because if the action key is released while other keys are pressed the remap should be inactive, but such a state can't occur for shortcut to shortcut remaps since they happen only when the exact keys are pressed. + - [**Case 4:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L529-L551) If a modifier in the original shortcut is pressed, suppress the event + - [**Case 5:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L553-L732) If any other key is pressed + - For remap to shortcut, we need to reset back to physical keys as the shortcut remaps can't be pressed in combination with other keys. We release the target action key if it was pressed, and we release the modifier keys of the target shortcut that are not common and set the remaining ones in the original shortcut. We then send the original shortcut's action key if the target action key was found to be pressed, and we send the current key press at the end. + - For remap to key, if it is remapped to disable or if the target key is not found to be pressed, we reset to the physical keys, we set the original shortcut's modifiers and if is remap to Disable and the original shortcut's action key is physically pressed (this is checked by the `isOriginalActionKeyPressed` flag which we keep track of whenever the action key is pressed or released for remap to Disable), then we set the original shortcut's action key, followed by the current key press. If it is not remapped to disable and the target key is pressed, then we don't suppress the event as we allow shortcut to key remappings to be pressed along with other keys. + - For all the above cases, dummy key isn't required as we want the current key press to behave like a normal key. + - [**Case 6:**](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L733) If any other key is released, do not suppress the event as this event didn't appear with a corresponding key down event (such as an app sending a key up event) or we processed the key down and let it continue (for shortcut to key scenario). +- All the remapped key events that we send above are sent with `KEYBOARDMANAGER_SHORTCUT_FLAG` on the `dwExtraInfo` field, except the usage of the current key press in Case 5, for which we don't send any extra info so that it is considered as a normal key event which may in turn invoke some other remap. + +**Note:** Shortcuts are considered valid if they have modifiers and an action key. The reason why we haven't supported key combinations of just modifiers (which is requested in this [issue](https://github.com/microsoft/PowerToys/issues/5670)) (like remapping Ctrl+Alt) is because this would require more cases and handling as these remappings have to take place only on press and release and if there is no key pressed in between similar to what Start Menu does. The remapping would have to be invoked only for this specific sequence Ctrl key down, Alt key down, Alt key up, Ctrl key up (ordering between Ctrl and Alt can be swapped). If any other key is pressed in between it shouldn't be invoked, and since this logic requires tracking exact states instead of using GetAsyncKeyStates, this could cause false positives if a user is not running as admin. + +## HandleOSLevelShortcutRemapEvent +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L741-L752) is used for handling global shortcut to shortcut and shortcut to key remaps. The general logic is as follows: +- Check if the `dwExtraInfo` field is set to `KEYBOARDMANAGER_SHORTCUT_FLAG`. This indicates that the key event was generated by the KBM shortcut remap method using `SendInput`. This ensures that we don't read events generated by the shortcut remap method, but we still read events which are generated by the key remap method. +- Call `HandleShortcutRemapEvent` without the `activatedApp` argument so that global shortcut remapping takes place if it applies for the current key event. + +## HandleAppSpecificShortcutRemapEvent +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L754-L809) is used for handling app-specific shortcut to shortcut and shortcut to key remaps. The general logic is as follows: +- Check if the `dwExtraInfo` field is set to `KEYBOARDMANAGER_SHORTCUT_FLAG`. This indicates that the key event was generated by the KBM shortcut remap method using `SendInput`. This ensures that we don't read events generated by the shortcut remap method, but we still read events which are generated by the key remap method. +- Get the name of the process in the foreground. This is done using `GetCurrentApplication` which uses `GetForegroundWindow` to get the window handle and `get_process_path` from the common lib. This approach can fail for UWP apps in full screen, so for that scenario we use the `GetGUIThreadInfo` approach to find the correct window handle, and hence the correct process name. This method is described in more detail [here](keyboardmanagercommon.md#Foreground-app-detection) +- By checking `KeyboardManagerState.GetActivatedApp` we check if an app-specific shortcut is currently invoked. If so, we consider this application to be the activated app. This is required because some shortcut remaps could cause the current app to lose focus and hence until the shortcut is completely released we should allow that remap to continue, otherwise the user could end up in a state where some keys do not get released. For example: remap Ctrl+A to Alt+Tab for Edge, when a user presses Ctrl+A the window loses focus as Alt+Tab gets executed. +- If there is no app-specific shortcut currently invoked, we check if the foreground process is present in the list of app-specific remaps, either with or without the file extension and case insensitive. If it is, this is considered to be the activated app. +- Call `HandleShortcutRemapEvent` with the `activatedApp` argument so that app-specific shortcut remapping takes place if it applies for the current key event. + +## HandleSingleKeyToggleToModEvent (Obsolete - Code from PoC which is commented out) +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L126-L176) was added to support a feature for converting the behavior of a key from behaving like a toggle (like Caps Lock/Num Lock) to a modifier (like Ctrl), such that when you hold Caps Lock it would behave as if Caps Lock was active, and when it was not pressed Caps Lock would be off. For Caps Lock this would be similar to behaving like Shift, but for Num Lock there is no existing key which can substitute for this. This was added while testing out remapping for the KBM PoC, but wasn't added as a feature since it wasn't a priority. + +## Tests +In order to test the remapping logic, a mocked keyboard input handler had to be created because otherwise the tests would process and send actual key events. For this the [`InputInterface`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/InputInterface.h) was made, and in production code the methods are implemented using [`SendInput`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput) and [`GetAsyncKeyState`](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate). In addition to this, [`GetCurrentApplication`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L226-L268) had to be mocked so that app-specific remapping can be tested. + +### MockedInput +The [`MockedInput`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/MockedInput.h) class uses a 256 size `bool` vector to store the key state for each key code. Identifying the foreground process is mocked by simply setting and getting a string value for the name of the current process. + +[To mock the `SendInput` method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/MockedInput.cpp#L10-L110), the steps for processing the input are as follows. This implementation is based on public documentation for SendInput and the behavior of key messages and keyboard hooks: +- Iterate over all the inputs in the INPUT array argument +- If the event is a key up event, then it is considered [`WM_SYSKEYUP`](https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-syskeyup) if Alt is held down, otherwise it is `WM_KEYUP`. +- If the event is a key down event, then it is considered [`WM_SYSKEYDOWN`](https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-syskeydown) if either Alt is held down or if it is F10, otherwise it is `WM_KEYDOWN`. +- An optional function which can be set on the `MockedInput` handler can be used to test for the number of times a key event is received by the system with a particular condition using [`sendVirtualInputCallCondition`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/MockedInput.cpp#L48-L52). +- The hook logic for a low level hook which returns 0 or 1 can be set on the `MockedInput` handler such that it behaves like a low level hook would behave with actual keyboard input. If the method returns 1, then the keyboard state is not updated, and if it returns 0 the corresponding key event is used to update the key state. This works in the recursive way as well similar to low level hooks, as `SendVirtualInput` can be called from within the hook, thus simulating identical behavior to calling `SendInput` in a low level hook (as soon as SendInput is called, the low level hook is called for the new input event, and only after those are processed it returns back to the current event, check this [blog](https://devblogs.microsoft.com/oldnewthing/20140213-00/?p=1773) for more details). +- For updating the keyboard state, KEYUP messages result in the state for that key code being set to false, and KEYDOWN result in the state for that key code being set to true. +- For modifiers the behavior is slightly different as if the key state of the L/R version is modified, it should also modify the common version, and if a common version is released, it should release both the L and R versions. + +### Tests for single key remaps and shortcut remaps +Using the MockedInput handler, all the expected (and known) key scenarios that can occur for while pressing a [remapped key](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/SingleKeyRemappingTests.cpp) or [remapped shortcut](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp) are tested. The foreground app behavior which is specific to app-specific shortcuts is tested [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/AppSpecificShortcutRemappingTests.cpp). diff --git a/doc/devdocs/modules/keyboardmanager/keyboardmanager.md b/doc/devdocs/modules/keyboardmanager/keyboardmanager.md new file mode 100644 index 0000000000..3dd5304eff --- /dev/null +++ b/doc/devdocs/modules/keyboardmanager/keyboardmanager.md @@ -0,0 +1,199 @@ +# Keyboard Manager module +This file contains the documentation for the KeyboardManager PowerToy module which is called by the runner. +## Table of Contents: +1. [Class members](#Class-members) +2. [Enable/Disable](#Enable/disable) +3. [Settings format](#Settings-format) +4. [Loading settings](#Loading-settings) +5. [Low level keyboard hook handler](#Low-level-keyboard-hook-handler) +6. [Custom Action to launch KBM UI](#Custom-Action-to-launch-KBM-UI) +7. [SendInput Special Scenarios](#SendInput-Special-Scenarios) + 1. [Extended keys](#Extended-keys) + 2. [Scan code](#Scan-code) +8. [Special Scenarios](#Special-Scenarios) + 1. [Dummy key events](#Dummy-key-events) + 2. [Suppressing Num Lock in a keyboard hook](#Suppressing-Num-Lock-in-a-keyboard-hook) + 3. [Modifier-Caps Lock interaction on Japanese IME keyboards](#Modifier-Caps-Lock-interaction-on-Japanese-IME-keyboards) + 4. [UIPI Issues (not resolved)](#UIPI-Issues-(not-resolved)) +9. [Other remapping approaches](#Other-remapping-approaches) + 1. [Registry approach](#Registry-approach) + 2. [Driver approach](#Driver-approach) +10. [Telemetry](#Telemetry) + +## Class members +The `KeyboardManager` module has [3 main class members](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L54-L61): +- A static pointer to the current object of `KeyboardManager`. This is required for using the `KeyboardManager` object in the low level keyboard hook handler as that method must be static. This is described in more detail in [this section](#Low-level-keyboard-hook-handler). +- An object of type `Input`, which is used for all the operations that involving getting or setting keyboard states. This is wrapped in an object to allow testing the remapping methods. +- An object of type `KeyboardManagerState`. This object contains all the data related to remappings and is also used in the sense of a View Model as it used to communicate common data that is shared between the KBM UI and the backend. This class is described in more detail [here](keyboardmanagercommon.md#keyboardmanagerstate). + +## Enable/Disable +On enabling KBM, the low level keyboard hook is started, and it is unhooked on disable. This is done to allow users to manually restart KBM if some other application which registers a keyboard hook was launched after PowerToys, so that it can be brought back to the highest priority hook (as the last hook to be registered receives the input first as mentioned [here](https://docs.microsoft.com/en-us/windows/win32/winmsg/about-hooks#hook-procedures)). + +In addition to stopping the hook, any active KBM UI windows are also closed on disabling. This is done because the KBM UI uses the same keyboard hook for the Type button where you can type a key/shortcut, so if KBM is disabled the windows would not be completely functional. + +The enable/disable code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L301-L322) + +## Settings format +KBM uses two sets of settings files. +- The main `settings.json` is of the following format: + + { + "properties": + { + "activeConfiguration": + { + "value":"default" + }, + "keyboardConfigurations": + { + "value":["default"] + } + }, + "name":"Keyboard Manager", + "version":"1" + } + + - The `activeConfiguration` attribute stores the current remapping profile, while `keyboardConfigurations` stores all the profiles that the user has. This was added to avoid any future breaking changes for the [profiles feature](https://github.com/microsoft/PowerToys/issues/1881), which would allow users to switch between remappings +- The profile format (`default.json`) is of the following format: + + { + "remapKeys": + { + "inProcess": + [ + { + "originalKeys":"91", + "newRemapKeys":"162;70" + }, + { + "originalKeys":"92", + "newRemapKeys":"162;70" + } + ] + }, + "remapShortcuts": + { + "global": + [ + { + "originalKeys":"164;37", + "newRemapKeys":"162;65" + }, + { + "originalKeys":"162;68", + "newRemapKeys":"91" + } + ], + "appSpecific": + [ + { + "originalKeys":"91;162;65", + "newRemapKeys":"162;86", + "targetApp":"msedge" + } + ] + } + } + + - `originalKeys` stores the key/shortcut which is to be pressed for the remap, and `newKeys` stores the key/shortcut which is to be executed. + - Both contain semi-colon separated virtual key codes. For `remapKeys`, `originalKeys` must have only one key code, whereas for `remapShortcuts` it must have atleast two key codes. + - `inProcess` sub-key was added in `remapKeys` because there was a possibility of adding the registry based remapping approach (used by [SharpKeys](https://github.com/randyrants/sharpkeys)), so that would be under a separate sub-key while `inProcess` would be for keyboard hook based remaps. This was deprioritized as there weren't enough requests for it. + - `remapShortcuts` is split into `global` and `appSpecific`, where `global` remaps would apply to all applications, whereas `appSpecific` would apply on when the `targetApp` is in focus. `targetApp` must be the process name of the app (with or without it's extension), e.g. `msedge` or `msedge.exe` for Microsoft Edge. + +## Loading settings +KBM settings are loaded only on the C++ side only at start up, in the [constructor](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L67-L68). The settings file may get modified from the KBM UI on applying new remappings, but the the file is not read again. The files are read from the PowerToys Settings process whenever a change is made to the file (using a FileWatcher) or whenever the KBM page is opened. The settings are updated only when the user presses the OK button from either of the Remap Keys or Remap Shortcuts windows. This is described in more detail [here](keyboardmanagerui.md#ok-and-cancel-button). + +## Low level keyboard hook handler +Since the [`hook_proc`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L330-L349) cannot be a member function in the class, this is declared `static` and a `static pointer` to the `KeyboardManager` project is used ([`keyboardmanager_object_ptr`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L54-L55)). + +As seen in the code for `hook_proc`, similar to other keyboard hooks in PowerToys it consists of a main method `HandleKeyboardHookEvent` which computes whether the key needs to be suppressed and accordingly returns 1 or calls the `CallNextHook` method. + +`HandleKeyboardHookEvent` is covered in the [next section](#HandleKeyboardHookEvent). The `SetNumLockToPreviousState` code in the above snippet is required for a special scenario with keyboard input, which is covered in [this section](#Suppressing-Num-Lock-in-a-keyboard-hook). + +## HandleKeyboardHookEvent +The [`HandleKeyboardHookEvent`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L384-L458) is the method which calls the corresponding remapping methods in the required order. The following checks are executed in order: +- **`KeyboardManagerState.AreRemappingsEnabled`:** This returns false while the KBM remap tables are getting updated. If it is in this state, `HandleKeyboardHookEvent` returns `0`, i.e. the key event is not suppressed and is forwarded normally. +- **Check for `KEYBOARDMANAGER_SUPPRESS_FLAG`:** If the key event has the suppress flag, the method returns 1 to suppress the key event. +- **[`KeyboardManagerState.DetectSingleRemapKeyUIBackend`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L399-L408):** This method is used for handling hook operations for the single key Type UI in the Remap keys window. If the Remap keys window is open, then `HandleKeyboardHookEvent` returns `0` and the key event is forwarded normally. If the left column Type button is clicked on the Remap keys window and and the window is in focus, then the key event is suppressed and the UI is updated with the latest key from the recent key events. This method is described in more detail [here](keyboardmanagercommon.md#DetectSingleRemapKeyUIBackend-and-DetectShortcutUIBackend). +- **[`KeyboardManagerState.DetectShortcutUIBackend(data, true)`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L410-L419):** This method is used for handling hook operations for the shortcut Type UI in the Remap keys window (when `isRemapKey` arg is `true`). If the Remap keys window is open, then `HandleKeyboardHookEvent` returns `0` and the key event is forwarded normally. If the right column Type button is clicked on the Remap keys window and and the window is in focus, then the key event is suppressed and the UI is updated with the shortcut from the recent key events. This method is described in more detail [here](keyboardmanagercommon.md#DetectSingleRemapKeyUIBackend-and-DetectShortcutUIBackend). +- **`HandleSingleKeyRemapEvent`:** This method handles the single key remap logic. If a remapping takes place, the key event is suppressed. This method is described in more detail [here](keyboardeventhandlers.md#HandleSingleKeyRemapEvent). +- **[`KeyboardManagerState.DetectShortcutUIBackend(data, false)`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L430-L439):** This method is used for handling hook operations for the shortcut Type UI in the Remap shortcuts window (when `isRemapKey` arg is `false`). If the Remap shortcuts window is open, then `HandleKeyboardHookEvent` returns `0` and the key event is forwarded normally. If the Type button is clicked on the Remap shortcuts window and and the window is in focus, then the key event is suppressed and the UI is updated with the shortcut from the recent key events. **Since this is executed after the single key remap method, all single key remappings are applied when the user is on the Remap shortcuts window.** +- **`HandleAppSpecificShortcutRemapEvent`:** This method handles the app-specific shortcut remap logic. If a remapping takes place, the key event is suppressed. This method is described in more detail [here](keyboardeventhandlers.md#HandleAppSpecificShortcutRemapEvent). **Since this is executed after the single key remap method, single key remappings have precedence over shortcut remaps and are correspondingly reflected in shortcut remaps.** +- **`HandleOSLevelShortcutRemapEvent`:** This method handles the global shortcut remap logic. If a remapping takes place, the key event is suppressed. This method is described in more detail [here](keyboardeventhandlers.md#HandleOSLevelShortcutRemapEvent). The app-specific remap method is executed before this because if a shortcut is remapped to different keys/shortcuts for a particular app and globally, the app-specific variant should be preferred if that app is in focus. **Since this is executed after the single key remap method, single key remappings have precedence over shortcut remaps and are correspondingly reflected in shortcut remaps.** + +**Note:** Single key remaps need to be executed before shortcut remaps, because otherwise there can be several logical issues. For example if a user has Ctrl remapped to X and Ctrl+A remapped to Y, we can't detect Ctrl+A because the moment Ctrl is pressed it would be remapped to X before the system ever sees Ctrl+A. This is why the design decision was made to separate Remap keys and Remap shortcuts, and all key remaps are reflected in the shortcut remaps. + +## Custom Action to launch KBM UI +KBM uses the [`call_custom_action`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L249-L280) method from the `PowertoyModuleIface` in order to launch the KBM UI when the user clicks the Remap a key or Remap a shortcut button from the KBM settings page. On clicking the button, we check if there is already any active KBM UI window, and if there is it is brought to the foreground. If not, the corresponding KBM UI window is launched on a separate detached thread. The UI is described in more detail [here](keyboardmanagerui.md). + +## SendInput Special Scenarios + +### Extended keys +Certain keys such as the arrow keys, right Ctrl/Alt, and Del/Home/Ins, etc need to be sent with the `KEYEVENTF_EXTENDEDKEY` flag because otherwise the NumPad versions get sent, which can cause weird behavior when NumLock is on. The code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L190-L194) and the list of extended keys in code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L73-L98). Docs about extended keys can be found [here](https://docs.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#extended-key-flag). + +The weird behavior that is caused by this can be found at these issues: +- https://github.com/microsoft/PowerToys/issues/3478 +- https://github.com/microsoft/PowerToys/issues/3647 +- https://github.com/microsoft/PowerToys/issues/3981 + +### Scan code +Certain applications (such as Windows Terminal) may filter out key events which are set to scan code 0. Even though the `KEYEVENTF_SCANCODE` flag is not set, the `wScan` field is still sent, which defaults to 0. To avoid this issue we use the `MapVirtualKey` API to find the scan code from the virtual key code. Code can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L196-L198). + +## Special Scenarios +Since we are using low level keyboard hooks and not actual OS level input handling certain scenarios with input require workarounds as do they not interact well with the OS input logic directly. These are covered in the sub-sections below. + +### Dummy key events +To prevent the behavior that some modifiers have that occur when you press and release the modifier without pressing any key in between, we need to send a dummy key event in between the two states. Some examples of this behavior are Win key for Start Menu and Alt key to focus the menu bar. We need to send the dummy key events at any point where an unintentional modifier press/release sequence may occur. We use the undocumented `0xFF` virtual key code for this as we haven't found any side effects of using this key code yet. Initially we used only a key up message, but it has been tweaked now to send a key down followed by key up (code can be found (here)[https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L201-L208]), as without the key down there were [compatibility issues with some apps](https://github.com/microsoft/PowerToys/issues/7133) (like Slack). + +The dummy key event is currently used in the following places (the linked code snippets contains an example scenario of why it is required): +- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L251-L253 +- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L289-L291 +- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L382-L383 +- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L409-L410 +- https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L509-L510 + +### Suppressing Num Lock in a keyboard hook +The Num Lock key state is updated by the OS before it is intercepted by low level hooks. This causes the issue that even if you suppress a Num Lock key event, Num Lock will still get toggled. In order to work around this, in the [`hook_proc`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L340-L344) whenever we suppress a Num Lock key down event, we send an additional Num Lock key up followed by key down so that the Num Lock state is reverted to it's previous value before the suppressed event. These are sent with a `KEYBOARDMANAGER_SUPPRESS_FLAG` in the `dwExtraInfo` field, so that we suppress them at the start of the hook (see code [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L811-L825)). Since these events will update the Num Lock state before the low level hooks, by suppressing them we ensure that these are not sent to any other hooks/applications and hence are only processed by the OS. + +This assumes that KBM is the last hook to be registered (since another hook-based app like AutoHotkey could remap NumLock to some other key which could mess up this logic). + +### Modifier-Caps Lock interaction on Japanese IME keyboards +While using Japanese IME on Windows, shortcuts like Shift/Alt/Ctrl + Caps Lock can be used to switch IME options. + +![japanese-ime](japanese-ime.png) + +These shortcuts are detected before low level hooks, and hence cause issues while remapping Caps Lock to Shift/Alt/Ctrl or vice-versa, as there could be an intermediate state where the system detects both the keys as being pressed. This results in a state where the modifier key does not get released since the OS suppresses the key up messages before they reach the low level hooks. + +In order to work around this when a key down for the modifier is being processed, we send a key up for the modifier key with the `KEYBOARDMANAGER_SUPPRESS_FLAG` in the `dwExtraInfo` field, so that we suppress them at the start of the hook, and this key event would only be processed by the OS, without getting forwarded to other hooks/apps. The approach is described in more detail at [this comment](https://github.com/microsoft/PowerToys/issues/3397#issuecomment-640136416), as discussed with the AutoHotkey team. The code for the workaround can be found [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L827-L846). Tests for these scenarios have also been added at: +- [Tests for workaround on single key remaps](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/SingleKeyRemappingTests.cpp#L110-L219) +- [Tests for workaround on shortcut remaps](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/test/OSLevelShortcutRemappingTests.cpp#L1935-L2144) + +For example, while [remapping Ctrl to Caps Lock](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L59-L63), before sending the Caps Lock key down message and suppressing Ctrl, we send a suppressed Ctrl key up, so that the OS doesn't see Ctrl and Caps Lock pressed together at any point. For the [Caps Lock to Ctrl scenario](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L104-L116), we send a suppressed CCtrltrl key up message after sending Ctrl key down before Caps Lock suppressed. Similar logic is added for such scenarios in shortcut remapping. + +While the above work around fixes most of the cases, there are still some scenarios where the modifier can get stuck, mentioned at this [comment](https://github.com/microsoft/PowerToys/issues/3397#issuecomment-663729278), which is why the issue is still open. This occurs if a modifier is pressed after the remap has been invoked before releasing the remapped key and it is a harder scenario to solve which requires refactoring the single key remap code. + +### UIPI Issues (not resolved) +`SendInput` does not work directly with certain key codes such as Play/Pause Media, Calculator key, etc as it requires UAC privileges to be injected to the OS and accordingly play the active media app or launch the Calculator app. In order to resolve this the correct approach is that the executable which calls `SendInput` needs to have the [UIAccess flag](https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-securityoverview) set to true, which will also avoid the requirement of KBM having to run as administrator to intercept key events when an elevated window is in focus. The UIAccess flag has many constraints such as it must be a signed executable and must be located in a protected path like Program Files. Since KBM currently runs out of the runner process, it would make more sense to do this work after KBM is moved to a separate executable, and it could be enabled by a separate toggle in settings only if PowerToys is installed in Program Files. [This comment](https://github.com/microsoft/PowerToys/issues/3192#issuecomment-646323661) has more details on this approach and (this)[https://github.com/microsoft/PowerToys/issues/3255] is the tracking issue. + +## Other remapping approaches +Other approaches for remapping which were deprioritized are: + +### Registry approach +This method is used by [SharpKeys](https://github.com/randyrants/sharpkeys) and involves using the [Microsoft Keyboard Scancode mapper registry key](https://github.com/randyrants/sharpkeys) to remap keys based on their scan codes. This has the advantage of being applied in all scenarios and not facing any elevation or UAC issues, however the disadvantages are that for modifying the settings the process must run elevated (as it modifies HKLM registry) and it requires a reboot to get applied. Another issue which is an advantage/disadvantage for users is that the process does not need to be running, so the remaps are applied all the time, including at the password prompt on logging in to the user's Windows account, which could get a user stuck if they orphaned a key in their password. This registry doesn't have any support for remapping shortcuts either, so the hook approach was prioritized over this. + +### Driver approach +Using a driver approach has the benefit of not depending on precedence orders as KBM could always run before low level hooks, and it also has the benefit of differentiating between different keyboards, allowing [multi keyboard-specific remaps](https://github.com/microsoft/PowerToys/issues/1460). The disadvantages are however that any bug or crash could have system level consequences. [Interception](https://github.com/oblitum/Interception) is an open source driver that could be used for implementing this. The approach was deprioritized due to the potential side effects. + +## Telemetry +Keyboard Manager emits the following telemetry events (implemented in [trace.h](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/trace.h) and [trace.cpp](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/trace.cpp)): +- **`KeyboardManager_EnableKeyboardManager`:** Logs a `boolean` value storing the KBM toggle state. It is logged whenever KBM is enabled or disabled (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L305-L316)). +- **`KeyboardManager_KeyRemapCount`:** Logs the number of key to key and key to shortcut remaps (i.e. all the remaps on the Remap a key window). This gets logged on saving new settings in the Remap a key window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L159-L163)). +- **`KeyboardManager_OSLevelShortcutRemapCount`:** Logs the number of global shortcut to shortcut and shortcut to key remaps. This gets logged on saving new settings in the Remap a shortcut window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L220)). +- **`KeyboardManager_AppSpecificShortcutRemapCount`:** Logs the number of app-specific shortcut to shortcut and shortcut to key remaps. This gets logged on saving new settings in the Remap a shortcut window (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/LoadingAndSavingRemappingHelper.cpp#L221)). +- **`KeyboardManager_KeyToKeyRemapInvoked`:** Logs an event when a key to key remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L101-L102)). +- **`KeyboardManager_KeyToShortcutRemapInvoked`:** Logs an event when a key to shortcut remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L101-L102)). +- **`KeyboardManager_OSLevelShortcutToShortcutRemapInvoked`:** Logs an event when a global shortcut to shortcut remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)). +- **`KeyboardManager_OSLevelShortcutToKeyRemapInvoked`:** Logs an event when a global shortcut to key remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)). +- **`KeyboardManager_AppSpecificShortcutToShortcutRemapInvoked`:** Logs an event when an app-specific shortcut to shortcut remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)). +- **`KeyboardManager_AppSpecificShortcutToKeyRemapInvoked`:** Logs an event when an app-specific shortcut to key remap is invoked (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/KeyboardEventHandlers.cpp#L320-L321)). +- **`KeyboardManager_Error`:** Logs the occurrence of an error in KBM with the name of the method, error code and the corresponding error message. This is currently used only for logging `SetWindowsHookEx` failures (emitted [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L364-L369)). diff --git a/doc/devdocs/modules/keyboardmanager/keyboardmanagercommon.md b/doc/devdocs/modules/keyboardmanager/keyboardmanagercommon.md new file mode 100644 index 0000000000..dbdfe930f3 --- /dev/null +++ b/doc/devdocs/modules/keyboardmanager/keyboardmanagercommon.md @@ -0,0 +1,63 @@ +# Keyboard Manager Common +This project contains any code that is to be shared between the backend and UI projects. This file covers any functionality in this project which hasn't been covered along with the other modules. + +## Table of Contents +1. [KeyboardManagerState](#KeyboardManagerState) + 1. [UI States](#UI-States) + 2. [DetectSingleRemapKeyUIBackend and DetectShortcutUIBackend](#DetectSingleRemapKeyUIBackend-and-DetectShortcutUIBackend) + 3. [HandleKeyDelayEvent](#HandleKeyDelayEvent) + 4. [Saving remappings to file](#Saving-remappings-to-file) + 5. [Concurrent Access to remap tables](#Concurrent-Access-to-remap-tables) +2. [KeyDelay](#KeyDelay) +3. [Shortcut and RemapShortcut classes](#Shortcut-and-RemapShortcut-classes) + 1. [IsKeyboardStateClearExceptShortcut](#IsKeyboardStateClearExceptShortcut) + 2. [CheckModifiersKeyboardState](#CheckModifiersKeyboardState) + 3. [Tests](#Tests) +4. [Helpers](#Helpers) + 1. [Foreground App Detection](#Foreground-App-Detection) + +## KeyboardManagerState +[This class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/KeyboardManagerState.cpp) stores all the data related to remappings and is also used in the sense of a View Model as it used to communicate common data that is shared between the KBM UI and the backend. They are accessed on the UI controls using static class members of `SingleKeyRemapControl` and `ShortcutControl`. + +### UI States +[UI states](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.h#L27-L42) are used to keep track in which step of the UI flow is the user at, such as which Remap window they are on, or if they have one of the Type windows open. This is required because the hook needs to suppress input and update UI in some cases, and in some cases remappings have to be disabled altogether. + +### DetectSingleRemapKeyUIBackend and DetectShortcutUIBackend +[These methods](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L374-L446) are [called on the low level hook](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/dllmain.cpp#L399-L408) in the main keyboard event handler. When the user opens any UI window the UI states are updated and in this case some remappings have to be disabled. On the Remap keys window, all remappings are disabled, while on the Remap shortcuts window, shortcut remappings are disabled. + +In addition to this, if the user has opened the Type window, and the window is in focus, [whenever a key event is received we have to update the set of selected keys in the TextBlock](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L266-L329) in the ContentDialog. These methods also call the `KeyDelay` handlers to check if the input is Esc/Enter and accordingly handle the Accessibility events for the Type window. When the user clicks the Type button, [variables in the KeyboardManagerState store the corresponding TextBlocks](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L375-L376) which appear in the ContentDialog, so that these UI controls can be updated from the hook on the dispatcher thread. + +### HandleKeyDelayEvent +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L482-L498) checks if the UI is in the foreground, and if so runs the key delay handlers that have been registered. + +### Saving remappings to file +The [`SaveConfigToFile`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L500-L607) method is called on clicking the OK button on the EditKeyboardWindow or EditShortcutsWindow. Since PowerToys Settings also reads the config JSON file, [a named mutex is used](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.cpp#L582-L600) before accessing the file, with a 1 second timeout. If the mutex is obtained the settings are written to the default.json file. + +### Concurrent Access to remap tables +To prevent the UI thread and low level hook thread from concurrently accessing the remap tables we use an [`atomic bool` variable](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyboardManagerState.h#L91-L92), which is set to `true` while the tables are getting updated. When this is `true` the hook will skip all remappings. Use of mutexes in the hook were removed to prevent re-entrant mutex bugs. + +## KeyDelay +[This class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/KeyDelay.cpp) implements a queue based approach for processing key events and based on the time difference between key down and key up events [executes separate methods for `ShortPress`, `LongPress` or `LongPressReleased`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.h#L69-L72). The class is used for the hold Enter/Esc functionality required for making the Type window accessible and prevent keyboard traps (see [this](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/SingleKeyRemapControl.cpp#L273-L292) for an example of it's usage). The `KeyEvents` are added to the queue from the hook thread of KBM, and a separate [`DelayThread`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.cpp#L142-L166) is used to process the key events by checking the `time` member in the key event. The thresholds for short vs long press and hold wait timeouts are `static` constants, but if the module is extended for other purposes these could be made into arguments. + +**Note:** [Deletion of the `KeyDelay`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/KeyDelay.cpp#L4-L12) object should never be called from the `DelayThread` i.e. from within one of the 3 handlers, as it can re-enter the mutex and would lead to a deadlock. This can be avoided by either deleting it on a separate thread or as done in the KBM UI, on the dispatcher thread. See [this PR](https://github.com/microsoft/PowerToys/pull/6959#issue-496583547) for more details on this issue. + +## Shortcut and RemapShortcut classes +The [`Shortcut` class](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/Shortcut.h) is a data structure for storing key combinations which are valid shortcuts and it contains several methods which are used for shortcut specific operations. [`RemapShortcut`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/RemapShortcut.h) consists of a shortcut/key union (`std::variant`), along with other boolean flags which are required on the hook side for storing any relevant keyboard states mid-execution. + +### IsKeyboardStateClearExceptShortcut +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L665-L813) is used by the `HandleShortcutRemapEvent` to check if any other keys on the keyboard have been pressed apart from the keys in the shortcut. This is required because shortcut to shortcut remaps should not be applied if the shortcut is pressed with other keys. The method iterates over all the possible key codes, except any keys that are considered reserved, unassigned, OEM-specific or undefined, as well as mouse buttons (see list [here](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L628-L663)). + +### CheckModifiersKeyboardState +[This method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Shortcut.cpp#L517-L614) uses `GetVirtualKeyState` (internally calls `GetAsyncKeyState` in production code), to check if all the modifiers of the current shortcut are being pressed. Since Win doesn't have a non-L/R key code we check this by checking both LWIN and RWIN. + +### Tests +Tests for some methods in the `Shortcut` class can be found [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/ShortcutTests.cpp). + +## Helpers +[This namespace](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/common/Helpers.cpp) has any methods which are used across either UI or the backend which aren't specific to either. Some of these methods have tests [here](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/test/SetKeyEventTests.cpp). + +### Foreground App Detection +[`GetCurrentApplication`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L226-L268) is used for detecting the foreground process for App-specific shortcuts. The logic is very similar to that used for FZ's app exception feature, involving `GetForegroundWindow` and `get_process_path`. The one additional case which has been added is for full-screen UWP apps, where the above method fails and returns `ApplicationFrameHost.exe`. The [`GetFullscreenUWPWindowHandle`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/common/Helpers.cpp#L210-L224) uses `GetGUIThreadInfo` API to find the window linked to the GUI thread. This logic is based on [this stackoverflow answer](https://stackoverflow.com/questions/39702704/connecting-uwp-apps-hosted-by-applicationframehost-to-their-real-processes/55353165#55353165). + +**Note:** The [`GetForegroundProcess` method](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/dll/Input.cpp#L17-L21) performs string allocation in a weird way because of exceptions that were occurring while running tests as a result of memory being allocated or deallocated across dll boundaries. Here's the comment from the PR where this was added +> To make app-specific logic test-able, a GetForegroundProcess was added to the input interface which internally calls GetCurrentApplication. This allows us to mock this method in the test project by just setting some process name as the foreground process for that function. When I set this to just return the string name, it would goes runtime errors on the test project in debug_heap with `__acrt_first_block == header`. Based on [this stackoverflow answer](https://stackoverflow.com/a/35311928), this would happen if allocation happens in one dll's code space and deallocation happens in another. One way to avoid this is to change both the projects to MD (multi threaded dll) instead of MT(multi threaded), however that results in many compile-time errors since all the PT projects are configured as MT. To solve this, the GetForegroundProcess was rewritten such that its argument is the output variable, and we allocate memory for that string within the AppSpecificHandler method rather than in that function. \ No newline at end of file diff --git a/doc/devdocs/modules/keyboardmanager/keyboardmanagerui.md b/doc/devdocs/modules/keyboardmanager/keyboardmanagerui.md new file mode 100644 index 0000000000..854d6f640d --- /dev/null +++ b/doc/devdocs/modules/keyboardmanager/keyboardmanagerui.md @@ -0,0 +1,122 @@ +# Keyboard Manager UI + +## Table of Contents: +1. [C++ XAML Islands](#c---xaml-islands) + 1. [Debugging exceptions in XAML Islands](#debugging-exceptions-in-xaml-islands) + 2. [Build times](#build-times) + 3. [Setting custom backgrounds for Xaml Controls using brushes](#setting-custom-backgrounds-for-xaml-controls-using-brushes) +2. [UI Structure](#ui-structure) +3. [EditKeyboardWindow/EditShortcutsWindow](#editkeyboardwindow-editshortcutswindow) + 1. [OK and Cancel button](#ok-and-cancel-button) + 2. [Delete button](#delete-button) + 3. [Handling common modifiers in EditKeyboardWindow](#handling-common-modifiers-in-editkeyboardwindow) +4. [SingleKeyRemapControl](#singlekeyremapcontrol) +5. [ShortcutControl](#shortcutcontrol) +6. [KeyDropDownControl](#keydropdowncontrol) + 1. [Localized key names](#localized-key-names) + 2. [Single Key ComboBox Selection Handler](#single-key-combobox-selection-handler) + 3. [Shortcut ComboBox Selection Handler](#shortcut-combobox-selection-handler) + +## C++ XAML Islands +The KBM UI is implemented as a C++ XAML Island, but all the controls are implemented in code behind rather than .xaml and .xaml.cs files. This was done as per a XAML Island Code sample and it didn't require a separate UWP project, which could be limited in terms of using hooks. There is a [tech debt item](https://github.com/microsoft/PowerToys/issues/2027) for moving this to XAML. The reason it wasn't implemented in the C# Settings was because it required communication with the low level hook thread, which could be too slow if IPC is used, since the UI needs to update on every key event. + +**Note:** For functions which take a XAML component as argument, pass it by value and not by reference. This is because `winrt` WinUI classes store their own internal references, so they are supposed to be passed by value (and internally ref counts are incremented). Passing by reference can lead to weird behavior where the object is `null`. + +The windows are [created as C++ windows](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L128-L140) and the window sizes are set to default by [scaling them as per DPI](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L120-L126) using the `DPIAware::Convert` API from common lib. Since the UI is launched on a new thread, the window may not be in the foreground, so [we call `SetForegroundWindow`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L146-L150). + +`DesktopWindowXamlSource` has to be declared and [it is initialized](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L159-L162) using the [`XamlBridge`](https://github.com/microsoft/PowerToys/blob/master/src/modules/keyboardmanager/ui/XamlBridge.cpp), and [a second window handle](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L161-L162) is generated for the internal Xaml Island window. Most of the code was based on the [Xaml Island Sample](https://github.com/microsoft/Xaml-Islands-Samples/blob/master/Samples/Win32/SampleCppApp/XamlBridge.cpp). The `XamlBridge` class contains code which handles initializing the Xaml Island containers as well as handling special messages like keyboard navigation, and focus between islands and between the C++ window and the island. It also has methods for clearing the xaml islands and closing the window. + +Once the UI controls are created, the parent container is set as the content for the `DesktopWindowXamlSource` and the `XamlBridge.MessageLoop` is executed. Messages are processed by the C++ window handler like [`EditKeyboardWindowProc`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp#L364-L404). The general structure we use for this is, for any `WM_PAINT` or `WM_SIZE` message we resize the Xaml Island window. For `WM_GETMINMAXINFO` we set minimum widths so that the window cannot be resized beyond a minimum height and width. This is done to prevent the WinUI elements from overlapping and getting cropped. If it is neither of these cases we send the message to the [`XamlBridge.MessageHandler`](https://github.com/microsoft/PowerToys/blob/b80578b1b9a4b24c9945bddac33c771204280107/src/modules/keyboardmanager/ui/XamlBridge.cpp#L291-L301) which handles Destroy, Activation and Focus. If `WM_NCDESTROY` is received when the `XamlBridge` is `nullptr`, the window thread is terminated. + +**Note:** `ContentDialog` in Xaml Islands requires manually settings a `XamlRoot`. This can generally be done by passing the XamlRoot from a component in the main window, such as the button used to open the dialog ([`sender.as

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 Ef@~h>-2eap literal 0 HcmV?d00001 diff --git a/doc/images/launcher/ui_vm_interaction.PNG b/doc/images/launcher/ui_vm_interaction.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2aea3a6094e9db55835f8513f21bcc36ebc41363 GIT binary patch literal 45518 zcmeFZd0dj&`#)^WRG+k|nQ|GY(y7T3a4DO~%&lk@EfEnhx5CV^TuO6SXtO4*EECOK z$Q08=4NY-{HnK3KEHySsg0q{RR`s~=h zLq&z2pf-DW0r>yLC-%7ntEjBL2>mxNK``bG{^(`1YX>&mV_4Q%YS0?9{%9jV+nj&7 z_`^So!^G_K#?S6p3}5;+!SLoUOU;qJ|C#(J>7({?+|HcN!t&0+fM3?_io>V{T;G3b z=J)A&s5|TOnt$H0{H)dXGb(FV{i6Q+rQi2m+o}@26nz7+*}0kHcHGIkrLN1VlHyah zvM=AU8eVX0)U!YGx|2}xU_MykA>%j=@Xu*W7}%ML%2W=19{A_o4Fa_ML-zmwAOF84 zgo^F}%ZX2e{-e{=gP9jS28=6zYYkxu*I6wRTXuPFe3Qi|{b3>hU_<%Cx=uwOr}7?c zY*ATt*9BiYygH#sXTbQDP|_STEFR@B8LSL~U`8KTv>ivAUiC5>LX(|ur z_1w8vPmfD*#x3jOb#&F*7X?hF+_#G(BTn=H%~MCH+`qe5=YuLaN+*(uK&m5N=HM&m z17$qmcb&~C3?zn39#4qD_Z<{{qD0daHa{j8x~7N3mofiSd6qy$1nYQMP9sS>*2<~_ z9(DTLyG4h=q651(>sO5q6s=UtF(TK!&A5X_38HWQeEbOH#&hbsakPx;PmYI%OeP@k&|QS@Y-jg*19Vw(r4wZ^lFN) zb^U<1#A`H>dBtan>)vhkW;iV-O2sXGw25;PQJ|e9h~#52`jU zY280sAlh2$9~UoN&8^E4yS}ny_Ce5p@oT(w|E07}>QMJLqVl-N1M{YyG27 zAp_^@t6JZ`s!Jm(8e1zX49A!kS{qobiQ39SZrxL%)w{`U&!pN`%st&ca2AbZaITe6 zIxf81_ajgZw`8^^f)X*CT@XkV20HVjsYxu?S}Z4w)z%%TYWH+pI9hX(}`Pa>dIxal6^npS9=zq%&bRr5ky&(`XI2-gBN{@Wd5SB&Szy~B^qq7IZ>@-G?kT&uZ3 zkLV}g_3j@bJsxu7CqEw7w7n(|4YR!ZH*b8CtdcL=7Ag+@NbnZRH2o!&@5CVs-j^6K z@RHsH5Bsd;O)0R5EE5B#EwLz%dw!~9Cf1CQRbu267mM0QMK3msN9rAM&0224Lcg#j zBU6_*C4oE{so|9i)M68IQ{YTz);u=Nng;sy*YBA8^^O zbBd)mMsHRcH%-nLhcHGBgodUSOpgOp*E*du2yj$5QfVOANW}t5U;lZ0;r%Ex|%{gqjgH z5kqy$d0Mlr68!>2wu$BBVQo~&`BW6NIyklj?*Rq1MT7dQ_XD7 ziSA?#y(@!{i%#(t87}D^w(KxW_sTW6U3_TAHiIRh#(CyrldB9nq{A8RG`r~4iv zBaQ8RF9PS(8TzpdU2}H9z=?TQlOgvEYNW&a8HdBAmF{ZeJ9PtR<*?%57+2MVuv3ao zv1WO2jy!tRlzC!jK(~)iux@sJ>CgdVTxcz`5HStpQ)9@&OGc1gQ>E9CdO2=)a?Bp{ zh%?Kn9(h<4*(oK)maH^UbImKV$HzIyqRmu%n?b0pTE*nqs1vM{=6luHU`=UkzvR_C z(!>JasEmofK4`rf2%TVT?kb-mmI`5&h0`(F{vXQ2>K|8!lRAel)`h?7^?xeWm6x`Y zTO;brmykkjQzp6I!#*{PNy*KL4%7Cb;qcXJDNZEa5=v=P?{T{-{(QFT!z+xB1VQy) z3tOr&rlrnZa>(HhNe2MzWEEk(9w1oq`gxUF+VCw#ks@B-^c=}=N z;iyhO*9`_J`}@CN;j<2m$<>P8r`j(UugGMKl(?`_2o@`RWnDx~=kcoXkN`Gj&5IB8 z)^eB!(?1PF630wwLrkG#)+(RWIoG=tY6oIuQd=+uVGbaSGY z3=^w1>w}p5u%z=eL2%Y;uO7^avm5oYU;~k7kI7Y6Bll)dON<~p!vp8QNkURF_h?nC zs?nDmXe!RxBC}s=5$0ZcnSX62*6$*%ub*I8&r@;Bjn#r)?U7{ycS=NhJKjr*Pr4a& zDe-74Fd+@N0OO6x0*iN_Tl~|jJw2Q_GOjy#bJ0iUJe8u>v+-n-IUG~24qp?Kny3YT zg7J2QUZ0DGrNA#jHb`}Yd{vg+VwVi2axE$<9jodMa8?S(f{UdDwlFUVcs4s&65LUh zd@bmD;!zJs4t4t2qFn4^uy*M4rnm89W^kznyw2R#+dc0Hm2(~`c*&n~jDvFI_x<>A zdJwG?3ygj*5Ql3X)|TuZi+Wy;^v2#>7t6`T!n9zU1k3driWstwaO@05P*@Mg5`a8a zR7~sc#FL+>k!!GR>hPHSpr=Ry%6c#O;;Oso#g*EW>=HvL13#VSMQ3w_O$0&n{yF>h z#@|~49X{AL8$&h5uBT8j29C&n4R}O;ViGJ0$OL+2!;I3{mHVhS!p*D|aMZ{-$`uu7 zP6uQ6P*IpXJ3}Xq9_m(_#0<{61Ev2JX34I!*%x()Sk8THs$1UlDzZap%vESlz^`<* zJKa;~BwcHkXuvncX}l+Zd~hydWY$To7g6hrUKL){VYWzF@KRl&ntjoTZ;>u@Lm!k* zDtcz0)`hO-g=dI=de~6*f#7}c|HNOdish8+<4(uZ!|0;fL1zE9z^L~UIk#@|`43qZ z;io3|DTMTq(YMCDb^Tk$`Rn4A3vO((~fb0Tpt;Enk@C9~afW1KFG^zgg z%9`#so3r?#Qy0rW~LEwB;6R5V}8dC7i zC*RFE%S7L4p;BGG7p?c4XeVYiuWnzPWn2DXL@jZ@s!#Ao2bwzn!kZ(}3d!VBghg)j zdYgf5o!%>SqY#>Zrd=+6(|I)9;zfw`@!hBn!DgRwnY)X8Ti8Hmy;*``?Z~IH{92<) z3O&R62Up^S+*!Am{FbKh6d~XV|Ff;kK9wwNHJbNo4Ib9t*P_!g1~vG~BxT0-Kf0@`S)|?``uy|*%;yxE z=dPuiDb!d&4*RITLv4(-ialxN^B+3{oN8;Dht=Eovtyyofu&knqJiKFg;(GzI{t-6 z>&NoD^2^PX;#s*+=4QulIeQMA&`04Obp#0OZueGUAbSjg%qG@E??_qt-1{1n*&mH$ zXU89~Ia9+0l(PG_r0Qx-sSIgWt9T*UIoowCR|_EtUG=GI0eSu*k=JoMW3AkPq2wWN zvGu61=l0sZ+jUD-q%P5P6A(z4XtRD7$SKxf2kMiM`6eJ=1#Zk&>0g2_BfVYb^dMtE zZKC4lDxpa{nZrB&OjS()-leF0L*e-+cs;1Sk@?0DzTjbBUCT`mBRiQkFR1q8zjoyV z+*+XGMe$3-mt!3a#v-$N{H>dT(Z3nc%5&v*{1ZR(`fRo5iKUv?sS8L0C3gN zfs&hED465H?e@mH<;HTyW}aORFX(x1fcsv0&|Aj*25IF@X5oTGmZ2)|xFA+|8YaUR zX~CN@AlNN0DMV|N;Wk+%%1CAh^2E|1f9q-}NsqA2g1qkgq)@FTr{478`WMCu~Tz9}ukI#`$8^uAG?;*R}k3a#0y1*EDA%I~cv3nHf8LYdkm$ zKkt1LR1v)Kv^tBZ}=Sd-8_*?ZRP#Tp;KC4C8&eayNW z^?TXRBOUm6W0ua;i|Sk|WUtHZ4RJle5r1brC{wvP{jNVnO)`FeXxk94NWNshv=RUX zCww*CX-8sF7-eqYoFF!X+w*xw531MdWoC&c23xIfB_V9GOv>|P9X7EW0T*cr7!LvjSeQXP&q?s>G#p8!O5tDd8Z9qn8BpBpK9@g&Uj`Y9&!=yx9*d zj~H14K5teqXxiT7b0ds2RvB_BQ4_)cpdh7?YG#^1e2$RwK#+(Y2!1kLDU?fbo~YtC z{C-PH)R9jyWzwpm^ZxVR=ki3_>r@`zffTdUepM}0G#$$-d7&Fqj#!Kel!CgCiIr4) z;%m*57A{i+h=uDJ?Lq635NQ~J+On|LHg!Y#Wyy{`H|#a9@>oN=)j zy&O#FDZvZN0(&B&cJ_Mnq9-vwb*(*heDcNA7tEnG?Ni0PitZj^LHNp_RSdd7-UMal zgEnepqheD@bXW_D5@tO$@xg#>L{eA1ksyCOhzn{Hj}i-`5U=-=PEI-xt<~F4x_}}r zte4qeWJpd8#F6`>ti@3_SxvRgLV9`nba&CN{MqprV+Q0R?0{|3HTh0o>rZ8h5fV*vgi?gY}F|~v&B?V2!_LboCo-$-l34%_~=uj-}yy%Ey-l+lp{E63| z2Q95Zc9;*2)&C6mVJySA`qc<+8FAFd+s6FOW0!CV16;fO^pi~*8=f$JWHVOO3ccvF zZFEEDbVZ%L!nDA1_NC!3E+;&q2g>>xtKV;=$R6|6eJ(#=KHg(nEVh>1w=kvQBPM^O zWMg2!?RuZMfQqiS-xtlZk967OOUFzfYWHaZC>o{-Bn9`*pJ&Ye$&gg?jWyx!U2rW# z0RtBpbKHZDAtKN-ve;5gViI@XrN9-c+A&M(wfhuurmpdb-L4~MAb+mAjlZ6j7-c<6 zZnjsX-IY?J@tGhWtN9wdwVA`hE9Tq@#lcsQ-j5~{yg#+UdM{hw+@h(LmP4T?Y9Z*m zv^7EW*ULdTEM#-;89P08R^ZZO;>r7A%hj&O#F6Du?dh$&)5yo6AbHI|uZ83AC7`w_ z4vj^XVcVSY&if(eGF?9u`2o5uM`j19t>PB9zi@jQl8SK399HO2&^IT13eKjmnN@P!bYy%e@Bq>S-T))Z@ zVE-zIcG4d=83H_@453&B;Ug*G&rs3v_KG!Sv5Z*&s!*owH!yVf@lxQ~1U;tUE&{hj z!Lh%Ex0^jW9@dN0Td#?5*%UOf8F$Qwdj73-&6X~bxK=PumXXXHF|JSTY<3NB-4iZwop+PJH4Yb z&?U1T(y2_yT}|?cK&i$$U%Ai1W!Exuv& z>J5)qqp`m4b@Lyx5LCH;;8Yl!aGPXj^NhVCTFn8c|2FPIpJbIn@?OZ;6iq}P_2Gd=#a|r`!t&B=HA)Ze1QVWe%@z>nB{oRCwGs+PWvj zhud&Hli%ZY(0Xrmahj&dIVokvLfymkeLot=5)`x1SL2X^-+)~NBt0Uqa7QOn#A=hG z$E@2Ael>Q})DpRL-w)p8319geb@S#ujAqTBdPi4UHXe|bM2+~DN416|Ow5L|_YIhh zQqJZ4n(uC!j2IX_)6`}j+(o`Ief zg;SD&%z{UPUZGyp(y0jI(1LxhVn{Xemd>e`U>4*o63ELymHtr| zaHw+Sp}I~dXb!rZbTGydc9S)ivb<-cNQ%ZSb5H3!Z(5 z*_`{Y^pjUUdQW6%Y3Oy1{~W-GqMdZ*NsrrJ9`@m^nwkxO+5VR1uQoG$6GM9$ zp`%*7@9-P2FW;vc=RC^9iL|_rzwHyB-^Avs{sI703lPVcLqoX47Z*S#{^YjA(slQ%o zU7cdsu;nOM_*S?B!0xwzTXqel2PGo)o(l8!Swj2DH<)GA%5o|`CA4~OFqo2>^z^Y& z2eH^jroQG6z5W3h1E+0cmlMW9j-@cJPR%Z)@3X=1y6`tA21Zz)A|I@`SQe*I@fzAs zP&|2qDLanqaJ}F%gnMm)e%TXGE|sj(2$WWCg21we7oa7aqGR9=P0*I_N+8$(mIPbV zVB!w2gRh^dzRm{Fymp;1?>X_?FHb_hvO9OQpO!Kj_BS=Q05Pa|3u0gwuL;c-Pb)QJ`I-qOuaQiPvlnQMr05 z`nv4f7v2#B;+=GW--|FH+|SkgIW8CkcHOtHRMlEx?WrpfCuAbXQ`dzR6rwjr`qTS2D(qL+&ox_I0!IM!0@0rOz`$I2}3m z^*NfrKl1kSS&<@%@fHbYlV|F!z^BnJM=;+$0V*pwm*hWbPwZ6~1{q4UC^Fp{$}Sa^ z?NFLj0%48sEr5M)V?z{+4cTCIN?0`gGEgK(2!1_b0)%q_THC`H|8G9Hs=-*%((25b zPIVos5k9dmlJh9U=o2o_J!K8Ua`X2kO8UdrTVh3fX#wd|HtGIficglH0y-&d`0mev zwW4Q())7KoO*QgOPg!l?MC*n6yUKm!m1mUo_-P~q@CPi`!QcEiyA5t|1=5Mr*@(Hn z?Nk2kHM#NN$#PX&CDr2nx~5WGdf{Wt+yX95&@_As?qeb8s~lLLu6(2&^tJm>_(ZuD z&X_pp$@an`c&G-*F2kh|fofNd{-S!02%XT3A`l%^_5 z44t=nLJK)MO*h>$%q(g6mRHj zTpxD4GELZUvWq4xG_yJ@O)!Ax3St} z7yu8CU~`^=A^{oajoO!Qw^-7+{-P#)4SOwk&+W^>Q8yjIt9_jF&aVTANDg{Hgmb+I zo|QKDtiyB>|YNM2!QP6;KBOIVEsD%>QoM>7L(MHPLB9NC_mWD z!MyWWRSh;r06-EI6+gNWZXwk51Px|LKG3>z&w~O12bK)pqV$LC<$C+`w`&WhHn!sP z&IA8^a^w^&8MY~G95es`1ijDW-udqZ1b{!X4D4F^mjMJ93+EEhm3wpHI zrV8BdfQGdhDNf_`g6e;lK{?{bHwvO|)j#2DD2To~qz5tSfS;p~{CJN$sbQWneDjZh zahRv>>776ljvDa2Q9S#seV1UGuua9G&`-uipeaF8N9&5np1s6FlW*@btE%#q?Iz`+ z{u~-clHM{ibUnJXW}0xpz3Cs{^FjqvuE~Jmt>t- zU)K{yeimVn92G|{&4u2Jqd^AsF_Opi8ug1$ysJ}1nsn2*vzkps=8F!djrftniah@2 zZj(G}R`a9)g9U14Gp9li5A22GZY_xLpXY+Wi5Pl6F|sDgsn;fZNND}1b(tH4&XW%RcT?Mz z$cv^T?ZO)i7VI6~BCTgw1^ofNuMJl$LDoe3=zCX88YDN z%Q1pJU`AQHwEIF+@U-YbM9j(MjR3NNyIb+Jj48wXMj){q3rSOTJFh*bvT-~cDX8xZ z$&`xvOF$5g3U1>8hu>DL!|Jw!!n> zo=|5SbQKqW`Lb4=EW}npt$pyjk;aeB3qq=4mHa+{Q-uqjUY_ zid?L(ZR#>osAEYq%b0*PE1}{S$G$l3Pj4c_>|oCs@PtfPIh#ExuM*!Pc7C?`mUs2D)sba zMqM{Q{@Sg|ZvEAZ2$Q5^X z224uw1{lUNW)s(AgVn`sO8lj7M~O1P<&xo46TNr3ld(!+ed7Kz%j3xtB~u@h0xez<@gt6u zh{zBSa`s7`jCNkt{_F;tj2|CWq)74}{6165sD-kaL{t`an=wWO?BUBg^==rcvEMz}>R=P|T9c zPecuKiHyQ?_3;V57m3nb4McCr5$X6}@=lNq)S2kxAlJyKUIjJnAUy@RcRr-2j?ZFI zRDkUzqe!7BeOwjSBcgRsz})^Kj@-WJ&DA(^w~Kz-a&J7Xqb=tkt)n5hI~H}BAeaTI zX|BG(!VLum&#QMIVpN#N6TG8Cx1Styxi7FP@xSNJ-0gOXVZ$6<8%OpS-t^M*WkOsM zF|FLHrHv~&k=9OOJXVbAyva*~{c16_4yarr2up;lu*(t%ZyUccw%h8*N8;5hT16Jp^M2~LF!n;r|m6YKDu?c@0Bo3WH0FYS| zj3R?@NlZ7H%Smn$5|D=qt9~EV3Ie!ZV} zUq@e#ok$iIIz{MUB*7*M$p@Ve6oyrqSuCi6<2uHH1{(|4M(|Bz&mjRLtNlr|}|Iw3aiDWGV6D74P9YfCb42LuFM zPaDj0*g8!x{K9*Giw|ubC8MMeA7KG=Dj`sf9qs{FkS2I(gnjH>IlVPxE-Bf#`|zf% zZRgi!%MQIdG7oR0cUI{SfTeUC{P`&_^3=@Q(u#fl>Xg!ocbVvSmyg8v^~j#_blp8_ zMqb8F{1Qiw&SKROnEb0!o#LdGZJ{5>(ix1`e!|{vX5z5_sQGLqZ^S>LZ06m}uq~x- zI_jD`gG3t;loCzjifsfwM<}iHD>jJ;RBZ0k=)3hS0j3~1OKPxR?g2OxNe&;Dc zFKGi^e_-=;E78MKG5$Plxu9E4ArQme@8y7E9$)$9C?IgW%(XLf0>nrnSuLR;ZcejW zs$!kWPh5?!9wX_EYWbUM5nQ$U(sp+pqT_40?ein*A6GuO-%(|Gvb)_|`nb~Bt!AMN z8B*g;7M8lZ)d@>#56r~K{C{F@V9~0EUA5k=P`kLA>l&(iL+8m$|Gy{sZ&Ezl#+ib@ z_%rFtCRl1@(&9YC{4oFEZaRDTKa30w#4=OHN*(8p%xPKna_Thx7`OK_<@%t%3OGAP z7=;SxRo`2YaB4jp$~^PVUv50$lCoic&&78a9_SuSs}*c8#1Vd3A@}WLZkIe;#KYv& z4ikXGhi7e%7~V`J2m(B4cEI5n(Y}PW?QoZAD$FQXy5QqsHtLVA15=*ey+~u5N#@Lg zBb3RrCxOowPuaO0N*>A9;_iB`2&ky_-;>}Uqq*~Cp8DTcJc_3_O{V-bQd)I|EG*0s zmA+o@7u9XG-tvMO?-j2jp!=^|(|Derq|IIH=j@@kM#d}oKJU6lN^0-}I<^O+-;x&k z%m#qAyl(@^@O0W?cN!>xN-%mbOj9}!0QE@fr*g^ze8l*b={4oL_)eXet^OXg^A#2T6O0o0)hGqs5)LuJfomv2@CTFg*|a7f>1*9OD%d50t%HXx3I zcJA{$I|x5f2YfFK$mNC)PrF4TVCGJb5cltaxRpm5&KV6iO3gswv zi$U`1i_!z7;^(wJ)$yJi#4@}6HM947%5@&w^1BLtr8?qAcAtPDmn=}*Q*sH}4f%PJ|u zR;KOEN(2SX=UT%rjto}$B{Ribf@GGP3_k~H;+>q->2gZYf60l>s3;JN42<-?R%v(e zG=r=!)smp3C-K`_7ec@u3{>IDvLzF$c88rSb1J?om_z76WS@LUf7Rjc?ZrW6CtrNq zMjAn&s!BGa&egN}zUx5|1Tlky=PEfyI_QKwPsezJL}0xU$iX13s6aAwBEu)k!=j@@ zKnG`mn!0YU<+9o)&!EE|;XxtX{Bp(EUU8(%SZ-#SYf0I8dZ#)F8kZ73SLC1oWmr$1 z0~Ex*ML3XB6|g}P9s~rVti5u-I#U=H30Ax2bw7JqVWukgk&mKeR?HJUwSU0n7j94` zg~fhOF*PtWHx)J~0%3KLTRd{yD2n$3S4>*CwTOoQzHUlI=RHmAt273Z0_A7)fV=y3 zQGRhbi76ZK1?VKGuRlvM1!M-v+TBb_IRA%&R=^H4Cgre35^7>5d(?m;+Hh`Qz`}mn z^ba8x0Vmhd-$4!L@#7 z>*FfGB*ke2n5a+zM**slqDLdZy(@u^{8-M+$0QcM_EQ(ys^<7)P!<;0Kes4TP4G0z z`hJzWzQePxs0tFavFto)7L#p@aE!-WV)_{MfOIW`876r94jyK?NGadji5OVGAWy)RCgf z=A=j&^QeFTVH`D5--{FkyLVsjYe_MU%9 zo*YuVJtpszWSAK)$!I=Kk!AHq3P6_=mvs{eqNBzrV)2-yyLaZfkfDyq9@_FkRh_N6 z0wh&eb3Kn7RpU0CrMqswszsz<);5}MXTN{XdRVvH&(~qw@Rr^?r-Exm{?CHe)GETQ z%VNjd|L!(FE>-O}s1kNM%Ok03pBlub>#cN8x{mse1b&h^R5i36|3!m%b!iN(Eyl@1 ze7!Ki=NWgOxMsargJ~KOJw}{@;kLRsnEF3HFk!;HQw3BEC{4eQ=!Ll=p-VGEwFuvWN& z?El5_;kNZz7QXThO@#Xzka;{(cxu7jn@p&98jW}tVcjLpYChgD^h)C=Qf1^=%wh9e zL(H3+KgT#Ex|tdtSqP#-`2)5s$t6sYy&Uv&cL6p1V?gsnEc@_UBa71A$4=7m_r1^5 zO1DUNi~n|TIrz3bLC-ZhnPt7Xioa8LJbkw~U3#z9qf_vNcXKBCsnpo;lk2(Rn+MPS zxipgY##2o9Pw<)H?yH^n=N=Ce-odWFC#Fl8^KyUHL?|uo$*OFu?|8F(czZ9`A)3x@#f04^k{AnGA7? zSdWv|Dd@cTmf4nZJuw*;2+H6!*7V2-_j~7ia#$AXYZ@qv*eIz+{PmM(z>tW(%_dBB zfB}H;skMISmh%&_`y(p}v6s{lM*xLmvUvqJ+O_YQVB;Iq#R~LlBh{5Ml8meQ!Yg*S zc!Eds^D0MYjCm?-_b|dfcx9G;u$r#?Psz{$lGQ!lZ~Mao;<#flo#WkG>IM^h8oB#O z3fIh(L0M8cy`r-WP$2o$(ZehGh(@(vDqSQ^y<8emtdLT~)EDIdcltn8q+I?n9(ac}u(G2T&szf?Px>4%bHCs5frFuCP@GE?B zCw!jHo-}Z}HG9(Y;Ot4U5Fj`N=X>h$SJ$~8Ud~_sKv31@dPam6O8zdFJ$2ft?A z%UXK3KruzJ?2;Eh-_JRmD@z$0i0_UgI;47xzFH7ko;S=g?l@{@tB)(M@#r0D42Sl4 zg<;k;6=@FVg}n00n6A>o7H{q~^Zlua!uOaYswPy2x1Db-4dqvND2{VAg|Yv1&}Oqq za(1(|WK2xtYEQrn5ru?lXZLm(>>8`R!Gfg=CPi-y4nE&=>5Phd1GQ|Ywtxk6& zP0^By_6^9XloJv9x_c;DiM6u33Ij4A8lZD%wwLAHG=iR{>g4=&IZ}DJ%&>L!+*9;% zH|^=j^&c&eo0q*jd5fUuK}w&9EDhM~nl#1BFskZBo~rZ8|E;sGqt0TB&udE=Q#HZ- zH_xzV;|`rI`n>+|J-a=3soS1=wj-hJdW<5uj*@4Usm-;42Lz|}MHPr0Bdy}NuSfW- z_Lv{+=tRUTI@nTMET`Wtsau#ovAh1FZkIZ|I*vSbnatb{Tb~4TKeOE0o@!`f)ikRx z?Ny9|Esgjk0iU(XmW5gc!H?^$|7OxE{0M2`6irnCG3OJDU>WIym34`T( z%*!iha0S^GE$+opMe^{aQtbg9VSgyt2xOT@{kYS>GWE3(P+Fvf5*$GA2l>YqDk^Pa zczYW!CUJ>;76vwNSEQ~&`sr~|WU&=9h zP;B4=&K>;WwQN;ww(3V8&RPE%LPZJsqZZj$dy{y}n^D7+8M`;N0xugQg~zE4R9tyd zFYIt0o*V>rZ!VMMY5w@S1@r!Oq#1ge*~=QKoar_D=(Dc6Q@eOD)28e%!?$0+*(-Z0DV0ty=;2XF$;ELXq;ldS1CWc}fb&Cf`CDrM;Q zYw~lxJknzQ^eoX)XWE3%y$2}_%8li=#T- zn6E8aEJH_003KgtzU>LM^TLBq4z!Ke39+F4y!5qkM`DiJ1n>-pqFoQ4dFNg}>R;a4 zph+%cAC=>C(|E~exsQd%w*xoS!;Ga4v z#ydl9xWgBj4`yEoU2c>yITp1v_X@i?CE&l74b>y${1r$ALrOR z=bjRq>Eqfbc!@`&tK&4*V`$gFkQmZQE5}juRXWx{BUjxyIHGgj(sCo*w;Vqo%wMc| zBFafNcVD<0b*ox%S(SXO#pmu*(B***6$c&u{mooH57YslJMB4QtM+lkUrX~{t2gg> zuzs=m!)^|nb3CFS>%m6L+GW6nz(sX4H#K}nYh=&qyK!X0Ing%!SSC+qty5C>l*<9p`9SGBn5^H&sBXov7EJE1pwOg&*RC!UmWe> z5x=FzP^Sy3Uwm|x038rJ=*Bz)8m5|rNuDXEOgcw&8{fU6#3i09*#TZYbm+b3=V}Dt zGC;2l8?QmhUhDkxchA^^quGIBziVK4ssBq6m9H#$K+0|WNf7z{%6?S`Q%}2#wkpe@ zHDE48<@6QM;?ze!gK2?wUt117_dLMf;y|ehzC0+HnX7ogxq@wdh$FK+L2L1U-Bf)1 z_v?0sND|q8ySE9xk&n#MqvVS_tEb)?79{r>;Qo4^|3h#-wOo-HXZVSa5tA> zwSgVXwdQJmPx1c#+n_s(0_~sbhy&oW0CR|~FhG3&UT{{*9;`#&^XuQAE2t>K>H(ea z{7aZqd$H)TYx3&vRiqLR7{x#+qN8S|YUEE&9;fO>-=8eVLBqz=@1Pg^vN-Ynm4H19 zbw1`)4kRGeU;u56sz%$t4un820d&Vib^Tr%i=*aOnfm>gmc)^FWR*~{pP`f3vW}16 zA6JW#=CS7codNScYN@JWw&Q#2O9RLx`q_8l`bSe63|IhQ;>M#>fcahr z|3Ki>;X$9v>$!b^B`I+U4}*BSf0>y(?Ij$bo)K9FCjZg}u%ebJa0UxXo?CstHy{vz zGTjCCae4RBOW&XIae9dyZXCCJ>G#j?9T|4Uk)|3ICnldJ%%1*u-F{ZAU^H9HM)^*& z=BddkIqKqFvkilH6%B7>ltU4pxB8Gi$3Ri;<%EHfm;$*=6_r)- zO1_HHp{Ue>`~uKel+yWs{uRzo;=bTw8gXnhW1+-&B+75nUeVyZC`Bd;jHy*D1qc&( zhXJ@@;exaU5lEBY2$OdY>dt=9^=pulhTG)kU>muPfU6Xz(cY8;u-o%Jdg>d&FM|P* z74U7$xex~hxMO3$_`8eGa#HeDfInQLd~7Uk7$Ty8&tHTHPjMP8&wL8Ex&l7N)+FU# z?{Be!2rl3YS#w`F6W$V6>IBy1HTQ*uJuZkw9ANld-7!b@kyJZ-;AQPzy2+N~y}C13 zz+DK>jnx$gLWRrZJ&rQ_wJIvNf#kqA#%#yv?At+#z}IysAar$3UMeQ_62qtOFT27ydi9%WaRf^8dKW7 zksmc&9pN!58XV&D5}kP+OCz$A!H2dqig$Xf?3*+w4h-_SY1&>x|BKI(%2rpFHfG#3 zt*bPD-f0k6G{Phc8+LTTeI{{=vfsXOx!TyAvub1lM0x=HL@!M+&Izs&h=s^s%P~fn zCNL-^!U%qan3>7|wGWalbmIW<&Bj;`73B<3)`}pCqq8aWDZg){k57?b=5}wWk!e^n zR8~+;DYgZoBHQUh^F3h91#=HHbH5S%0Fg}<#IdkqFcY>qmUA7j7Bv4aOi&Ghe&V-> z04iichVR!o&#U-6w*g_^WfZv=_zfW#=}}Id&XL;z->tM4Okk@;@a#SF?5u2|0H)lu z9?WqHjIl#ANuNj9f$k{@heW!lGgcjL16a_2d1E=Ie0B~RR1FXbQ3zNZ-@O1D?{1Zq zQ&z_U$Wz<9Rj8Z}_{N5FS*=8mzfk!Z_=p~_?6m^;*BM(<(TpuM?VZC&}yKy&sP67G<+YrBmv-{RIE#g*-_=N>E{pcj3cM|fC7y}*7~vu zFoWGX`>%C>A_%HLrmUR*`=3U==cc7Uj|u>~A^&Pzl9v`xqY^+qO@_y01-&fAf|l85 zy%JP`X>Ma^bTYjhtDJbAlc^tFbOJ|9Zxce-8dQRQ&*alUDPYC`*2ou~S(Ob@Gz*NJ zmBgwq0xQK!W-IWOfFbd}oq(PrG9L*k`(8;N$CHP^Slk-uSYXh4A+Q_Q>IgykU!Gls zZ)2dflK~GKOo9SE{d&Ct6_V|LKgV7CUv^aq8X6(WQP+PB?xOSD-t&m4Z^TI={mb$U!G40apO4R$MumUBbYK9CKUz#ziqKe3!j*6>|0IS?ESro3I1=`cje)bymi{c5M+ z776w5?%SyBf_e^jaw>sfl=2oHgm_xtWKszl^sUviaK;AdS0W`6Hz+DIx z%9+#8%+)bAr>_)Sln?ow?Ej6zS3Xr<4f6RLfd3sRdr?fgiu-ZIpMHa5kxuy_4W;z7brFp@QVI`v8__3OfDe-}tc5YQczVdO12j84gkP0M}P} zzsP>2!+{*q_gvxU$3Uy;oAU#D-K+Vps|XC|u0{ClyaMQ=yR52e=%S7nKKbhPN!KDE zw+*VgENo>mKq31#@Pgj|zy+5nv?akwGHO)2G@P3fP-yIm`l>$xyXc7;Uv^+A7v@>S z1Xh1)6utJuccT7v5sDsA#E#YKh`=c-XSCSr=koDjmZv_Lj^fy|9z@y)ccO2-ZN#({ z<0FntJ_=o_1DoxXtg|ozp&26Qf?-V1tisM+aFB<-G!Rb~TgztpmylV~*yie;hfgRJ z4`#AKZ)UO-3j)W>D!dK%0GKvvMgl}IDej_7S?<^>pXEl2z5|9U=G>@>z~9jC z(PHMO6OpwPH_PNCxTk`kA3zMBTxom-MIPf3k(WeeAO)pzsi1Kn#Zhw5E;Q8n=r9+|=-F@aMn#$HMxB^!9pkEP^`hb+qT!eK0%kZR<_`K! zPDF@;>#(?O$_zfVE*4^c7~n=o+WNm)L*h0xK z#0+n20hd)2MDVy3*u_3~C)k{=1F3NLGfk`o`ev?r>oYS%vEiYdP9JC1FP!A^t$;4J ziR;5gdE7Z~&DhPEDPe90doRG}siOclHV#aS+7k^dE=1udv$&wz9Y%KnA1gOU@^qAx zZRotKFM0*BZr*8MXeI#(bP^XwcDA1_r{vga17_9GW*p)Aa_gOfi_R>0*o%vAh~rvP z5-cyd&)+(0-{L@-i=y*WDHeGhkichGj3*dNM~pMp-RAmxyVLfz2nOB|4H|i4=E(J!=qbOHeLZKa`hTEr@&ciHaBEG zvsMp*yQOXgZV;i-jMJvL8^Qu51NE19-!qaM;0Np<6H>oBfMm}RJ zKEG>ul=2v^=7!349MU}|&^8)bm0Vu)uy z4Ysn{v=Bp#`7#gJ+_#{A*w6-BleI5`Cj0%}bPL7Qnal8I-^b@?W+Zx)#|26%s|b3z z(v7@{m*jc`4&!JGuDVG#U35`pV?xXZTWD^fwP-XLivkTl4DBg~+VG~6)i^#<$87Oz zA?+KUHnetCCFAd@bI~sv?G{G_Or{MBZzaW(msza@Sn{uKG4!U4%93<~URmK0fObU$ zpZJf;_`9$YXpjr^MqToQXdv!ufWsnyVAlSWdvL%isoZj>9&`2IGVb~?U;fB=CE#97 z#&T>GRh3=#MLMop2$}VjSvr`Q)kTrFq}4NDYau$d*SG`Ju9S|qQ9C!?T_X0EoAn(8 zEwA=bo4{&ghlPp`(PjUNXXoqws;l_-N=);VLmhwvp}Z9Z%!(qfC$6*HtY?g4vSteE zs${QV zHlDPnLq9F&Zh>{wy)Sh_E~KJfK80RC-0rOJ1hseM_7Ba1z6b-%mE?n**x4!XP&@}S_oI2OblV2Ggb2r~O!x)-W!KhLIs zoTQJ+3DJQ3I-o1ZWQ!6X^(yppY&($lhYS#j6Y)r8`as2bLx+-aHEVgf~ap#xC@?1NW! zhc0CnZVpKj4m@2dbE$w?*sDk#fWNOd#K~t{!_?DR!%*vZ>hJc@O~3%i zAuu?U954pC6maK6E66Y+^1&S%U@|BJeAkh2I}%)DLuvthsQ;)Ve89BN*YAMTWAy)M z?>)ns&boeK97h-h!BGSw2r^crN{}KY3S&dsh(hQ^2qIm&l&B0a3Ia;6k&&W9@10N# z9ipHh1PDD+0@4B`BzgBgSZ40$exCQ7b6w{;U+ynhLX!R8d$qmRZ~YcyGk@I%1Ta(H zwy$$o_qNMvH$-nGPJuYQ8zf71X>dM(>T{P+&zJmFm+L<--VQEjwO4kaF_Qa1S!emv z>@&(?CEnD~1y6_=vC*5>L+C6Q#cIziO%Xl}n^!3N)Qua54wC1}GAJ7-RTd^CEKI8i zVV-r|#sR2IM6)S=hEJ&s@dsX=Q5cokI4>t2mqW-=<}wGA$T3M&y2@uMrWsg*x2%Be(!s-&f>A!00Zx^>wi=dR2hus zGE(}gV65hrN&@|`et`KSbu-QfNt)2L8nkggwFfj9-=fXL6E$j6$}f?I@k>7xR2)sV zR0Ew^_xh+fV^1IdvqomT&TlSRhBX*6K_!6uFV6KB6eDtl-|U2tne%ng$YG*tgzLE5`Ae3x?De0^J!)01-1mQy z-;iu&v#{89l_EIL@ZTNIFk&0p2gxspC8Drr&wSV4-9b;v>Ef#398XK`3FT~rc}mn% zu{`U)b$d4;jV%_;(uHcSiYxOMI~98)2<6qrvd(5vvyCdRYW0;QG1Q7v&R(8qnsW1F z{0wgpIe+BJZRAbCnKjWm_G&b$AH_@!v&J`+&{V1RJ6zPEYY7gb3xhh-VlrNdmps}2 z#_>n4?c+tajQ1^=o&Lx7(ZKI*#5X6@3=h!BD~C?0X6@1|!`>HuS`5l6Cgp`R#duF* zNF5)Wd<^@3nv~t`UzEaDl>gvJTp0TW-O;FW zT5?1{Ns{QG<0sJhiBdeb%h;@ZomJAmnZI72Y6jhL5^+1}Dvk~Dm+N)HoAju0DU z0wn<V)7K}JR>YZinuI@%4DQ! zqPackbw6@2yV-_x!C5Xe9~1*t|0!tZZ2A*vSTU|v_|Ck}?KcIR9en)7FPZm8Bxj2V z#G-of5p6Ge0i8o?|F-fC<73G}i0%c3_N^S=1-KJo^nODu5NC9;@WdOEy9JffLOQ!u z{2>Wb2+))yujaD+(5I7CrVroQY{Zu-hn&EXKM7x_9P&hP5CG(|n{EztO$+GSaJ*Fp zxZ@50+bBX{k?`0XurdINCo0u!V8Bccg{8{S)m`xHP;F${w(xUeYMQC_`#{{4b;AGAfNOh>eru<2$bpYYoA+k<80 zRB~9q{bD&*9Ibr@Z~0+k>0Ddc?LoJZ+Dxz0dyW9kGog(?So7A zjCjS8pSB2_0v=#t^Wk-GCJF8}mlh&**EjBT9Xrd5?`9L!hRzz?(gRp7%%=FpB~MVq z9yrY>_BYI(s_>JTx$=kNFYenseNKEIRO%W6!B0Z-jq^L;TI(eG@U2*cI{ zf@*k~L@vZ!oHR1>xvtmh1cNErL>vAKyQsB?(EpKAq0!TFe#SS;;fim{!t&t6FkM-b zS(%u=G3baM{&R~YMjRQy-+o7FNp`*xHzud!tH~x90@)zz!bZ!0X#m2hTWc4fV;+c( zKUzvf6~;=uWraV;niI@5Wy$!K&{3z~;>Bf})=%!zs**l(TH=q;(8(F*3Fa%p{zZAQ zBsromCMvSa?GS%`HU9{i!YyQA@_+~H)jx42q1aKc{Ftgv6Jf|?y{>`GyI|jp|6n~} zUrzH7Ge70D_?a~Ew%?n2d!gL!^Z8%(gbuK^qysku>KTkN-?{>77n<~G|1?tS5GQA) zXIctiEX7%uRb)%BD-F{%#o^p%^uwzqOcM(I#|~qfa^laZhCjZ0siC_C;r_WSCa>RI zZX|XV-}6Z>lWEeWTNQC6-Lo{Odg9(T#c@ayq*w)&Zpghj=JqW-Bg zVoR-!5;Ab2mT3)zkG`9m&4A7+nzNRV zCVfTs42liFvl@Fu_3u0-vhz-W!_g|Y7^0Xr(02JHHvTCgsoXCr@%uz$fll=yvXp>0 z(w=kmUD+g>s5o0zvP?Q^dR4gQQ@0aB{IBW`jrC&f8P}(sgfcrqVfKaBrgikX#OU@1 z8|TUQb8xio#bam*t7p%wJMim_d{^nEvk`gnb7$A^fqeu%Zn+c$z0cAbQ zx$PH#k%ue{IKZ{-k7Z+R^SCq|$n|p_a5KSAr8!CwEl1BHj zO&2a&e<_1{{O9HWY|H;kaqyXmk=IAB$(Pd*4a=wXA#Beqlsr%0F4KEJQP2$*lI{VE zib9kHytt48`uiV%ayQ7FyZ{^&E+|%Gf|6=o6)DYt%9%$5Jhx`GxdWLrp+%{R;}MAa z?;Q~>q+gtRRT1!FA^bB;hkB=fCqEtTxA)sOS%{7|igsNLePtTjswW}Cb4DLZL|;k)drQGxc->}((4TqlVdoIn`qO6Vk_UCqJDo#Xy!Ys zI^(ScV_jKZv19o;LN#9QgbdOPA_H(oY3t_jVnR7RUgIb)?fv%l(YbmLkIYN zF9p|j?4V;a+`U<}?$$4D7eO$QOUSuPd<^W)_6gSCTMJDRQ@(vdvVH+ptCe2U+FdSXT4KXVZ$Jk{aF#DM z=3#5xPhR#5)n4}cfE&IULwe<14PU_e3O#S(1914%@fBseG4r8j>PpF6-Kn`ndGnum z%-3J%J5q~dhEZc@yQ_y?Ha}B`SETQUU&l|?Aq;{RIjd-0Qh2kKgnWCdf;^sBvh2~f zuI;bN?Z0&@6A2-@UICtm&|9V-wQrhKoY;fLnmw@LT=Hu$FsYCmZ@f$L#G4??%99)o zunI$23O{KO_VI_kBqRqg*IM@7;!nsRC#)%x>lSCIgu{qw#^wN(>O>nj<7m8emd~Mj zc)nCrnLlWe$Rz#cp0dDVvwH2aIa*|xKR4})!qa{yId!iC{5QAX-gH;XeO1?NG`Xzy-wwl6h=_SZ|7n2KC~p%Uao8-Dy?rSOfF&Kzp1pi zmdTHf#;3Jzu+9nL|7=i-%{IAkzq4=h*xDJ+j*3x2=?hHus$k55J)S14JU!`K-Jx?c zXZ7y73jWnqm{hv2o*7~GHuo7scCWKMbHw6aVbS^u-0#RBO>B$lByc6;O=o{8Re{!0 z;Ap1F0D*tYjtJ(P?>csE{D(W#MpWn#PJjss<{X~=L0qz+|5Ez~{_%Xkgt1IJ6Bkh7 zUm7&E@QbBX%r5`(qdMj51vFuz*-WK#OquQU4}Rik@s;$@@l~c*CKfsz>j>8cvi4?z zqxHJm2L9IiRxl~O8tY9UdzP*bJGX48qUyko_;gy?M38PTwxF%PS-yfpbhT`x{(Oe{ z@q^C!1)m(=>_V3PbY?4Ve(+IkwO^xEZo$<&sd*|{g@Rs_lynjpC_CcG99~IOHo(!I zuAi-{@gAPx9G$Nt&6?9_LQ)cuS=ch;@?*YXZqDT{!;N@{0K}Dz%Dc|RJ|+<%wCh6V zzRWTF@NHOKz*7g~N7T8)!nU4DhKkRV7`492!Zg*ti_N7!LhD5{G_Xg-BUGr`-$FjDmrJchM`PZyU@1X)s`9j`q*GwPL*v0| z({-Ym)G&il#!ieg=QEFT@O?r+`lOy5UN@opt9-s=`B0f&N)9Nyj8OlLa)?A+_>B1} zf{3WX_P8modF0NfP7Gpy?=@2mNO`1~Z~xLad16kUN)~1a?d_sMhnxD3!`#9N?|9Fxb-m9J#N#V6D;NlJTB zQ9+L8f7!c$2v|IyL8@LI`qJk)MY8Mh$Cp%g_23&e6h*OR!;YE~`i~UL36A~Un1RQ5 znVDNy zws4R)5P$ehQ(TmRL)iUIZvR*OCEEp!?Qjrci8-3_%`&n@ZsY8LEns82`puZLxu``T zs_qjY|GK!uz`N}D{%s0rR@?ONMdd1={g}22fB^5yy4jK=t%5i~@5mRsTfbXWzv9C8 zm#@2mG=zb(Zwv6MR<1waTa3y!rW5lypB^v8s{)#n)%#;|@>Mh+@3m1*`mWzVqr9nH z&9K&j&!?D$Jx?9i_ZnRM_7oPPR%5RC+NMAMT!Z*m)P8%Ge4@t`A!Sfybxc&Y5!}bS zL~t5e0nP1swBYO)-_}&XTX_04AD`jHC8+(aC2lbwse9&0%<#W__+LRS$?#vT25!`( z{QH-$_zCEqdx<{_GeKZ$dk=~|J@PM~;K?TjCtCFmo0;D`PV@zZZ-Z**iameZjNc@b zxwqz@FOb!e2(?eFP8=r6o9y})?L5c;Al9Yg>l9j6XfZ(|_QaAZn33{c_&_q?{QMFH z)!%TC5E&;tyv&r*rK#98yfc%Mu%PZwUzOrG5$9nW>pozbbCcC3kd^hf4XDO1d|`t9=NbfK_E>Qhu0XXF*3Lk$1U&t>L@D&EeUi`yxy zh&&;?{Ii$n6ur%|>GgMxP0)~oL*{7jVY>+5mX-C5m%~#Nji6!8#A}cqRzf7I1P{8M zCs&TpsXG33k5;R8woOQMm=k;aHPQY}Q*F0b`hKa9`MQGu^PquFaepVwKe73PHvx8# zPTb3vKUU;7h8;+)h|H7N&?7iw^{TW1Q@9#>gtA(0e1GTw2AjwAu{76sA?rAwoR(Zf z8usb**&+S~Fm5KMMb4E*QZ^sXAXsPUw6W*R@h9*i96m=LqKdBYjjl zFV4!wo$j$)rY@!Nc2X7HEj1r`*E+xHO@9@|tr|b4v|0IMczc5gTjyoUr@&+-HR`+{l0A5PF}3)-dO4+qz+D`u5aabJocqA zyM)~6lqYvD;lexQ*FmEZ>!~74bLLm5u^NX)&wLfUsyQ+JM-FF|oAP@8WYSz{Q^3@F z^8c{%B&<+0sEIP?&bip7<~u^U>EugU>5toq!*XUScfU!)wTF?h3@aN>@{om{1|O<(0sRG$wJAG)0XY8tc)i-3QA(ChjY z_5jBIy^CYJ_9Wwqxsby$i+dR>;BB)uT067$<+6hXe9{9u;bH<@e?kVBII;6`yDk}JICqvzzrZ+Jh-W4pE><>y>93?Mlv3?G-~ zJubNK&pq{K@SdgaqaXd-o|&rNIDM$9=ugj+*H7^sF%-RVMtn~nPBX0}p5g7u4{~dx z`@fp=^SJhFANZLA1A-^~6CzVQie5&(PPqtRA_Hr&33tcN&Mm!xThE?|1T?X~e&4lw z8cUAw51kT#zi2mrVNI*1Hmt1>fZvL1{l3-OqI{eO_?deAH!-x&{WqnwgV z<4!Cdi+*0)^>;DL#wXfWMgB50XwK z;|vl*C;aAOGKP;=%OX^eSrnCP)DFM$Fkhf2Tyyp7t#KW0K0K;gSBpH*#M*Zzp3mSGj`(zKc&d>9Xlp_%6IyJ5kK>>sVwqqjl!?5MB~bLDoX$OVE7wj zcI)q~-@Ra{pob$oV6&)lfqD>;Ma81}Bi=KcAH1;CU5bHQ<5Eo8hwJ8|%oGzxGkOPN z0j)k-;e@7(;V_B=DOkn?!bD~3F&^|HX6_o@Kj5{1L2Nc5jOd+L82(F()##vJHR zBz*#Hr`U}aX8(s?<|M*cWd+MX$Zrz!eqrL${T!2-^pBh9lq-x)kxeP7V+eRR+M{f< z*ozU;elUEY+l%3}b_ziiHhEVgfqyTXm5|@1dEPQr)TB(?Rn_S_Jf!>Vsl+HW1HrhG z9f#e}W%mB$0-IOj!JBV6BTQ;)v|O1L67;&+p?iP&lMF^y)(y}rpLf!AjmGGt&+=*{wL(+3HUs{XSrr`phoTr@{jzSL}i@RP?>K zF;8J5Tc{{^fo#UuIc<2sG zDJ&@Gwl)e@@y@{%-yf;CQksy48yM`wkDDCn>NSOzDyZMqD28jnPw^zCwdDws?zj~v zJa!{Z%_}B!HbMM!m4NF@@;47+0vSQ0qso|?l%znqZ4qAcHZj4v1gq($PDug%;9i+H z4Mh4$p1&gBy)fd*20xz+%soJ4%2udR8)Ek6N51=P#8VL2$i^wko&V)2D6l&sfoXg) zhfxzIV2E`OPx*n=DSU|>@S9b|a;MsnKOjDdvAgeYUu9k_6LH~w9Ypl##4IKEA`OIdmIqUBZiPJ7TI zzaq}Mve3G3XwW)jyBJF^{B2wBpcAIq$=h51BnI)C>#s;_UGial0DS=zd%*^+cf4~s zkXJ1q1o4I#B%+XA61R#h`Fgo>)q{;%e*;|-s7S{n_eAI}+1yp&?;m7rM}t83xuq9q zwp9pfXc#Lq^!+`s(V>}-boZ)VX0R;Wz1^g?44et-@`4f~!bcaGlF%hSWUJqu@CP0TahB`gaMcsPNX9c zScMX`L=lfqpPvlKy-|CzQ(VjL!P8!@oXVY!3%Z;M5O;gXphDNaB&Eq|uBym}uX5tk zngWJ4Xj}TbAd^Z7)ANQxyurLEyQ{9j&Cw{^M3lCWtooG|nXccs_oyc(c#CiZLDO6J zAE{g9f|2F>Y2A@xLtc67m>@dpsw)PjH)x(|M~R@MB+;#b6#57oLe2dt24D!5QO>IR z-Sz?_o*e6|Pm8@kXYyeak**i#`~FoT^g@iTDt%OISC`Q8c>$iGuu@$Tm2b)aoT~zm z-z~dTv-WkY!4h%1*ib34uzK2o{6aci&LFh7Gy#LFJfE0Vjk^2o0lHJt^hl(4( zQg_E~d>bWOxf<%!Gx>$q&DvqK@=P5(y#^m9x+v8vOKagA_Bx~AO$0MtGcF#KIec@@ z68d?TU^E&z{`QIJ-n_^F7n>$AYuTEEcp} z3v3)0bex_LSy>4d=4}S$mFw0-!|TQ9lEwL`d9fBC#Wb8Kpf$k4#q=5O)B<3#3e=vb z#q7-+uLq0Ejqmxq2evmqUY#@MWz3nbx96>21qlMy7CZKVJ`w(H9kXLMlyGA=1H{8Z zclrV7CresELAmkb*eY1XYp{wG8H0RiPZOTey79M#c)Jy)lh2D~b+>}O%bo^}=O%x4 zjCcjl7cM3jGfNi50jI(u4+-MK=q^SY@?@*9>$jGr9lRlEB+?Z*c&;Xst6*)P7*|33 zINNo-!)6oTOzB_)-wmO=cJ1np$*4cNj@)x&H*K}}7<7DRUNrcs);#!E*(@f9?S*yq zt@-V(Yz%DtH+JhZN03ODrb+!pOHgvC_?41k2P|q2C1rq7Of(3G+Y@1R?SKgu+PIZ7 z`ix~A+QnOk^sB)_M*xS6oeMalStK}4g_@q|;C_X!`a#F6Ly^U^RQ^ zh50KMZ$c+6u75f3t_tu`foD+0oPsw5k!Ld+4)*ZmId}(!1^3?vrimSS)zv#gbZ@?E z;=@vpc-(4W&iVIh&oAn?|2q@qI~tU~{P}zw^Z*N^pBE2KJIEOH3bM{Tjo)AQkW6Bn zUH3R70uMRxt;;6oLF@)aIVamFDI&md3Q|%&&~1Tn8uibDG#m}4omvDPSD#Y|6ib(_ z0p3&$Mc4;yeL*}5c_jCyU2va>x`Z{v-z;=@LN?H0?gx?dZ>|$?*6`%Ifrcc#LxO_Z z%BMT0?OpSNqfvLS!qu}nKRBN70O}0(u>0XyH0-=>fLR-4(s|YsV)SgSX}40Zw16R< z(4o&j789t7;5-S;Rcqf=B3eyF2es#oowIq68-lcafaB#rCiZ+joCQO=aSRTn@%3<* zMK0@J*MnB2?ywLUI$-}z{&Kp{eV4!gR`ULf$24>YknRW9-6d$<4ot;C=Rq$|Q4ow! z=~F*!yUGBZhEh&h^ci2kX!Q4U%-g|tL(t4lqscxQWkH6&RbvNRCfnIu3Bbzf!cHG9 zLh9?v-Xxh0yF&nsB|Lw*ffAeEM?t~x>A5@2+L(N|>DfD}3yH6Bu)}(ZKm`;lJ;LQy zT<5j~yV_+BbbMloT@xgBvhadfAa;SQ@pF&om2Ok%8U7>-qUS8&dm;K96vGEu*~q@K zDl4rQ!96^vci7}?#u%`JW^-VXhb%;JV=Q+|bIf6bU40Ja7qo(FzhN&u9 zECsG+scr?4OOz}Rf}?bQQaCWp0#(}z0ZgBRLQW=EF0jaZ?1JB?{axJ1f+&%$`b4F- z)7+(zfK%YA&nsY?i)J5$0vo6rD2eK>=LBXna0Zasj`4yFV85sCp?gmZ2Rqvo;qKjA z%I(l150rOzqJ$RUU(B9c-Y?r45N<{E$zYigNqud@SDG-3IT8Is7H4rgVl!oHn(f&8 z8g_zHYi+jUFb3b8A<9$YnkXXY)ry-xH?Q`5hXJ726}lP+8t0)%Q4=*^vN_oKcHF^n z+SWBMe0nA?!RT8!!_oEDT0h*aq;jD1P36ixO0wqk7{q>5Qwe+^nPeq(V2o7B ze?hcDB*UB%5T^eBcqxB&qgIPoz;X;IKrzm0Q||e1#_f1hZZx2@I%IkmVDlTNM_s!A zhe(Sj0doLl>!Y1%H$B$I10n<%@;XpQxB-ZRT^@(CY?(OAsa~OVL)7GpTTfzMLQ?-< zMak`Yj6*z5R(&oqjqe^HPy^P%IK<>CV(70xAn(?toiJ~RFX$)J`(R;e$_mMH=GWop z(i773re{l!KmvV_xardw*x1wQx77kVd0TmMoK!|Sn<|U%b%!~C;BN|=hY1B%olwa4 zk=DIdS48y619q0QprkJ8O?(aQ;H{h?>WT`Ou6WfEW+sLH#4%{zDvPJTyW_0|vl0QP zeDa71#!!WSVNo4(O_CFw_t3*Kk5~R>)fm9CTPe;}dJ>OzS-a^sv`8PF^|Y+W*tsx; zSk}m7(n7hewjm_B5e<76PP>Y8T;9hZF;>DdH>d%A~uK$qysJ(HZ0 zm8EiO0>!v#AU;#>7!)zMO;tfL<-2i83V{-XTWf(f;3lm*2f3Tp8DPG-VrdRr$DF0t z-Ampz&x(XW8Q@| z4Vw^zn$}Xh`v-^#oaPe$n!Zl0>M1X(y=P*plY0+sbMt*xA`Hf;Q9bRafN7z_0w#PaeLAdLtM#Q? z0vk`}`)A4^S~!B!t^&bzc1p0r%fVe>U+z9BC?f2h7PvbMq_nBJ*XEmKF(WFkHQP3| zOw!uB0^AGwu3nE>3pi^gH)0Up&zDpJWbWy+BT;dbB*=gvJi@;Qp|fq)$PD1U^2SPq zEYMZ=$FdrwdYHCr%id71a=u3O!`{aj>c9u`+ELmHLr(2+5zN}Ou!sJq>Y8qGE_w9+ zy|qT)CL6oT9J>Bbiv*iAJJVt*%VhYS^G^Aq_cIh%6DZpq== zd2-GCL}2$sz?p(&Fa`>6;6 z<}s(L{2`DlN*RXr%)|RzCS4JmYG}>62P_+4dZBRpl6r=_K!*xRv4_cbjThRHh8bL?;Zn{OB+i9=zmTEQCGyyn7G<$f0_xMamRXsXM zcfl#Vq5fiHTB0n>w@bwG!5TBe!@h8Tdvun8RN1b#1?SAnh4?sPnB#-ot?NNJb;RVL za&HXR*z(#70oKlOST9-W6lNG?jwTrQZsz1L)qkzof^4uW zh*;`oh9D+GTkw&<#v&?;#t!Ze)?XhhnX}3`Vo@s62k6!Hz+f*)uEIR`f#k>gLt{un z0(*;%hhe96R90iG<71x0NVh)6|GFEk&G)0J>vCQLhgfsp#_M$oQ-C;KtX+w;!2?o$v$gdxp67@WvA=)#={V)l$Ud;r(Ec`iQn{#lp`}?AXo`(#2I<64+=R;5lP! zYn~Gpg(*@_#>`cIJWi8xn!8u!BK(jr%Aj63ovxKoSFeAajp0}__UmBefmTC1!wXqqw7HDGuKyZ{(nl{YK z9YP)$)l;*1naJLP71&$SQxM7-xJ5?zU+ZBQd~~Y!2n_){k}SbRy~s~wzuBe3rK)73 zo0Hz;qya|ioNJnR3nq~7eU*5dPfUw_-D~I(Xz3B<;^9t$Rk`H_8-iO$#>6I+iF4!T z;@}88+s3sQ2BrzkbUHjwEqpG-D_2YoB1LT`Frrp*Zvt^nX56H)3X8|i&*np8ymgUE z(!h;V#p@zBbXxfV>2$X8DM^Vhf|dZ36rp}1^$5bteBcxwy#QH5_<+g`hM*~sHk6_hC%vjQ;zv@<+X(A z#bV2Tp2{^+wkEB7ydT$YQCI+T2RJb0RR{^?*jZ^jVt>HP<6r_2h;%vM4xQ%#1-M{^fIJQPPjaC_P7fRn4~2!sc-E^7 zW0?i`s*4N31dETQfqBfxK}zvWs)&IGVqOlXAv3B5zHsAAEdLVx`sFzM8U1$VeVwzX zPV4^_^iBwpl}(UP(&>knVzMT9r$3#XP&}^i#Kxywkab%@_TQ4~#wjw_a zGq>@f5rq3FCUU?FbxC7J0x`GNd`H-5qebd3=OjmLFfHk}P?WjX7bAnx)dDQYch%=P zhq3RY(9(`xvF&=8t(66Q`3NyadeJejT*zVqtyT#`YJnj({8ySBOmntys28*avJf)7DL6MA= z-%`Da_*^q%DL(3co7INjmflwbRN%^eubI$iljbusiBkat09`iT6AgIw-(k7lJDD53 z5d`3$^{5dvBOWlkvQi_l({@)aGr6ZfDRd<#yII6{<2}ab=iv%RxduAh#S3*Gi}H#M zo6LuPayJ8ec?zRani|#iy2H8DIg|@?-E*_)$aQePbF{bv!e2JO6O<3*ePT5%y>TT? zf1$JSr}6%l%B^4uX1a=A1`K(vkC{h%fwT+Oe~q*YF{Eyu?pn`Sv=pS9CQUl3mZAkz z>&(y6hoZZz(mHabl!SzePnO7B>fRc#NV6=26HWELc`}ZBajbP z?U;2~2x8sC)1}&k6=s+wEe%KjRn{86ZASWIrwK6oygb}eOD|kZUcCw9=94cjTF!s@ z6m=)5gN3$r6ez&|cUS%L4y0HIkB)A7*^7-q%HV*0E(w;%)c@6u$iCAcmR zaFsgRu^TO$o6LdKd!oXpz8U`A6FFdJ)Y1z9FjYoqe-Q{=v@Km+ybp2&;XqZfMSYr8 zRg7X)70p0ZaW2OJWg+S|4Kj-ix;e;$)SoC?3}clw41^%N*=v;n)1LsODhbAaSvQGi z!i++=N+Vx_vS8Oy!ud&%C)PjW4*s5Pvz=*bx|j*M$s8W;>&3F^P{qv+RNRhvb-(*s z0a75=e&bsPBnp{|FM)|C-jqq$tQ?VHqGv%+bcj*n@&$n`n3Y?INvBzpGg(P0Lgf_nOjIpahW6C37vDOD&giLgE8wYo%{o+Z{qQ9q{A|}j{UjIc=D)9> z#J=9HpZr*ah7wbwqXl0pm&eM%KB@}IAdc`#g7%Kl{ll&PwjRuZMX79{kSO9Eq7Rtb z-c8&*C}u!cJcD}((i5!O9iX;NSAGvNb_0F8)ULu?DKPi5U#cQ(5Se^(BNcqh74<|# zMQ}XrTq$rw{v?zV521CozlIml&oG^cliM2z0~$|O%2$RQ3gEX}F_!>YuJ0+qp@(u_ zuYyVfCBPT7xa#lELx|SR$wvgm0&IK>n{Cl8}D$DdJp` z5R_n(^dZ7-d_6f^0Z25NRvG`Mg7MUC3Zy}|Q)$9Z6I{WjSK)8VfI2WT;wHdA4$){x zG@&XmYcHKrFfR=gP*yP0R7fklmmz6k?*k%*#$<$UXWFmLe|g$E5dGYV>EX%_3^CM1 zwEm?oaU5oy@$V{5#T;fEXP8ADc98!M<_KYxY@aEClI^ke6ikcq=^T)8cDk$yq@3Tw2Eb#XGX$XxjV)f}V(B^m!7uTVfH}D%%4jCUZ=mIsg~S#Y{VCSd)NUv`BJc?B%^ z=pKqXA}Hjh--oic)0V@=WDt7~x!nTStb8vR8OBGPou0h5 zot7pkfFk-I{v_~ERvLP1t+(sNnS-KdyXrOc1n-E@k7k2<#ye>NQvDcZ86R?SiSi+o z_!HVG7%4L;hwk6nToPUkuoM>NsUpq>|MuKCf+u9y9zzCQKWpCSClgn9f+TZ4`*88x z#h=-=ZD_49fHGN87Dk85p16vy}?U1eR>^^)F*N};PXb9>fEvaA9 z`~z~QdJXNg&Bj?W0ygR~*eGb=V0RYM2M^{#!;I{TzS-Bp!Eq^UHvLj3v45j-fq&B< zq-;3RW<0eD^ND^F4?TZUUV28n8*F^Y-793LBzGNuKpu9)*_queYK@KBy66D@0%C4P zGFNQ_)7dOkcIJf`Pi=s7>0(+~9DQmQw;ts9(SO(-$-RIT{++BlFEzJ-l^*K8^XZ5Z zr1AbP750#>!@2i#xXGCGb-s}+RfM5FfgLwKFm1h}bVoZCnkx&cnuA_uwost^!;=`4 zg((=Y4i%+~b{GIP8zJzN#|OOd5Y{JfmADr6a8-Ej`#tR=ca6eiDw(~F7LZq2gPqTv zED9LKb)?=mhaYWpG32TB9u64gVmB4MF~MGetzoA2yqyc~^R5V5-6;t(DxGU?h~utZ zP`t`v*XrWi7l(QGR>>2{D9BuX>}<`2%O=E3%)9AUXeUPro7D30a1|>KY*p%B;2~Kj z$5c;Gx(IQD=;U1Dcj2*hB*OCTi9YR+rvoIYpnjbN2Fil4AFTfVz3`C0xXkIRr06(B2Bz_iI34nvPu z0G5>#ec<33*Ls_-rQxh<^DT@syU`(+i8PQH;HT=X{srT%-Ox$QCC(ihnK;DWVT|qN z4qwAkdbxwGEuIFC+<$vq-A>tJIn6*=TLiQf%sE#scz?oyH!2dpEOfkKEP2xhfOFPr zlsA*ZI0AzdE1$R(F;n2DfVcUFXn-)>_GC1`QyjMK{tl?2M}`KqpLcEb&)Z~nU6>0Q z%~W)fIdnhm^tF-R__DUSi~PMjm30>$FM2p|Xl;O54C~Blk>0&I)<|o0XW8`Tz*lX* z1)Is-?0>ztww;Xnwu1mQ1QrI0S!*c;_YkBj|w(N*)H=N`T zEc6Fxv<5(4DB5jHE(E7oitLE0TeJNv_d-p^fea^S7~ew_~jTlNS#!bXlt>Z;0LxLLcF*q7b7$ca`eq$&e}0W$4L#~{Z!X5A!QMapI4eX&&slcblfft(eKrM@R04vmiz!j!o1Pe^#rWu)e*s1l64|V==|yEo&Q(} zWcoU6H2w#yqxngQP|#)1L}1f$7yvdkRdNLD*?x(wbta4cvE^H#F>Zk3`~BDYw-^|A z#oXW41zDIsI6|giirVl4M|j(Rh8FSe+WJ2rTy99#JSQ)3>!<{z$ASNV#6U;p^Q#&Z z?3IA%@?`4P3+dwtk0-!ImAJQZXj_Lw`(con;;n3EoN17-x&CSey@LYYA>{NGiJAIr zinzOS>mP3c=~CxZ3BJ=AtP327#wy}bk!1KMt7)#9NJ{n==P?=R8BPPt?TQPj(_wl{ zwfNpF1UcGvN^p9H{!v-7|WCHa7!VX-jD9{jM(TsnKxY&$S zw+5vK=*s;${tJ`>v0elm{okGk)ND*%g!OXC1U(T4NHHk*Qm`@8PT9t1F?`~Z0Lst> zz>L0#qhU@oXEcDtloj6uC2-MgNC1?xK*N5eK#4nO6TfC+^lT@o*;~bu@~5DuPjMoG zTAeTp&U@1d&^eM8bDqTXGbxqn3a`OtDgi`pK*cQ%aK&xaNPy3)0SvSGkI(#}I|sOQ z0-)`Au_PF>JsB9-7Rv4KOGS8pHN?YzIrWM?(d{xoL|iDSQP{Zowt~p%TFT zC?!E-98i%lMc**on;d47A0f303~XZIR<~Bf_y6O4z(gn=fG9oVpTZAqXPjmWI3c0_ zcnJb_K?tLvbEi1qG62U{3e*5|`xy(!H%04iXY|(TX+s0)l)xnJY-R^fUMgdT>9qK50VQVBhivp_3*C9QU`xv4*6^%Oz$)TSKy#-?C3S0)xgnfu#u!%z zJq7hPKhe5fOi)0`pXtuh$s}|d({55Q1yHL7-`bE``K9RbjUc^B`dU6OdivMAU%)MM zjUOY?E&D9{Clc8K;?rV#0LDCk@lR|YqX3N-V3*U`{$CY{^@EL#lK!6;|Fa4IHzc7p bN1urnaBDZc%#)3VzTny=?O*fMEFS%TCl2zj literal 0 HcmV?d00001 diff --git a/doc/images/launcher/vm_plugin_interaction.PNG b/doc/images/launcher/vm_plugin_interaction.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2a00496bbda4c51a87423e7d4235e3976d7562b0 GIT binary patch literal 46241 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 Date: Tue, 20 Oct 2020 14:53:32 -0700 Subject: [PATCH 37/65] Fix autocomplete text issue on query change (#7392) * Fix autocomplete text issue on query change * Update from invariant to ordinal case for exact byte to byte matching * Add tests for checking when autocomplete should be empty --- .../launcher/PowerLauncher/MainWindow.xaml.cs | 3 +- .../PowerLauncher/ViewModel/MainViewModel.cs | 16 +++++- .../launcher/Wox.Test/MainViewModelTest.cs | 56 +++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs b/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs index 74217db0bc..5d24b77631 100644 --- a/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs +++ b/src/modules/launcher/PowerLauncher/MainWindow.xaml.cs @@ -336,8 +336,9 @@ namespace PowerLauncher { var textBox = (TextBox)sender; var text = textBox.Text; + var autoCompleteText = SearchBox.AutoCompleteTextBlock.Text; - if (string.IsNullOrEmpty(text)) + if (MainViewModel.ShouldAutoCompleteTextBeEmpty(text, autoCompleteText)) { SearchBox.AutoCompleteTextBlock.Text = string.Empty; } diff --git a/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs b/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs index bec5b2fe3f..195a51a23b 100644 --- a/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs +++ b/src/modules/launcher/PowerLauncher/ViewModel/MainViewModel.cs @@ -871,13 +871,25 @@ namespace PowerLauncher.ViewModel } } + public static bool ShouldAutoCompleteTextBeEmpty(string queryText, string autoCompleteText) + { + if (string.IsNullOrEmpty(autoCompleteText)) + { + return false; + } + else + { + return string.IsNullOrEmpty(queryText) || autoCompleteText.IndexOf(queryText, StringComparison.Ordinal) != 0; + } + } + public static string GetAutoCompleteText(int index, string input, string query) { if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(query)) { if (index == 0) { - if (input.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) == 0) + if (input.IndexOf(query, StringComparison.OrdinalIgnoreCase) == 0) { // Use the same case as the input query for the matched portion of the string return query + input.Substring(query.Length); @@ -894,7 +906,7 @@ namespace PowerLauncher.ViewModel { if (index == 0 && !string.IsNullOrEmpty(query)) { - if (input.IndexOf(query, StringComparison.InvariantCultureIgnoreCase) == 0) + if (input.IndexOf(query, StringComparison.OrdinalIgnoreCase) == 0) { return query + input.Substring(query.Length); } diff --git a/src/modules/launcher/Wox.Test/MainViewModelTest.cs b/src/modules/launcher/Wox.Test/MainViewModelTest.cs index 9675c74dd1..8701df2e2a 100644 --- a/src/modules/launcher/Wox.Test/MainViewModelTest.cs +++ b/src/modules/launcher/Wox.Test/MainViewModelTest.cs @@ -207,5 +207,61 @@ namespace Wox.Test // Assert Assert.AreEqual(input, autoCompleteText); } + + [Test] + public void ShouldAutoCompleteTextBeEmpty_ShouldReturnFalse_WhenAutoCompleteTextIsEmpty() + { + // Arrange + string queryText = "Te"; + string autoCompleteText = string.Empty; + + // Act + bool result = MainViewModel.ShouldAutoCompleteTextBeEmpty(queryText, autoCompleteText); + + // Assert + Assert.AreEqual(false, result); + } + + [Test] + public void ShouldAutoCompleteTextBeEmpty_ShouldReturnTrue_WhenQueryTextMatchAutoCompleteText() + { + // Arrange + string queryText = "Te"; + string autoCompleteText = "Teams"; + + // Act + bool result = MainViewModel.ShouldAutoCompleteTextBeEmpty(queryText, autoCompleteText); + + // Assert + Assert.AreEqual(false, result); + } + + [Test] + public void ShouldAutoCompleteTextBeEmpty_ShouldReturnTrue_WhenQueryTextIsEmpty() + { + // Arrange + string queryText = string.Empty; + string autoCompleteText = "Teams"; + + // Act + bool result = MainViewModel.ShouldAutoCompleteTextBeEmpty(queryText, autoCompleteText); + + // Assert + Assert.AreEqual(true, result); + } + + [Test] + public void ShouldAutoCompleteTextBeEmpty_ShouldReturnTrue_WhenQueryTextDoesNotMatchAutoCompleteText() + { + // Arrange + string queryText = "TE"; + string autoCompleteText = "Teams"; + + // Act + bool result = MainViewModel.ShouldAutoCompleteTextBeEmpty(queryText, autoCompleteText); + + // Assert + Assert.AreEqual(true, result); + } } } From 4da4673e2486d81900f057d3779b0bc55be391cb Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Tue, 20 Oct 2020 16:14:48 -0700 Subject: [PATCH 38/65] [KBM] Ignore IME keys while checking keyboard state for Shortcut Remaps (#7386) * Ignore IME keys while checking keyboard state for Shortcut Remaps * Add bool check * Update Shortcut.cpp --- src/modules/keyboardmanager/common/Shortcut.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/modules/keyboardmanager/common/Shortcut.cpp b/src/modules/keyboardmanager/common/Shortcut.cpp index f0f2ad78f6..26542dc4e1 100644 --- a/src/modules/keyboardmanager/common/Shortcut.cpp +++ b/src/modules/keyboardmanager/common/Shortcut.cpp @@ -652,10 +652,13 @@ bool IgnoreKeyCode(DWORD key) // Unassigned keys bool isUnassigned = in_range(key, 0x88, 0x8F) || in_range(key, 0x97, 0x9F) || in_range(key, 0xD8, 0xDA) || equals(key, 0xE8); - //OEM Specific keys. Ignore these key codes as some of them are used by IME keyboards. More information at https://github.com/microsoft/PowerToys/issues/5225 + // OEM Specific keys. Ignore these key codes as some of them are used by IME keyboards. More information at https://github.com/microsoft/PowerToys/issues/5225 bool isOEMSpecific = in_range(key, 0x92, 0x96) || equals(key, 0xE1) || in_range(key, 0xE3, 0xE4) || equals(key, 0xE6) || in_range(key, 0xE9, 0xF5); - if (isUndefined || isReserved || isUnassigned || isOEMSpecific) + // IME keys. Ignore these key codes as some of them are used by IME keyboards. More information at https://github.com/microsoft/PowerToys/issues/6951 + bool isIME = in_range(key, VK_KANA, 0x1A) || in_range(key, VK_CONVERT, VK_MODECHANGE) || equals(key, VK_PROCESSKEY); + + if (isUndefined || isReserved || isUnassigned || isOEMSpecific || isIME) { return true; } From 3801ad303057dda7b16c47a68d745927917cde6e Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 20 Oct 2020 21:17:06 -0700 Subject: [PATCH 39/65] LEGO: check in for master to temporary branch. (#7436) --- .../Strings/en-us/Resources.resw.lcl | 45 +++++++++++++++++++ .../keyboardmanager/dll/Resources.resx.lcl | 8 ++-- .../keyboardmanager/dll/Resources.resx.lcl | 2 +- .../powerpreview/Resources.resx.lcl | 18 ++++++++ 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/core/Microsoft.PowerToys.Settings.UI/loc/ru/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl b/src/core/Microsoft.PowerToys.Settings.UI/loc/ru/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl index 02e547b7cf..4d4719db25 100644 --- a/src/core/Microsoft.PowerToys.Settings.UI/loc/ru/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl +++ b/src/core/Microsoft.PowerToys.Settings.UI/loc/ru/src/core/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw.lcl @@ -280,6 +280,15 @@ + + + + + + + + + @@ -460,6 +469,15 @@ + + + + + + + + + @@ -496,6 +514,24 @@ + + + + + + + + + + + + + + + + + + @@ -928,6 +964,15 @@ + + + + + + + + + diff --git a/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl index 82e830901d..8e10833418 100644 --- a/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/ru/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -103,8 +103,8 @@ - - + + @@ -178,8 +178,8 @@ - - + + diff --git a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl index c9afbeea5d..830346b63b 100644 --- a/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl +++ b/src/modules/keyboardmanager/dll/loc/zh-Hans/src/modules/keyboardmanager/dll/Resources.resx.lcl @@ -398,7 +398,7 @@ - + diff --git a/src/modules/previewpane/powerpreview/loc/ru/src/modules/previewpane/powerpreview/Resources.resx.lcl b/src/modules/previewpane/powerpreview/loc/ru/src/modules/previewpane/powerpreview/Resources.resx.lcl index 3f4edd4ea6..b498a16939 100644 --- a/src/modules/previewpane/powerpreview/loc/ru/src/modules/previewpane/powerpreview/Resources.resx.lcl +++ b/src/modules/previewpane/powerpreview/loc/ru/src/modules/previewpane/powerpreview/Resources.resx.lcl @@ -37,6 +37,24 @@ + + + + + + + + + + + + + + + + + + From eaec26a01276ad5e32a490966ed6bab86d2ffb44 Mon Sep 17 00:00:00 2001 From: Mykhailo Pylyp Date: Wed, 21 Oct 2020 11:14:30 +0300 Subject: [PATCH 40/65] Fix dropdown popup narrator bug (#7422) --- src/modules/keyboardmanager/ui/KeyDropDownControl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp b/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp index 971271778e..73bf264839 100644 --- a/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp +++ b/src/modules/keyboardmanager/ui/KeyDropDownControl.cpp @@ -67,6 +67,12 @@ void KeyDropDownControl::SetDefaultProperties(bool isShortcut, bool renderDisabl // Attach flyout to the drop down warningFlyout.as().Content(warningMessage.as()); + + // Enable narrator for Content of FlyoutPresenter. For details https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.flyout?view=winrt-19041#accessibility + Style style = Style(winrt::xaml_typename()); + style.Setters().Append(Setter(Windows::UI::Xaml::Controls::Control::IsTabStopProperty(), winrt::box_value(true))); + style.Setters().Append(Setter(Windows::UI::Xaml::Controls::Control::TabNavigationProperty(), winrt::box_value(Windows::UI::Xaml::Input::KeyboardNavigationMode::Cycle))); + warningFlyout.as().FlyoutPresenterStyle(style); dropDown.as().ContextFlyout().SetAttachedFlyout((FrameworkElement)dropDown.as(), warningFlyout.as()); // To set the accessible name of the combo-box (by default index 1) SetAccessibleNameForComboBox(dropDown.as(), 1); From e05146acf960fa5907a5e928ff35e1293c94fbe3 Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Tue, 20 Oct 2020 01:44:57 +0300 Subject: [PATCH 41/65] update Microsoft.Windows.ImplementationLibrary nuget package --- .../PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj | 4 ++-- installer/PowerToysBootstrapper/bootstrapper/packages.config | 2 +- src/common/common-md-flag/common-md-flag.vcxproj | 4 ++-- src/common/common-md-flag/packages.config | 2 +- src/common/common.vcxproj | 4 ++-- src/common/packages.config | 2 +- src/modules/fancyzones/dll/FancyZonesModule.vcxproj | 4 ++-- src/modules/fancyzones/dll/packages.config | 2 +- src/modules/fancyzones/lib/FancyZonesLib.vcxproj | 4 ++-- src/modules/fancyzones/lib/packages.config | 2 +- src/modules/fancyzones/tests/UnitTests/UnitTests.vcxproj | 4 ++-- src/modules/fancyzones/tests/UnitTests/packages.config | 2 +- src/runner/packages.config | 2 +- src/runner/runner.vcxproj | 4 ++-- 14 files changed, 21 insertions(+), 21 deletions(-) diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj index 4691001006..0f20390820 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj +++ b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.vcxproj @@ -145,12 +145,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/installer/PowerToysBootstrapper/bootstrapper/packages.config b/installer/PowerToysBootstrapper/bootstrapper/packages.config index bac888e145..3e9434647c 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/packages.config +++ b/installer/PowerToysBootstrapper/bootstrapper/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/common/common-md-flag/common-md-flag.vcxproj b/src/common/common-md-flag/common-md-flag.vcxproj index 640951a24c..4a9200ebb3 100644 --- a/src/common/common-md-flag/common-md-flag.vcxproj +++ b/src/common/common-md-flag/common-md-flag.vcxproj @@ -114,12 +114,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/common/common-md-flag/packages.config b/src/common/common-md-flag/packages.config index bac888e145..3e9434647c 100644 --- a/src/common/common-md-flag/packages.config +++ b/src/common/common-md-flag/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 97a46b404e..4a2ed39280 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -197,15 +197,15 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/common/packages.config b/src/common/packages.config index 20da4fefa3..fda08e21c1 100644 --- a/src/common/packages.config +++ b/src/common/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/modules/fancyzones/dll/FancyZonesModule.vcxproj b/src/modules/fancyzones/dll/FancyZonesModule.vcxproj index 85adb7f0b4..1c3392cfe7 100644 --- a/src/modules/fancyzones/dll/FancyZonesModule.vcxproj +++ b/src/modules/fancyzones/dll/FancyZonesModule.vcxproj @@ -39,7 +39,7 @@ - + @@ -134,7 +134,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/modules/fancyzones/dll/packages.config b/src/modules/fancyzones/dll/packages.config index bca9425304..f0ed7a6f44 100644 --- a/src/modules/fancyzones/dll/packages.config +++ b/src/modules/fancyzones/dll/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj index 4352317aff..dab978dd97 100644 --- a/src/modules/fancyzones/lib/FancyZonesLib.vcxproj +++ b/src/modules/fancyzones/lib/FancyZonesLib.vcxproj @@ -158,14 +158,14 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/modules/fancyzones/lib/packages.config b/src/modules/fancyzones/lib/packages.config index bca9425304..f0ed7a6f44 100644 --- a/src/modules/fancyzones/lib/packages.config +++ b/src/modules/fancyzones/lib/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/modules/fancyzones/tests/UnitTests/UnitTests.vcxproj b/src/modules/fancyzones/tests/UnitTests/UnitTests.vcxproj index 3881b1d8bc..b04600b595 100644 --- a/src/modules/fancyzones/tests/UnitTests/UnitTests.vcxproj +++ b/src/modules/fancyzones/tests/UnitTests/UnitTests.vcxproj @@ -140,14 +140,14 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/src/modules/fancyzones/tests/UnitTests/packages.config b/src/modules/fancyzones/tests/UnitTests/packages.config index 20da4fefa3..fda08e21c1 100644 --- a/src/modules/fancyzones/tests/UnitTests/packages.config +++ b/src/modules/fancyzones/tests/UnitTests/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/runner/packages.config b/src/runner/packages.config index 20da4fefa3..fda08e21c1 100644 --- a/src/runner/packages.config +++ b/src/runner/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/runner/runner.vcxproj b/src/runner/runner.vcxproj index bf1a43a943..29d6aa0c72 100644 --- a/src/runner/runner.vcxproj +++ b/src/runner/runner.vcxproj @@ -250,14 +250,14 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + From 6c62be1818810e2dc0d3a26026cdbabd4c1798fe Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Tue, 20 Oct 2020 12:25:13 +0300 Subject: [PATCH 42/65] bootstrapper: add cmd argument for custom log location --- .../bootstrapper/bootstrapper.cpp | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp index 2cbc5184ab..d4739e02bf 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp +++ b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp @@ -65,18 +65,18 @@ std::optional extractIcon() return iconRes->saveAsFile(icoPath) ? std::make_optional(std::move(icoPath)) : std::nullopt; } -void setup_log(const spdlog::level::level_enum severity) +void setup_log(fs::path directory, const spdlog::level::level_enum severity) { try { std::shared_ptr logger; if (severity != spdlog::level::off) { - logger = spdlog::basic_logger_mt("file", LOG_FILENAME); + logger = spdlog::basic_logger_mt("file", (directory / LOG_FILENAME).string()); std::error_code _; const DWORD msiSev = severity == spdlog::level::debug ? INSTALLLOGMODE_VERBOSE : INSTALLLOGMODE_ERROR; - const auto msiLogPath = fs::current_path(_) / MSI_LOG_FILENAME; + const auto msiLogPath = directory / MSI_LOG_FILENAME; MsiEnableLogW(msiSev, msiLogPath.c_str(), INSTALLLOGATTRIBUTES_APPEND); } else @@ -106,7 +106,8 @@ int bootstrapper() ("s,silent", "Suppress MSI UI and notifications") ("no_start_pt", "Do not launch PowerToys after the installation is complete") ("skip_dotnet_install", "Skip dotnet 3.X installation even if it's not detected") - ("log_level", "Log level. Possible values: off|debug|error", cxxopts::value()->default_value("off")); + ("log_level", "Log level. Possible values: off|debug|error", cxxopts::value()->default_value("off")) + ("log_dir", "Log directory.", cxxopts::value()->default_value(".")); // clang-format on cxxopts::ParseResult cmdArgs; options.allow_unrecognised_options(); @@ -123,8 +124,22 @@ int bootstrapper() const bool skipDotnetInstall = cmdArgs["skip_dotnet_install"].as(); const bool noStartPT = cmdArgs["no_start_pt"].as(); const auto logLevel = cmdArgs["log_level"].as(); + const auto logDirArg = cmdArgs["log_dir"].as(); spdlog::level::level_enum severity = spdlog::level::off; + fs::path logDir = "."; + try + { + fs::path logDirArgPath = logDirArg; + if (fs::exists(logDirArgPath) && fs::is_directory(logDirArgPath)) + { + logDir = logDirArgPath; + } + } + catch (...) + { + } + if (logLevel == "debug") { severity = spdlog::level::debug; @@ -133,7 +148,7 @@ int bootstrapper() { severity = spdlog::level::err; } - setup_log(severity); + setup_log(logDir, severity); if (showHelp) { std::ostringstream helpMsg; From f506980e4d9c257e106a869b601b5816a7879aeb Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Tue, 20 Oct 2020 15:01:45 +0300 Subject: [PATCH 43/65] previewpane: use RAII for FileExplorerPreviewSettings classes to avoid memory leaks --- .../previewpane/powerpreview/powerpreview.cpp | 66 +++++++++---------- .../previewpane/powerpreview/powerpreview.h | 2 +- .../powerpreview/preview_handler.h | 4 +- .../previewpane/powerpreview/settings.cpp | 12 +--- .../previewpane/powerpreview/settings.h | 5 +- .../powerpreview/thumbnail_provider.h | 4 +- .../FileExplorerPreviewSettingsTest.cpp | 4 +- 7 files changed, 43 insertions(+), 54 deletions(-) diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp index 7c00ee4202..0073f004fc 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.cpp +++ b/src/modules/previewpane/powerpreview/powerpreview.cpp @@ -10,38 +10,36 @@ // Constructor PowerPreviewModule::PowerPreviewModule() : m_moduleName(GET_RESOURCE_STRING(IDS_MODULE_NAME)), - app_key(powerpreviewConstants::ModuleKey), - m_fileExplorerModules( - { // SVG Preview Handler settings object. - new PreviewHandlerSettings( - true, - L"svg-previewer-toggle-setting", - GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION), - L"{ddee2b8a-6807-48a6-bb20-2338174ff779}", - L"Svg Preview Handler", - new RegistryWrapper()), - - // MarkDown Preview Handler Settings Object. - new PreviewHandlerSettings( - true, - L"md-previewer-toggle-setting", - GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DESCRIPTION), - L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}", - L"Markdown Preview Handler", - new RegistryWrapper()), - //SVG Thumbnail Provider settings object. - new ThumbnailProviderSettings( - true, - L"svg-thumbnail-toggle-setting", - GET_RESOURCE_STRING(IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), - L"{36B27788-A8BB-4698-A756-DF9F11F64F84}", - L"Svg Thumbnail Provider", - new RegistryWrapper(), - L".svg\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}") }) + app_key(powerpreviewConstants::ModuleKey) { // Initialize the toggle states for each module init_settings(); + m_fileExplorerModules.emplace_back(std::make_unique( + true, + L"svg-previewer-toggle-setting", + GET_RESOURCE_STRING(IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION), + L"{ddee2b8a-6807-48a6-bb20-2338174ff779}", + L"Svg Preview Handler", + std::make_unique())); + + m_fileExplorerModules.emplace_back(std::make_unique( + true, + L"md-previewer-toggle-setting", + GET_RESOURCE_STRING(IDS_PREVPANE_MD_SETTINGS_DESCRIPTION), + L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}", + L"Markdown Preview Handler", + std::make_unique())); + + m_fileExplorerModules.emplace_back(std::make_unique( + true, + L"svg-thumbnail-toggle-setting", + GET_RESOURCE_STRING(IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), + L"{36B27788-A8BB-4698-A756-DF9F11F64F84}", + L"Svg Thumbnail Provider", + std::make_unique(), + L".svg\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}")); + // If the user is on the new settings interface, File Explorer might be disabled if they updated from old to new settings, so initialize the registry state in the constructor as PowerPreviewModule::enable/disable will not be called on startup if (UseNewSettings()) { @@ -87,7 +85,7 @@ bool PowerPreviewModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_siz GET_RESOURCE_STRING(IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_DESC), GET_RESOURCE_STRING(IDS_PRVPANE_FILE_PREV_STTNGS_GROUP_TEXT)); - for (auto fileExplorerModule : this->m_fileExplorerModules) + for (auto& fileExplorerModule : m_fileExplorerModules) { settings.add_bool_toggle( fileExplorerModule->GetToggleSettingName(), @@ -107,7 +105,7 @@ void PowerPreviewModule::set_config(const wchar_t* config) bool updateSuccess = true; bool isElevated = is_process_elevated(false); - for (auto fileExplorerModule : this->m_fileExplorerModules) + for (auto& fileExplorerModule : m_fileExplorerModules) { // If the user is using the new settings interface, as it does not have a toggle to modify enabled consider File Explorer to always be enabled updateSuccess = updateSuccess && fileExplorerModule->UpdateState(settings, this->m_enabled || UseNewSettings(), isElevated); @@ -147,7 +145,7 @@ void PowerPreviewModule::enable() void PowerPreviewModule::disable() { elevation_check_wrapper([this]() { - for (auto fileExplorerModule : this->m_fileExplorerModules) + for (auto& fileExplorerModule : m_fileExplorerModules) { fileExplorerModule->Disable(); } @@ -177,7 +175,7 @@ void PowerPreviewModule::init_settings() PowerToysSettings::PowerToyValues::load_from_settings_file(PowerPreviewModule::get_key()); // Load settings states. - for (auto fileExplorerModule : this->m_fileExplorerModules) + for (auto& fileExplorerModule : m_fileExplorerModules) { fileExplorerModule->LoadState(settings); } @@ -191,7 +189,7 @@ void PowerPreviewModule::init_settings() // Function to check if the registry states need to be updated bool PowerPreviewModule::is_registry_update_required() { - for (auto fileExplorerModule : this->m_fileExplorerModules) + for (auto& fileExplorerModule : m_fileExplorerModules) { if (fileExplorerModule->GetToggleSettingState() != fileExplorerModule->CheckRegistryState()) { @@ -241,7 +239,7 @@ void PowerPreviewModule::elevation_check_wrapper(std::function method) void PowerPreviewModule::update_registry_to_match_toggles() { registry_and_elevation_check_wrapper([this]() { - for (auto fileExplorerModule : this->m_fileExplorerModules) + for (auto& fileExplorerModule : m_fileExplorerModules) { if (fileExplorerModule->GetToggleSettingState()) { diff --git a/src/modules/previewpane/powerpreview/powerpreview.h b/src/modules/previewpane/powerpreview/powerpreview.h index b88387e758..04307530bc 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.h +++ b/src/modules/previewpane/powerpreview/powerpreview.h @@ -21,7 +21,7 @@ private: std::wstring m_moduleName; //contains the non localized key of the powertoy std::wstring app_key; - std::vector m_fileExplorerModules; + std::vector> m_fileExplorerModules; // Function to check if the registry states need to be updated bool is_registry_update_required(); diff --git a/src/modules/previewpane/powerpreview/preview_handler.h b/src/modules/previewpane/powerpreview/preview_handler.h index c2d79d9b84..b4248d4149 100644 --- a/src/modules/previewpane/powerpreview/preview_handler.h +++ b/src/modules/previewpane/powerpreview/preview_handler.h @@ -11,8 +11,8 @@ namespace PowerPreviewSettings static const LPCWSTR preview_handlers_subkey; public: - PreviewHandlerSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, RegistryWrapperIface* registryWrapper) : - FileExplorerPreviewSettings(toggleSettingEnabled, toggleSettingName, toggleSettingDescription, clsid, registryValueData, registryWrapper) + PreviewHandlerSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr registryWrapper) : + FileExplorerPreviewSettings(toggleSettingEnabled, toggleSettingName, toggleSettingDescription, clsid, registryValueData, std::move(registryWrapper)) { } diff --git a/src/modules/previewpane/powerpreview/settings.cpp b/src/modules/previewpane/powerpreview/settings.cpp index aa017f3492..08c3e82d82 100644 --- a/src/modules/previewpane/powerpreview/settings.cpp +++ b/src/modules/previewpane/powerpreview/settings.cpp @@ -12,24 +12,16 @@ namespace PowerPreviewSettings extern "C" IMAGE_DOS_HEADER __ImageBase; // Base Settings Class Implementation - FileExplorerPreviewSettings::FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, RegistryWrapperIface* registryWrapper) : + FileExplorerPreviewSettings::FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr registryWrapper) : m_toggleSettingEnabled(toggleSettingEnabled), m_toggleSettingName(toggleSettingName), m_toggleSettingDescription(toggleSettingDescription), m_clsid(clsid), m_registryValueData(registryValueData), - m_registryWrapper(registryWrapper) + m_registryWrapper(std::move(registryWrapper)) { } - FileExplorerPreviewSettings::~FileExplorerPreviewSettings() - { - if (this->m_registryWrapper != NULL) - { - delete this->m_registryWrapper; - } - } - bool FileExplorerPreviewSettings::GetToggleSettingState() const { return this->m_toggleSettingEnabled; diff --git a/src/modules/previewpane/powerpreview/settings.h b/src/modules/previewpane/powerpreview/settings.h index 431c93feb1..aef433fe7e 100644 --- a/src/modules/previewpane/powerpreview/settings.h +++ b/src/modules/previewpane/powerpreview/settings.h @@ -18,11 +18,10 @@ namespace PowerPreviewSettings LPCWSTR m_clsid; protected: - RegistryWrapperIface* m_registryWrapper; + std::unique_ptr m_registryWrapper; public: - FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, RegistryWrapperIface* registryWrapper); - ~FileExplorerPreviewSettings(); + FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr); virtual bool GetToggleSettingState() const; virtual void UpdateToggleSettingState(bool state); diff --git a/src/modules/previewpane/powerpreview/thumbnail_provider.h b/src/modules/previewpane/powerpreview/thumbnail_provider.h index 03eba9e306..1e30b9bcf7 100644 --- a/src/modules/previewpane/powerpreview/thumbnail_provider.h +++ b/src/modules/previewpane/powerpreview/thumbnail_provider.h @@ -11,8 +11,8 @@ namespace PowerPreviewSettings LPCWSTR thumbnail_provider_subkey; public: - ThumbnailProviderSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, RegistryWrapperIface* registryWrapper, LPCWSTR subkey) : - FileExplorerPreviewSettings(toggleSettingEnabled, toggleSettingName, toggleSettingDescription, clsid, registryValueData, registryWrapper), thumbnail_provider_subkey(subkey) + ThumbnailProviderSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, std::unique_ptr registryWrapper, LPCWSTR subkey) : + FileExplorerPreviewSettings(toggleSettingEnabled, toggleSettingName, toggleSettingDescription, clsid, registryValueData, std::move(registryWrapper)), thumbnail_provider_subkey(subkey) { } diff --git a/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp b/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp index fe66476dcd..804dc982c0 100644 --- a/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp +++ b/src/modules/previewpane/powerpreviewTest/FileExplorerPreviewSettingsTest.cpp @@ -417,7 +417,7 @@ namespace FileExplorerPreviewSettingsTest L"valid-description", L"valid-guid", L"valid-handler", - registryMock); + std::unique_ptr(registryMock)); } ThumbnailProviderSettings GetThumbnailProviderSettingsObject(bool defaultState, RegistryWrapperIface* registryMock) @@ -428,7 +428,7 @@ namespace FileExplorerPreviewSettingsTest L"valid-description", L"valid-guid", L"valid-handler", - registryMock, + std::unique_ptr(registryMock), L"valid-subkey"); } From 9c341cc9bc63379a79f0f09010d3855205622675 Mon Sep 17 00:00:00 2001 From: yuyoyuppe Date: Tue, 20 Oct 2020 12:07:35 +0300 Subject: [PATCH 44/65] bootstrapper: treat invalid flags as fatal errors --- .../bootstrapper/bootstrapper.cpp | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp index d4739e02bf..24671366c9 100644 --- a/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp +++ b/installer/PowerToysBootstrapper/bootstrapper/bootstrapper.cpp @@ -110,15 +110,47 @@ int bootstrapper() ("log_dir", "Log directory.", cxxopts::value()->default_value(".")); // clang-format on cxxopts::ParseResult cmdArgs; - options.allow_unrecognised_options(); + bool showHelp = false; try { cmdArgs = options.parse(__argc, const_cast(__argv)); } + catch (cxxopts::option_has_no_value_exception&) + { + showHelp = true; + } + catch (cxxopts::option_not_exists_exception&) + { + showHelp = true; + } + catch (cxxopts::option_not_present_exception&) + { + showHelp = true; + } + catch (cxxopts::option_not_has_argument_exception&) + { + showHelp = true; + } + catch (cxxopts::option_required_exception&) + { + showHelp = true; + } + catch (cxxopts::option_requires_argument_exception&) + { + showHelp = true; + } catch (...) { } - const bool showHelp = cmdArgs["help"].as(); + + showHelp = showHelp || cmdArgs["help"].as(); + if (showHelp) + { + std::ostringstream helpMsg; + helpMsg << options.help(); + MessageBoxA(nullptr, helpMsg.str().c_str(), "Help", MB_OK | MB_ICONINFORMATION); + return 0; + } const bool noFullUI = cmdArgs["no_full_ui"].as(); const bool silent = cmdArgs["silent"].as(); const bool skipDotnetInstall = cmdArgs["skip_dotnet_install"].as(); @@ -149,13 +181,6 @@ int bootstrapper() severity = spdlog::level::err; } setup_log(logDir, severity); - if (showHelp) - { - std::ostringstream helpMsg; - helpMsg << options.help(); - MessageBoxA(nullptr, helpMsg.str().c_str(), "Help", MB_OK | MB_ICONINFORMATION); - return 0; - } spdlog::debug("PowerToys Bootstrapper is launched!\nnoFullUI: {}\nsilent: {}\nno_start_pt: {}\nskip_dotnet_install: {}\nlog_level: {}", noFullUI, silent, noStartPT, skipDotnetInstall, logLevel); if (!noFullUI) @@ -392,7 +417,7 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) } catch (const std::exception& ex) { - MessageBoxA(nullptr, ex.what(), "Unhandled stdexception encountered!", MB_OK | MB_ICONERROR); + MessageBoxA(nullptr, ex.what(), "Unhandled std exception encountered!", MB_OK | MB_ICONERROR); } catch (winrt::hresult_error const& ex) { From 147b78ffce6a2781e6fa6b654e582162e0a8421d Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Wed, 21 Oct 2020 08:30:40 -0700 Subject: [PATCH 45/65] Dev docs for Keyboard Manager (#7340) * Create kbm md file * Documented KBM main module (without links) * Completed docs for backend except links * Added docs for UI and created doc file for KBM Common * Added docs for KBM common and for tests * Add table of contents for all files * Started updating links * Added some more links * Updated links * testing link * Resolve all links on keyboardmanager.md * Added links in KBM Common * Added comments for keyboardeventhandlers * Added links for KBM-UI * Added mention of shortcut to key * Add section link for settings update code. * Include more information on updating remap tables --- doc/devdocs/modules/keyboardmanager/README.md | 6 + .../modules/keyboardmanager/japanese-ime.png | Bin 0 -> 22178 bytes .../keyboardmanager/keyboardeventhandlers.md | 84 ++++++++ .../keyboardmanager/keyboardmanager.md | 199 ++++++++++++++++++ .../keyboardmanager/keyboardmanagercommon.md | 63 ++++++ .../keyboardmanager/keyboardmanagerui.md | 122 +++++++++++ 6 files changed, 474 insertions(+) create mode 100644 doc/devdocs/modules/keyboardmanager/README.md create mode 100644 doc/devdocs/modules/keyboardmanager/japanese-ime.png create mode 100644 doc/devdocs/modules/keyboardmanager/keyboardeventhandlers.md create mode 100644 doc/devdocs/modules/keyboardmanager/keyboardmanager.md create mode 100644 doc/devdocs/modules/keyboardmanager/keyboardmanagercommon.md create mode 100644 doc/devdocs/modules/keyboardmanager/keyboardmanagerui.md diff --git a/doc/devdocs/modules/keyboardmanager/README.md b/doc/devdocs/modules/keyboardmanager/README.md new file mode 100644 index 0000000000..9e363a9468 --- /dev/null +++ b/doc/devdocs/modules/keyboardmanager/README.md @@ -0,0 +1,6 @@ +# Table of Contents +The devdocs for Keyboard Manager have been divided into the following modules: +1. [Keyboard Manager Module](keyboardmanager.md) +2. [Keyboard Event Handlers](keyboardeventhandlers.md) +3. [Keyboard Manager UI](keyboardmanagerui.md) +4. [Keyboard Manager Common](keyboardmanagercommon.md) \ No newline at end of file diff --git a/doc/devdocs/modules/keyboardmanager/japanese-ime.png b/doc/devdocs/modules/keyboardmanager/japanese-ime.png new file mode 100644 index 0000000000000000000000000000000000000000..6f19508c1f16aa992384f7a79d9d6fbc68afe371 GIT binary patch literal 22178 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