mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-20 18:20:27 +01:00
Compare commits
8 Commits
async-cpp-
...
v0.27.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bb149718f | ||
|
|
df5c513603 | ||
|
|
047b455601 | ||
|
|
da384d3d65 | ||
|
|
e6879aa97c | ||
|
|
4ced84b46d | ||
|
|
1240598635 | ||
|
|
9d39952670 |
@@ -22,7 +22,7 @@ namespace updating
|
|||||||
|
|
||||||
bool install_dotnet(const bool silent)
|
bool install_dotnet(const bool silent)
|
||||||
{
|
{
|
||||||
const wchar_t DOTNET_DESKTOP_DOWNLOAD_LINK[] = L"https://download.visualstudio.microsoft.com/download/pr/3eb7efa1-96c6-4e97-bb9f-563ecf595f8a/7efd9c1cdd74df8fb0a34c288138a84f/windowsdesktop-runtime-3.1.6-win-x64.exe";
|
const wchar_t DOTNET_DESKTOP_DOWNLOAD_LINK[] = L"https://download.visualstudio.microsoft.com/download/pr/513acf37-8da2-497d-bdaa-84d6e33c1fee/eb7b010350df712c752f4ec4b615f89d/windowsdesktop-runtime-3.1.10-win-x64.exe";
|
||||||
const wchar_t DOTNET_DESKTOP_FILENAME[] = L"windowsdesktop-runtime.exe";
|
const wchar_t DOTNET_DESKTOP_FILENAME[] = L"windowsdesktop-runtime.exe";
|
||||||
|
|
||||||
auto dotnet_download_path = fs::temp_directory_path() / DOTNET_DESKTOP_FILENAME;
|
auto dotnet_download_path = fs::temp_directory_path() / DOTNET_DESKTOP_FILENAME;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace ColorPicker.Helpers
|
|||||||
{
|
{
|
||||||
private readonly IColorEditorViewModel _colorEditorViewModel;
|
private readonly IColorEditorViewModel _colorEditorViewModel;
|
||||||
private ColorEditorWindow _colorEditorWindow;
|
private ColorEditorWindow _colorEditorWindow;
|
||||||
|
private bool _colorPickerShown;
|
||||||
|
private object _colorPickerVisibilityLock = new object();
|
||||||
|
|
||||||
[ImportingConstructor]
|
[ImportingConstructor]
|
||||||
public AppStateHandler(IColorEditorViewModel colorEditorViewModel)
|
public AppStateHandler(IColorEditorViewModel colorEditorViewModel)
|
||||||
@@ -30,16 +32,30 @@ namespace ColorPicker.Helpers
|
|||||||
|
|
||||||
public void ShowColorPicker()
|
public void ShowColorPicker()
|
||||||
{
|
{
|
||||||
AppShown?.Invoke(this, EventArgs.Empty);
|
lock (_colorPickerVisibilityLock)
|
||||||
Application.Current.MainWindow.Opacity = 0;
|
{
|
||||||
Application.Current.MainWindow.Visibility = Visibility.Visible;
|
if (!_colorPickerShown)
|
||||||
|
{
|
||||||
|
AppShown?.Invoke(this, EventArgs.Empty);
|
||||||
|
Application.Current.MainWindow.Opacity = 0;
|
||||||
|
Application.Current.MainWindow.Visibility = Visibility.Visible;
|
||||||
|
_colorPickerShown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HideColorPicker()
|
public void HideColorPicker()
|
||||||
{
|
{
|
||||||
Application.Current.MainWindow.Opacity = 0;
|
lock (_colorPickerVisibilityLock)
|
||||||
Application.Current.MainWindow.Visibility = Visibility.Collapsed;
|
{
|
||||||
AppHidden?.Invoke(this, EventArgs.Empty);
|
if (_colorPickerShown)
|
||||||
|
{
|
||||||
|
Application.Current.MainWindow.Opacity = 0;
|
||||||
|
Application.Current.MainWindow.Visibility = Visibility.Collapsed;
|
||||||
|
AppHidden?.Invoke(this, EventArgs.Empty);
|
||||||
|
_colorPickerShown = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowColorPickerEditor()
|
public void ShowColorPickerEditor()
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using static ColorPicker.NativeMethods;
|
||||||
|
|
||||||
namespace ColorPicker.Helpers
|
namespace ColorPicker.Helpers
|
||||||
{
|
{
|
||||||
@@ -23,15 +25,24 @@ namespace ColorPicker.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Clipboard.SetText(colorRepresentationToCopy);
|
Clipboard.SetDataObject(colorRepresentationToCopy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (COMException ex)
|
catch (COMException ex)
|
||||||
{
|
{
|
||||||
|
var hwnd = GetOpenClipboardWindow();
|
||||||
|
var sb = new StringBuilder(501);
|
||||||
|
_ = GetWindowText(hwnd.ToInt32(), sb, 500);
|
||||||
|
var applicationUsingClipboard = sb.ToString();
|
||||||
|
|
||||||
if ((uint)ex.ErrorCode != ErrorCodeClipboardCantOpen)
|
if ((uint)ex.ErrorCode != ErrorCodeClipboardCantOpen)
|
||||||
{
|
{
|
||||||
Logger.LogError("Failed to set text into clipboard", ex);
|
Logger.LogError("Failed to set text into clipboard", ex);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.LogError("Failed to set text into clipboard, application that is locking clipboard - " + applicationUsingClipboard, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Threading.Thread.Sleep(10);
|
System.Threading.Thread.Sleep(10);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using ColorPicker.Helpers;
|
using ColorPicker.Helpers;
|
||||||
using ColorPicker.Settings;
|
using ColorPicker.Settings;
|
||||||
@@ -21,10 +22,12 @@ namespace ColorPicker.Keyboard
|
|||||||
{
|
{
|
||||||
private readonly AppStateHandler _appStateHandler;
|
private readonly AppStateHandler _appStateHandler;
|
||||||
private readonly IUserSettings _userSettings;
|
private readonly IUserSettings _userSettings;
|
||||||
|
private List<string> _previouslyPressedKeys;
|
||||||
|
|
||||||
private List<string> _activationKeys = new List<string>();
|
private List<string> _activationKeys = new List<string>();
|
||||||
private GlobalKeyboardHook _keyboardHook;
|
private GlobalKeyboardHook _keyboardHook;
|
||||||
private bool disposedValue;
|
private bool disposedValue;
|
||||||
|
private bool _activationShortcutPressed;
|
||||||
|
|
||||||
[ImportingConstructor]
|
[ImportingConstructor]
|
||||||
public KeyboardMonitor(AppStateHandler appStateHandler, IUserSettings userSettings)
|
public KeyboardMonitor(AppStateHandler appStateHandler, IUserSettings userSettings)
|
||||||
@@ -80,26 +83,38 @@ namespace ColorPicker.Keyboard
|
|||||||
// If the last key pressed is a modifier key, then currentlyPressedKeys cannot possibly match with _activationKeys
|
// If the last key pressed is a modifier key, then currentlyPressedKeys cannot possibly match with _activationKeys
|
||||||
// because _activationKeys contains exactly 1 non-modifier key. Hence, there's no need to check if `name` is a
|
// because _activationKeys contains exactly 1 non-modifier key. Hence, there's no need to check if `name` is a
|
||||||
// modifier key or to do any additional processing on it.
|
// modifier key or to do any additional processing on it.
|
||||||
|
|
||||||
// Check pressed modifier keys.
|
|
||||||
AddModifierKeys(currentlyPressedKeys);
|
|
||||||
|
|
||||||
if (e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown || e.KeyboardState == GlobalKeyboardHook.KeyboardState.SysKeyDown)
|
if (e.KeyboardState == GlobalKeyboardHook.KeyboardState.KeyDown || e.KeyboardState == GlobalKeyboardHook.KeyboardState.SysKeyDown)
|
||||||
{
|
{
|
||||||
|
// Check pressed modifier keys.
|
||||||
|
AddModifierKeys(currentlyPressedKeys);
|
||||||
|
|
||||||
currentlyPressedKeys.Add(name);
|
currentlyPressedKeys.Add(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentlyPressedKeys.Sort();
|
currentlyPressedKeys.Sort();
|
||||||
|
|
||||||
|
if (currentlyPressedKeys.Count == 0 && _previouslyPressedKeys.Count != 0)
|
||||||
|
{
|
||||||
|
// no keys pressed, we can enable activation shortcut again
|
||||||
|
_activationShortcutPressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_previouslyPressedKeys = currentlyPressedKeys;
|
||||||
|
|
||||||
if (ArraysAreSame(currentlyPressedKeys, _activationKeys))
|
if (ArraysAreSame(currentlyPressedKeys, _activationKeys))
|
||||||
{
|
{
|
||||||
if (_userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenEditor)
|
// avoid triggering this action multiple times as this will be called nonstop while keys are pressed
|
||||||
|
if (!_activationShortcutPressed)
|
||||||
{
|
{
|
||||||
_appStateHandler.ShowColorPickerEditor();
|
_activationShortcutPressed = true;
|
||||||
}
|
if (_userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenEditor)
|
||||||
else
|
{
|
||||||
{
|
_appStateHandler.ShowColorPickerEditor();
|
||||||
_appStateHandler.ShowColorPicker();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_appStateHandler.ShowColorPicker();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace ColorPicker
|
namespace ColorPicker
|
||||||
{
|
{
|
||||||
@@ -161,5 +162,11 @@ namespace ColorPicker
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr AdditionalInformation;
|
public IntPtr AdditionalInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern IntPtr GetOpenClipboardWindow();
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern int GetWindowText(int hwnd, StringBuilder text, int count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
SelectedIndex="{Binding SelectedColorIndex}"
|
SelectedIndex="{Binding SelectedColorIndex}"
|
||||||
ItemContainerStyle="{DynamicResource ColorHistoryListViewStyle}">
|
ItemContainerStyle="{DynamicResource ColorHistoryListViewStyle}">
|
||||||
<ui:ListView.ContextMenu>
|
<ui:ListView.ContextMenu>
|
||||||
<ContextMenu>
|
<ContextMenu Visibility="{Binding ColorsHistory.Count, Converter={StaticResource numberToVisibilityConverter}}">
|
||||||
<MenuItem Header="{x:Static p:Resources.Remove}"
|
<MenuItem Header="{x:Static p:Resources.Remove}"
|
||||||
Command="{Binding RemoveColorCommand}">
|
Command="{Binding RemoveColorCommand}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
|
|||||||
@@ -91,6 +91,22 @@ namespace FancyZonesEditor
|
|||||||
Overlay.Show();
|
Overlay.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void App_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Key == System.Windows.Input.Key.LeftShift || e.Key == System.Windows.Input.Key.RightShift)
|
||||||
|
{
|
||||||
|
MainWindowSettings.IsShiftKeyPressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void App_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Key == System.Windows.Input.Key.LeftShift || e.Key == System.Windows.Input.Key.RightShift)
|
||||||
|
{
|
||||||
|
MainWindowSettings.IsShiftKeyPressed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void ShowExceptionMessageBox(string message, Exception exception = null)
|
public static void ShowExceptionMessageBox(string message, Exception exception = null)
|
||||||
{
|
{
|
||||||
string fullMessage = FancyZonesEditor.Properties.Resources.Error_Report + PowerToysIssuesURL + " \n" + message;
|
string fullMessage = FancyZonesEditor.Properties.Resources.Error_Report + PowerToysIssuesURL + " \n" + message;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace FancyZonesEditor
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
KeyUp += GridEditorWindow_KeyUp;
|
KeyUp += GridEditorWindow_KeyUp;
|
||||||
|
KeyDown += ((App)Application.Current).App_KeyDown;
|
||||||
|
|
||||||
_stashedModel = (GridLayoutModel)(App.Overlay.CurrentDataContext as GridLayoutModel).Clone();
|
_stashedModel = (GridLayoutModel)(App.Overlay.CurrentDataContext as GridLayoutModel).Clone();
|
||||||
}
|
}
|
||||||
@@ -36,6 +37,8 @@ namespace FancyZonesEditor
|
|||||||
{
|
{
|
||||||
OnCancel(sender, null);
|
OnCancel(sender, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
((App)Application.Current).App_KeyUp(sender, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GridLayoutModel _stashedModel;
|
private GridLayoutModel _stashedModel;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using FancyZonesEditor.Utils;
|
using FancyZonesEditor.Utils;
|
||||||
|
|
||||||
@@ -32,6 +33,9 @@ namespace FancyZonesEditor.Models
|
|||||||
Window.Background = (Brush)properties[milliseconds % properties.Length].GetValue(null, null);
|
Window.Background = (Brush)properties[milliseconds % properties.Length].GetValue(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window.KeyUp += ((App)Application.Current).App_KeyUp;
|
||||||
|
Window.KeyDown += ((App)Application.Current).App_KeyDown;
|
||||||
|
|
||||||
Window.Left = workArea.X;
|
Window.Left = workArea.X;
|
||||||
Window.Top = workArea.Y;
|
Window.Top = workArea.Y;
|
||||||
Window.Width = workArea.Width;
|
Window.Width = workArea.Width;
|
||||||
|
|||||||
@@ -634,53 +634,73 @@ void FancyZones::ToggleEditor() noexcept
|
|||||||
|
|
||||||
const bool spanZonesAcrossMonitors = m_settings->GetSettings()->spanZonesAcrossMonitors;
|
const bool spanZonesAcrossMonitors = m_settings->GetSettings()->spanZonesAcrossMonitors;
|
||||||
params += std::to_wstring(spanZonesAcrossMonitors) + divider; /* Span zones */
|
params += std::to_wstring(spanZonesAcrossMonitors) + divider; /* Span zones */
|
||||||
|
|
||||||
std::vector<std::pair<HMONITOR, MONITORINFOEX>> allMonitors;
|
std::vector<std::pair<HMONITOR, MONITORINFOEX>> allMonitors;
|
||||||
allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>();
|
allMonitors = FancyZonesUtils::GetAllMonitorInfo<&MONITORINFOEX::rcWork>();
|
||||||
|
|
||||||
|
// device id map
|
||||||
|
std::unordered_map<std::wstring, DWORD> displayDeviceIdxMap;
|
||||||
|
|
||||||
bool showDpiWarning = false;
|
bool showDpiWarning = false;
|
||||||
int prevDpiX = -1, prevDpiY = -1;
|
int prevDpiX = -1, prevDpiY = -1;
|
||||||
std::wstring monitorsData;
|
std::wstring monitorsDataStr;
|
||||||
for (auto& monitor : allMonitors)
|
for (auto& monitorData : allMonitors)
|
||||||
{
|
{
|
||||||
auto monitorId = FancyZonesUtils::GenerateMonitorId(monitor.second, monitor.first, m_currentDesktopId);
|
HMONITOR monitor = monitorData.first;
|
||||||
if (monitor.first == targetMonitor)
|
auto monitorInfo = monitorData.second;
|
||||||
|
|
||||||
|
std::wstring monitorId;
|
||||||
|
std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(monitorInfo.szDevice, displayDeviceIdxMap);
|
||||||
|
wil::unique_cotaskmem_string virtualDesktopId;
|
||||||
|
if (SUCCEEDED(StringFromCLSID(m_currentDesktopId, &virtualDesktopId)))
|
||||||
{
|
{
|
||||||
params += *monitorId + divider; /* Monitor id where the Editor should be opened */
|
monitorId = FancyZonesUtils::GenerateUniqueId(monitor, deviceId, virtualDesktopId.get());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (monitorId.has_value())
|
if (monitor == targetMonitor)
|
||||||
{
|
{
|
||||||
monitorsData += std::move(*monitorId) + divider; /* Monitor id */
|
params += monitorId + divider; /* Monitor id where the Editor should be opened */
|
||||||
|
}
|
||||||
|
|
||||||
UINT dpiX = 0;
|
monitorsDataStr += std::move(monitorId) + divider; /* Monitor id */
|
||||||
UINT dpiY = 0;
|
|
||||||
if (GetDpiForMonitor(monitor.first, MDT_EFFECTIVE_DPI, &dpiX, &dpiY) == S_OK)
|
UINT dpiX = 0;
|
||||||
|
UINT dpiY = 0;
|
||||||
|
if (GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY) == S_OK)
|
||||||
|
{
|
||||||
|
monitorsDataStr += std::to_wstring(dpiX) + divider; /* DPI */
|
||||||
|
if (spanZonesAcrossMonitors && prevDpiX != -1 && (prevDpiX != dpiX || prevDpiY != dpiY))
|
||||||
{
|
{
|
||||||
monitorsData += std::to_wstring(dpiX) + divider; /* DPI */
|
showDpiWarning = true;
|
||||||
if (spanZonesAcrossMonitors && prevDpiX != -1 && (prevDpiX != dpiX || prevDpiY != dpiY))
|
|
||||||
{
|
|
||||||
showDpiWarning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
prevDpiX = dpiX;
|
|
||||||
prevDpiY = dpiY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
monitorsData += std::to_wstring(monitor.second.rcMonitor.left) + divider;
|
prevDpiX = dpiX;
|
||||||
monitorsData += std::to_wstring(monitor.second.rcMonitor.top) + divider;
|
prevDpiY = dpiY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
monitorsDataStr += std::to_wstring(monitorInfo.rcMonitor.left) + divider;
|
||||||
|
monitorsDataStr += std::to_wstring(monitorInfo.rcMonitor.top) + divider;
|
||||||
}
|
}
|
||||||
|
|
||||||
params += std::to_wstring(allMonitors.size()) + divider; /* Monitors count */
|
params += std::to_wstring(allMonitors.size()) + divider; /* Monitors count */
|
||||||
params += monitorsData;
|
params += monitorsDataStr;
|
||||||
|
|
||||||
if (showDpiWarning)
|
if (showDpiWarning)
|
||||||
{
|
{
|
||||||
MessageBoxW(NULL,
|
// We must show the message box in a separate thread, since this code is called from a low-level
|
||||||
GET_RESOURCE_STRING(IDS_SPAN_ACROSS_ZONES_WARNING).c_str(),
|
// keyboard hook callback, and launching messageboxes from it has unexpected side effects,
|
||||||
GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
|
// like triggering EVENT_SYSTEM_MOVESIZEEND prematurely.
|
||||||
MB_OK | MB_ICONWARNING);
|
// TODO: understand the root cause of this, until then it's commented out.
|
||||||
|
//std::thread{ [] {
|
||||||
|
// MessageBoxW(nullptr,
|
||||||
|
// GET_RESOURCE_STRING(IDS_SPAN_ACROSS_ZONES_WARNING).c_str(),
|
||||||
|
// GET_RESOURCE_STRING(IDS_POWERTOYS_FANCYZONES).c_str(),
|
||||||
|
// MB_OK | MB_ICONWARNING);
|
||||||
|
//} }.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& fancyZonesData = FancyZonesDataInstance();
|
const auto& fancyZonesData = FancyZonesDataInstance();
|
||||||
@@ -951,30 +971,8 @@ void FancyZones::UpdateZoneWindows() noexcept
|
|||||||
auto& displayDeviceIdxMap = *(params->displayDeviceIdx);
|
auto& displayDeviceIdxMap = *(params->displayDeviceIdx);
|
||||||
FancyZones* fancyZones = params->fancyZones;
|
FancyZones* fancyZones = params->fancyZones;
|
||||||
|
|
||||||
DISPLAY_DEVICE displayDevice{ .cb = sizeof(displayDevice) };
|
std::wstring deviceId = FancyZonesUtils::GetDisplayDeviceId(mi.szDevice, displayDeviceIdxMap);
|
||||||
std::wstring deviceId;
|
fancyZones->AddZoneWindow(monitor, deviceId);
|
||||||
while (EnumDisplayDevicesW(mi.szDevice, displayDeviceIdxMap[mi.szDevice], &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME))
|
|
||||||
{
|
|
||||||
++displayDeviceIdxMap[mi.szDevice];
|
|
||||||
// Only take active monitors (presented as being "on" by the respective GDI view) and monitors that don't
|
|
||||||
// represent a pseudo device used to mirror application drawing.
|
|
||||||
if (WI_IsFlagSet(displayDevice.StateFlags, DISPLAY_DEVICE_ACTIVE) &&
|
|
||||||
WI_IsFlagClear(displayDevice.StateFlags, DISPLAY_DEVICE_MIRRORING_DRIVER))
|
|
||||||
{
|
|
||||||
deviceId = displayDevice.DeviceID;
|
|
||||||
fancyZones->AddZoneWindow(monitor, deviceId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deviceId.empty())
|
|
||||||
{
|
|
||||||
deviceId = GetSystemMetrics(SM_REMOTESESSION) ?
|
|
||||||
L"\\\\?\\DISPLAY#REMOTEDISPLAY#" :
|
|
||||||
L"\\\\?\\DISPLAY#LOCALDISPLAY#";
|
|
||||||
|
|
||||||
fancyZones->AddZoneWindow(monitor, deviceId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -120,8 +120,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const UINT dpi = GetDpiForMonitor(m_monitor);
|
workAreaRect = Rect(mi.rcWork);
|
||||||
workAreaRect = Rect(mi.rcWork, dpi);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -315,4 +315,9 @@ ZoneWindowDrawing::~ZoneWindowDrawing()
|
|||||||
}
|
}
|
||||||
m_cv.notify_all();
|
m_cv.notify_all();
|
||||||
m_renderThread.join();
|
m_renderThread.join();
|
||||||
|
|
||||||
|
if (m_renderTarget)
|
||||||
|
{
|
||||||
|
m_renderTarget->Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,6 +155,34 @@ namespace FancyZonesUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef BOOL(WINAPI* GetDpiForMonitorInternalFunc)(HMONITOR, UINT, UINT*, UINT*);
|
typedef BOOL(WINAPI* GetDpiForMonitorInternalFunc)(HMONITOR, UINT, UINT*, UINT*);
|
||||||
|
std::wstring GetDisplayDeviceId(const std::wstring& device, std::unordered_map<std::wstring, DWORD>& displayDeviceIdxMap)
|
||||||
|
{
|
||||||
|
DISPLAY_DEVICE displayDevice{ .cb = sizeof(displayDevice) };
|
||||||
|
std::wstring deviceId;
|
||||||
|
while (EnumDisplayDevicesW(device.c_str(), displayDeviceIdxMap[device], &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME))
|
||||||
|
{
|
||||||
|
++displayDeviceIdxMap[device];
|
||||||
|
|
||||||
|
// Only take active monitors (presented as being "on" by the respective GDI view) and monitors that don't
|
||||||
|
// represent a pseudo device used to mirror application drawing.
|
||||||
|
if (WI_IsFlagSet(displayDevice.StateFlags, DISPLAY_DEVICE_ACTIVE) &&
|
||||||
|
WI_IsFlagClear(displayDevice.StateFlags, DISPLAY_DEVICE_MIRRORING_DRIVER))
|
||||||
|
{
|
||||||
|
deviceId = displayDevice.DeviceID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceId.empty())
|
||||||
|
{
|
||||||
|
deviceId = GetSystemMetrics(SM_REMOTESESSION) ?
|
||||||
|
L"\\\\?\\DISPLAY#REMOTEDISPLAY#" :
|
||||||
|
L"\\\\?\\DISPLAY#LOCALDISPLAY#";
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
|
||||||
UINT GetDpiForMonitor(HMONITOR monitor) noexcept
|
UINT GetDpiForMonitor(HMONITOR monitor) noexcept
|
||||||
{
|
{
|
||||||
UINT dpi{};
|
UINT dpi{};
|
||||||
@@ -582,36 +610,6 @@ namespace FancyZonesUtils
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::wstring> GenerateMonitorId(MONITORINFOEX mi, HMONITOR monitor, const GUID& virtualDesktopId)
|
|
||||||
{
|
|
||||||
DISPLAY_DEVICE displayDevice = { sizeof(displayDevice) };
|
|
||||||
PCWSTR deviceId = nullptr;
|
|
||||||
|
|
||||||
bool validMonitor = true;
|
|
||||||
if (EnumDisplayDevices(mi.szDevice, 0, &displayDevice, 1))
|
|
||||||
{
|
|
||||||
if (displayDevice.DeviceID[0] != L'\0')
|
|
||||||
{
|
|
||||||
deviceId = displayDevice.DeviceID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!deviceId)
|
|
||||||
{
|
|
||||||
deviceId = GetSystemMetrics(SM_REMOTESESSION) ?
|
|
||||||
L"\\\\?\\DISPLAY#REMOTEDISPLAY#" :
|
|
||||||
L"\\\\?\\DISPLAY#LOCALDISPLAY#";
|
|
||||||
}
|
|
||||||
|
|
||||||
wil::unique_cotaskmem_string vdId;
|
|
||||||
if (SUCCEEDED(StringFromCLSID(virtualDesktopId, &vdId)))
|
|
||||||
{
|
|
||||||
return GenerateUniqueId(monitor, deviceId, vdId.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ChooseNextZoneByPosition(DWORD vkCode, RECT windowRect, const std::vector<RECT>& zoneRects) noexcept
|
size_t ChooseNextZoneByPosition(DWORD vkCode, RECT windowRect, const std::vector<RECT>& zoneRects) noexcept
|
||||||
{
|
{
|
||||||
using complex = std::complex<double>;
|
using complex = std::complex<double>;
|
||||||
|
|||||||
@@ -184,6 +184,8 @@ namespace FancyZonesUtils
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring GetDisplayDeviceId(const std::wstring& device, std::unordered_map<std::wstring, DWORD>& displayDeviceIdxMap);
|
||||||
|
|
||||||
UINT GetDpiForMonitor(HMONITOR monitor) noexcept;
|
UINT GetDpiForMonitor(HMONITOR monitor) noexcept;
|
||||||
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
||||||
void SizeWindowToRect(HWND window, RECT rect) noexcept;
|
void SizeWindowToRect(HWND window, RECT rect) noexcept;
|
||||||
@@ -202,7 +204,6 @@ namespace FancyZonesUtils
|
|||||||
|
|
||||||
std::wstring GenerateUniqueId(HMONITOR monitor, const std::wstring& devideId, const std::wstring& virtualDesktopId);
|
std::wstring GenerateUniqueId(HMONITOR monitor, const std::wstring& devideId, const std::wstring& virtualDesktopId);
|
||||||
std::wstring GenerateUniqueIdAllMonitorsArea(const std::wstring& virtualDesktopId);
|
std::wstring GenerateUniqueIdAllMonitorsArea(const std::wstring& virtualDesktopId);
|
||||||
std::optional<std::wstring> GenerateMonitorId(MONITORINFOEX mi, HMONITOR monitor, const GUID& virtualDesktopId);
|
|
||||||
|
|
||||||
std::wstring TrimDeviceId(const std::wstring& deviceId);
|
std::wstring TrimDeviceId(const std::wstring& deviceId);
|
||||||
std::optional<FancyZonesDataTypes::DeviceIdData> ParseDeviceId(const std::wstring& deviceId);
|
std::optional<FancyZonesDataTypes::DeviceIdData> ParseDeviceId(const std::wstring& deviceId);
|
||||||
|
|||||||
Reference in New Issue
Block a user