Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Window with ExtendClientAreaToDecorationsHint="True" cannot be moved in 0.10.5

Open Outreaver opened this issue 3 years ago • 13 comments

Describe the bug In version 0.10.3 moving window with flag ExtendClientAreaToDecorationsHint = "True" worked fine. I also checked version 0.10.4 and there it works too. After upgrading package to version 0.10.5 window is stuck in place and cannot be moved.

To Reproduce

  1. Create avalonia project (mine is creating in vesrion 0.10.3 by default and im and creating MVVM template).
  2. Upgrade Avalonia packages to version 0.10.5 (Avalonia, Avalonia.Desktop, Avalonia.Diagnostics, Avalonia.ReactiveUI).
  3. In MainWindow.axaml add flag ExtendClientAreaToDecorationsHint="True" in Window tag. Xaml is looking like this
<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:AvaloniaMoveTest.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="AvaloniaMoveTest.Views.MainWindow"
        Icon="/Assets/avalonia-logo.ico"
        Title="AvaloniaMoveTest"
	ExtendClientAreaToDecorationsHint="True">

    <Design.DataContext>
        <vm:MainWindowViewModel/>
    </Design.DataContext>

    <TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>

</Window>
  1. Build project and run.
  2. Window cannot be moved.

Expected behavior Should be possible to move window with mouse.

Desktop (please complete the following information):

  • OS: Window
  • Version: 20H2 (19042.985)

Outreaver avatar May 25 '21 20:05 Outreaver

This issue is actually to do with using ExtendClientAreaToDecorationsHint="True" and CanResize="False" in the same window, at least in my experimentation. I'm pretty sure this isn't the intended results for this, since they don't create the issue independently.

MaddyGuthridge avatar May 26 '21 10:05 MaddyGuthridge

@MiguelGuthridge that's not in the repro above, and adding CanResize="True" does not change anything when I test locally. But if it works for you when you remove it perhaps that is some insight into what is going on...

piksel avatar May 26 '21 13:05 piksel

#5923 seems to be the cause. Reverted it locally and built against and it successfully restored window movement. There are comments made after the merge, so maybe they already figured out the problem... I am not familiar enough with the internals to say exactly how it should be fixed.

piksel avatar May 26 '21 14:05 piksel

Most likely fixed by https://github.com/AvaloniaUI/Avalonia/pull/5968

maxkatz6 avatar May 26 '21 14:05 maxkatz6

Confirmed as fixed in 0.10.6, closeable?

piksel avatar Jun 06 '21 15:06 piksel

I have this problem in 0.10.13, following the music store tutorial.

aggieben avatar May 01 '22 23:05 aggieben

Similar problem in 0.10.14. In some areas of the window top, I can grab the window and move it, in other areas I cannot.

sergevm avatar Jun 12 '22 13:06 sergevm

Please open a new issue with details

maxkatz6 avatar Jun 12 '22 16:06 maxkatz6

The problem resumes at 0.10.18. It occurs when the control is located on top of the screen.

In this code, StackPanel fills the row from the top, it is impossible to move the window across the screen (the grid is the root control):

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <StackPanel Grid.Row="0"
                        Orientation="Horizontal"
                        Classes="Status">
                <Button Classes="List"
                        Command="{Binding HiddenNavigationMenuCommand}"
                        HotKey="Escape"
                        ToolTip.Tip="Back"
                        Margin="5 5 5 0"/>
            </StackPanel>

            <ContentControl Grid.Row="1"
                            Content="{Binding Content}"
                            HorizontalContentAlignment="Stretch"
                            VerticalContentAlignment="Stretch"/>
        </Grid>

In this code, the row at the top is empty, the window can be moved around the screen:

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="10"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>

            <StackPanel Grid.Row="1"
                        Orientation="Horizontal"
                        Classes="Status">
                <Button Classes="List"
                        Command="{Binding HiddenNavigationMenuCommand}"
                        HotKey="Escape"
                        ToolTip.Tip="Back"
                        Margin="5 5 5 0"/>
            </StackPanel>

            <ContentControl Grid.Row="2"
                            Content="{Binding Content}"
                            HorizontalContentAlignment="Stretch"
                            VerticalContentAlignment="Stretch"/>
        </Grid>

Clarification: StackPanel "blocks" click events when it has an opaque background.

Oleg-Olegovich avatar Aug 17 '22 09:08 Oleg-Olegovich

I was also affected by the issue in 0.10.18. Adding margin to the root control helped to restore the draggable header.

Is it so by design now? Documentation should probably be updated to explain this caveat. How should I go about adding non-interactive elements to the header area without affecting the window draggability?

Update: Setting ExtendClientAreaChromeHints="PreferSystemChrome" on my Window as found there had no observable effect. Setting CanResize explicitly to any value has no observable effect.

Update 2: Using IsHitTestVisible allows to have controls in the header area without affecting the draggability.

KillyMXI avatar Sep 02 '22 20:09 KillyMXI

I have a dropdown menu on top of the screen (menubar), so I did it like this. The idea is that the menu items will still be visible to the hit test. and the area next to the menubar isn't, the same way the Visual Studio menubar works.

<Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"></RowDefinition>
      <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"></ColumnDefinition>
      <ColumnDefinition Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <Menu Grid.Row="0" Grid.Column="0" Margin="0 8" IsHitTestVisible="True">
      <common:MatMenuItem>
      </common:MatMenuItem>
    </Menu>

    <Grid Grid.Row="0" Grid.Column="1" IsHitTestVisible="False">
    </Grid>
  </Grid>

