mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
Merge Master Latest: 4/15/20
This commit is contained in:
@@ -12,6 +12,10 @@
|
||||
<!-- Accent and AppTheme setting -->
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<SolidColorBrush x:Key="CanvasZoneBackgroundBrush" Color="#BF333333"/>
|
||||
<SolidColorBrush x:Key="GridZoneBackgroundBrush" Color="#FF1a1a1a"/>
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@@ -5,51 +5,113 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:FancyZonesEditor"
|
||||
mc:Ignorable="d"
|
||||
Background="LightGray"
|
||||
Opacity="0.75"
|
||||
Background="Transparent"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid x:Name="Frame">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="8"/>
|
||||
<RowDefinition Height="16"/>
|
||||
<RowDefinition Height="24"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="16"/>
|
||||
<RowDefinition Height="8"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="8"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<ColumnDefinition Width="8"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Thumb x:Name="NWResize" Cursor="SizeNWSE" Background="Black" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="NWResize_DragStarted"/>
|
||||
<Thumb x:Name="NEResize" Cursor="SizeNESW" Background="Black" Grid.Row="0" Grid.Column="3" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="NEResize_DragStarted"/>
|
||||
<Thumb x:Name="SWResize" Cursor="SizeNESW" Background="Black" Grid.Row="4" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="SWResize_DragStarted"/>
|
||||
<Thumb x:Name="SEResize" Cursor="SizeNWSE" Background="Black" Grid.Row="4" Grid.Column="3" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="SEResize_DragStarted"/>
|
||||
<Thumb x:Name="NResize" Cursor="SizeNS" Background="Black" Margin="1,0,1,0" Grid.Row="0" Grid.Column="2" DragDelta="UniversalDragDelta" DragStarted="NResize_DragStarted"/>
|
||||
<Thumb x:Name="SResize" Cursor="SizeNS" Background="Black" Margin="1,0,1,0" Grid.Row="5" Grid.Column="2" DragDelta="UniversalDragDelta" DragStarted="SResize_DragStarted"/>
|
||||
<Thumb x:Name="WResize" Cursor="SizeWE" Background="Black" Margin="0,1,0,1" Grid.Row="2" Grid.Column="0" Grid.RowSpan="2" DragDelta="UniversalDragDelta" DragStarted="WResize_DragStarted"/>
|
||||
<Thumb x:Name="EResize" Cursor="SizeWE" Background="Black" Margin="0,1,0,1" Grid.Row="2" Grid.Column="4" Grid.RowSpan="2" DragDelta="UniversalDragDelta" DragStarted="EResize_DragStarted"/>
|
||||
<DockPanel Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="3">
|
||||
<Button DockPanel.Dock="Right" Padding="8,0" Click="OnClose">
|
||||
<Image Source="images/ChromeClose.png" Height="24" Width="24" />
|
||||
</Button>
|
||||
<Thumb x:Name="Caption" Cursor="SizeAll" Background="DarkGray" DragDelta="UniversalDragDelta" DragStarted="Caption_DragStarted"/>
|
||||
</DockPanel>
|
||||
<Rectangle Fill="LightGray" Grid.Row="3" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="3"/>
|
||||
<Canvas x:Name="Body" />
|
||||
<Label Name="LabelID"
|
||||
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="CanvasZoneThumbStyle" TargetType="{x:Type Thumb}">
|
||||
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Thumb}">
|
||||
<Border x:Name="ThumbBorder" Opacity="0" BorderBrush="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates" >
|
||||
<VisualStateGroup.Transitions>
|
||||
<VisualTransition GeneratedDuration="0:0:0.15">
|
||||
<VisualTransition.GeneratedEasingFunction>
|
||||
<ExponentialEase EasingMode="EaseInOut"/>
|
||||
</VisualTransition.GeneratedEasingFunction>
|
||||
</VisualTransition>
|
||||
</VisualStateGroup.Transitions>
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="MouseOver">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="ThumbBorder" Duration="0:0:0.15" Storyboard.TargetProperty="Opacity" To="1"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}">
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="1"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Button}">
|
||||
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
|
||||
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsDefaulted" Value="true">
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.6"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="true">
|
||||
<Setter Property="Opacity" TargetName="contentPresenter" Value="0.4"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Border BorderBrush="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}" Background="{StaticResource CanvasZoneBackgroundBrush}" BorderThickness="1">
|
||||
<Grid x:Name="Frame">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="8"/>
|
||||
<RowDefinition Height="16"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="16"/>
|
||||
<RowDefinition Height="8"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="8"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="16"/>
|
||||
<ColumnDefinition Width="8"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Name="LabelID"
|
||||
Content="ID"
|
||||
Canvas.Left="10"
|
||||
Canvas.Bottom="10"
|
||||
FontSize="80"
|
||||
FontFamily="Segoe UI"
|
||||
Foreground="Black"
|
||||
FontSize="64"
|
||||
FontFamily="Segoe UI Light"
|
||||
Foreground="White"
|
||||
Grid.Column="2"
|
||||
Grid.Row="3"
|
||||
Grid.Row="2"
|
||||
VerticalContentAlignment="Center"
|
||||
HorizontalContentAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
<Thumb x:Name="Caption" Cursor="SizeAll" Background="Transparent" BorderThickness="3" Padding="4" Grid.Column="0" Grid.ColumnSpan="5" Grid.Row="0" Grid.RowSpan="5" DragDelta="UniversalDragDelta" DragStarted="Caption_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
|
||||
<Thumb x:Name="NResize" Cursor="SizeNS" BorderThickness="0,3,0,0" Grid.ColumnSpan="5" DragDelta="UniversalDragDelta" DragStarted="NResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
<Thumb x:Name="SResize" Cursor="SizeNS" BorderThickness="0,0,0,3" Grid.Row="4" Grid.ColumnSpan="5" DragDelta="UniversalDragDelta" DragStarted="SResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
<Thumb x:Name="WResize" Cursor="SizeWE" BorderThickness="3,0,0,0" Grid.RowSpan="5" DragDelta="UniversalDragDelta" DragStarted="WResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
<Thumb x:Name="EResize" Cursor="SizeWE" BorderThickness="0,0,3,0" Grid.Column="4" Grid.RowSpan="5" DragDelta="UniversalDragDelta" DragStarted="EResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
|
||||
<Thumb x:Name="NWResize" Cursor="SizeNWSE" BorderThickness="3,3,0,0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="NWResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
<Thumb x:Name="NEResize" Cursor="SizeNESW" BorderThickness="0,3,3,0" Grid.Row="0" Grid.Column="3" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="NEResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
<Thumb x:Name="SWResize" Cursor="SizeNESW" BorderThickness="3,0,0,3" Grid.Row="3" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="SWResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
<Thumb x:Name="SEResize" Cursor="SizeNWSE" BorderThickness="0,0,3,3" Grid.Row="3" Grid.Column="3" Grid.RowSpan="2" Grid.ColumnSpan="2" DragDelta="UniversalDragDelta" DragStarted="SEResize_DragStarted" Style="{DynamicResource CanvasZoneThumbStyle}"/>
|
||||
|
||||
<Button Content="" BorderThickness="0" ToolTip="Delete zone" Background="Transparent" Foreground="White" FontSize="16" Padding="4" Click="OnClose" Grid.Row="2" Grid.Column="2" FontFamily="Segoe MDL2 Assets" HorizontalAlignment="Right" VerticalAlignment="Top" Style="{DynamicResource CloseButtonStyle}"/>
|
||||
|
||||
<Canvas x:Name="Body" />
|
||||
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
|
||||
@@ -76,6 +76,9 @@
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
<CodeAnalysisRuleSet>..\..\..\..\codeAnalysis\Rules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>images\FancyZonesEditor.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
@@ -248,5 +251,8 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="images\Merge.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="images\FancyZonesEditor.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -9,10 +9,16 @@
|
||||
<Thumb.Template>
|
||||
<ControlTemplate>
|
||||
<StackPanel x:Name="Body" Grid.Column="0" Width="48" Height="48">
|
||||
<Ellipse Height="48" Width="48" Fill="#0078D7" />
|
||||
|
||||
<Ellipse x:Name="BackgroundEllipse" Height="48" Width="48" Fill="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}" />
|
||||
<Rectangle Height="20" Width="2" Fill="White" Margin="5,-48,0,0"/>
|
||||
<Rectangle Height="20" Width="2" Fill="White" Margin="-5,-48,0,0"/>
|
||||
</StackPanel>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="true">
|
||||
<Setter Property="Opacity" TargetName="BackgroundEllipse" Value="0.6"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Thumb.Template>
|
||||
</Thumb>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
Background="LightGray"
|
||||
BorderBrush="DarkGray"
|
||||
Background="{StaticResource GridZoneBackgroundBrush}"
|
||||
BorderBrush="{Binding Source={x:Static SystemParameters.WindowGlassBrush}}"
|
||||
BorderThickness="1"
|
||||
Opacity="0.5"
|
||||
Opacity="0.8"
|
||||
mc:Ignorable="d">
|
||||
<Grid x:Name="Frame">
|
||||
<Canvas x:Name="Body" />
|
||||
@@ -23,9 +23,9 @@
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="ID"
|
||||
FontFamily="Segoe UI"
|
||||
FontSize="80"
|
||||
Foreground="Black" />
|
||||
FontFamily="Segoe UI Light"
|
||||
FontSize="64"
|
||||
Foreground="White" />
|
||||
<!--<TextBlock Margin="2" Text="Shift Key switches direction Ctrl Key repeats"/>-->
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace FancyZonesEditor
|
||||
|
||||
private void OnSelectionChanged()
|
||||
{
|
||||
Background = IsSelected ? Brushes.SteelBlue : Brushes.LightGray;
|
||||
Background = IsSelected ? SystemParameters.WindowGlassBrush : App.Current.Resources["GridZoneBackgroundBrush"] as SolidColorBrush;
|
||||
}
|
||||
|
||||
public bool IsSelected
|
||||
@@ -60,7 +60,7 @@ namespace FancyZonesEditor
|
||||
OnSelectionChanged();
|
||||
_splitter = new Rectangle
|
||||
{
|
||||
Fill = Brushes.DarkGray,
|
||||
Fill = SystemParameters.WindowGlassBrush,
|
||||
};
|
||||
Body.Children.Add(_splitter);
|
||||
|
||||
@@ -101,7 +101,16 @@ namespace FancyZonesEditor
|
||||
|
||||
private int SplitterThickness
|
||||
{
|
||||
get { return Math.Max(((App)Application.Current).ZoneSettings.Spacing, 5); }
|
||||
get
|
||||
{
|
||||
Settings settings = ((App)Application.Current).ZoneSettings;
|
||||
if (!settings.ShowSpacing)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Math.Max(settings.Spacing, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSplitter()
|
||||
@@ -146,7 +155,7 @@ namespace FancyZonesEditor
|
||||
|
||||
protected override void OnMouseEnter(MouseEventArgs e)
|
||||
{
|
||||
_splitter.Fill = Brushes.DarkGray;
|
||||
_splitter.Fill = SystemParameters.WindowGlassBrush; // Active Accent color
|
||||
base.OnMouseEnter(e);
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
@@ -150,6 +150,7 @@ public:
|
||||
void AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept;
|
||||
|
||||
void MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index) noexcept;
|
||||
void MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector<int>& indexSet) noexcept;
|
||||
|
||||
protected:
|
||||
static LRESULT CALLBACK s_WndProc(HWND, UINT, WPARAM, LPARAM) noexcept;
|
||||
@@ -180,6 +181,7 @@ private:
|
||||
};
|
||||
|
||||
bool IsInterestingWindow(HWND window) noexcept;
|
||||
bool IsCursorTypeIndicatingSizeEvent();
|
||||
void UpdateZoneWindows() noexcept;
|
||||
void MoveWindowsOnDisplayChange() noexcept;
|
||||
void UpdateDragState(HWND window, require_write_lock) noexcept;
|
||||
@@ -679,7 +681,7 @@ void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept
|
||||
//const bool flash = m_settings->GetSettings()->zoneSetChange_flashZones && newWorkArea;
|
||||
const bool flash = false;
|
||||
|
||||
auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash);
|
||||
auto zoneWindow = MakeZoneWindow(this, m_hinstance, monitor, uniqueId, flash, newWorkArea);
|
||||
if (zoneWindow)
|
||||
{
|
||||
m_zoneWindowMap[monitor] = std::move(zoneWindow);
|
||||
@@ -694,6 +696,12 @@ void FancyZones::AddZoneWindow(HMONITOR monitor, PCWSTR deviceId) noexcept
|
||||
}
|
||||
|
||||
void FancyZones::MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int index) noexcept
|
||||
{
|
||||
std::shared_lock readLock(m_lock);
|
||||
MoveWindowIntoZoneByIndexSet(window, monitor, { index });
|
||||
}
|
||||
|
||||
void FancyZones::MoveWindowIntoZoneByIndexSet(HWND window, HMONITOR monitor, const std::vector<int>& indexSet) noexcept
|
||||
{
|
||||
std::shared_lock readLock(m_lock);
|
||||
if (window != m_windowMoveSize)
|
||||
@@ -705,7 +713,7 @@ void FancyZones::MoveWindowIntoZoneByIndex(HWND window, HMONITOR monitor, int in
|
||||
if (zoneWindow != m_zoneWindowMap.end())
|
||||
{
|
||||
const auto& zoneWindowPtr = zoneWindow->second;
|
||||
zoneWindowPtr->MoveWindowIntoZoneByIndex(window, index);
|
||||
zoneWindowPtr->MoveWindowIntoZoneByIndexSet(window, indexSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -745,6 +753,33 @@ bool FancyZones::IsInterestingWindow(HWND window) noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FancyZones::IsCursorTypeIndicatingSizeEvent()
|
||||
{
|
||||
CURSORINFO cursorInfo = { 0 };
|
||||
cursorInfo.cbSize = sizeof(cursorInfo);
|
||||
|
||||
if (::GetCursorInfo(&cursorInfo))
|
||||
{
|
||||
if (::LoadCursor(NULL, IDC_SIZENS) == cursorInfo.hCursor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (::LoadCursor(NULL, IDC_SIZEWE) == cursorInfo.hCursor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (::LoadCursor(NULL, IDC_SIZENESW) == cursorInfo.hCursor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (::LoadCursor(NULL, IDC_SIZENWSE) == cursorInfo.hCursor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FancyZones::UpdateZoneWindows() noexcept
|
||||
{
|
||||
auto callback = [](HMONITOR monitor, HDC, RECT*, LPARAM data) -> BOOL {
|
||||
@@ -832,10 +867,8 @@ void FancyZones::UpdateDragState(HWND window, require_write_lock) noexcept
|
||||
m_dragEnabled = !(shift | mouse);
|
||||
}
|
||||
|
||||
const bool windowElevated = IsProcessOfWindowElevated(window);
|
||||
static const bool meElevated = is_process_elevated();
|
||||
static bool warning_shown = false;
|
||||
if (windowElevated && !meElevated)
|
||||
if (!is_process_elevated() && IsProcessOfWindowElevated(window))
|
||||
{
|
||||
m_dragEnabled = false;
|
||||
if (!warning_shown && !is_cant_drag_elevated_warning_disabled())
|
||||
@@ -920,23 +953,10 @@ bool FancyZones::OnSnapHotkey(DWORD vkCode) noexcept
|
||||
|
||||
void FancyZones::MoveSizeStartInternal(HWND window, HMONITOR monitor, POINT const& ptScreen, require_write_lock writeLock) noexcept
|
||||
{
|
||||
// Only enter move/size if the cursor is inside the window rect by a certain padding.
|
||||
// This prevents resize from triggering zones.
|
||||
RECT windowRect{};
|
||||
::GetWindowRect(window, &windowRect);
|
||||
|
||||
const auto padding_x = 8;
|
||||
const auto padding_y = 6;
|
||||
windowRect.top += padding_y;
|
||||
windowRect.left += padding_x;
|
||||
windowRect.right -= padding_x;
|
||||
windowRect.bottom -= padding_y;
|
||||
|
||||
if (PtInRect(&windowRect, ptScreen) == FALSE)
|
||||
if (IsCursorTypeIndicatingSizeEvent())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_inMoveSize = true;
|
||||
|
||||
auto iter = m_zoneWindowMap.find(monitor);
|
||||
|
||||
@@ -604,9 +604,6 @@ namespace JSONHelpers
|
||||
|
||||
if (!std::filesystem::exists(jsonFilePath))
|
||||
{
|
||||
TmpMigrateAppliedZoneSetsFromRegistry();
|
||||
|
||||
// Custom zone sets have to be migrated after applied zone sets!
|
||||
MigrateCustomZoneSetsFromRegistry();
|
||||
|
||||
SaveFancyZonesData();
|
||||
@@ -639,56 +636,6 @@ namespace JSONHelpers
|
||||
json::to_file(jsonFilePath, root);
|
||||
}
|
||||
|
||||
void FancyZonesData::TmpMigrateAppliedZoneSetsFromRegistry()
|
||||
{
|
||||
std::wregex ex(L"^[0-9]{3,4}_[0-9]{3,4}$");
|
||||
|
||||
std::scoped_lock lock{ dataLock };
|
||||
wchar_t key[256];
|
||||
StringCchPrintf(key, ARRAYSIZE(key), L"%s", RegistryHelpers::REG_SETTINGS);
|
||||
HKEY hkey;
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS)
|
||||
{
|
||||
wchar_t resolutionKey[256]{};
|
||||
DWORD resolutionKeyLength = ARRAYSIZE(resolutionKey);
|
||||
DWORD i = 0;
|
||||
while (RegEnumKeyW(hkey, i++, resolutionKey, resolutionKeyLength) == ERROR_SUCCESS)
|
||||
{
|
||||
std::wstring resolution{ resolutionKey };
|
||||
wchar_t appliedZoneSetskey[256];
|
||||
StringCchPrintf(appliedZoneSetskey, ARRAYSIZE(appliedZoneSetskey), L"%s\\%s", RegistryHelpers::REG_SETTINGS, resolutionKey);
|
||||
HKEY appliedZoneSetsHkey;
|
||||
if (std::regex_match(resolution, ex) && RegOpenKeyExW(HKEY_CURRENT_USER, appliedZoneSetskey, 0, KEY_ALL_ACCESS, &appliedZoneSetsHkey) == ERROR_SUCCESS)
|
||||
{
|
||||
ZoneSetPersistedDataOLD data;
|
||||
DWORD dataSize = sizeof(data);
|
||||
wchar_t value[256]{};
|
||||
DWORD valueLength = ARRAYSIZE(value);
|
||||
DWORD i = 0;
|
||||
|
||||
while (RegEnumValueW(appliedZoneSetsHkey, i++, value, &valueLength, nullptr, nullptr, reinterpret_cast<BYTE*>(&data), &dataSize) == ERROR_SUCCESS)
|
||||
{
|
||||
ZoneSetData appliedZoneSetData;
|
||||
appliedZoneSetData.type = TypeFromLayoutId(data.LayoutId);
|
||||
if (appliedZoneSetData.type != ZoneSetLayoutType::Custom)
|
||||
{
|
||||
appliedZoneSetData.uuid = std::wstring{ value };
|
||||
}
|
||||
else
|
||||
{
|
||||
// uuid is changed later to actual uuid when migrating custom zone sets
|
||||
appliedZoneSetData.uuid = std::to_wstring(data.LayoutId);
|
||||
}
|
||||
appliedZoneSetsMap[value] = appliedZoneSetData;
|
||||
dataSize = sizeof(data);
|
||||
valueLength = ARRAYSIZE(value);
|
||||
}
|
||||
}
|
||||
resolutionKeyLength = ARRAYSIZE(resolutionKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FancyZonesData::MigrateCustomZoneSetsFromRegistry()
|
||||
{
|
||||
std::scoped_lock lock{ dataLock };
|
||||
@@ -709,29 +656,19 @@ namespace JSONHelpers
|
||||
zoneSetData.type = static_cast<CustomLayoutType>(data[2]);
|
||||
// int version = data[0] * 256 + data[1]; - Not used anymore
|
||||
|
||||
std::wstring uuid = std::to_wstring(data[3] * 256 + data[4]);
|
||||
auto it = std::find_if(appliedZoneSetsMap.cbegin(), appliedZoneSetsMap.cend(), [&uuid](std::pair<std::wstring, ZoneSetData> zoneSetMap) {
|
||||
return zoneSetMap.second.uuid.compare(uuid) == 0;
|
||||
});
|
||||
GUID guid;
|
||||
auto result = CoCreateGuid(&guid);
|
||||
if (result != S_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
wil::unique_cotaskmem_string guidString;
|
||||
if (!SUCCEEDED_LOG(StringFromCLSID(guid, &guidString)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it != appliedZoneSetsMap.cend())
|
||||
{
|
||||
uuid = it->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUID guid;
|
||||
auto result = CoCreateGuid(&guid);
|
||||
if (result != S_OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
wil::unique_cotaskmem_string guidString;
|
||||
if (SUCCEEDED_LOG(StringFromCLSID(guid, &guidString)))
|
||||
{
|
||||
uuid = guidString.get();
|
||||
}
|
||||
}
|
||||
std::wstring uuid = guidString.get();
|
||||
|
||||
switch (zoneSetData.type)
|
||||
{
|
||||
|
||||
@@ -207,12 +207,16 @@ namespace JSONHelpers
|
||||
#if defined(UNIT_TESTS)
|
||||
inline void clear_data()
|
||||
{
|
||||
appliedZoneSetsMap.clear();
|
||||
appZoneHistoryMap.clear();
|
||||
deviceInfoMap.clear();
|
||||
customZoneSetsMap.clear();
|
||||
activeDeviceId.clear();
|
||||
}
|
||||
|
||||
inline void SetDeviceInfo(const std::wstring& deviceId, DeviceInfoData data)
|
||||
{
|
||||
deviceInfoMap[deviceId] = data;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void SetActiveDeviceId(const std::wstring& deviceId)
|
||||
@@ -254,10 +258,8 @@ namespace JSONHelpers
|
||||
void SaveFancyZonesData() const;
|
||||
|
||||
private:
|
||||
void TmpMigrateAppliedZoneSetsFromRegistry();
|
||||
void MigrateCustomZoneSetsFromRegistry();
|
||||
|
||||
std::unordered_map<std::wstring, ZoneSetData> appliedZoneSetsMap{};
|
||||
std::unordered_map<std::wstring, AppZoneHistoryData> appZoneHistoryMap{};
|
||||
std::unordered_map<std::wstring, DeviceInfoData> deviceInfoMap{};
|
||||
std::unordered_map<std::wstring, CustomZoneSetData> customZoneSetsMap{};
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#include <common/monitors.h>
|
||||
#include "Zone.h"
|
||||
#include "Settings.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "common/monitors.h"
|
||||
|
||||
struct Zone : winrt::implements<Zone, IZone>
|
||||
{
|
||||
@@ -20,6 +23,7 @@ public:
|
||||
IFACEMETHODIMP_(void) RemoveWindowFromZone(HWND window, bool restoreSize) noexcept;
|
||||
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;
|
||||
|
||||
private:
|
||||
void SizeWindowToZone(HWND window, HWND zoneWindow) noexcept;
|
||||
@@ -61,14 +65,13 @@ IFACEMETHODIMP_(void) Zone::RemoveWindowFromZone(HWND window, bool restoreSize)
|
||||
|
||||
void Zone::SizeWindowToZone(HWND window, HWND zoneWindow) noexcept
|
||||
{
|
||||
// Skip invisible windows
|
||||
if (!IsWindowVisible(window))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SizeWindowToRect(window, ComputeActualZoneRect(window, zoneWindow));
|
||||
}
|
||||
|
||||
RECT Zone::ComputeActualZoneRect(HWND window, HWND zoneWindow) noexcept
|
||||
{
|
||||
// Take care of 1px border
|
||||
RECT zoneRect = m_zoneRect;
|
||||
RECT newWindowRect = m_zoneRect;
|
||||
|
||||
RECT windowRect{};
|
||||
::GetWindowRect(window, &windowRect);
|
||||
@@ -77,57 +80,43 @@ void Zone::SizeWindowToZone(HWND window, HWND zoneWindow) noexcept
|
||||
|
||||
const auto level = DPIAware::GetAwarenessLevel(GetWindowDpiAwarenessContext(window));
|
||||
const bool accountForUnawareness = level < DPIAware::PER_MONITOR_AWARE;
|
||||
|
||||
if (SUCCEEDED(DwmGetWindowAttribute(window, DWMWA_EXTENDED_FRAME_BOUNDS, &frameRect, sizeof(frameRect))))
|
||||
{
|
||||
const auto left_margin = frameRect.left - windowRect.left;
|
||||
const auto right_margin = frameRect.right - windowRect.right;
|
||||
const auto bottom_margin = frameRect.bottom - windowRect.bottom;
|
||||
zoneRect.left -= left_margin;
|
||||
zoneRect.right -= right_margin;
|
||||
zoneRect.bottom -= bottom_margin;
|
||||
LONG leftMargin = frameRect.left - windowRect.left;
|
||||
LONG rightMargin = frameRect.right - windowRect.right;
|
||||
LONG bottomMargin = frameRect.bottom - windowRect.bottom;
|
||||
newWindowRect.left -= leftMargin;
|
||||
newWindowRect.right -= rightMargin;
|
||||
newWindowRect.bottom -= bottomMargin;
|
||||
}
|
||||
|
||||
// Map to screen coords
|
||||
MapWindowRect(zoneWindow, nullptr, &zoneRect);
|
||||
MapWindowRect(zoneWindow, nullptr, &newWindowRect);
|
||||
|
||||
MONITORINFO mi{sizeof(mi)};
|
||||
MONITORINFO mi{ sizeof(mi) };
|
||||
if (GetMonitorInfoW(MonitorFromWindow(zoneWindow, MONITOR_DEFAULTTONEAREST), &mi))
|
||||
{
|
||||
const auto taskbar_left_size = std::abs(mi.rcMonitor.left - mi.rcWork.left);
|
||||
const auto taskbar_top_size = std::abs(mi.rcMonitor.top - mi.rcWork.top);
|
||||
OffsetRect(&zoneRect, -taskbar_left_size, -taskbar_top_size);
|
||||
if (accountForUnawareness)
|
||||
OffsetRect(&newWindowRect, -taskbar_left_size, -taskbar_top_size);
|
||||
|
||||
if (accountForUnawareness && MonitorInfo::GetMonitorsCount() > 1)
|
||||
{
|
||||
zoneRect.left = max(mi.rcMonitor.left, zoneRect.left);
|
||||
zoneRect.right = min(mi.rcMonitor.right - taskbar_left_size, zoneRect.right);
|
||||
zoneRect.top = max(mi.rcMonitor.top, zoneRect.top);
|
||||
zoneRect.bottom = min(mi.rcMonitor.bottom - taskbar_top_size, zoneRect.bottom);
|
||||
newWindowRect.left = max(mi.rcMonitor.left, newWindowRect.left);
|
||||
newWindowRect.right = min(mi.rcMonitor.right - taskbar_left_size, newWindowRect.right);
|
||||
newWindowRect.top = max(mi.rcMonitor.top, newWindowRect.top);
|
||||
newWindowRect.bottom = min(mi.rcMonitor.bottom - taskbar_top_size, newWindowRect.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
WINDOWPLACEMENT placement{};
|
||||
::GetWindowPlacement(window, &placement);
|
||||
|
||||
//wait if SW_SHOWMINIMIZED would be removed from window (Issue #1685)
|
||||
for (int i = 0; i < 5 && (placement.showCmd & SW_SHOWMINIMIZED) != 0; i++)
|
||||
if ((::GetWindowLong(window, GWL_STYLE) & WS_SIZEBOX) == 0)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
::GetWindowPlacement(window, &placement);
|
||||
newWindowRect.right = newWindowRect.left + (windowRect.right - windowRect.left);
|
||||
newWindowRect.bottom = newWindowRect.top + (windowRect.bottom - windowRect.top);
|
||||
}
|
||||
|
||||
// Do not restore minimized windows. We change their placement though so they restore to the correct zone.
|
||||
if ((placement.showCmd & SW_SHOWMINIMIZED) == 0)
|
||||
{
|
||||
placement.showCmd = SW_RESTORE | SW_SHOWNA;
|
||||
}
|
||||
|
||||
placement.rcNormalPosition = zoneRect;
|
||||
placement.flags |= WPF_ASYNCWINDOWPLACEMENT;
|
||||
|
||||
::SetWindowPlacement(window, &placement);
|
||||
// Do it again, allowing Windows to resize the window and set correct scaling
|
||||
// This fixes Issue #365
|
||||
::SetWindowPlacement(window, &placement);
|
||||
return newWindowRect;
|
||||
}
|
||||
|
||||
void Zone::StampZone(HWND window, bool stamp) noexcept
|
||||
|
||||
@@ -42,9 +42,20 @@ interface __declspec(uuid("{8228E934-B6EF-402A-9892-15A1441BF8B0}")) IZone : pub
|
||||
*/
|
||||
IFACEMETHOD_(void, SetId)(size_t id) = 0;
|
||||
/**
|
||||
* @retirns Zone identifier.
|
||||
* @returns Zone identifier.
|
||||
*/
|
||||
IFACEMETHOD_(size_t, Id)() = 0;
|
||||
|
||||
/**
|
||||
* Compute the coordinates of the rectangle to which a window should be resized.
|
||||
*
|
||||
* @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.
|
||||
* @returns a RECT structure, describing global coordinates to which a window should be resized
|
||||
*/
|
||||
IFACEMETHOD_(RECT, ComputeActualZoneRect)(HWND window, HWND zoneWindow) = 0;
|
||||
|
||||
};
|
||||
|
||||
winrt::com_ptr<IZone> MakeZone(const RECT& zoneRect) noexcept;
|
||||
|
||||
@@ -122,14 +122,16 @@ public:
|
||||
IFACEMETHODIMP_(JSONHelpers::ZoneSetLayoutType)
|
||||
LayoutType() noexcept { return m_config.LayoutType; }
|
||||
IFACEMETHODIMP AddZone(winrt::com_ptr<IZone> zone) noexcept;
|
||||
IFACEMETHODIMP_(winrt::com_ptr<IZone>)
|
||||
ZoneFromPoint(POINT pt) noexcept;
|
||||
IFACEMETHODIMP_(std::vector<int>)
|
||||
ZonesFromPoint(POINT pt) noexcept;
|
||||
IFACEMETHODIMP_(int)
|
||||
GetZoneIndexFromWindow(HWND window) noexcept;
|
||||
IFACEMETHODIMP_(std::vector<winrt::com_ptr<IZone>>)
|
||||
GetZones() noexcept { return m_zones; }
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowIntoZoneByIndex(HWND window, HWND zoneWindow, int index) noexcept;
|
||||
MoveWindowIntoZoneByIndex(HWND window, HWND zoneWindow, int index, bool stampZone) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::vector<int>& indexSet, bool stampZone) noexcept;
|
||||
IFACEMETHODIMP_(bool)
|
||||
MoveWindowIntoZoneByDirection(HWND window, HWND zoneWindow, DWORD vkCode, bool cycle) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
@@ -162,41 +164,79 @@ IFACEMETHODIMP ZoneSet::AddZone(winrt::com_ptr<IZone> zone) noexcept
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(winrt::com_ptr<IZone>)
|
||||
ZoneSet::ZoneFromPoint(POINT pt) noexcept
|
||||
IFACEMETHODIMP_(std::vector<int>)
|
||||
ZoneSet::ZonesFromPoint(POINT pt) noexcept
|
||||
{
|
||||
winrt::com_ptr<IZone> smallestKnownZone = nullptr;
|
||||
// To reduce redundant calculations, we will store the last known zones area.
|
||||
int smallestKnownZoneArea = INT32_MAX;
|
||||
for (auto iter = m_zones.rbegin(); iter != m_zones.rend(); iter++)
|
||||
const int SENSITIVITY_RADIUS = 20;
|
||||
std::vector<int> capturedZones;
|
||||
std::vector<int> strictlyCapturedZones;
|
||||
for (size_t i = 0; i < m_zones.size(); i++)
|
||||
{
|
||||
if (winrt::com_ptr<IZone> zone = iter->try_as<IZone>())
|
||||
auto zone = m_zones[i];
|
||||
RECT newZoneRect = zone->GetZoneRect();
|
||||
if (newZoneRect.left < newZoneRect.right && newZoneRect.top < newZoneRect.bottom) // proper zone
|
||||
{
|
||||
RECT* newZoneRect = &zone->GetZoneRect();
|
||||
if (PtInRect(newZoneRect, pt))
|
||||
if (newZoneRect.left - SENSITIVITY_RADIUS <= pt.x && pt.x <= newZoneRect.right + SENSITIVITY_RADIUS &&
|
||||
newZoneRect.top - SENSITIVITY_RADIUS <= pt.y && pt.y <= newZoneRect.bottom + SENSITIVITY_RADIUS)
|
||||
{
|
||||
if (smallestKnownZone == nullptr)
|
||||
{
|
||||
smallestKnownZone = zone;
|
||||
|
||||
RECT* r = &smallestKnownZone->GetZoneRect();
|
||||
smallestKnownZoneArea = (r->right - r->left) * (r->bottom - r->top);
|
||||
}
|
||||
else
|
||||
{
|
||||
int newZoneArea = (newZoneRect->right - newZoneRect->left) * (newZoneRect->bottom - newZoneRect->top);
|
||||
|
||||
if (newZoneArea < smallestKnownZoneArea)
|
||||
{
|
||||
smallestKnownZone = zone;
|
||||
smallestKnownZoneArea = newZoneArea;
|
||||
}
|
||||
}
|
||||
capturedZones.emplace_back(static_cast<int>(i));
|
||||
}
|
||||
|
||||
if (newZoneRect.left <= pt.x && pt.x < newZoneRect.right &&
|
||||
newZoneRect.top <= pt.y && pt.y < newZoneRect.bottom)
|
||||
{
|
||||
strictlyCapturedZones.emplace_back(static_cast<int>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return smallestKnownZone;
|
||||
// If only one zone is captured, but it's not strictly captured
|
||||
// don't consider it as captured
|
||||
if (capturedZones.size() == 1 && strictlyCapturedZones.size() == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// 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) < min(rectI.bottom, rectJ.bottom) &&
|
||||
max(rectI.left, rectJ.left) < min(rectI.right, rectJ.right))
|
||||
{
|
||||
overlap = true;
|
||||
i = capturedZones.size() - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (overlap)
|
||||
{
|
||||
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();
|
||||
int smallestSize = (rectS.bottom - rectS.top) * (rectS.right - rectS.left);
|
||||
int iSize = (rectI.bottom - rectI.top) * (rectI.right - rectI.left);
|
||||
|
||||
if (iSize <= smallestSize)
|
||||
{
|
||||
smallestIdx = i;
|
||||
}
|
||||
}
|
||||
|
||||
capturedZones = { capturedZones[smallestIdx] };
|
||||
}
|
||||
|
||||
return capturedZones;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(int)
|
||||
@@ -217,7 +257,7 @@ ZoneSet::GetZoneIndexFromWindow(HWND window) noexcept
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, int index) noexcept
|
||||
ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, int index, bool stampZone) noexcept
|
||||
{
|
||||
if (m_zones.empty())
|
||||
{
|
||||
@@ -236,7 +276,55 @@ ZoneSet::MoveWindowIntoZoneByIndex(HWND window, HWND windowZone, int index) noex
|
||||
|
||||
if (auto zone = m_zones.at(index))
|
||||
{
|
||||
zone->AddWindowToZone(window, windowZone, false);
|
||||
zone->AddWindowToZone(window, windowZone, stampZone);
|
||||
}
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
ZoneSet::MoveWindowIntoZoneByIndexSet(HWND window, HWND windowZone, const std::vector<int>& indexSet, bool stampZone) noexcept
|
||||
{
|
||||
if (m_zones.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (auto zoneDrop = ZoneFromWindow(window))
|
||||
{
|
||||
zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window));
|
||||
}
|
||||
|
||||
if (indexSet.size() == 1)
|
||||
{
|
||||
MoveWindowIntoZoneByIndex(window, windowZone, indexSet[0], stampZone);
|
||||
return;
|
||||
}
|
||||
|
||||
RECT size;
|
||||
bool sizeEmpty = true;
|
||||
|
||||
for (int index : indexSet)
|
||||
{
|
||||
if (index < static_cast<int>(m_zones.size()))
|
||||
{
|
||||
RECT newSize = m_zones.at(index)->ComputeActualZoneRect(window, windowZone);
|
||||
if (!sizeEmpty)
|
||||
{
|
||||
size.left = min(size.left, newSize.left);
|
||||
size.top = min(size.top, newSize.top);
|
||||
size.right = max(size.right, newSize.right);
|
||||
size.bottom = max(size.bottom, newSize.bottom);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = newSize;
|
||||
sizeEmpty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizeEmpty)
|
||||
{
|
||||
SizeWindowToRect(window, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,10 +394,8 @@ ZoneSet::MoveWindowIntoZoneByPoint(HWND window, HWND zoneWindow, POINT ptClient)
|
||||
zoneDrop->RemoveWindowFromZone(window, !IsZoomed(window));
|
||||
}
|
||||
|
||||
if (auto zone = ZoneFromPoint(ptClient))
|
||||
{
|
||||
zone->AddWindowToZone(window, zoneWindow, true);
|
||||
}
|
||||
auto zones = ZonesFromPoint(ptClient);
|
||||
MoveWindowIntoZoneByIndexSet(window, zoneWindow, zones, true);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(bool)
|
||||
|
||||
@@ -24,12 +24,12 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
||||
*/
|
||||
IFACEMETHOD(AddZone)(winrt::com_ptr<IZone> zone) = 0;
|
||||
/**
|
||||
* Get zone from cursor coordinates.
|
||||
* Get zones from cursor coordinates.
|
||||
*
|
||||
* @param pt Cursor coordinates.
|
||||
* @returns Zone object (defining coordinates of the zone).
|
||||
* @returns Vector of indices, corresponding to the current set of zones - the zones considered active.
|
||||
*/
|
||||
IFACEMETHOD_(winrt::com_ptr<IZone>, ZoneFromPoint)(POINT pt) = 0;
|
||||
IFACEMETHOD_(std::vector<int>, ZonesFromPoint)(POINT pt) = 0;
|
||||
/**
|
||||
* Get index of the zone inside zone layout by window assigned to it.
|
||||
*
|
||||
@@ -48,8 +48,20 @@ interface __declspec(uuid("{E4839EB7-669D-49CF-84A9-71A2DFD851A3}")) IZoneSet :
|
||||
* @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 stampZone Whether the window being added to the zone should be stamped.
|
||||
*/
|
||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, HWND zoneWindow, int index) = 0;
|
||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, HWND zoneWindow, int index, bool stampZone) = 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 stampZone Whether the window being added to the zone should be stamped,
|
||||
in case a single window is to be added.
|
||||
*/
|
||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndexSet)(HWND window, HWND zoneWindow, const std::vector<int>& indexSet, bool stampZone) = 0;
|
||||
/**
|
||||
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow).
|
||||
*
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace ZoneWindowDrawUtils
|
||||
Gdiplus::Color fillColor(colorSetting.fillAlpha, GetRValue(colorSetting.fill), GetGValue(colorSetting.fill), GetBValue(colorSetting.fill));
|
||||
Gdiplus::Color borderColor(colorSetting.borderAlpha, GetRValue(colorSetting.border), GetGValue(colorSetting.border), GetBValue(colorSetting.border));
|
||||
|
||||
Gdiplus::Rect rectangle(zoneRect.left, zoneRect.top, zoneRect.right - zoneRect.left, zoneRect.bottom - zoneRect.top);
|
||||
Gdiplus::Rect rectangle(zoneRect.left, zoneRect.top, zoneRect.right - zoneRect.left - 1, zoneRect.bottom - zoneRect.top - 1);
|
||||
|
||||
Gdiplus::Pen pen(borderColor, static_cast<Gdiplus::REAL>(colorSetting.thickness));
|
||||
g.FillRectangle(new Gdiplus::SolidBrush(fillColor), rectangle);
|
||||
@@ -148,7 +148,7 @@ namespace ZoneWindowDrawUtils
|
||||
COLORREF highlightColor,
|
||||
int zoneOpacity,
|
||||
const std::vector<winrt::com_ptr<IZone>>& zones,
|
||||
const winrt::com_ptr<IZone>& highlightZone,
|
||||
const std::vector<int>& highlightZones,
|
||||
bool flashMode,
|
||||
bool drawHints) noexcept
|
||||
{
|
||||
@@ -158,15 +158,22 @@ namespace ZoneWindowDrawUtils
|
||||
ColorSetting colorHighlight{ OpacitySettingToAlpha(zoneOpacity), 0, 255, 0, -2 };
|
||||
ColorSetting const colorFlash{ OpacitySettingToAlpha(zoneOpacity), RGB(81, 92, 107), 200, RGB(104, 118, 138), -2 };
|
||||
|
||||
std::vector<bool> isHighlighted(zones.size(), false);
|
||||
for (int x : highlightZones)
|
||||
{
|
||||
isHighlighted[x] = true;
|
||||
}
|
||||
|
||||
for (auto iter = zones.begin(); iter != zones.end(); iter++)
|
||||
{
|
||||
int zoneId = static_cast<int>(iter - zones.begin());
|
||||
winrt::com_ptr<IZone> zone = iter->try_as<IZone>();
|
||||
if (!zone)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (zone != highlightZone)
|
||||
if (!isHighlighted[zoneId])
|
||||
{
|
||||
if (flashMode)
|
||||
{
|
||||
@@ -182,13 +189,12 @@ namespace ZoneWindowDrawUtils
|
||||
DrawZone(hdc, colorViewer, zone, zones, flashMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightZone)
|
||||
{
|
||||
colorHighlight.fill = highlightColor;
|
||||
colorHighlight.border = zoneBorderColor;
|
||||
DrawZone(hdc, colorHighlight, highlightZone, zones, flashMode);
|
||||
else
|
||||
{
|
||||
colorHighlight.fill = highlightColor;
|
||||
colorHighlight.border = zoneBorderColor;
|
||||
DrawZone(hdc, colorHighlight, zone, zones, flashMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,7 +205,7 @@ public:
|
||||
ZoneWindow(HINSTANCE hinstance);
|
||||
~ZoneWindow();
|
||||
|
||||
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones);
|
||||
bool Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea);
|
||||
|
||||
IFACEMETHODIMP MoveSizeEnter(HWND window, bool dragEnabled) noexcept;
|
||||
IFACEMETHODIMP MoveSizeUpdate(POINT const& ptScreen, bool dragEnabled) noexcept;
|
||||
@@ -210,6 +216,8 @@ public:
|
||||
IsDragEnabled() noexcept { return m_dragEnabled; }
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowIntoZoneByIndex(HWND window, int index) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet) noexcept;
|
||||
IFACEMETHODIMP_(bool)
|
||||
MoveWindowIntoZoneByDirection(HWND window, DWORD vkCode, bool cycle) noexcept;
|
||||
IFACEMETHODIMP_(void)
|
||||
@@ -232,13 +240,13 @@ protected:
|
||||
|
||||
private:
|
||||
void LoadSettings() noexcept;
|
||||
void InitializeZoneSets(MONITORINFO const& mi) noexcept;
|
||||
void InitializeZoneSets(bool newWorkArea) noexcept;
|
||||
void CalculateZoneSet() noexcept;
|
||||
void UpdateActiveZoneSet(_In_opt_ IZoneSet* zoneSet) noexcept;
|
||||
LRESULT WndProc(UINT message, WPARAM wparam, LPARAM lparam) noexcept;
|
||||
void OnPaint(wil::unique_hdc& hdc) noexcept;
|
||||
void OnKeyUp(WPARAM wparam) noexcept;
|
||||
winrt::com_ptr<IZone> ZoneFromPoint(POINT pt) noexcept;
|
||||
std::vector<int> ZonesFromPoint(POINT pt) noexcept;
|
||||
void CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept;
|
||||
void FlashZones() noexcept;
|
||||
|
||||
@@ -253,7 +261,7 @@ private:
|
||||
bool m_dragEnabled{};
|
||||
winrt::com_ptr<IZoneSet> m_activeZoneSet;
|
||||
std::vector<winrt::com_ptr<IZoneSet>> m_zoneSets;
|
||||
winrt::com_ptr<IZone> m_highlightZone;
|
||||
std::vector<int> m_highlightZone;
|
||||
WPARAM m_keyLast{};
|
||||
size_t m_keyCycle{};
|
||||
static const UINT m_showAnimationDuration = 200; // ms
|
||||
@@ -289,7 +297,7 @@ ZoneWindow::~ZoneWindow()
|
||||
Gdiplus::GdiplusShutdown(gdiplusToken);
|
||||
}
|
||||
|
||||
bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones)
|
||||
bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea)
|
||||
{
|
||||
m_host.copy_from(host);
|
||||
|
||||
@@ -308,7 +316,7 @@ bool ZoneWindow::Init(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monit
|
||||
|
||||
m_uniqueId = uniqueId;
|
||||
LoadSettings();
|
||||
InitializeZoneSets(mi);
|
||||
InitializeZoneSets(newWorkArea);
|
||||
|
||||
m_window = wil::unique_hwnd{
|
||||
CreateWindowExW(WS_EX_TOOLWINDOW, L"SuperFancyZones_ZoneWindow", L"", WS_POPUP, workAreaRect.left(), workAreaRect.top(), workAreaRect.width(), workAreaRect.height(), nullptr, nullptr, hinstance, this)
|
||||
@@ -363,7 +371,7 @@ IFACEMETHODIMP ZoneWindow::MoveSizeEnter(HWND window, bool dragEnabled) noexcept
|
||||
m_dragEnabled = dragEnabled;
|
||||
m_windowMoveSize = window;
|
||||
m_drawHints = true;
|
||||
m_highlightZone = nullptr;
|
||||
m_highlightZone = {};
|
||||
ShowZoneWindow();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -378,13 +386,13 @@ IFACEMETHODIMP ZoneWindow::MoveSizeUpdate(POINT const& ptScreen, bool dragEnable
|
||||
|
||||
if (dragEnabled)
|
||||
{
|
||||
auto highlightZone = ZoneFromPoint(ptClient);
|
||||
auto highlightZone = ZonesFromPoint(ptClient);
|
||||
redraw = (highlightZone != m_highlightZone);
|
||||
m_highlightZone = std::move(highlightZone);
|
||||
}
|
||||
else if (m_highlightZone)
|
||||
else if (m_highlightZone.size())
|
||||
{
|
||||
m_highlightZone = nullptr;
|
||||
m_highlightZone = {};
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
@@ -432,10 +440,16 @@ ZoneWindow::RestoreOrginalTransparency() noexcept
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
ZoneWindow::MoveWindowIntoZoneByIndex(HWND window, int index) noexcept
|
||||
{
|
||||
MoveWindowIntoZoneByIndexSet(window, { index });
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(void)
|
||||
ZoneWindow::MoveWindowIntoZoneByIndexSet(HWND window, const std::vector<int>& indexSet) noexcept
|
||||
{
|
||||
if (m_activeZoneSet)
|
||||
{
|
||||
m_activeZoneSet->MoveWindowIntoZoneByIndex(window, m_window.get(), index);
|
||||
m_activeZoneSet->MoveWindowIntoZoneByIndexSet(window, m_window.get(), indexSet, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -518,7 +532,7 @@ ZoneWindow::HideZoneWindow() noexcept
|
||||
m_keyLast = 0;
|
||||
m_windowMoveSize = nullptr;
|
||||
m_drawHints = false;
|
||||
m_highlightZone = nullptr;
|
||||
m_highlightZone = {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,10 +543,10 @@ void ZoneWindow::LoadSettings() noexcept
|
||||
JSONHelpers::FancyZonesDataInstance().AddDevice(m_uniqueId);
|
||||
}
|
||||
|
||||
void ZoneWindow::InitializeZoneSets(MONITORINFO const& mi) noexcept
|
||||
void ZoneWindow::InitializeZoneSets(bool newWorkArea) noexcept
|
||||
{
|
||||
auto parent = m_host->GetParentZoneWindow(m_monitor);
|
||||
if (parent)
|
||||
if (newWorkArea && parent)
|
||||
{
|
||||
// Update device info with device info from parent virtual desktop (if empty).
|
||||
JSONHelpers::FancyZonesDataInstance().CloneDeviceInfo(parent->UniqueId(), m_uniqueId);
|
||||
@@ -685,13 +699,13 @@ void ZoneWindow::OnKeyUp(WPARAM wparam) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
winrt::com_ptr<IZone> ZoneWindow::ZoneFromPoint(POINT pt) noexcept
|
||||
std::vector<int> ZoneWindow::ZonesFromPoint(POINT pt) noexcept
|
||||
{
|
||||
if (m_activeZoneSet)
|
||||
{
|
||||
return m_activeZoneSet->ZoneFromPoint(pt);
|
||||
return m_activeZoneSet->ZonesFromPoint(pt);
|
||||
}
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
|
||||
void ZoneWindow::CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::InputMode mode) noexcept
|
||||
@@ -739,7 +753,7 @@ void ZoneWindow::CycleActiveZoneSetInternal(DWORD wparam, Trace::ZoneWindow::Inp
|
||||
{
|
||||
m_host->MoveWindowsOnActiveZoneSetChange();
|
||||
}
|
||||
m_highlightZone = nullptr;
|
||||
m_highlightZone = {};
|
||||
}
|
||||
|
||||
void ZoneWindow::FlashZones() noexcept
|
||||
@@ -773,10 +787,10 @@ LRESULT CALLBACK ZoneWindow::s_WndProc(HWND window, UINT message, WPARAM wparam,
|
||||
DefWindowProc(window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones) noexcept
|
||||
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor, const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept
|
||||
{
|
||||
auto self = winrt::make_self<ZoneWindow>(hinstance);
|
||||
if (self->Init(host, hinstance, monitor, uniqueId, flashZones))
|
||||
if (self->Init(host, hinstance, monitor, uniqueId, flashZones, newWorkArea))
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,13 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
||||
* @param index Zone index within zone layout.
|
||||
*/
|
||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndex)(HWND window, int 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 indexSet The set of zone indices within zone layout.
|
||||
*/
|
||||
IFACEMETHOD_(void, MoveWindowIntoZoneByIndexSet)(HWND window, const std::vector<int>& indexSet) = 0;
|
||||
/**
|
||||
* Assign window to the zone based on direction (using WIN + LEFT/RIGHT arrow).
|
||||
*
|
||||
@@ -98,4 +105,4 @@ interface __declspec(uuid("{7F017528-8110-4FB3-BE41-F472969C2560}")) IZoneWindow
|
||||
};
|
||||
|
||||
winrt::com_ptr<IZoneWindow> MakeZoneWindow(IZoneWindowHost* host, HINSTANCE hinstance, HMONITOR monitor,
|
||||
const std::wstring& uniqueId, bool flashZones) noexcept;
|
||||
const std::wstring& uniqueId, bool flashZones, bool newWorkArea) noexcept;
|
||||
|
||||
@@ -108,3 +108,30 @@ void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo)
|
||||
|
||||
monitorInfo = std::move(sortedMonitorInfo);
|
||||
}
|
||||
|
||||
void SizeWindowToRect(HWND window, RECT rect) noexcept
|
||||
{
|
||||
WINDOWPLACEMENT placement{};
|
||||
::GetWindowPlacement(window, &placement);
|
||||
|
||||
//wait if SW_SHOWMINIMIZED would be removed from window (Issue #1685)
|
||||
for (int i = 0; i < 5 && (placement.showCmd & SW_SHOWMINIMIZED) != 0; i++)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
::GetWindowPlacement(window, &placement);
|
||||
}
|
||||
|
||||
// Do not restore minimized windows. We change their placement though so they restore to the correct zone.
|
||||
if ((placement.showCmd & SW_SHOWMINIMIZED) == 0)
|
||||
{
|
||||
placement.showCmd = SW_RESTORE | SW_SHOWNA;
|
||||
}
|
||||
|
||||
placement.rcNormalPosition = rect;
|
||||
placement.flags |= WPF_ASYNCWINDOWPLACEMENT;
|
||||
|
||||
::SetWindowPlacement(window, &placement);
|
||||
// Do it again, allowing Windows to resize the window and set correct scaling
|
||||
// This fixes Issue #365
|
||||
::SetWindowPlacement(window, &placement);
|
||||
}
|
||||
|
||||
@@ -118,3 +118,4 @@ inline BYTE OpacitySettingToAlpha(int opacity)
|
||||
|
||||
UINT GetDpiForMonitor(HMONITOR monitor) noexcept;
|
||||
void OrderMonitors(std::vector<std::pair<HMONITOR, RECT>>& monitorInfo);
|
||||
void SizeWindowToRect(HWND window, RECT rect) noexcept;
|
||||
|
||||
@@ -132,8 +132,8 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD (ZoneFromPointEmpty)
|
||||
{
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ 0, 0 });
|
||||
Assert::IsTrue(nullptr == actual);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 0, 0 });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointInner)
|
||||
@@ -146,9 +146,9 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
for (int j = top + 1; j < bottom; j++)
|
||||
{
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ i, j });
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
compareZones(expected, actual);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ i, j });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,29 +161,29 @@ namespace FancyZonesUnitTests
|
||||
|
||||
for (int i = left; i < right; i++)
|
||||
{
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ i, top });
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
compareZones(expected, actual);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ i, top });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||
}
|
||||
|
||||
for (int i = top; i < bottom; i++)
|
||||
{
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ left, i });
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
compareZones(expected, actual);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ left, i });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(expected, m_set->GetZones()[actual[0]]);
|
||||
}
|
||||
|
||||
//bottom and right borders considered to be outside
|
||||
for (int i = left; i < right; i++)
|
||||
{
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ i, bottom });
|
||||
Assert::IsTrue(nullptr == actual);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ i, bottom });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
|
||||
for (int i = top; i < bottom; i++)
|
||||
{
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ right, i });
|
||||
Assert::IsTrue(nullptr == actual);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ right, i });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,8 +193,8 @@ namespace FancyZonesUnitTests
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ left, top, right, bottom });
|
||||
m_set->AddZone(zone);
|
||||
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ 101, 101 });
|
||||
Assert::IsTrue(actual == nullptr);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 200, 200 });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointOverlapping)
|
||||
@@ -208,9 +208,65 @@ namespace FancyZonesUnitTests
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 10, 10, 50, 50 });
|
||||
m_set->AddZone(zone4);
|
||||
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ 50, 50 });
|
||||
Assert::IsTrue(actual != nullptr);
|
||||
compareZones(zone2, actual);
|
||||
// zone4 is expected because it's the smallest one, and it's considered to be inside
|
||||
// since Multizones support
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 50, 50 });
|
||||
Assert::IsTrue(actual.size() == 1);
|
||||
compareZones(zone4, m_set->GetZones()[actual[0]]);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointMultizoneHorizontal)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 });
|
||||
m_set->AddZone(zone1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 });
|
||||
m_set->AddZone(zone2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 });
|
||||
m_set->AddZone(zone3);
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 });
|
||||
m_set->AddZone(zone4);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 50, 100 });
|
||||
Assert::IsTrue(actual.size() == 2);
|
||||
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||
compareZones(zone3, m_set->GetZones()[actual[1]]);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointMultizoneVertical)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 });
|
||||
m_set->AddZone(zone1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 });
|
||||
m_set->AddZone(zone2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 });
|
||||
m_set->AddZone(zone3);
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 });
|
||||
m_set->AddZone(zone4);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 100, 50 });
|
||||
Assert::IsTrue(actual.size() == 2);
|
||||
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||
compareZones(zone2, m_set->GetZones()[actual[1]]);
|
||||
}
|
||||
|
||||
TEST_METHOD(ZoneFromPointMultizoneQuad)
|
||||
{
|
||||
winrt::com_ptr<IZone> zone1 = MakeZone({ 0, 0, 100, 100 });
|
||||
m_set->AddZone(zone1);
|
||||
winrt::com_ptr<IZone> zone2 = MakeZone({ 100, 0, 200, 100 });
|
||||
m_set->AddZone(zone2);
|
||||
winrt::com_ptr<IZone> zone3 = MakeZone({ 0, 100, 100, 200 });
|
||||
m_set->AddZone(zone3);
|
||||
winrt::com_ptr<IZone> zone4 = MakeZone({ 100, 100, 200, 200 });
|
||||
m_set->AddZone(zone4);
|
||||
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 100, 100 });
|
||||
Assert::IsTrue(actual.size() == 4);
|
||||
compareZones(zone1, m_set->GetZones()[actual[0]]);
|
||||
compareZones(zone2, m_set->GetZones()[actual[1]]);
|
||||
compareZones(zone3, m_set->GetZones()[actual[2]]);
|
||||
compareZones(zone4, m_set->GetZones()[actual[3]]);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointWithNotNormalizedRect)
|
||||
@@ -218,8 +274,8 @@ namespace FancyZonesUnitTests
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ 100, 100, 0, 0 });
|
||||
m_set->AddZone(zone);
|
||||
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ 50, 50 });
|
||||
Assert::IsTrue(actual == nullptr);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 50, 50 });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneFromPointWithZeroRect)
|
||||
@@ -227,8 +283,8 @@ namespace FancyZonesUnitTests
|
||||
winrt::com_ptr<IZone> zone = MakeZone({ 0, 0, 0, 0 });
|
||||
m_set->AddZone(zone);
|
||||
|
||||
auto actual = m_set->ZoneFromPoint(POINT{ 0, 0 });
|
||||
Assert::IsTrue(actual == nullptr);
|
||||
auto actual = m_set->ZonesFromPoint(POINT{ 0, 0 });
|
||||
Assert::IsTrue(actual.size() == 0);
|
||||
}
|
||||
|
||||
TEST_METHOD (ZoneIndexFromWindow)
|
||||
@@ -316,7 +372,7 @@ namespace FancyZonesUnitTests
|
||||
m_set->AddZone(zone3);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1, false);
|
||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||
Assert::IsTrue(zone2->ContainsWindow(window));
|
||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||
@@ -325,7 +381,7 @@ namespace FancyZonesUnitTests
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndexWithNoZones)
|
||||
{
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||
}
|
||||
|
||||
TEST_METHOD (MoveWindowIntoZoneByIndexWithInvalidIndex)
|
||||
@@ -338,8 +394,8 @@ namespace FancyZonesUnitTests
|
||||
m_set->AddZone(zone3);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 100);
|
||||
Assert::IsTrue(zone1->ContainsWindow(window));
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 100, false);
|
||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||
}
|
||||
@@ -355,17 +411,17 @@ namespace FancyZonesUnitTests
|
||||
m_set->AddZone(zone3);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||
Assert::IsTrue(zone1->ContainsWindow(window));
|
||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 1, false);
|
||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||
Assert::IsTrue(zone2->ContainsWindow(window));
|
||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 2, false);
|
||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||
Assert::IsTrue(zone3->ContainsWindow(window));
|
||||
@@ -382,9 +438,9 @@ namespace FancyZonesUnitTests
|
||||
m_set->AddZone(zone3);
|
||||
|
||||
HWND window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||
m_set->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||
Assert::IsTrue(zone1->ContainsWindow(window));
|
||||
Assert::IsFalse(zone2->ContainsWindow(window));
|
||||
Assert::IsFalse(zone3->ContainsWindow(window));
|
||||
@@ -401,7 +457,7 @@ namespace FancyZonesUnitTests
|
||||
m_set->AddZone(zone1);
|
||||
|
||||
auto window = Mocks::Window();
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 101, 101 });
|
||||
m_set->MoveWindowIntoZoneByPoint(window, Mocks::Window(), POINT{ 200, 200 });
|
||||
|
||||
Assert::IsFalse(zone1->ContainsWindow(window));
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
const std::wstring m_deviceId = L"\\\\?\\DISPLAY#DELA026#5&10a58c63&0&UID16777488#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}";
|
||||
const std::wstring m_virtualDesktopId = L"MyVirtualDesktopId";
|
||||
std::wstringstream m_parentUniqueId;
|
||||
std::wstringstream m_uniqueId;
|
||||
|
||||
HINSTANCE m_hInst{};
|
||||
@@ -75,6 +76,7 @@ namespace FancyZonesUnitTests
|
||||
m_monitorInfo.cbSize = sizeof(m_monitorInfo);
|
||||
Assert::AreNotEqual(0, GetMonitorInfoW(m_monitor, &m_monitorInfo));
|
||||
|
||||
m_parentUniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{61FA9FC0-26A6-4B37-A834-491C148DFC57}";
|
||||
m_uniqueId << L"DELA026#5&10a58c63&0&UID16777488_" << m_monitorInfo.rcMonitor.right << "_" << m_monitorInfo.rcMonitor.bottom << "_{39B25DD2-130D-4B5D-8851-4791D66B1539}";
|
||||
|
||||
Assert::IsFalse(ZoneWindowUtils::GetActiveZoneSetTmpPath().empty());
|
||||
@@ -113,7 +115,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
|
||||
return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
return MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
}
|
||||
|
||||
void testZoneWindow(winrt::com_ptr<IZoneWindow> zoneWindow)
|
||||
@@ -129,14 +131,14 @@ namespace FancyZonesUnitTests
|
||||
public:
|
||||
TEST_METHOD(CreateZoneWindow)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
testZoneWindow(m_zoneWindow);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
}
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoHinst)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
testZoneWindow(m_zoneWindow);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
@@ -144,7 +146,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoHinstFlashZones)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, {}, m_monitor, m_uniqueId.str(), true, false);
|
||||
|
||||
testZoneWindow(m_zoneWindow);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
@@ -152,7 +154,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoMonitor)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), false, false);
|
||||
|
||||
Assert::IsNull(m_zoneWindow.get());
|
||||
Assert::IsNotNull(m_hostPtr);
|
||||
@@ -160,7 +162,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(CreateZoneWindowNoMonitorFlashZones)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, {}, m_uniqueId.str(), true, false);
|
||||
|
||||
Assert::IsNull(m_zoneWindow.get());
|
||||
Assert::IsNotNull(m_hostPtr);
|
||||
@@ -170,7 +172,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// Generate unique id without device id
|
||||
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, nullptr, m_virtualDesktopId.c_str());
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false);
|
||||
|
||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||
const std::wstring expectedUniqueId = L"FallbackDevice_" + std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom) + L"_" + m_virtualDesktopId;
|
||||
@@ -186,7 +188,7 @@ namespace FancyZonesUnitTests
|
||||
{
|
||||
// Generate unique id without virtual desktop id
|
||||
std::wstring uniqueId = ZoneWindowUtils::GenerateUniqueId(m_monitor, m_deviceId.c_str(), nullptr);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, uniqueId, false, false);
|
||||
|
||||
const std::wstring expectedWorkArea = std::to_wstring(m_monitorInfo.rcMonitor.right) + L"_" + std::to_wstring(m_monitorInfo.rcMonitor.bottom);
|
||||
Assert::IsNotNull(m_zoneWindow.get());
|
||||
@@ -213,7 +215,7 @@ namespace FancyZonesUnitTests
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
@@ -237,7 +239,7 @@ namespace FancyZonesUnitTests
|
||||
m_fancyZonesData.ParseDeviceInfoFromTmpFile(activeZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
@@ -273,7 +275,7 @@ namespace FancyZonesUnitTests
|
||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
@@ -320,7 +322,7 @@ namespace FancyZonesUnitTests
|
||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
@@ -367,7 +369,7 @@ namespace FancyZonesUnitTests
|
||||
m_fancyZonesData.ParseCustomZoneSetFromTmpFile(appliedZoneSetTempPath);
|
||||
|
||||
//temp file read on initialization
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
auto actual = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
testZoneWindow(actual);
|
||||
|
||||
@@ -376,9 +378,68 @@ namespace FancyZonesUnitTests
|
||||
Assert::AreEqual((size_t)1, actualZoneSet.size());
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowClonedFromParent)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
|
||||
const int spacing = 10;
|
||||
const int zoneCount = 5;
|
||||
const auto customSetGuid = Helpers::CreateGuidString();
|
||||
const auto parentZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount };
|
||||
m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo);
|
||||
|
||||
auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false);
|
||||
m_zoneWindowHost.m_zoneWindow = parentZoneWindow.get();
|
||||
|
||||
// newWorkArea = true - zoneWindow will be cloned from parent
|
||||
auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, true);
|
||||
|
||||
Assert::IsNotNull(actualZoneWindow->ActiveZoneSet());
|
||||
const auto actualZoneSet = actualZoneWindow->ActiveZoneSet()->GetZones();
|
||||
Assert::AreEqual((size_t)zoneCount, actualZoneSet.size());
|
||||
|
||||
Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str()));
|
||||
auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str());
|
||||
Assert::AreEqual(zoneCount, currentDeviceInfo.zoneCount);
|
||||
Assert::AreEqual(spacing, currentDeviceInfo.spacing);
|
||||
Assert::AreEqual(static_cast<int>(type), static_cast<int>(currentDeviceInfo.activeZoneSet.type));
|
||||
}
|
||||
|
||||
TEST_METHOD (CreateZoneWindowNotClonedFromParent)
|
||||
{
|
||||
using namespace JSONHelpers;
|
||||
|
||||
const ZoneSetLayoutType type = ZoneSetLayoutType::PriorityGrid;
|
||||
const int spacing = 10;
|
||||
const int zoneCount = 5;
|
||||
const auto customSetGuid = Helpers::CreateGuidString();
|
||||
const auto parentZoneSet = ZoneSetData{ customSetGuid, type };
|
||||
const auto parentDeviceInfo = DeviceInfoData{ parentZoneSet, true, spacing, zoneCount };
|
||||
m_fancyZonesData.SetDeviceInfo(m_parentUniqueId.str(), parentDeviceInfo);
|
||||
|
||||
auto parentZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_parentUniqueId.str(), false, false);
|
||||
m_zoneWindowHost.m_zoneWindow = parentZoneWindow.get();
|
||||
|
||||
// newWorkArea = false - zoneWindow won't be cloned from parent
|
||||
auto actualZoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
Assert::IsNull(actualZoneWindow->ActiveZoneSet());
|
||||
|
||||
Assert::IsTrue(m_fancyZonesData.GetDeviceInfoMap().contains(m_uniqueId.str()));
|
||||
auto currentDeviceInfo = m_fancyZonesData.GetDeviceInfoMap().at(m_uniqueId.str());
|
||||
// default values
|
||||
Assert::AreEqual(false, currentDeviceInfo.showSpacing);
|
||||
Assert::AreEqual(0, currentDeviceInfo.zoneCount);
|
||||
Assert::AreEqual(0, currentDeviceInfo.spacing);
|
||||
Assert::AreEqual(std::wstring{ L"null" }, currentDeviceInfo.activeZoneSet.uuid);
|
||||
Assert::AreEqual(static_cast<int>(ZoneSetLayoutType::Blank), static_cast<int>(currentDeviceInfo.activeZoneSet.type));
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveSizeEnter)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeEnter(Mocks::Window(), true);
|
||||
@@ -389,7 +450,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(MoveSizeEnterTwice)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
const auto expected = E_INVALIDARG;
|
||||
|
||||
@@ -402,7 +463,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(MoveSizeUpdate)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ 0, 0 }, true);
|
||||
@@ -413,7 +474,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(MoveSizeUpdatePointNegativeCoordinates)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ -10, -10 }, true);
|
||||
@@ -424,7 +485,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(MoveSizeUpdatePointBigCoordinates)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = m_zoneWindow->MoveSizeUpdate(POINT{ m_monitorInfo.rcMonitor.right + 1, m_monitorInfo.rcMonitor.bottom + 1 }, true);
|
||||
@@ -445,7 +506,7 @@ namespace FancyZonesUnitTests
|
||||
Assert::AreEqual(expected, actual);
|
||||
|
||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), false);
|
||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
||||
Assert::AreNotEqual(-1, actualZoneIndex);
|
||||
}
|
||||
@@ -458,7 +519,7 @@ namespace FancyZonesUnitTests
|
||||
zoneWindow->MoveSizeEnter(window, true);
|
||||
|
||||
const auto expected = S_OK;
|
||||
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ 0, 0 });
|
||||
const auto actual = zoneWindow->MoveSizeEnd(window, POINT{ -100, -100 });
|
||||
Assert::AreEqual(expected, actual);
|
||||
|
||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||
@@ -468,7 +529,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(MoveSizeEndDifferentWindows)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
const auto window = Mocks::Window();
|
||||
m_zoneWindow->MoveSizeEnter(window, true);
|
||||
@@ -481,7 +542,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(MoveSizeEndWindowNotSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
|
||||
const auto expected = E_INVALIDARG;
|
||||
const auto actual = m_zoneWindow->MoveSizeEnd(Mocks::Window(), POINT{ 0, 0 });
|
||||
@@ -501,14 +562,14 @@ namespace FancyZonesUnitTests
|
||||
Assert::AreEqual(expected, actual);
|
||||
|
||||
const auto zoneSet = zoneWindow->ActiveZoneSet();
|
||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), false);
|
||||
zoneSet->MoveWindowIntoZoneByIndex(window, Mocks::Window(), 0, false);
|
||||
const auto actualZoneIndex = zoneSet->GetZoneIndexFromWindow(window);
|
||||
Assert::AreNotEqual(-1, actualZoneIndex); //with invalid point zone remains the same
|
||||
}
|
||||
|
||||
TEST_METHOD(MoveWindowIntoZoneByIndexNoActiveZoneSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||
@@ -526,7 +587,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(MoveWindowIntoZoneByDirectionNoActiveZoneSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->MoveWindowIntoZoneByIndex(Mocks::Window(), 0);
|
||||
@@ -564,7 +625,7 @@ namespace FancyZonesUnitTests
|
||||
|
||||
TEST_METHOD(SaveWindowProcessToZoneIndexNoActiveZoneSet)
|
||||
{
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false);
|
||||
m_zoneWindow = MakeZoneWindow(m_hostPtr, m_hInst, m_monitor, m_uniqueId.str(), false, false);
|
||||
Assert::IsNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
m_zoneWindow->SaveWindowProcessToZoneIndex(Mocks::Window());
|
||||
@@ -650,5 +711,29 @@ namespace FancyZonesUnitTests
|
||||
const auto actual = m_fancyZonesData.GetAppZoneHistoryMap().at(processPath).zoneIndex;
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
TEST_METHOD (WhenWindowIsNotResizablePlacingItIntoTheZoneShouldNotResizeIt)
|
||||
{
|
||||
m_zoneWindow = InitZoneWindowWithActiveZoneSet();
|
||||
Assert::IsNotNull(m_zoneWindow->ActiveZoneSet());
|
||||
|
||||
auto window = Mocks::WindowCreate(m_hInst);
|
||||
|
||||
int orginalWidth = 450;
|
||||
int orginalHeight = 550;
|
||||
|
||||
SetWindowPos(window, nullptr, 150, 150, orginalWidth, orginalHeight, SWP_SHOWWINDOW);
|
||||
SetWindowLong(window, GWL_STYLE, GetWindowLong(window, GWL_STYLE) & ~WS_SIZEBOX);
|
||||
|
||||
auto zone = MakeZone(RECT{ 50, 50, 300, 300 });
|
||||
m_zoneWindow->ActiveZoneSet()->AddZone(zone);
|
||||
|
||||
m_zoneWindow->MoveWindowIntoZoneByDirection(window, VK_LEFT, true);
|
||||
|
||||
RECT inZoneRect;
|
||||
GetWindowRect(window, &inZoneRect);
|
||||
Assert::AreEqual(orginalWidth, (int)inZoneRect.right - (int) inZoneRect.left);
|
||||
Assert::AreEqual(orginalHeight, (int)inZoneRect.bottom - (int)inZoneRect.top);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user