Compare commits
5 commits
main
...
feature/Vi
Author | SHA1 | Date | |
---|---|---|---|
f51ee065c2 | |||
afdefa2428 | |||
45d2752dbb | |||
52c9f35369 | |||
03e5e77171 |
|
@ -62,11 +62,10 @@ build:
|
|||
- 'x64/**/*.pdb'
|
||||
exclude:
|
||||
- 'x64/Release/obj/**/*.pdb'
|
||||
# TODO(yuyoyuppe): uncomment when VCM should be enabled
|
||||
#- from: 'x86/Release'
|
||||
# to: 'Build_Output'
|
||||
# include:
|
||||
# - 'modules\VideoConference\VideoConferenceProxyFilter_x86.dll'
|
||||
- from: 'x86/Release'
|
||||
to: 'Build_Output'
|
||||
include:
|
||||
- 'modules\VideoConference\VideoConferenceProxyFilter_x86.dll'
|
||||
- from: 'x64/Release'
|
||||
to: 'Build_Output'
|
||||
include:
|
||||
|
@ -170,10 +169,9 @@ build:
|
|||
- 'modules\PowerRename\PowerRenameExt.dll'
|
||||
- 'modules\ShortcutGuide\ShortcutGuide\PowerToys.ShortcutGuide.exe'
|
||||
- 'modules\ShortcutGuide\ShortcutGuideModuleInterface\ShortcutGuideModuleInterface.dll'
|
||||
# TODO(yuyoyuppe): uncomment when VCM should be enabled
|
||||
#- 'modules\VideoConference\VideoConferenceModule.dll'
|
||||
#- 'modules\VideoConference\VideoConferenceProxyFilter_x64.dll'
|
||||
#- 'modules\VideoConference\VideoConferenceProxyFilter_x86.dll'
|
||||
- 'modules\VideoConference\VideoConferenceModule.dll'
|
||||
- 'modules\VideoConference\VideoConferenceProxyFilter_x64.dll'
|
||||
- 'modules\VideoConference\VideoConferenceProxyFilter_x86.dll'
|
||||
- 'Settings\ManagedTelemetry.dll'
|
||||
- 'Settings\Microsoft.PowerToys.Settings.UI.exe'
|
||||
- 'Settings\Microsoft.PowerToys.Settings.UI.Lib.dll'
|
||||
|
|
|
@ -242,10 +242,9 @@
|
|||
</Directory>
|
||||
<Directory Id="ShortcutGuideModuleInterfaceInstallFolder" Name="ShortcutGuideModuleInterface"/>
|
||||
</Directory>
|
||||
<!-- TODO(yuyoyuppe): uncomment when VCM should be enabled -->
|
||||
<!-- <Directory Id="VideoConferenceInstallFolder" Name="$(var.VideoConferenceProjectName)">
|
||||
<Directory Id="VideoConferenceInstallFolder" Name="$(var.VideoConferenceProjectName)">
|
||||
<Directory Id="VideoConferenceIconsFolder" Name="Icons" />
|
||||
</Directory> -->
|
||||
</Directory>
|
||||
<Directory Id="FileExplorerPreviewInstallFolder" Name="FileExplorerPreview" />
|
||||
<Directory Id="FancyZonesInstallFolder" Name="$(var.FancyZonesProjectName)" />
|
||||
<Directory Id="AwakeInstallFolder" Name="$(var.AwakeProjectName)">
|
||||
|
@ -707,8 +706,7 @@
|
|||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<!-- TODO(yuyoyuppe): uncomment when VCM should be enabled -->
|
||||
<!-- <DirectoryRef Id="VideoConferenceInstallFolder" FileSource="$(var.BinX64Dir)modules\$(var.VideoConferenceProjectName)\">
|
||||
<DirectoryRef Id="VideoConferenceInstallFolder" FileSource="$(var.BinX64Dir)modules\$(var.VideoConferenceProjectName)\">
|
||||
<Component Id="Module_VideoConference" Guid="5996527a-40fc-432e-b3ac-abc0b4bd3887" Win64="yes">
|
||||
<Condition>WINDOWSBUILDNUMBER >= 18362</Condition>
|
||||
<File SelfRegCost="1" Source="$(var.BinX64Dir)modules\$(var.VideoConferenceProjectName)\VideoConferenceProxyFilter_x64.dll" KeyPath="yes">
|
||||
|
@ -736,7 +734,7 @@
|
|||
<File Source="$(var.BinX64Dir)modules\$(var.VideoConferenceProjectName)\Icons\On-On Dark.png" />
|
||||
<File Source="$(var.BinX64Dir)modules\$(var.VideoConferenceProjectName)\Icons\On-On Light.png" />
|
||||
</Component>
|
||||
</DirectoryRef> -->
|
||||
</DirectoryRef>
|
||||
|
||||
<DirectoryRef Id="ShortcutGuideExecutableInstallFolder" FileSource="$(var.ShortcutGuideExecutable)">
|
||||
<Component Id="Module_ShortcutGuideExecutable" Guid="DA6E5710-F1DF-44EB-A316-300FA39544E9" Win64="yes">
|
||||
|
@ -993,9 +991,8 @@
|
|||
<ComponentRef Id="ShortcutGuideSvgs" />
|
||||
<ComponentRef Id="Module_ShortcutGuideModuleInterface" />
|
||||
<ComponentRef Id="Module_ShortcutGuideExecutable" />
|
||||
<!-- TODO(yuyoyuppe): uncomment when VCM should be enabled -->
|
||||
<!-- <ComponentRef Id="Module_VideoConference" />
|
||||
<ComponentRef Id="Module_VideoConferenceIcons" /> -->
|
||||
<ComponentRef Id="Module_VideoConference" />
|
||||
<ComponentRef Id="Module_VideoConferenceIcons" />
|
||||
<ComponentRef Id="Module_FancyZones" />
|
||||
<ComponentRef Id="DesktopShortcut" />
|
||||
<ComponentRef Id="Module_PowerRename" />
|
||||
|
|
|
@ -171,6 +171,10 @@ public
|
|||
return gcnew String(CommonSharedConstants::POWER_LAUNCHER_SHARED_EVENT);
|
||||
}
|
||||
|
||||
static String ^ PowerLauncherCentralizedHookSharedEvent() {
|
||||
return gcnew String(CommonSharedConstants::POWER_LAUNCHER_CENTRALIZED_HOOK_SHARED_EVENT);
|
||||
}
|
||||
|
||||
static String ^ RunSendSettingsTelemetryEvent() {
|
||||
return gcnew String(CommonSharedConstants::RUN_SEND_SETTINGS_TELEMETRY_EVENT);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace CommonSharedConstants
|
|||
// Path to the event used by PowerLauncher
|
||||
const wchar_t POWER_LAUNCHER_SHARED_EVENT[] = L"Local\\PowerToysRunInvokeEvent-30f26ad7-d36d-4c0e-ab02-68bb5ff3c4ab";
|
||||
|
||||
const wchar_t POWER_LAUNCHER_CENTRALIZED_HOOK_SHARED_EVENT[] = L"Local\\PowerToysRunCentralizedHookInvokeEvent-30f26ad7-d36d-4c0e-ab02-68bb5ff3c4ab";
|
||||
|
||||
const wchar_t RUN_SEND_SETTINGS_TELEMETRY_EVENT[] = L"Local\\PowerToysRunInvokeEvent-638ec522-0018-4b96-837d-6bd88e06f0d6";
|
||||
|
||||
const wchar_t RUN_EXIT_EVENT[] = L"Local\\PowerToysRunExitEvent-3e38e49d-a762-4ef1-88f2-fd4bc7481516";
|
||||
|
|
|
@ -7,4 +7,6 @@ struct ShortcutGuideSettings
|
|||
int overlayOpacity = 90;
|
||||
std::wstring theme = L"system";
|
||||
std::wstring disabledApps = L"";
|
||||
bool shouldReactToPressedWinKey = false;
|
||||
int windowsKeyPressTime = 900;
|
||||
};
|
||||
|
|
|
@ -221,6 +221,15 @@ void OverlayWindow::CloseWindow(HideWindowType type, int mainThreadId)
|
|||
|
||||
if (this->winkey_popup)
|
||||
{
|
||||
if (shouldReactToPressedWinKey.value)
|
||||
{
|
||||
// Send a dummy key to prevent Start Menu from activating
|
||||
INPUT dummyEvent[1] = {};
|
||||
dummyEvent[0].type = INPUT_KEYBOARD;
|
||||
dummyEvent[0].ki.wVk = 0xFF;
|
||||
dummyEvent[0].ki.dwFlags = KEYEVENTF_KEYUP;
|
||||
SendInput(1, dummyEvent, sizeof(INPUT));
|
||||
}
|
||||
this->winkey_popup->SetWindowCloseType(ToWstring(type));
|
||||
Logger::trace(L"Terminating process");
|
||||
PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);
|
||||
|
@ -300,6 +309,7 @@ void OverlayWindow::init_settings()
|
|||
overlayOpacity.value = settings.overlayOpacity;
|
||||
theme.value = settings.theme;
|
||||
disabledApps.value = settings.disabledApps;
|
||||
shouldReactToPressedWinKey.value = settings.shouldReactToPressedWinKey;
|
||||
update_disabled_apps();
|
||||
}
|
||||
|
||||
|
@ -399,6 +409,22 @@ ShortcutGuideSettings OverlayWindow::GetSettings() noexcept
|
|||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
settings.shouldReactToPressedWinKey = properties.GetNamedObject(ShouldReactToPressedWinKey::name).GetNamedBoolean(L"value");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
settings.windowsKeyPressTime = (int)properties.GetNamedObject(WindowsKeyPressTime::name).GetNamedNumber(L"value");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
settings.theme = (std::wstring)properties.GetNamedObject(Theme::name).GetNamedString(L"value");
|
||||
|
|
|
@ -78,6 +78,17 @@ private:
|
|||
std::wstring value;
|
||||
} disabledApps;
|
||||
|
||||
struct ShouldReactToPressedWinKey
|
||||
{
|
||||
static inline PCWSTR name = L"use_legacy_press_win_key_behavior";
|
||||
bool value;
|
||||
} shouldReactToPressedWinKey;
|
||||
|
||||
struct WindowsKeyPressTime
|
||||
{
|
||||
static inline PCWSTR name = L"press_time";
|
||||
} windowsKeyPressTime;
|
||||
|
||||
struct OpenShortcut
|
||||
{
|
||||
static inline PCWSTR name = L"open_shortcutguide";
|
||||
|
|
|
@ -39,6 +39,8 @@ void Trace::SendSettings(ShortcutGuideSettings settings) noexcept
|
|||
TraceLoggingInt32(settings.overlayOpacity, "OverlayOpacity"),
|
||||
TraceLoggingWideString(settings.theme.c_str(), "Theme"),
|
||||
TraceLoggingWideString(settings.disabledApps.c_str(), "DisabledApps"),
|
||||
TraceLoggingBoolean(settings.shouldReactToPressedWinKey, "ShouldReactToPressedWinKey"),
|
||||
TraceLoggingInt32(settings.windowsKeyPressTime, "WindowsKeyPressTime"),
|
||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
||||
|
|
|
@ -180,11 +180,18 @@ const std::unordered_map<std::wstring, std::vector<FancyZonesDataTypes::AppZoneH
|
|||
return appZoneHistoryMap;
|
||||
}
|
||||
|
||||
std::optional<FancyZonesDataTypes::DeviceInfoData> FancyZonesData::FindDeviceInfo(const FancyZonesDataTypes::DeviceIdData& zoneWindowId) const
|
||||
std::optional<FancyZonesDataTypes::DeviceInfoData> FancyZonesData::FindDeviceInfo(const FancyZonesDataTypes::DeviceIdData& id) const
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
auto it = deviceInfoMap.find(zoneWindowId);
|
||||
return it != end(deviceInfoMap) ? std::optional{ it->second } : std::nullopt;
|
||||
for (const auto& [deviceId, deviceInfo] : deviceInfoMap)
|
||||
{
|
||||
if (id.isEqualWithNullVirtualDesktopId(deviceId))
|
||||
{
|
||||
return deviceInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<FancyZonesDataTypes::CustomZoneSetData> FancyZonesData::FindCustomZoneSet(const std::wstring& guid) const
|
||||
|
@ -199,8 +206,11 @@ bool FancyZonesData::AddDevice(const FancyZonesDataTypes::DeviceIdData& deviceId
|
|||
_TRACER_;
|
||||
using namespace FancyZonesDataTypes;
|
||||
|
||||
auto deviceInfo = FindDeviceInfo(deviceId);
|
||||
|
||||
std::scoped_lock lock{ dataLock };
|
||||
if (!deviceInfoMap.contains(deviceId))
|
||||
|
||||
if (!deviceInfo.has_value())
|
||||
{
|
||||
wil::unique_cotaskmem_string virtualDesktopId;
|
||||
if (SUCCEEDED(StringFromCLSID(deviceId.virtualDesktopId, &virtualDesktopId)))
|
||||
|
@ -217,13 +227,12 @@ bool FancyZonesData::AddDevice(const FancyZonesDataTypes::DeviceIdData& deviceId
|
|||
const ZoneSetData zoneSetData{ guidString.get(), ZoneSetLayoutType::PriorityGrid };
|
||||
DeviceInfoData defaultDeviceInfoData{ zoneSetData, DefaultValues::ShowSpacing, DefaultValues::Spacing, DefaultValues::ZoneCount, DefaultValues::SensitivityRadius };
|
||||
deviceInfoMap[deviceId] = std::move(defaultDeviceInfoData);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceInfoMap[deviceId] = DeviceInfoData{ ZoneSetData{ NonLocalizable::NullStr, ZoneSetLayoutType::Blank } };
|
||||
Logger::error("Failed to create an ID for the new layout");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -238,7 +247,7 @@ void FancyZonesData::CloneDeviceInfo(const FancyZonesDataTypes::DeviceIdData& so
|
|||
std::scoped_lock lock{ dataLock };
|
||||
|
||||
// The source virtual desktop is deleted, simply ignore it.
|
||||
if (!deviceInfoMap.contains(source))
|
||||
if (!FindDeviceInfo(source).has_value())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -559,31 +568,33 @@ void FancyZonesData::SetActiveZoneSet(const FancyZonesDataTypes::DeviceIdData& d
|
|||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
|
||||
auto deviceIt = deviceInfoMap.find(deviceId);
|
||||
if (deviceIt == deviceInfoMap.end())
|
||||
for (auto& [deviceIdData, deviceInfo] : deviceInfoMap)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
deviceIt->second.activeZoneSet = data;
|
||||
|
||||
// If the zone set is custom, we need to copy its properties to the device
|
||||
auto zonesetIt = customZoneSetsMap.find(data.uuid);
|
||||
if (zonesetIt != customZoneSetsMap.end())
|
||||
{
|
||||
if (zonesetIt->second.type == FancyZonesDataTypes::CustomLayoutType::Grid)
|
||||
if (deviceId.isEqualWithNullVirtualDesktopId(deviceIdData))
|
||||
{
|
||||
auto layoutInfo = std::get<FancyZonesDataTypes::GridLayoutInfo>(zonesetIt->second.info);
|
||||
deviceIt->second.sensitivityRadius = layoutInfo.sensitivityRadius();
|
||||
deviceIt->second.showSpacing = layoutInfo.showSpacing();
|
||||
deviceIt->second.spacing = layoutInfo.spacing();
|
||||
deviceIt->second.zoneCount = layoutInfo.zoneCount();
|
||||
}
|
||||
else if (zonesetIt->second.type == FancyZonesDataTypes::CustomLayoutType::Canvas)
|
||||
{
|
||||
auto layoutInfo = std::get<FancyZonesDataTypes::CanvasLayoutInfo>(zonesetIt->second.info);
|
||||
deviceIt->second.sensitivityRadius = layoutInfo.sensitivityRadius;
|
||||
deviceIt->second.zoneCount = (int)layoutInfo.zones.size();
|
||||
deviceInfo.activeZoneSet = data;
|
||||
|
||||
// If the zone set is custom, we need to copy its properties to the device
|
||||
auto zonesetIt = customZoneSetsMap.find(data.uuid);
|
||||
if (zonesetIt != customZoneSetsMap.end())
|
||||
{
|
||||
if (zonesetIt->second.type == FancyZonesDataTypes::CustomLayoutType::Grid)
|
||||
{
|
||||
auto layoutInfo = std::get<FancyZonesDataTypes::GridLayoutInfo>(zonesetIt->second.info);
|
||||
deviceInfo.sensitivityRadius = layoutInfo.sensitivityRadius();
|
||||
deviceInfo.showSpacing = layoutInfo.showSpacing();
|
||||
deviceInfo.spacing = layoutInfo.spacing();
|
||||
deviceInfo.zoneCount = layoutInfo.zoneCount();
|
||||
}
|
||||
else if (zonesetIt->second.type == FancyZonesDataTypes::CustomLayoutType::Canvas)
|
||||
{
|
||||
auto layoutInfo = std::get<FancyZonesDataTypes::CanvasLayoutInfo>(zonesetIt->second.info);
|
||||
deviceInfo.sensitivityRadius = layoutInfo.sensitivityRadius;
|
||||
deviceInfo.zoneCount = (int)layoutInfo.zones.size();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
|
||||
void SetVirtualDesktopCheckCallback(std::function<bool(GUID)> callback);
|
||||
|
||||
std::optional<FancyZonesDataTypes::DeviceInfoData> FindDeviceInfo(const FancyZonesDataTypes::DeviceIdData& zoneWindowId) const;
|
||||
std::optional<FancyZonesDataTypes::DeviceInfoData> FindDeviceInfo(const FancyZonesDataTypes::DeviceIdData& id) const;
|
||||
std::optional<FancyZonesDataTypes::CustomZoneSetData> FindCustomZoneSet(const std::wstring& guid) const;
|
||||
|
||||
const JSONHelpers::TDeviceInfoMap& GetDeviceInfoMap() const;
|
||||
|
|
|
@ -146,6 +146,11 @@ namespace FancyZonesDataTypes
|
|||
int sensitivityRadius;
|
||||
};
|
||||
|
||||
inline bool operator==(const ZoneSetData& lhs, const ZoneSetData& rhs)
|
||||
{
|
||||
return lhs.type == rhs.type && lhs.uuid == rhs.uuid;
|
||||
}
|
||||
|
||||
inline bool operator==(const DeviceIdData& lhs, const DeviceIdData& rhs)
|
||||
{
|
||||
return lhs.deviceName.compare(rhs.deviceName) == 0 && lhs.width == rhs.width && lhs.height == rhs.height && lhs.virtualDesktopId == rhs.virtualDesktopId && lhs.monitorId.compare(rhs.monitorId) == 0;
|
||||
|
@ -160,6 +165,11 @@ namespace FancyZonesDataTypes
|
|||
{
|
||||
return lhs.deviceName.compare(rhs.deviceName) < 0 || lhs.width < rhs.width || lhs.height < rhs.height || lhs.monitorId.compare(rhs.monitorId) < 0;
|
||||
}
|
||||
|
||||
inline bool operator==(const DeviceInfoData& lhs, const DeviceInfoData& rhs)
|
||||
{
|
||||
return lhs.activeZoneSet == rhs.activeZoneSet && lhs.showSpacing == rhs.showSpacing && lhs.spacing == rhs.spacing && lhs.zoneCount == rhs.zoneCount && lhs.sensitivityRadius == rhs.sensitivityRadius;
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
|
|
|
@ -2042,6 +2042,258 @@ namespace FancyZonesUnitTests
|
|||
|
||||
Assert::IsFalse(data.RemoveAppLastZone(nullptr, deviceId, zoneSetId));
|
||||
}
|
||||
|
||||
TEST_METHOD (AddDevice)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData expected{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
auto result = m_fzData.AddDevice(expected);
|
||||
Assert::IsTrue(result);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
|
||||
Assert::IsFalse(actualMap.find(expected) == actualMap.end());
|
||||
}
|
||||
|
||||
TEST_METHOD (AddDeviceWithNullVirtualDesktopId)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData expected{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
|
||||
auto result = m_fzData.AddDevice(expected);
|
||||
Assert::IsTrue(result);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
|
||||
Assert::IsFalse(actualMap.find(expected) == actualMap.end());
|
||||
}
|
||||
|
||||
TEST_METHOD (AddDeviceDuplicate)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData expected{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
auto result = m_fzData.AddDevice(expected);
|
||||
Assert::IsTrue(result);
|
||||
|
||||
auto result2 = m_fzData.AddDevice(expected);
|
||||
Assert::IsFalse(result2);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
|
||||
Assert::IsFalse(actualMap.find(expected) == actualMap.end());
|
||||
}
|
||||
|
||||
TEST_METHOD (AddDeviceWithNullVirtualDesktopIdDuplicated)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData expected{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
|
||||
auto result = m_fzData.AddDevice(expected);
|
||||
Assert::IsTrue(result);
|
||||
|
||||
auto result2 = m_fzData.AddDevice(expected);
|
||||
Assert::IsFalse(result2);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
|
||||
Assert::IsFalse(actualMap.find(expected) == actualMap.end());
|
||||
}
|
||||
|
||||
TEST_METHOD (AddDeviceDuplicatedComparedWithNillVirtualDesktopId)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData device1{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
FancyZonesDataTypes::DeviceIdData device2{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
|
||||
auto result = m_fzData.AddDevice(device1);
|
||||
Assert::IsTrue(result);
|
||||
|
||||
auto result2 = m_fzData.AddDevice(device2);
|
||||
Assert::IsFalse(result2);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
|
||||
Assert::IsFalse(actualMap.find(device1) == actualMap.end());
|
||||
Assert::IsTrue(actualMap.find(device2) == actualMap.end());
|
||||
}
|
||||
|
||||
TEST_METHOD (AddDeviceDuplicatedComparedWithNillVirtualDesktopId2)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData device1{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
FancyZonesDataTypes::DeviceIdData device2{
|
||||
.deviceName = L"Device",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
|
||||
auto result2 = m_fzData.AddDevice(device2);
|
||||
Assert::IsTrue(result2);
|
||||
|
||||
auto result1 = m_fzData.AddDevice(device1);
|
||||
Assert::IsFalse(result1);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
|
||||
Assert::IsFalse(actualMap.find(device2) == actualMap.end());
|
||||
Assert::IsTrue(actualMap.find(device1) == actualMap.end());
|
||||
}
|
||||
|
||||
TEST_METHOD(CloneDeviceInfo)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData deviceSrc{
|
||||
.deviceName = L"Device1",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
FancyZonesDataTypes::DeviceIdData deviceDst{
|
||||
.deviceName = L"Device2",
|
||||
.width = 300,
|
||||
.height = 400,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
Assert::IsTrue(m_fzData.AddDevice(deviceSrc));
|
||||
Assert::IsTrue(m_fzData.AddDevice(deviceDst));
|
||||
|
||||
m_fzData.CloneDeviceInfo(deviceSrc, deviceDst);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
Assert::IsFalse(actualMap.find(deviceSrc) == actualMap.end());
|
||||
Assert::IsFalse(actualMap.find(deviceDst) == actualMap.end());
|
||||
|
||||
auto expected = m_fzData.FindDeviceInfo(deviceSrc);
|
||||
auto actual = m_fzData.FindDeviceInfo(deviceDst);
|
||||
|
||||
Assert::IsTrue(expected.has_value());
|
||||
Assert::IsTrue(actual.has_value());
|
||||
Assert::IsTrue(expected.value() == actual.value());
|
||||
}
|
||||
|
||||
TEST_METHOD (CloneDeviceInfoIntoUnknownDevice)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData deviceSrc{
|
||||
.deviceName = L"Device1",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
FancyZonesDataTypes::DeviceIdData deviceDst{
|
||||
.deviceName = L"Device2",
|
||||
.width = 300,
|
||||
.height = 400,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
Assert::IsTrue(m_fzData.AddDevice(deviceSrc));
|
||||
|
||||
m_fzData.CloneDeviceInfo(deviceSrc, deviceDst);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
Assert::IsFalse(actualMap.find(deviceSrc) == actualMap.end());
|
||||
Assert::IsFalse(actualMap.find(deviceDst) == actualMap.end());
|
||||
|
||||
auto expected = m_fzData.FindDeviceInfo(deviceSrc);
|
||||
auto actual = m_fzData.FindDeviceInfo(deviceDst);
|
||||
|
||||
Assert::IsTrue(expected.has_value());
|
||||
Assert::IsTrue(actual.has_value());
|
||||
Assert::IsTrue(expected.value() == actual.value());
|
||||
}
|
||||
|
||||
TEST_METHOD (CloneDeviceInfoFromUnknownDevice)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData deviceSrc{
|
||||
.deviceName = L"Device1",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
FancyZonesDataTypes::DeviceIdData deviceDst{
|
||||
.deviceName = L"Device2",
|
||||
.width = 300,
|
||||
.height = 400,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
Assert::IsTrue(m_fzData.AddDevice(deviceDst));
|
||||
|
||||
m_fzData.CloneDeviceInfo(deviceSrc, deviceDst);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
Assert::IsTrue(actualMap.find(deviceSrc) == actualMap.end());
|
||||
Assert::IsFalse(actualMap.find(deviceDst) == actualMap.end());
|
||||
|
||||
Assert::IsFalse(m_fzData.FindDeviceInfo(deviceSrc).has_value());
|
||||
Assert::IsTrue(m_fzData.FindDeviceInfo(deviceDst).has_value());
|
||||
}
|
||||
|
||||
TEST_METHOD(CloneDeviceInfoNullVirtualDesktopId)
|
||||
{
|
||||
FancyZonesDataTypes::DeviceIdData deviceSrc{
|
||||
.deviceName = L"Device1",
|
||||
.width = 200,
|
||||
.height = 100,
|
||||
.virtualDesktopId = GUID_NULL
|
||||
};
|
||||
FancyZonesDataTypes::DeviceIdData deviceDst{
|
||||
.deviceName = L"Device2",
|
||||
.width = 300,
|
||||
.height = 400,
|
||||
.virtualDesktopId = m_defaultVDId
|
||||
};
|
||||
|
||||
Assert::IsTrue(m_fzData.AddDevice(deviceSrc));
|
||||
Assert::IsTrue(m_fzData.AddDevice(deviceDst));
|
||||
|
||||
m_fzData.CloneDeviceInfo(deviceSrc, deviceDst);
|
||||
|
||||
auto actualMap = m_fzData.GetDeviceInfoMap();
|
||||
Assert::IsFalse(actualMap.find(deviceSrc) == actualMap.end());
|
||||
Assert::IsFalse(actualMap.find(deviceDst) == actualMap.end());
|
||||
|
||||
auto expected = m_fzData.FindDeviceInfo(deviceSrc);
|
||||
auto actual = m_fzData.FindDeviceInfo(deviceDst);
|
||||
|
||||
Assert::IsTrue(expected.has_value());
|
||||
Assert::IsTrue(actual.has_value());
|
||||
Assert::IsTrue(expected.value() == actual.value());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_CLASS(EditorArgsUnitTests)
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace
|
|||
const wchar_t JSON_KEY_SHIFT[] = L"shift";
|
||||
const wchar_t JSON_KEY_CODE[] = L"code";
|
||||
const wchar_t JSON_KEY_OPEN_POWERLAUNCHER[] = L"open_powerlauncher";
|
||||
const wchar_t JSON_KEY_USE_CENTRALIZED_KEYBOARD_HOOK[] = L"use_centralized_keyboard_hook";
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
|
@ -73,11 +74,15 @@ private:
|
|||
// Hotkey to invoke the module
|
||||
Hotkey m_hotkey = { .key = 0 };
|
||||
|
||||
// If the centralized keyboard hook should be used to activate PowerToys Run
|
||||
bool m_use_centralized_keyboard_hook = false;
|
||||
|
||||
// Helper function to extract the hotkey from the settings
|
||||
void parse_hotkey(PowerToysSettings::PowerToyValues& settings);
|
||||
|
||||
// Handle to event used to invoke the Runner
|
||||
HANDLE m_hEvent;
|
||||
HANDLE m_hCentralizedKeyboardHookEvent;
|
||||
|
||||
HANDLE send_telemetry_event;
|
||||
|
||||
|
@ -115,6 +120,8 @@ public:
|
|||
init_settings();
|
||||
|
||||
m_hEvent = CreateDefaultEvent(CommonSharedConstants::POWER_LAUNCHER_SHARED_EVENT);
|
||||
m_hCentralizedKeyboardHookEvent = CreateDefaultEvent(CommonSharedConstants::POWER_LAUNCHER_CENTRALIZED_HOOK_SHARED_EVENT);
|
||||
|
||||
send_telemetry_event = CreateDefaultEvent(CommonSharedConstants::RUN_SEND_SETTINGS_TELEMETRY_EVENT);
|
||||
};
|
||||
|
||||
|
@ -199,7 +206,7 @@ public:
|
|||
{
|
||||
Logger::info("Microsoft_Launcher::enable()");
|
||||
m_enabled = true;
|
||||
ResetEvent(m_hEvent);
|
||||
ResetEvent(m_hCentralizedKeyboardHookEvent);
|
||||
ResetEvent(send_telemetry_event);
|
||||
|
||||
unsigned long powertoys_pid = GetCurrentProcessId();
|
||||
|
@ -210,7 +217,7 @@ public:
|
|||
std::wstring executable_args;
|
||||
executable_args += L" -powerToysPid ";
|
||||
executable_args += std::to_wstring(powertoys_pid);
|
||||
executable_args += L" --centralized-kb-hook";
|
||||
executable_args += L" --started-from-runner";
|
||||
|
||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
||||
|
@ -234,7 +241,7 @@ public:
|
|||
std::wstring runExecutablePath = get_module_folderpath();
|
||||
std::wstring params;
|
||||
params += L" -powerToysPid " + std::to_wstring(powertoys_pid) + L" ";
|
||||
params += L"--centralized-kb-hook ";
|
||||
params += L"--started-from-runner ";
|
||||
runExecutablePath += L"\\modules\\launcher\\PowerLauncher.exe";
|
||||
if (RunNonElevatedEx(runExecutablePath, params))
|
||||
{
|
||||
|
@ -268,6 +275,7 @@ public:
|
|||
TerminateRunningInstance();
|
||||
processStarted = false;
|
||||
ResetEvent(m_hEvent);
|
||||
ResetEvent(m_hCentralizedKeyboardHookEvent);
|
||||
ResetEvent(send_telemetry_event);
|
||||
}
|
||||
|
||||
|
@ -310,13 +318,13 @@ public:
|
|||
enable();
|
||||
}
|
||||
|
||||
/* Before we used the central keyboard hook to trigger PowerToys Run.
|
||||
* Now, PowerToys Run uses a global hotkey so that it can get focus.
|
||||
* This means we can't return true so that the hotkey can propagate to PowerToys Run.
|
||||
Logger::trace("Set POWER_LAUNCHER_SHARED_EVENT");
|
||||
SetEvent(m_hEvent);
|
||||
return true;
|
||||
*/
|
||||
/* Now, PowerToys Run uses a global hotkey so that it can get focus.
|
||||
* Activate it with the centralized keyboard hook only if the setting is on.*/
|
||||
if (m_use_centralized_keyboard_hook) {
|
||||
Logger::trace("Set POWER_LAUNCHER_SHARED_EVENT");
|
||||
SetEvent(m_hCentralizedKeyboardHookEvent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -360,6 +368,7 @@ void Microsoft_Launcher::init_settings()
|
|||
|
||||
void Microsoft_Launcher::parse_hotkey(PowerToysSettings::PowerToyValues& settings)
|
||||
{
|
||||
m_use_centralized_keyboard_hook = false;
|
||||
auto settingsObject = settings.get_raw_json();
|
||||
if (settingsObject.GetView().Size())
|
||||
{
|
||||
|
@ -376,6 +385,15 @@ void Microsoft_Launcher::parse_hotkey(PowerToysSettings::PowerToyValues& setting
|
|||
{
|
||||
Logger::error("Failed to initialize PT Run start shortcut");
|
||||
}
|
||||
try
|
||||
{
|
||||
auto jsonPropertiesObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES);
|
||||
m_use_centralized_keyboard_hook = (bool)jsonPropertiesObject.GetNamedBoolean(JSON_KEY_USE_CENTRALIZED_KEYBOARD_HOOK);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Logger::warn("Failed to get centralized keyboard hook setting");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -109,7 +109,7 @@ namespace PowerLauncher
|
|||
|
||||
_settingsVM = new SettingWindowViewModel();
|
||||
_settings = _settingsVM.Settings;
|
||||
_settings.UsePowerToysRunnerKeyboardHook = e.Args.Contains("--centralized-kb-hook");
|
||||
_settings.StartedFromPowerToysRunner = e.Args.Contains("--started-from-runner");
|
||||
|
||||
_stringMatcher = new StringMatcher();
|
||||
StringMatcher.Instance = _stringMatcher;
|
||||
|
|
|
@ -100,6 +100,11 @@ namespace PowerLauncher
|
|||
_settings.Hotkey = openPowerlauncher;
|
||||
}
|
||||
|
||||
if (_settings.UseCentralizedKeyboardHook != overloadSettings.Properties.UseCentralizedKeyboardHook)
|
||||
{
|
||||
_settings.UseCentralizedKeyboardHook = overloadSettings.Properties.UseCentralizedKeyboardHook;
|
||||
}
|
||||
|
||||
if (_settings.MaxResultsToShow != overloadSettings.Properties.MaximumNumberOfResults)
|
||||
{
|
||||
_settings.MaxResultsToShow = overloadSettings.Properties.MaximumNumberOfResults;
|
||||
|
|
|
@ -88,9 +88,15 @@ namespace PowerLauncher.ViewModel
|
|||
// Allow OOBE to call PowerToys Run.
|
||||
NativeEventWaiter.WaitForEventLoop(Constants.PowerLauncherSharedEvent(), OnHotkey);
|
||||
|
||||
if (_settings.StartedFromPowerToysRunner)
|
||||
{
|
||||
// Allow runner to call PowerToys Run from the centralized keyboard hook.
|
||||
NativeEventWaiter.WaitForEventLoop(Constants.PowerLauncherCentralizedHookSharedEvent(), OnCentralizedKeyboardHookHotKey);
|
||||
}
|
||||
|
||||
_settings.PropertyChanged += (s, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(PowerToysRunSettings.Hotkey))
|
||||
if (e.PropertyName == nameof(PowerToysRunSettings.Hotkey) || e.PropertyName == nameof(PowerToysRunSettings.UseCentralizedKeyboardHook))
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
|
@ -741,26 +747,33 @@ namespace PowerLauncher.ViewModel
|
|||
Log.Info("Unregistering previous low level key handler", GetType());
|
||||
}
|
||||
|
||||
_globalHotKeyVK = hotkey.Key;
|
||||
_globalHotKeyFSModifiers = VKModifiersFromHotKey(hotkey);
|
||||
if (NativeMethods.RegisterHotKey(hwnd, _globalHotKeyId, _globalHotKeyFSModifiers, _globalHotKeyVK))
|
||||
if (_settings.StartedFromPowerToysRunner && _settings.UseCentralizedKeyboardHook)
|
||||
{
|
||||
// Using global hotkey registered through the native RegisterHotKey method.
|
||||
_globalHotKeyHwnd = hwnd;
|
||||
_usingGlobalHotKey = true;
|
||||
Log.Info("Registered global hotkey", GetType());
|
||||
return;
|
||||
Log.Info("Using the Centralized Keyboard Hook for the HotKey.", GetType());
|
||||
}
|
||||
|
||||
Log.Warn("Registering global shortcut failed. Will use low-level keyboard hook instead.", GetType());
|
||||
|
||||
// Using fallback low-level keyboard hook through HotkeyManager.
|
||||
if (HotkeyManager == null)
|
||||
else
|
||||
{
|
||||
HotkeyManager = new HotkeyManager();
|
||||
}
|
||||
_globalHotKeyVK = hotkey.Key;
|
||||
_globalHotKeyFSModifiers = VKModifiersFromHotKey(hotkey);
|
||||
if (NativeMethods.RegisterHotKey(hwnd, _globalHotKeyId, _globalHotKeyFSModifiers, _globalHotKeyVK))
|
||||
{
|
||||
// Using global hotkey registered through the native RegisterHotKey method.
|
||||
_globalHotKeyHwnd = hwnd;
|
||||
_usingGlobalHotKey = true;
|
||||
Log.Info("Registered global hotkey", GetType());
|
||||
return;
|
||||
}
|
||||
|
||||
_hotkeyHandle = HotkeyManager.RegisterHotkey(hotkey, action);
|
||||
Log.Warn("Registering global shortcut failed. Will use low-level keyboard hook instead.", GetType());
|
||||
|
||||
// Using fallback low-level keyboard hook through HotkeyManager.
|
||||
if (HotkeyManager == null)
|
||||
{
|
||||
HotkeyManager = new HotkeyManager();
|
||||
}
|
||||
|
||||
_hotkeyHandle = HotkeyManager.RegisterHotkey(hotkey, action);
|
||||
}
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception)
|
||||
|
@ -817,6 +830,14 @@ namespace PowerLauncher.ViewModel
|
|||
}
|
||||
*/
|
||||
|
||||
private void OnCentralizedKeyboardHookHotKey()
|
||||
{
|
||||
if (_settings.StartedFromPowerToysRunner && _settings.UseCentralizedKeyboardHook)
|
||||
{
|
||||
OnHotkey();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHotkey()
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
|
|
|
@ -42,6 +42,25 @@ namespace Wox.Infrastructure.UserSettings
|
|||
}
|
||||
}
|
||||
|
||||
private bool _useCentralizedKeyboardHook;
|
||||
|
||||
public bool UseCentralizedKeyboardHook
|
||||
{
|
||||
get
|
||||
{
|
||||
return _useCentralizedKeyboardHook;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_useCentralizedKeyboardHook != value)
|
||||
{
|
||||
_useCentralizedKeyboardHook = value;
|
||||
OnPropertyChanged(nameof(UseCentralizedKeyboardHook));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string Language { get; set; } = "en";
|
||||
|
||||
public Theme Theme { get; set; } = Theme.System;
|
||||
|
@ -172,7 +191,7 @@ namespace Wox.Infrastructure.UserSettings
|
|||
|
||||
public bool IgnoreHotkeysOnFullscreen { get; set; }
|
||||
|
||||
public bool UsePowerToysRunnerKeyboardHook { get; set; }
|
||||
public bool StartedFromPowerToysRunner { get; set; }
|
||||
|
||||
public HttpProxy Proxy { get; set; } = new HttpProxy();
|
||||
|
||||
|
|
|
@ -144,13 +144,12 @@ int runner(bool isProcessElevated, bool openSettings, bool openOobe)
|
|||
L"modules/Awake/AwakeModuleInterface.dll"
|
||||
|
||||
};
|
||||
// TODO(yuyoyuppe): uncomment when VCM should be enabled
|
||||
//const auto VCM_PATH = L"modules/VideoConference/VideoConferenceModule.dll";
|
||||
//if (const auto mf = LoadLibraryA("mf.dll"))
|
||||
//{
|
||||
// FreeLibrary(mf);
|
||||
// knownModules.emplace_back(VCM_PATH);
|
||||
//}
|
||||
const auto VCM_PATH = L"modules/VideoConference/VideoConferenceModule.dll";
|
||||
if (const auto mf = LoadLibraryA("mf.dll"))
|
||||
{
|
||||
FreeLibrary(mf);
|
||||
knownModules.emplace_back(VCM_PATH);
|
||||
}
|
||||
|
||||
for (const auto& moduleSubdir : knownModules)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
[JsonPropertyName("startupPosition")]
|
||||
public StartupPosition Position { get; set; }
|
||||
|
||||
[JsonPropertyName("use_centralized_keyboard_hook")]
|
||||
public bool UseCentralizedKeyboardHook { get; set; }
|
||||
|
||||
public PowerLauncherProperties()
|
||||
{
|
||||
OpenPowerLauncher = new HotkeySettings(false, false, true, false, 32);
|
||||
|
@ -61,6 +64,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||
MaximumNumberOfResults = 4;
|
||||
Theme = Theme.System;
|
||||
Position = StartupPosition.Cursor;
|
||||
UseCentralizedKeyboardHook = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -275,6 +275,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public bool UseCentralizedKeyboardHook
|
||||
{
|
||||
get
|
||||
{
|
||||
return settings.Properties.UseCentralizedKeyboardHook;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (settings.Properties.UseCentralizedKeyboardHook != value)
|
||||
{
|
||||
settings.Properties.UseCentralizedKeyboardHook = value;
|
||||
UpdateSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HotkeySettings OpenFileLocation
|
||||
{
|
||||
get
|
||||
|
|
|
@ -180,8 +180,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
|||
Link = "https://aka.ms/PowerToysOverview_ShortcutGuide",
|
||||
});
|
||||
|
||||
// TODO(yuyoyuppe): uncomment when VCM should be enabled
|
||||
/* Modules.Insert((int)PowerToysModulesEnum.VideoConference, new OobePowerToysModule()
|
||||
Modules.Insert((int)PowerToysModulesEnum.VideoConference, new OobePowerToysModule()
|
||||
{
|
||||
ModuleName = loader.GetString("Oobe_VideoConference"),
|
||||
Tag = "VideoConference",
|
||||
|
@ -192,7 +191,7 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views
|
|||
Description = loader.GetString("Oobe_VideoConference_Description"),
|
||||
PreviewImageSource = "ms-appx:///Assets/Modules/OOBE/VideoConferenceMute.png",
|
||||
Link = "https://aka.ms/PowerToysOverview_VideoConference",
|
||||
}); */
|
||||
});
|
||||
}
|
||||
|
||||
public void OnClosing()
|
||||
|
|
|
@ -401,6 +401,9 @@
|
|||
<data name="PowerLauncher_IgnoreHotkeysInFullScreen.Content" xml:space="preserve">
|
||||
<value>Ignore shortcuts in fullscreen mode</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_UseCentralizedKeyboardHook.Content" xml:space="preserve">
|
||||
<value>Use centralized keyboard hook (try it if there are issues with the shortcut)</value>
|
||||
</data>
|
||||
<data name="PowerLauncher_ClearInputOnLaunch.Content" xml:space="preserve">
|
||||
<value>Clear the previous query on launch</value>
|
||||
</data>
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
</controls:SettingExpander.Header>
|
||||
<controls:SettingExpander.Content>
|
||||
<StackPanel>
|
||||
<CheckBox x:Uid="PowerLauncher_UseCentralizedKeyboardHook" IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.UseCentralizedKeyboardHook}" Margin="{StaticResource ExpanderSettingMargin}" />
|
||||
<Rectangle Style="{StaticResource ExpanderSeparatorStyle}" />
|
||||
<CheckBox x:Uid="PowerLauncher_IgnoreHotkeysInFullScreen" IsChecked="{x:Bind Mode=TwoWay, Path=ViewModel.IgnoreHotkeysInFullScreen}" Margin="{StaticResource ExpanderSettingMargin}" />
|
||||
</StackPanel>
|
||||
</controls:SettingExpander.Content>
|
||||
|
|
|
@ -119,15 +119,14 @@
|
|||
</muxc:NavigationViewItem.Icon>
|
||||
</muxc:NavigationViewItem>
|
||||
|
||||
<!--TODO(yuyoyuppe): uncomment when VCM should be enabled-->
|
||||
<!--<muxc:NavigationViewItem x:Uid="Shell_VideoConference"
|
||||
<muxc:NavigationViewItem x:Uid="Shell_VideoConference"
|
||||
helpers:NavHelper.NavigateTo="views:VideoConferencePage"
|
||||
IsEnabled="{x:Bind ViewModel.IsVideoConferenceBuild, Mode=OneWay}">
|
||||
<muxc:NavigationViewItem.Icon>
|
||||
<BitmapIcon UriSource="ms-appx:///Assets/FluentIcons/FluentIconsVideoConferenceMute.png"
|
||||
ShowAsMonochrome="False" />
|
||||
</muxc:NavigationViewItem.Icon>
|
||||
</muxc:NavigationViewItem>-->
|
||||
</muxc:NavigationViewItem>
|
||||
|
||||
</muxc:NavigationView.MenuItems>
|
||||
<muxc:NavigationView.PaneFooter>
|
||||
|
@ -154,4 +153,4 @@
|
|||
<Frame x:Name="shellFrame" />
|
||||
</muxc:NavigationView>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
</UserControl>
|
||||
|
|
Loading…
Reference in a new issue