lazzy07 avatar Sep 11 '22 07:09 lazzy07

It's still not working

ccmvn avatar Sep 20 '22 14:09 ccmvn

@CHMarvin maybe you may want to take a look into FluentAvalonia's Core window. https://github.com/amwx/FluentAvalonia

timunie avatar Sep 22 '22 07:09 timunie

I can move it by manually adding a view with IsHitTestVisible="False" at the top. Is this by design or a bug?

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:views="clr-namespace:PlayAvalonia.Views"
        mc:Ignorable="d" 
        d:DesignWidth="500" 
        d:DesignHeight="750"
        Width="900"
        Height="750"
        x:Class="PlayAvalonia.Views.MainWindow"
        Icon="/Assets/avalonia-logo.ico"
        Title="PlayAvalonia"
        TransparencyLevelHint="AcrylicBlur"
        Background="Transparent"
        ExtendClientAreaToDecorationsHint="True">
    
    <Panel>
        <ExperimentalAcrylicBorder IsHitTestVisible="False">
            <ExperimentalAcrylicBorder.Material>
                <ExperimentalAcrylicMaterial
                    BackgroundSource="Digger"
                    TintColor="Black"
                    TintOpacity="1"
                    MaterialOpacity="0.7" />
            </ExperimentalAcrylicBorder.Material>
        </ExperimentalAcrylicBorder>
        
        <Grid RowDefinitions="Auto,*">
            <Border Height="30" IsHitTestVisible="False"/>
            <views:MainView Grid.Row="1"/>
        </Grid>
    </Panel>
</Window>

xleon avatar Nov 16 '22 00:11 xleon

@xleon this is by design. The pointer stops at the first control hat is:

  1. HitTestVisible
  2. Has a Brush set (can be Transparent, but not null)

If no other control was hit, the window gets the pointer and can handle it, for example move the window

timunie avatar Nov 16 '22 12:11 timunie

I am closing this issue, assuming previous reports weren't setting IsHitTestVisible to false. Let me know if there is another bug.

maxkatz6 avatar Jan 25 '23 06:01 maxkatz6

I'm still a little confused, IsHitTestVisible works different than in the WPF window chrome component.

  • To whom is "the hit test visible"? To Avalonia to get control events, or to the DWM to control the window chrome?
  • From which "direction" does the pointer stop checking for IsHitTestVisible? From the root control or from the top most control it clicked at?

I have a DockPanel as a title bar container whose last child is a Border with a non-transparent brush and IsHitTestVisible="False" and nothing above it, yet I can't move the window through it.

EDIT: I made a small sample: While I can get the window to become movable with the red dockpanel, I can no longer click the button inside of it:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="AvaloniaApplication1.MainWindow"
        Title="AvaloniaApplication1"
        ExtendClientAreaTitleBarHeightHint="40"
        ExtendClientAreaToDecorationsHint="True">
  <DockPanel>
    <DockPanel DockPanel.Dock="Top" Background="Red" Height="40" IsHitTestVisible="False">
      <Button IsHitTestVisible="True">Can't Click Me...</Button>
    </DockPanel>
    <Border Background="White"/>
  </DockPanel>
</Window>

RayKoopa avatar Apr 02 '23 18:04 RayKoopa

I can't get this to work at all :(

phillip-haydon avatar Apr 21 '23 10:04 phillip-haydon

It still doesn't work on v11. However, it works with a bit of tricks.

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        TransparencyLevelHint="AcrylicBlur"
        Background="Transparent"
        ExtendClientAreaToDecorationsHint="True"
        ExtendClientAreaTitleBarHeightHint="40"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="AvaloniaApplication2.MainWindow"
        Title="AvaloniaApplication2">
    <Panel>
        <ExperimentalAcrylicBorder IsHitTestVisible="False">
            <ExperimentalAcrylicBorder.Material>
                <ExperimentalAcrylicMaterial
                    BackgroundSource="Digger"
                    TintColor="Black"
                    TintOpacity="1"
                    MaterialOpacity="0.65" />
            </ExperimentalAcrylicBorder.Material>
        </ExperimentalAcrylicBorder>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="20"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <DockPanel Grid.Row="1">
                <Menu DockPanel.Dock="Top">
                    <MenuItem Header="_File">
                        <MenuItem Header="_Open..."/>
                        <Separator/>
                        <MenuItem Header="_Exit"/>
                    </MenuItem>
                    <MenuItem Header="_Edit">
                        <MenuItem Header="Copy"/>
                        <MenuItem Header="Paste"/>
                    </MenuItem>
                </Menu>
                <TextBlock/>
            </DockPanel>
            <StackPanel Grid.Row="2" Margin="40">
                <Button>Press Me!</Button>
                <TextBlock Margin="0 10">Ready...</TextBlock>
            </StackPanel>
            <StackPanel Grid.Row="3" Margin="40">
                <Button>Press Me!</Button>
                <TextBlock Margin="0 10">Ready...</TextBlock>
            </StackPanel>            
        </Grid>
    </Panel>
</Window>

nameofSEOKWONHONG avatar Jul 05 '23 13:07 nameofSEOKWONHONG

Easiest workaround: on the top Container of the view, like the <Panel> of the example above, just add Margin.

Example: <Panel Margin="10">

That will give you space to drag around.

Eskeminha avatar Jan 19 '24 22:01 Eskeminha