From 7f455e945d7a4b3afca59366595955c3fa5d7497 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Sun, 15 Oct 2017 21:33:45 -0500 Subject: [PATCH 1/6] Update Portable.Xaml --- Avalonia.sln | 3 ++- .../Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs | 2 ++ .../Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Avalonia.sln b/Avalonia.sln index 7f516667ee..c6509817ce 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.3 +VisualStudioVersion = 15.0.26730.10 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base", "src\Avalonia.Base\Avalonia.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}" EndProject @@ -204,6 +204,7 @@ Global tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{48840edd-24bf-495d-911e-2eb12ae75d3b}*SharedItemsImports = 13 src\Shared\PlatformSupport\PlatformSupport.projitems*{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}*SharedItemsImports = 4 src\Shared\PlatformSupport\PlatformSupport.projitems*{7863ea94-f0fb-4386-bf8c-e5bfa761560a}*SharedItemsImports = 4 + src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 4 src\Shared\RenderHelpers\RenderHelpers.projitems*{7d2d3083-71dd-4cc9-8907-39a0d86fb322}*SharedItemsImports = 4 src\Windows\Avalonia.Win32\Avalonia.Win32.Shared.projitems*{811a76cf-1cf6-440f-963b-bbe31bd72a82}*SharedItemsImports = 4 src\Windows\Avalonia.Win32\Avalonia.Win32.Shared.projitems*{9defc6b7-845b-4d8f-afc0-d32bf0032b8c}*SharedItemsImports = 13 diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs index 71c8902cbd..0cc08ac6ee 100644 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs @@ -294,6 +294,8 @@ namespace Avalonia.Markup.Xaml.PortableXaml return Property.IsReadOnly; } + protected override bool LookupIsUnknown() => false; + protected override Type GetPropertyType() { return Property.PropertyType; diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github index eebf9dbb92..f226a516fe 160000 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github @@ -1 +1 @@ -Subproject commit eebf9dbb9275ecc48c18ec24f6fbad8cb494857f +Subproject commit f226a516fe2bc191145c1fbf732f5a087f121a33 From 17337882b3cbc5d89f402caafd1448b75afedf8c Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 17 Oct 2017 13:04:12 +0300 Subject: [PATCH 2/6] [GTK3] Special resize handling for popups --- src/Gtk/Avalonia.Gtk3/Interop/Native.cs | 4 ++++ src/Gtk/Avalonia.Gtk3/PopupImpl.cs | 1 + src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs index 15b3a11fbb..3b9007786d 100644 --- a/src/Gtk/Avalonia.Gtk3/Interop/Native.cs +++ b/src/Gtk/Avalonia.Gtk3/Interop/Native.cs @@ -102,6 +102,9 @@ namespace Avalonia.Gtk3.Interop [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] public delegate void gdk_window_resize(IntPtr gtkWindow, int width, int height); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gdk)] + public delegate void gdk_window_set_override_redirect(IntPtr gdkWindow, bool value); [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] public delegate void gtk_widget_realize(GtkWidget gtkWidget); @@ -402,6 +405,7 @@ namespace Avalonia.Gtk3.Interop public static D.gtk_window_get_size GtkWindowGetSize; public static D.gtk_window_resize GtkWindowResize; public static D.gdk_window_resize GdkWindowResize; + public static D.gdk_window_set_override_redirect GdkWindowSetOverrideRedirect; public static D.gtk_widget_set_size_request GtkWindowSetSizeRequest; public static D.gtk_window_set_default_size GtkWindowSetDefaultSize; public static D.gtk_window_get_position GtkWindowGetPosition; diff --git a/src/Gtk/Avalonia.Gtk3/PopupImpl.cs b/src/Gtk/Avalonia.Gtk3/PopupImpl.cs index 8fd1c28ea4..13beff580e 100644 --- a/src/Gtk/Avalonia.Gtk3/PopupImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/PopupImpl.cs @@ -19,6 +19,7 @@ namespace Avalonia.Gtk3 public PopupImpl() : base(CreateWindow()) { + OverrideRedirect = true; } } } diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs index e14ed77877..3128be23aa 100644 --- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs @@ -32,6 +32,7 @@ namespace Avalonia.Gtk3 private IDeferredRenderOperation _nextRenderOperation; private readonly AutoResetEvent _canSetNextOperation = new AutoResetEvent(true); internal IntPtr? GdkWindowHandle; + private bool _overrideRedirect; public WindowBaseImpl(GtkWindow gtkWidget) { @@ -406,6 +407,28 @@ namespace Avalonia.Gtk3 if (GtkWidget.IsClosed) return; Native.GtkWindowResize(GtkWidget, (int)value.Width, (int)value.Height); + if (OverrideRedirect) + { + var size = ClientSize = value; + if (_lastSize != size) + { + Resized?.Invoke(size); + _lastSize = size; + } + } + } + + public bool OverrideRedirect + { + get => _overrideRedirect; + set + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Native.GdkWindowSetOverrideRedirect(Native.GtkWidgetGetWindow(GtkWidget), value); + _overrideRedirect = value; + } + } } public IScreenImpl Screen From 4e98c3494048934f12028a30f8cbadc7cc567d49 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 17 Oct 2017 14:08:30 +0300 Subject: [PATCH 3/6] [GTK3] Skip resize part of configure event if OverrideRedirect=true --- src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs index 3128be23aa..136023c31d 100644 --- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs @@ -70,12 +70,15 @@ namespace Avalonia.Gtk3 private bool OnConfigured(IntPtr gtkwidget, IntPtr ev, IntPtr userdata) { int w, h; - Native.GtkWindowGetSize(GtkWidget, out w, out h); - var size = ClientSize = new Size(w, h); - if (_lastSize != size) + if (!OverrideRedirect) { - Resized?.Invoke(size); - _lastSize = size; + Native.GtkWindowGetSize(GtkWidget, out w, out h); + var size = ClientSize = new Size(w, h); + if (_lastSize != size) + { + Resized?.Invoke(size); + _lastSize = size; + } } var pos = Position; if (_lastPosition != pos) From ca7584ce3fef1ba5f8a7e8b7bb916dc4617a1f21 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 17 Oct 2017 23:45:00 +0200 Subject: [PATCH 4/6] Added failing test for #1218 --- .../Avalonia.Styling.UnitTests/SetterTests.cs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/Avalonia.Styling.UnitTests/SetterTests.cs b/tests/Avalonia.Styling.UnitTests/SetterTests.cs index 84536fa47b..9c43097a21 100644 --- a/tests/Avalonia.Styling.UnitTests/SetterTests.cs +++ b/tests/Avalonia.Styling.UnitTests/SetterTests.cs @@ -8,6 +8,9 @@ using Avalonia.Data; using Xunit; using System; using Avalonia.Controls.Templates; +using Avalonia.Markup.Xaml.Data; +using Avalonia.Markup; +using System.Globalization; namespace Avalonia.Styling.UnitTests { @@ -61,5 +64,39 @@ namespace Avalonia.Styling.UnitTests Assert.NotNull(NameScope.GetNameScope((Control)control.Child)); } + + [Fact] + public void Does_Not_Call_Converter_ConvertBack_On_OneWay_Binding() + { + var control = new Decorator { Name = "foo" }; + var style = Mock.Of(); + var binding = new Binding("Name", BindingMode.OneWay) + { + Converter = new TestConverter(), + RelativeSource = new RelativeSource(RelativeSourceMode.Self), + }; + var setter = new Setter(Decorator.TagProperty, binding); + var activator = new BehaviorSubject(true); + + setter.Apply(style, control, activator); + Assert.Equal("foobar", control.Tag); + + // Issue #1218 caused TestConverter.ConvertBack to throw here. + activator.OnNext(false); + Assert.Null(control.Tag); + } + + private class TestConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value.ToString() + "bar"; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } } } From dede306531fc38eef26807cd0eb028f9dbd66470 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 17 Oct 2017 23:45:35 +0200 Subject: [PATCH 5/6] Fixed #1218 --- src/Avalonia.Styling/Styling/Setter.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Styling/Styling/Setter.cs b/src/Avalonia.Styling/Styling/Setter.cs index d065b231ce..eb5218cd6f 100644 --- a/src/Avalonia.Styling/Styling/Setter.cs +++ b/src/Avalonia.Styling/Styling/Setter.cs @@ -141,20 +141,20 @@ namespace Avalonia.Styling { var description = style?.ToString(); - if (sourceInstance.Subject != null) + if (sourceInstance.Mode == BindingMode.TwoWay || sourceInstance.Mode == BindingMode.OneWayToSource) { var activated = new ActivatedSubject(activator, sourceInstance.Subject, description); cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); } - else if (sourceInstance.Observable != null) + else if (sourceInstance.Mode == BindingMode.OneTime) { - var activated = new ActivatedObservable(activator, sourceInstance.Observable, description); - cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); + var activated = new ActivatedValue(activator, sourceInstance.Value, description); + cloned = new InstancedBinding(activated, BindingMode.OneWay, BindingPriority.StyleTrigger); } else { - var activated = new ActivatedValue(activator, sourceInstance.Value, description); - cloned = new InstancedBinding(activated, BindingMode.OneWay, BindingPriority.StyleTrigger); + var activated = new ActivatedObservable(activator, sourceInstance.Observable ?? sourceInstance.Subject, description); + cloned = new InstancedBinding(activated, sourceInstance.Mode, BindingPriority.StyleTrigger); } } else From 871d689445d8f34b960cf2bb76f582ab8d01144d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 18 Oct 2017 14:52:11 -0500 Subject: [PATCH 6/6] Mark properties tracked by all of our XAML property types as not unkown. --- .../Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs index 0cc08ac6ee..a38029964f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs @@ -135,6 +135,8 @@ namespace Avalonia.Markup.Xaml.PortableXaml }; } + protected override bool LookupIsUnknown() => false; + protected override XamlType LookupType() { var propType = GetPropertyType(); @@ -294,8 +296,6 @@ namespace Avalonia.Markup.Xaml.PortableXaml return Property.IsReadOnly; } - protected override bool LookupIsUnknown() => false; - protected override Type GetPropertyType() { return Property.PropertyType;