Browse Source

Merge branch 'master' into fixes/3094-focusable-hang

pull/3096/head
danwalmsley 7 years ago
committed by GitHub
parent
commit
15ea7ed1d2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      native/Avalonia.Native/src/OSX/menu.mm
  2. 1
      native/Avalonia.Native/src/OSX/window.h
  3. 11
      native/Avalonia.Native/src/OSX/window.mm
  4. 8
      samples/ControlCatalog/DecoratedWindow.xaml.cs
  5. 9
      src/Avalonia.Base/AvaloniaObjectExtensions.cs
  6. 50
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  7. 4
      src/Avalonia.Controls.DataGrid/DataGridCell.cs
  8. 4
      src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
  9. 8
      src/Avalonia.Controls.DataGrid/DataGridRow.cs
  10. 4
      src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs
  11. 18
      src/Avalonia.Controls/AutoCompleteBox.cs
  12. 2
      src/Avalonia.Controls/Button.cs
  13. 25
      src/Avalonia.Controls/Calendar/Calendar.cs
  14. 2
      src/Avalonia.Controls/Calendar/CalendarButton.cs
  15. 2
      src/Avalonia.Controls/Calendar/CalendarDayButton.cs
  16. 16
      src/Avalonia.Controls/Calendar/DatePicker.cs
  17. 12
      src/Avalonia.Controls/Carousel.cs
  18. 4
      src/Avalonia.Controls/ComboBox.cs
  19. 2
      src/Avalonia.Controls/ContentControl.cs
  20. 2
      src/Avalonia.Controls/ContextMenu.cs
  21. 2
      src/Avalonia.Controls/DataValidationErrors.cs
  22. 2
      src/Avalonia.Controls/Decorator.cs
  23. 2
      src/Avalonia.Controls/Expander.cs
  24. 4
      src/Avalonia.Controls/ItemsControl.cs
  25. 8
      src/Avalonia.Controls/LayoutTransformControl.cs
  26. 2
      src/Avalonia.Controls/MenuBase.cs
  27. 16
      src/Avalonia.Controls/MenuItem.cs
  28. 2
      src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs
  29. 13
      src/Avalonia.Controls/Platform/IWindowImpl.cs
  30. 4
      src/Avalonia.Controls/Presenters/CarouselPresenter.cs
  31. 6
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  32. 2
      src/Avalonia.Controls/Presenters/ItemsPresenter.cs
  33. 2
      src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs
  34. 6
      src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs
  35. 2
      src/Avalonia.Controls/Primitives/HeaderedContentControl.cs
  36. 2
      src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs
  37. 2
      src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs
  38. 4
      src/Avalonia.Controls/Primitives/Popup.cs
  39. 2
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  40. 4
      src/Avalonia.Controls/Primitives/ScrollBar.cs
  41. 6
      src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
  42. 2
      src/Avalonia.Controls/Primitives/TemplatedControl.cs
  43. 6
      src/Avalonia.Controls/Primitives/Thumb.cs
  44. 6
      src/Avalonia.Controls/Primitives/Track.cs
  45. 5
      src/Avalonia.Controls/Primitives/UniformGrid.cs
  46. 5
      src/Avalonia.Controls/ProgressBar.cs
  47. 4
      src/Avalonia.Controls/RepeatButton.cs
  48. 4
      src/Avalonia.Controls/ScrollViewer.cs
  49. 6
      src/Avalonia.Controls/Slider.cs
  50. 2
      src/Avalonia.Controls/TabControl.cs
  51. 4
      src/Avalonia.Controls/TabItem.cs
  52. 8
      src/Avalonia.Controls/TopLevel.cs
  53. 2
      src/Avalonia.Controls/TreeViewItem.cs
  54. 2
      src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs
  55. 8
      src/Avalonia.Controls/Window.cs
  56. 2
      src/Avalonia.Controls/WindowBase.cs
  57. 5
      src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
  58. 14
      src/Avalonia.DesignerSupport/Remote/Stubs.cs
  59. 2
      src/Avalonia.Input/Gestures.cs
  60. 24
      src/Avalonia.Input/InputElement.cs
  61. 5
      src/Avalonia.Input/MouseDevice.cs
  62. 29
      src/Avalonia.Input/PointerEventArgs.cs
  63. 25
      src/Avalonia.Input/PointerPoint.cs
  64. 2
      src/Avalonia.Input/TouchDevice.cs
  65. 30
      src/Avalonia.Interactivity/RoutedEvent.cs
  66. 142
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  67. 4
      src/Avalonia.Native/WindowImplBase.cs
  68. 2
      src/Avalonia.Styling/StyledElement.cs
  69. 2
      src/Avalonia.Visuals/Media/Geometry.cs
  70. 4
      src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs
  71. 2
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs
  72. 12
      src/Avalonia.X11/X11Window.cs
  73. 5
      src/Windows/Avalonia.Win32/WindowImpl.cs
  74. 4
      tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs
  75. 2
      tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs
  76. 3
      tests/Avalonia.UnitTests/MouseTestHelper.cs
  77. 53
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs
  78. 19
      tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs

4
native/Avalonia.Native/src/OSX/menu.mm

@ -1,6 +1,7 @@
#include "common.h" #include "common.h"
#include "menu.h" #include "menu.h"
#include "window.h"
@implementation AvnMenu @implementation AvnMenu
@end @end
@ -283,7 +284,8 @@ extern void SetAppMenu (NSString* appName, IAvnAppMenu* menu)
auto quitItem = [[NSMenuItem alloc] init]; auto quitItem = [[NSMenuItem alloc] init];
quitItem.title = [@"Quit " stringByAppendingString:appName]; quitItem.title = [@"Quit " stringByAppendingString:appName];
quitItem.keyEquivalent = @"q"; quitItem.keyEquivalent = @"q";
quitItem.action = @selector(terminate:); quitItem.target = [AvnWindow class];
quitItem.action = @selector(closeAll);
[appMenu addItem:quitItem]; [appMenu addItem:quitItem];
} }
else else

1
native/Avalonia.Native/src/OSX/window.h

@ -15,6 +15,7 @@ class WindowBaseImpl;
@end @end
@interface AvnWindow : NSWindow <NSWindowDelegate> @interface AvnWindow : NSWindow <NSWindowDelegate>
+(void) closeAll;
-(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent; -(AvnWindow* _Nonnull) initWithParent: (WindowBaseImpl* _Nonnull) parent;
-(void) setCanBecomeKeyAndMain; -(void) setCanBecomeKeyAndMain;
-(void) pollModalSession: (NSModalSession _Nonnull) session; -(void) pollModalSession: (NSModalSession _Nonnull) session;

11
native/Avalonia.Native/src/OSX/window.mm

@ -1076,6 +1076,17 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
bool _isAppMenuApplied; bool _isAppMenuApplied;
} }
+(void)closeAll
{
NSArray<NSWindow*>* windows = [NSArray arrayWithArray:[NSApp windows]];
auto numWindows = [windows count];
for(int i = 0; i < numWindows; i++)
{
[[windows objectAtIndex:i] performClose:nil];
}
}
- (void)dealloc - (void)dealloc
{ {
} }

8
samples/ControlCatalog/DecoratedWindow.xaml.cs

@ -18,18 +18,18 @@ namespace ControlCatalog
{ {
var ctl = this.FindControl<Control>(name); var ctl = this.FindControl<Control>(name);
ctl.Cursor = new Cursor(cursor); ctl.Cursor = new Cursor(cursor);
ctl.PointerPressed += delegate ctl.PointerPressed += (i, e) =>
{ {
PlatformImpl?.BeginResizeDrag(edge); PlatformImpl?.BeginResizeDrag(edge, e);
}; };
} }
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
this.FindControl<Control>("TitleBar").PointerPressed += delegate this.FindControl<Control>("TitleBar").PointerPressed += (i, e) =>
{ {
PlatformImpl?.BeginMoveDrag(); PlatformImpl?.BeginMoveDrag(e);
}; };
SetupSide("Left", StandardCursorType.LeftSide, WindowEdge.West); SetupSide("Left", StandardCursorType.LeftSide, WindowEdge.West);
SetupSide("Right", StandardCursorType.RightSide, WindowEdge.East); SetupSide("Right", StandardCursorType.RightSide, WindowEdge.East);

9
src/Avalonia.Base/AvaloniaObjectExtensions.cs

@ -192,9 +192,9 @@ namespace Avalonia
{ {
return observable.Subscribe(e => return observable.Subscribe(e =>
{ {
if (e.Sender is TTarget) if (e.Sender is TTarget target)
{ {
action((TTarget)e.Sender, e); action(target, e);
} }
}); });
} }
@ -207,6 +207,7 @@ namespace Avalonia
/// <param name="observable">The property changed observable.</param> /// <param name="observable">The property changed observable.</param>
/// <param name="handler">Given a TTarget, returns the handler.</param> /// <param name="handler">Given a TTarget, returns the handler.</param>
/// <returns>A disposable that can be used to terminate the subscription.</returns> /// <returns>A disposable that can be used to terminate the subscription.</returns>
[Obsolete("Use overload taking Action<TTarget, AvaloniaPropertyChangedEventArgs>.")]
public static IDisposable AddClassHandler<TTarget>( public static IDisposable AddClassHandler<TTarget>(
this IObservable<AvaloniaPropertyChangedEventArgs> observable, this IObservable<AvaloniaPropertyChangedEventArgs> observable,
Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler) Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler)
@ -238,9 +239,7 @@ namespace Avalonia
Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler) Func<TTarget, Action<AvaloniaPropertyChangedEventArgs>> handler)
where TTarget : class where TTarget : class
{ {
var target = e.Sender as TTarget; if (e.Sender is TTarget target)
if (target != null)
{ {
handler(target)(e); handler(target)(e);
} }

50
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -723,29 +723,29 @@ namespace Avalonia.Controls
PseudoClass<DataGrid, bool>(IsValidProperty, x => !x, ":invalid"); PseudoClass<DataGrid, bool>(IsValidProperty, x => !x, ":invalid");
ItemsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnItemsPropertyChanged); ItemsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnItemsPropertyChanged(e));
CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnCanUserResizeColumnsChanged); CanUserResizeColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnCanUserResizeColumnsChanged(e));
ColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnColumnWidthChanged); ColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnColumnWidthChanged(e));
RowBackgroundProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowBackgroundChanged); RowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
AlternatingRowBackgroundProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowBackgroundChanged); AlternatingRowBackgroundProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowBackgroundChanged(e));
FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>(x => x.OnFrozenColumnCountChanged); FrozenColumnCountProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnFrozenColumnCountChanged(e));
GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>(x => x.OnGridLinesVisibilityChanged); GridLinesVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnGridLinesVisibilityChanged(e));
HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>(x => x.OnHeadersVisibilityChanged); HeadersVisibilityProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHeadersVisibilityChanged(e));
HorizontalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>(x => x.OnHorizontalGridLinesBrushChanged); HorizontalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnHorizontalGridLinesBrushChanged(e));
IsReadOnlyProperty.Changed.AddClassHandler<DataGrid>(x => x.OnIsReadOnlyChanged); IsReadOnlyProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnIsReadOnlyChanged(e));
MaxColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnMaxColumnWidthChanged); MaxColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnMaxColumnWidthChanged(e));
MinColumnWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnMinColumnWidthChanged); MinColumnWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnMinColumnWidthChanged(e));
RowHeightProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowHeightChanged); RowHeightProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowHeightChanged(e));
RowHeaderWidthProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowHeaderWidthChanged); RowHeaderWidthProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowHeaderWidthChanged(e));
SelectionModeProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectionModeChanged); SelectionModeProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectionModeChanged(e));
VerticalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>(x => x.OnVerticalGridLinesBrushChanged); VerticalGridLinesBrushProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnVerticalGridLinesBrushChanged(e));
SelectedIndexProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectedIndexChanged); SelectedIndexProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectedIndexChanged(e));
SelectedItemProperty.Changed.AddClassHandler<DataGrid>(x => x.OnSelectedItemChanged); SelectedItemProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnSelectedItemChanged(e));
IsEnabledProperty.Changed.AddClassHandler<DataGrid>(x => x.DataGrid_IsEnabledChanged); IsEnabledProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.DataGrid_IsEnabledChanged(e));
AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler<DataGrid>(x => x.OnAreRowGroupHeadersFrozenChanged); AreRowGroupHeadersFrozenProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnAreRowGroupHeadersFrozenChanged(e));
RowDetailsTemplateProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowDetailsTemplateChanged); RowDetailsTemplateProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowDetailsTemplateChanged(e));
RowDetailsVisibilityModeProperty.Changed.AddClassHandler<DataGrid>(x => x.OnRowDetailsVisibilityModeChanged); RowDetailsVisibilityModeProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnRowDetailsVisibilityModeChanged(e));
AutoGenerateColumnsProperty.Changed.AddClassHandler<DataGrid>(x => x.OnAutoGenerateColumnsChanged); AutoGenerateColumnsProperty.Changed.AddClassHandler<DataGrid>((x, e) => x.OnAutoGenerateColumnsChanged(e));
} }
/// <summary> /// <summary>
@ -3533,7 +3533,7 @@ namespace Avalonia.Controls
if (AreColumnHeadersVisible && if (AreColumnHeadersVisible &&
_vScrollBar != null && _vScrollBar.IsVisible) _vScrollBar != null && _vScrollBar.IsVisible)
{ {
_topRightCornerHeader.IsVisible = true; ; _topRightCornerHeader.IsVisible = true;
} }
else else
{ {
@ -5594,7 +5594,7 @@ namespace Avalonia.Controls
{ {
// This will trigger a call to this method via Cells_SizeChanged for // This will trigger a call to this method via Cells_SizeChanged for
// which no processing is needed. // which no processing is needed.
_vScrollBar.IsVisible = true; ; _vScrollBar.IsVisible = true;
if (_vScrollBar.DesiredSize.Width == 0) if (_vScrollBar.DesiredSize.Width == 0)
{ {
// We need to know the width for the rest of layout to work correctly so measure it now // We need to know the width for the rest of layout to work correctly so measure it now

4
src/Avalonia.Controls.DataGrid/DataGridCell.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
static DataGridCell() static DataGridCell()
{ {
PointerPressedEvent.AddClassHandler<DataGridCell>( PointerPressedEvent.AddClassHandler<DataGridCell>(
x => x.DataGridCell_PointerPressed, handledEventsToo: true); (x,e) => x.DataGridCell_PointerPressed(e), handledEventsToo: true);
} }
public DataGridCell() public DataGridCell()
{ } { }
@ -219,4 +219,4 @@ namespace Avalonia.Controls
} }
} }
} }
} }

4
src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs

@ -67,7 +67,7 @@ namespace Avalonia.Controls
static DataGridColumnHeader() static DataGridColumnHeader()
{ {
AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>(x => x.OnAreSeparatorsVisibleChanged); AreSeparatorsVisibleProperty.Changed.AddClassHandler<DataGridColumnHeader>((x,e) => x.OnAreSeparatorsVisibleChanged(e));
} }
/// <summary> /// <summary>
@ -468,7 +468,7 @@ namespace Avalonia.Controls
private void DataGridColumnHeader_PointerReleased(object sender, PointerReleasedEventArgs e) private void DataGridColumnHeader_PointerReleased(object sender, PointerReleasedEventArgs e)
{ {
if (OwningColumn == null || e.Handled || !IsEnabled || e.MouseButton != MouseButton.Left) if (OwningColumn == null || e.Handled || !IsEnabled || e.InitialPressMouseButton != MouseButton.Left)
{ {
return; return;
} }

8
src/Avalonia.Controls.DataGrid/DataGridRow.cs

@ -116,10 +116,10 @@ namespace Avalonia.Controls
static DataGridRow() static DataGridRow()
{ {
HeaderProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnHeaderChanged); HeaderProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnHeaderChanged(e));
DetailsTemplateProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnDetailsTemplateChanged); DetailsTemplateProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnDetailsTemplateChanged(e));
AreDetailsVisibleProperty.Changed.AddClassHandler<DataGridRow>(x => x.OnAreDetailsVisibleChanged); AreDetailsVisibleProperty.Changed.AddClassHandler<DataGridRow>((x, e) => x.OnAreDetailsVisibleChanged(e));
PointerPressedEvent.AddClassHandler<DataGridRow>(x => x.DataGridRow_PointerPressed, handledEventsToo: true); PointerPressedEvent.AddClassHandler<DataGridRow>((x, e) => x.DataGridRow_PointerPressed(e), handledEventsToo: true);
} }
/// <summary> /// <summary>

4
src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs

@ -109,7 +109,7 @@ namespace Avalonia.Controls
static DataGridRowGroupHeader() static DataGridRowGroupHeader()
{ {
SublevelIndentProperty.Changed.AddClassHandler<DataGridRowGroupHeader>(x => x.OnSublevelIndentChanged); SublevelIndentProperty.Changed.AddClassHandler<DataGridRowGroupHeader>((x,e) => x.OnSublevelIndentChanged(e));
} }
/// <summary> /// <summary>
@ -446,4 +446,4 @@ namespace Avalonia.Controls
} }
} }
} }

18
src/Avalonia.Controls/AutoCompleteBox.cs

@ -805,15 +805,15 @@ namespace Avalonia.Controls
{ {
FocusableProperty.OverrideDefaultValue<AutoCompleteBox>(true); FocusableProperty.OverrideDefaultValue<AutoCompleteBox>(true);
MinimumPopulateDelayProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnMinimumPopulateDelayChanged); MinimumPopulateDelayProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnMinimumPopulateDelayChanged(e));
IsDropDownOpenProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnIsDropDownOpenChanged); IsDropDownOpenProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnIsDropDownOpenChanged(e));
SelectedItemProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnSelectedItemPropertyChanged); SelectedItemProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnSelectedItemPropertyChanged(e));
TextProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnTextPropertyChanged); TextProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnTextPropertyChanged(e));
SearchTextProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnSearchTextPropertyChanged); SearchTextProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnSearchTextPropertyChanged(e));
FilterModeProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnFilterModePropertyChanged); FilterModeProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnFilterModePropertyChanged(e));
ItemFilterProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnItemFilterPropertyChanged); ItemFilterProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnItemFilterPropertyChanged(e));
ItemsProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnItemsPropertyChanged); ItemsProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnItemsPropertyChanged(e));
IsEnabledProperty.Changed.AddClassHandler<AutoCompleteBox>(x => x.OnControlIsEnabledChanged); IsEnabledProperty.Changed.AddClassHandler<AutoCompleteBox>((x,e) => x.OnControlIsEnabledChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Button.cs

@ -294,7 +294,7 @@ namespace Avalonia.Controls
{ {
base.OnPointerReleased(e); base.OnPointerReleased(e);
if (IsPressed && e.MouseButton == MouseButton.Left) if (IsPressed && e.InitialPressMouseButton == MouseButton.Left)
{ {
IsPressed = false; IsPressed = false;
e.Handled = true; e.Handled = true;

25
src/Avalonia.Controls/Calendar/Calendar.cs

@ -1565,7 +1565,7 @@ namespace Avalonia.Controls
protected override void OnPointerReleased(PointerReleasedEventArgs e) protected override void OnPointerReleased(PointerReleasedEventArgs e)
{ {
base.OnPointerReleased(e); base.OnPointerReleased(e);
if (!HasFocusInternal && e.MouseButton == MouseButton.Left) if (!HasFocusInternal && e.InitialPressMouseButton == MouseButton.Left)
{ {
FocusManager.Instance.Focus(this); FocusManager.Instance.Focus(this);
} }
@ -2057,18 +2057,17 @@ namespace Avalonia.Controls
static Calendar() static Calendar()
{ {
IsEnabledProperty.Changed.AddClassHandler<Calendar>(x => x.OnIsEnabledChanged); IsEnabledProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnIsEnabledChanged(e));
FirstDayOfWeekProperty.Changed.AddClassHandler<Calendar>(x => x.OnFirstDayOfWeekChanged); FirstDayOfWeekProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnFirstDayOfWeekChanged(e));
IsTodayHighlightedProperty.Changed.AddClassHandler<Calendar>(x => x.OnIsTodayHighlightedChanged); IsTodayHighlightedProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnIsTodayHighlightedChanged(e));
DisplayModeProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayModePropertyChanged); DisplayModeProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayModePropertyChanged(e));
SelectionModeProperty.Changed.AddClassHandler<Calendar>(x => x.OnSelectionModeChanged); SelectionModeProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnSelectionModeChanged(e));
SelectedDateProperty.Changed.AddClassHandler<Calendar>(x => x.OnSelectedDateChanged); SelectedDateProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnSelectedDateChanged(e));
DisplayDateProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateChanged); DisplayDateProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateChanged(e));
DisplayDateStartProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateStartChanged); DisplayDateStartProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateStartChanged(e));
DisplayDateEndProperty.Changed.AddClassHandler<Calendar>(x => x.OnDisplayDateEndChanged); DisplayDateEndProperty.Changed.AddClassHandler<Calendar>((x,e) => x.OnDisplayDateEndChanged(e));
KeyDownEvent.AddClassHandler<Calendar>(x => x.Calendar_KeyDown); KeyDownEvent.AddClassHandler<Calendar>((x,e) => x.Calendar_KeyDown(e));
KeyUpEvent.AddClassHandler<Calendar>(x => x.Calendar_KeyUp); KeyUpEvent.AddClassHandler<Calendar>((x,e) => x.Calendar_KeyUp(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Calendar/CalendarButton.cs

@ -173,7 +173,7 @@ namespace Avalonia.Controls.Primitives
protected override void OnPointerReleased(PointerReleasedEventArgs e) protected override void OnPointerReleased(PointerReleasedEventArgs e)
{ {
base.OnPointerReleased(e); base.OnPointerReleased(e);
if (e.MouseButton == MouseButton.Left) if (e.InitialPressMouseButton == MouseButton.Left)
CalendarLeftMouseButtonUp?.Invoke(this, e); CalendarLeftMouseButtonUp?.Invoke(this, e);
} }
} }

2
src/Avalonia.Controls/Calendar/CalendarDayButton.cs

@ -231,7 +231,7 @@ namespace Avalonia.Controls.Primitives
{ {
base.OnPointerReleased(e); base.OnPointerReleased(e);
if (e.MouseButton == MouseButton.Left) if (e.InitialPressMouseButton == MouseButton.Left)
CalendarDayButtonMouseUp?.Invoke(this, e); CalendarDayButtonMouseUp?.Invoke(this, e);
} }
} }

16
src/Avalonia.Controls/Calendar/DatePicker.cs

@ -393,14 +393,14 @@ namespace Avalonia.Controls
{ {
FocusableProperty.OverrideDefaultValue<DatePicker>(true); FocusableProperty.OverrideDefaultValue<DatePicker>(true);
DisplayDateProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateChanged); DisplayDateProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateChanged(e));
DisplayDateStartProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateStartChanged); DisplayDateStartProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateStartChanged(e));
DisplayDateEndProperty.Changed.AddClassHandler<DatePicker>(x => x.OnDisplayDateEndChanged); DisplayDateEndProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnDisplayDateEndChanged(e));
IsDropDownOpenProperty.Changed.AddClassHandler<DatePicker>(x => x.OnIsDropDownOpenChanged); IsDropDownOpenProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnIsDropDownOpenChanged(e));
SelectedDateProperty.Changed.AddClassHandler<DatePicker>(x => x.OnSelectedDateChanged); SelectedDateProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnSelectedDateChanged(e));
SelectedDateFormatProperty.Changed.AddClassHandler<DatePicker>(x => x.OnSelectedDateFormatChanged); SelectedDateFormatProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnSelectedDateFormatChanged(e));
CustomDateFormatStringProperty.Changed.AddClassHandler<DatePicker>(x => x.OnCustomDateFormatStringChanged); CustomDateFormatStringProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnCustomDateFormatStringChanged(e));
TextProperty.Changed.AddClassHandler<DatePicker>(x => x.OnTextChanged); TextProperty.Changed.AddClassHandler<DatePicker>((x,e) => x.OnTextChanged(e));
} }
/// <summary> /// <summary>
/// Initializes a new instance of the /// Initializes a new instance of the

12
src/Avalonia.Controls/Carousel.cs

@ -84,17 +84,5 @@ namespace Avalonia.Controls
--SelectedIndex; --SelectedIndex;
} }
} }
/// <inheritdoc/>
protected override void OnKeyDown(KeyEventArgs e)
{
// Ignore key presses.
}
/// <inheritdoc/>
protected override void OnPointerPressed(PointerPressedEventArgs e)
{
// Ignore pointer presses.
}
} }
} }

4
src/Avalonia.Controls/ComboBox.cs

@ -65,8 +65,8 @@ namespace Avalonia.Controls
{ {
ItemsPanelProperty.OverrideDefaultValue<ComboBox>(DefaultPanel); ItemsPanelProperty.OverrideDefaultValue<ComboBox>(DefaultPanel);
FocusableProperty.OverrideDefaultValue<ComboBox>(true); FocusableProperty.OverrideDefaultValue<ComboBox>(true);
SelectedItemProperty.Changed.AddClassHandler<ComboBox>(x => x.SelectedItemChanged); SelectedItemProperty.Changed.AddClassHandler<ComboBox>((x,e) => x.SelectedItemChanged(e));
KeyDownEvent.AddClassHandler<ComboBox>(x => x.OnKeyDown, Interactivity.RoutingStrategies.Tunnel); KeyDownEvent.AddClassHandler<ComboBox>((x, e) => x.OnKeyDown(e), Interactivity.RoutingStrategies.Tunnel);
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/ContentControl.cs

@ -43,7 +43,7 @@ namespace Avalonia.Controls
static ContentControl() static ContentControl()
{ {
ContentProperty.Changed.AddClassHandler<ContentControl>(x => x.ContentChanged); ContentProperty.Changed.AddClassHandler<ContentControl>((x, e) => x.ContentChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/ContextMenu.cs

@ -192,7 +192,7 @@ namespace Avalonia.Controls
e.Handled = true; e.Handled = true;
} }
if (e.MouseButton == MouseButton.Right) if (e.InitialPressMouseButton == MouseButton.Right)
{ {
if (contextMenu.CancelOpening()) if (contextMenu.CancelOpening())
return; return;

2
src/Avalonia.Controls/DataValidationErrors.cs

@ -56,7 +56,7 @@ namespace Avalonia.Controls
{ {
ErrorsProperty.Changed.Subscribe(ErrorsChanged); ErrorsProperty.Changed.Subscribe(ErrorsChanged);
HasErrorsProperty.Changed.Subscribe(HasErrorsChanged); HasErrorsProperty.Changed.Subscribe(HasErrorsChanged);
TemplatedParentProperty.Changed.AddClassHandler<DataValidationErrors>(x => x.OnTemplatedParentChange); TemplatedParentProperty.Changed.AddClassHandler<DataValidationErrors>((x, e) => x.OnTemplatedParentChange(e));
} }
private void OnTemplatedParentChange(AvaloniaPropertyChangedEventArgs e) private void OnTemplatedParentChange(AvaloniaPropertyChangedEventArgs e)

2
src/Avalonia.Controls/Decorator.cs

@ -29,7 +29,7 @@ namespace Avalonia.Controls
static Decorator() static Decorator()
{ {
AffectsMeasure<Decorator>(ChildProperty, PaddingProperty); AffectsMeasure<Decorator>(ChildProperty, PaddingProperty);
ChildProperty.Changed.AddClassHandler<Decorator>(x => x.ChildChanged); ChildProperty.Changed.AddClassHandler<Decorator>((x, e) => x.ChildChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Expander.cs

@ -37,7 +37,7 @@ namespace Avalonia.Controls
PseudoClass<Expander>(IsExpandedProperty, ":expanded"); PseudoClass<Expander>(IsExpandedProperty, ":expanded");
IsExpandedProperty.Changed.AddClassHandler<Expander>(x => x.OnIsExpandedChanged); IsExpandedProperty.Changed.AddClassHandler<Expander>((x, e) => x.OnIsExpandedChanged(e));
} }
public IPageTransition ContentTransition public IPageTransition ContentTransition

4
src/Avalonia.Controls/ItemsControl.cs

@ -64,8 +64,8 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
static ItemsControl() static ItemsControl()
{ {
ItemsProperty.Changed.AddClassHandler<ItemsControl>(x => x.ItemsChanged); ItemsProperty.Changed.AddClassHandler<ItemsControl>((x, e) => x.ItemsChanged(e));
ItemTemplateProperty.Changed.AddClassHandler<ItemsControl>(x => x.ItemTemplateChanged); ItemTemplateProperty.Changed.AddClassHandler<ItemsControl>((x, e) => x.ItemTemplateChanged(e));
} }
/// <summary> /// <summary>

8
src/Avalonia.Controls/LayoutTransformControl.cs

@ -28,11 +28,13 @@ namespace Avalonia.Controls
ClipToBoundsProperty.OverrideDefaultValue<LayoutTransformControl>(true); ClipToBoundsProperty.OverrideDefaultValue<LayoutTransformControl>(true);
LayoutTransformProperty.Changed LayoutTransformProperty.Changed
.AddClassHandler<LayoutTransformControl>(x => x.OnLayoutTransformChanged); .AddClassHandler<LayoutTransformControl>((x, e) => x.OnLayoutTransformChanged(e));
ChildProperty.Changed ChildProperty.Changed
.AddClassHandler<LayoutTransformControl>(x => x.OnChildChanged); .AddClassHandler<LayoutTransformControl>((x, e) => x.OnChildChanged(e));
UseRenderTransformProperty.Changed.AddClassHandler<LayoutTransformControl>(x => x.OnUseRenderTransformPropertyChanged);
UseRenderTransformProperty.Changed
.AddClassHandler<LayoutTransformControl>((x, e) => x.OnUseRenderTransformPropertyChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/MenuBase.cs

@ -64,7 +64,7 @@ namespace Avalonia.Controls
/// </summary> /// </summary>
static MenuBase() static MenuBase()
{ {
MenuItem.SubmenuOpenedEvent.AddClassHandler<MenuBase>(x => x.OnSubmenuOpened); MenuItem.SubmenuOpenedEvent.AddClassHandler<MenuBase>((x, e) => x.OnSubmenuOpened(e));
} }
/// <summary> /// <summary>

16
src/Avalonia.Controls/MenuItem.cs

@ -102,13 +102,13 @@ namespace Avalonia.Controls
SelectableMixin.Attach<MenuItem>(IsSelectedProperty); SelectableMixin.Attach<MenuItem>(IsSelectedProperty);
CommandProperty.Changed.Subscribe(CommandChanged); CommandProperty.Changed.Subscribe(CommandChanged);
FocusableProperty.OverrideDefaultValue<MenuItem>(true); FocusableProperty.OverrideDefaultValue<MenuItem>(true);
HeaderProperty.Changed.AddClassHandler<MenuItem>(x => x.HeaderChanged); HeaderProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.HeaderChanged(e));
IconProperty.Changed.AddClassHandler<MenuItem>(x => x.IconChanged); IconProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.IconChanged(e));
IsSelectedProperty.Changed.AddClassHandler<MenuItem>(x => x.IsSelectedChanged); IsSelectedProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.IsSelectedChanged(e));
ItemsPanelProperty.OverrideDefaultValue<MenuItem>(DefaultPanel); ItemsPanelProperty.OverrideDefaultValue<MenuItem>(DefaultPanel);
ClickEvent.AddClassHandler<MenuItem>(x => x.OnClick); ClickEvent.AddClassHandler<MenuItem>((x, e) => x.OnClick(e));
SubmenuOpenedEvent.AddClassHandler<MenuItem>(x => x.OnSubmenuOpened); SubmenuOpenedEvent.AddClassHandler<MenuItem>((x, e) => x.OnSubmenuOpened(e));
IsSubMenuOpenProperty.Changed.AddClassHandler<MenuItem>(x => x.SubMenuOpenChanged); IsSubMenuOpenProperty.Changed.AddClassHandler<MenuItem>((x, e) => x.SubMenuOpenChanged(e));
} }
public MenuItem() public MenuItem()
@ -337,7 +337,7 @@ namespace Avalonia.Controls
{ {
base.OnPointerEnter(e); base.OnPointerEnter(e);
var point = e.GetPointerPoint(null); var point = e.GetCurrentPoint(null);
RaiseEvent(new PointerEventArgs(PointerEnterItemEvent, this, e.Pointer, this.VisualRoot, point.Position, RaiseEvent(new PointerEventArgs(PointerEnterItemEvent, this, e.Pointer, this.VisualRoot, point.Position,
e.Timestamp, point.Properties, e.KeyModifiers)); e.Timestamp, point.Properties, e.KeyModifiers));
} }
@ -347,7 +347,7 @@ namespace Avalonia.Controls
{ {
base.OnPointerLeave(e); base.OnPointerLeave(e);
var point = e.GetPointerPoint(null); var point = e.GetCurrentPoint(null);
RaiseEvent(new PointerEventArgs(PointerLeaveItemEvent, this, e.Pointer, this.VisualRoot, point.Position, RaiseEvent(new PointerEventArgs(PointerLeaveItemEvent, this, e.Pointer, this.VisualRoot, point.Position,
e.Timestamp, point.Properties, e.KeyModifiers)); e.Timestamp, point.Properties, e.KeyModifiers));
} }

2
src/Avalonia.Controls/Platform/DefaultMenuInteractionHandler.cs

@ -356,7 +356,7 @@ namespace Avalonia.Controls.Platform
{ {
var item = GetMenuItem(e.Source as IControl); var item = GetMenuItem(e.Source as IControl);
if (e.MouseButton == MouseButton.Left && item?.HasSubMenu == false) if (e.InitialPressMouseButton == MouseButton.Left && item?.HasSubMenu == false)
{ {
Click(item); Click(item);
e.Handled = true; e.Handled = true;

13
src/Avalonia.Controls/Platform/IWindowImpl.cs

@ -3,6 +3,7 @@
using System; using System;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
namespace Avalonia.Platform namespace Avalonia.Platform
{ {
@ -57,28 +58,28 @@ namespace Avalonia.Platform
/// Return true to prevent the underlying implementation from closing. /// Return true to prevent the underlying implementation from closing.
/// </summary> /// </summary>
Func<bool> Closing { get; set; } Func<bool> Closing { get; set; }
/// <summary> /// <summary>
/// Starts moving a window with left button being held. Should be called from left mouse button press event handler. /// Starts moving a window with left button being held. Should be called from left mouse button press event handler.
/// </summary> /// </summary>
void BeginMoveDrag(); void BeginMoveDrag(PointerPressedEventArgs e);
/// <summary> /// <summary>
/// Starts resizing a window. This function is used if an application has window resizing controls. /// Starts resizing a window. This function is used if an application has window resizing controls.
/// Should be called from left mouse button press event handler /// Should be called from left mouse button press event handler
/// </summary> /// </summary>
void BeginResizeDrag(WindowEdge edge); void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e);
/// <summary> /// <summary>
/// Sets the client size of the top level. /// Sets the client size of the top level.
/// </summary> /// </summary>
void Resize(Size clientSize); void Resize(Size clientSize);
/// <summary> /// <summary>
/// Sets the client size of the top level. /// Sets the client size of the top level.
/// </summary> /// </summary>
void Move(PixelPoint point); void Move(PixelPoint point);
/// <summary> /// <summary>
/// Minimum width of the window. /// Minimum width of the window.
/// </summary> /// </summary>

4
src/Avalonia.Controls/Presenters/CarouselPresenter.cs

@ -46,8 +46,8 @@ namespace Avalonia.Controls.Presenters
/// </summary> /// </summary>
static CarouselPresenter() static CarouselPresenter()
{ {
IsVirtualizedProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.IsVirtualizedChanged); IsVirtualizedProperty.Changed.AddClassHandler<CarouselPresenter>((x, e) => x.IsVirtualizedChanged(e));
SelectedIndexProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.SelectedIndexChanged); SelectedIndexProperty.Changed.AddClassHandler<CarouselPresenter>((x, e) => x.SelectedIndexChanged(e));
} }
/// <summary> /// <summary>

6
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -94,9 +94,9 @@ namespace Avalonia.Controls.Presenters
{ {
AffectsRender<ContentPresenter>(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty); AffectsRender<ContentPresenter>(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty, CornerRadiusProperty);
AffectsMeasure<ContentPresenter>(BorderThicknessProperty, PaddingProperty); AffectsMeasure<ContentPresenter>(BorderThicknessProperty, PaddingProperty);
ContentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged); ContentProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.ContentChanged(e));
ContentTemplateProperty.Changed.AddClassHandler<ContentPresenter>(x => x.ContentChanged); ContentTemplateProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.ContentChanged(e));
TemplatedParentProperty.Changed.AddClassHandler<ContentPresenter>(x => x.TemplatedParentChanged); TemplatedParentProperty.Changed.AddClassHandler<ContentPresenter>((x, e) => x.TemplatedParentChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Presenters/ItemsPresenter.cs

@ -35,7 +35,7 @@ namespace Avalonia.Controls.Presenters
KeyboardNavigationMode.Once); KeyboardNavigationMode.Once);
VirtualizationModeProperty.Changed VirtualizationModeProperty.Changed
.AddClassHandler<ItemsPresenter>(x => x.VirtualizationModeChanged); .AddClassHandler<ItemsPresenter>((x, e) => x.VirtualizationModeChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs

@ -45,7 +45,7 @@ namespace Avalonia.Controls.Presenters
/// </summary> /// </summary>
static ItemsPresenterBase() static ItemsPresenterBase()
{ {
TemplatedParentProperty.Changed.AddClassHandler<ItemsPresenterBase>(x => x.TemplatedParentChanged); TemplatedParentProperty.Changed.AddClassHandler<ItemsPresenterBase>((x,e) => x.TemplatedParentChanged(e));
} }
/// <summary> /// <summary>

6
src/Avalonia.Controls/Presenters/ScrollContentPresenter.cs

@ -73,7 +73,7 @@ namespace Avalonia.Controls.Presenters
static ScrollContentPresenter() static ScrollContentPresenter()
{ {
ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true); ClipToBoundsProperty.OverrideDefaultValue(typeof(ScrollContentPresenter), true);
ChildProperty.Changed.AddClassHandler<ScrollContentPresenter>(x => x.ChildChanged); ChildProperty.Changed.AddClassHandler<ScrollContentPresenter>((x, e) => x.ChildChanged(e));
AffectsArrange<ScrollContentPresenter>(OffsetProperty); AffectsArrange<ScrollContentPresenter>(OffsetProperty);
} }
@ -246,7 +246,7 @@ namespace Avalonia.Controls.Presenters
if (isLogical) if (isLogical)
_activeLogicalGestureScrolls?.TryGetValue(e.Id, out delta); _activeLogicalGestureScrolls?.TryGetValue(e.Id, out delta);
delta += e.Delta; delta += e.Delta;
if (Extent.Height > Viewport.Height) if (Extent.Height > Viewport.Height)
{ {
double dy; double dy;
@ -293,7 +293,7 @@ namespace Avalonia.Controls.Presenters
} }
} }
private void OnScrollGestureEnded(object sender, ScrollGestureEndedEventArgs e) private void OnScrollGestureEnded(object sender, ScrollGestureEndedEventArgs e)
=> _activeLogicalGestureScrolls?.Remove(e.Id); => _activeLogicalGestureScrolls?.Remove(e.Id);
/// <inheritdoc/> /// <inheritdoc/>

2
src/Avalonia.Controls/Primitives/HeaderedContentControl.cs

@ -30,7 +30,7 @@ namespace Avalonia.Controls.Primitives
/// </summary> /// </summary>
static HeaderedContentControl() static HeaderedContentControl()
{ {
ContentProperty.Changed.AddClassHandler<HeaderedContentControl>(x => x.HeaderChanged); ContentProperty.Changed.AddClassHandler<HeaderedContentControl>((x, e) => x.HeaderChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Primitives/HeaderedItemsControl.cs

@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives
/// </summary> /// </summary>
static HeaderedItemsControl() static HeaderedItemsControl()
{ {
HeaderProperty.Changed.AddClassHandler<HeaderedItemsControl>(x => x.HeaderChanged); HeaderProperty.Changed.AddClassHandler<HeaderedItemsControl>((x, e) => x.HeaderChanged(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Primitives/HeaderedSelectingItemsControl.cs

@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives
/// </summary> /// </summary>
static HeaderedSelectingItemsControl() static HeaderedSelectingItemsControl()
{ {
HeaderProperty.Changed.AddClassHandler<HeaderedSelectingItemsControl>(x => x.HeaderChanged); HeaderProperty.Changed.AddClassHandler<HeaderedSelectingItemsControl>((x, e) => x.HeaderChanged(e));
} }
/// <summary> /// <summary>

4
src/Avalonia.Controls/Primitives/Popup.cs

@ -93,8 +93,8 @@ namespace Avalonia.Controls.Primitives
static Popup() static Popup()
{ {
IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false); IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false);
ChildProperty.Changed.AddClassHandler<Popup>(x => x.ChildChanged); ChildProperty.Changed.AddClassHandler<Popup>((x, e) => x.ChildChanged(e));
IsOpenProperty.Changed.AddClassHandler<Popup>(x => x.IsOpenChanged); IsOpenProperty.Changed.AddClassHandler<Popup>((x, e) => x.IsOpenChanged(e));
} }
public Popup() public Popup()

2
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -17,7 +17,7 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// The root window of a <see cref="Popup"/>. /// The root window of a <see cref="Popup"/>.
/// </summary> /// </summary>
public class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost public sealed class PopupRoot : WindowBase, IInteractive, IHostedVisualTreeRoot, IDisposable, IStyleHost, IPopupHost
{ {
private readonly TopLevel _parent; private readonly TopLevel _parent;
private PopupPositionerParameters _positionerParameters; private PopupPositionerParameters _positionerParameters;

4
src/Avalonia.Controls/Primitives/ScrollBar.cs

@ -58,8 +58,8 @@ namespace Avalonia.Controls.Primitives
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical"); PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); PseudoClass<ScrollBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragDelta, RoutingStrategies.Bubble); Thumb.DragDeltaEvent.AddClassHandler<ScrollBar>((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>(o => o.OnThumbDragComplete, RoutingStrategies.Bubble); Thumb.DragCompletedEvent.AddClassHandler<ScrollBar>((x, e) => x.OnThumbDragComplete(e), RoutingStrategies.Bubble);
} }
/// <summary> /// <summary>

6
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs

@ -119,7 +119,7 @@ namespace Avalonia.Controls.Primitives
/// </summary> /// </summary>
static SelectingItemsControl() static SelectingItemsControl()
{ {
IsSelectedChangedEvent.AddClassHandler<SelectingItemsControl>(x => x.ContainerSelectionChanged); IsSelectedChangedEvent.AddClassHandler<SelectingItemsControl>((x, e) => x.ContainerSelectionChanged(e));
} }
/// <summary> /// <summary>
@ -1088,8 +1088,8 @@ namespace Avalonia.Controls.Primitives
} }
else else
{ {
SelectedIndex = _updateSelectedIndex != int.MinValue ? SelectedIndex = _updateSelectedIndex != int.MinValue ?
_updateSelectedIndex : _updateSelectedIndex :
AlwaysSelected ? 0 : -1; AlwaysSelected ? 0 : -1;
} }
} }

2
src/Avalonia.Controls/Primitives/TemplatedControl.cs

@ -99,7 +99,7 @@ namespace Avalonia.Controls.Primitives
static TemplatedControl() static TemplatedControl()
{ {
ClipToBoundsProperty.OverrideDefaultValue<TemplatedControl>(true); ClipToBoundsProperty.OverrideDefaultValue<TemplatedControl>(true);
TemplateProperty.Changed.AddClassHandler<TemplatedControl>(x => x.OnTemplateChanged); TemplateProperty.Changed.AddClassHandler<TemplatedControl>((x, e) => x.OnTemplateChanged(e));
} }
/// <summary> /// <summary>

6
src/Avalonia.Controls/Primitives/Thumb.cs

@ -22,9 +22,9 @@ namespace Avalonia.Controls.Primitives
static Thumb() static Thumb()
{ {
DragStartedEvent.AddClassHandler<Thumb>(x => x.OnDragStarted, RoutingStrategies.Bubble); DragStartedEvent.AddClassHandler<Thumb>((x,e) => x.OnDragStarted(e), RoutingStrategies.Bubble);
DragDeltaEvent.AddClassHandler<Thumb>(x => x.OnDragDelta, RoutingStrategies.Bubble); DragDeltaEvent.AddClassHandler<Thumb>((x, e) => x.OnDragDelta(e), RoutingStrategies.Bubble);
DragCompletedEvent.AddClassHandler<Thumb>(x => x.OnDragCompleted, RoutingStrategies.Bubble); DragCompletedEvent.AddClassHandler<Thumb>((x, e) => x.OnDragCompleted(e), RoutingStrategies.Bubble);
} }
public event EventHandler<VectorEventArgs> DragStarted public event EventHandler<VectorEventArgs> DragStarted

6
src/Avalonia.Controls/Primitives/Track.cs

@ -48,9 +48,9 @@ namespace Avalonia.Controls.Primitives
{ {
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical"); PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); PseudoClass<Track, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
ThumbProperty.Changed.AddClassHandler<Track>(x => x.ThumbChanged); ThumbProperty.Changed.AddClassHandler<Track>((x,e) => x.ThumbChanged(e));
IncreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged); IncreaseButtonProperty.Changed.AddClassHandler<Track>((x, e) => x.ButtonChanged(e));
DecreaseButtonProperty.Changed.AddClassHandler<Track>(x => x.ButtonChanged); DecreaseButtonProperty.Changed.AddClassHandler<Track>((x, e) => x.ButtonChanged(e));
AffectsArrange<Track>(MinimumProperty, MaximumProperty, ValueProperty, OrientationProperty); AffectsArrange<Track>(MinimumProperty, MaximumProperty, ValueProperty, OrientationProperty);
} }

5
src/Avalonia.Controls/Primitives/UniformGrid.cs

@ -28,6 +28,11 @@ namespace Avalonia.Controls.Primitives
private int _rows; private int _rows;
private int _columns; private int _columns;
static UniformGrid()
{
AffectsMeasure<UniformGrid>(RowsProperty, ColumnsProperty, FirstColumnProperty);
}
/// <summary> /// <summary>
/// Specifies the row count. If set to 0, row count will be calculated automatically. /// Specifies the row count. If set to 0, row count will be calculated automatically.
/// </summary> /// </summary>

5
src/Avalonia.Controls/ProgressBar.cs

@ -2,6 +2,7 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Layout; using Avalonia.Layout;
@ -38,8 +39,8 @@ namespace Avalonia.Controls
PseudoClass<ProgressBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); PseudoClass<ProgressBar, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
PseudoClass<ProgressBar>(IsIndeterminateProperty, ":indeterminate"); PseudoClass<ProgressBar>(IsIndeterminateProperty, ":indeterminate");
ValueProperty.Changed.AddClassHandler<ProgressBar>(x => x.UpdateIndicatorWhenPropChanged); ValueProperty.Changed.AddClassHandler<ProgressBar>((x, e) => x.UpdateIndicatorWhenPropChanged(e));
IsIndeterminateProperty.Changed.AddClassHandler<ProgressBar>(x => x.UpdateIndicatorWhenPropChanged); IsIndeterminateProperty.Changed.AddClassHandler<ProgressBar>((x, e) => x.UpdateIndicatorWhenPropChanged(e));
} }
public bool IsIndeterminate public bool IsIndeterminate

4
src/Avalonia.Controls/RepeatButton.cs

@ -98,10 +98,10 @@ namespace Avalonia.Controls
{ {
base.OnPointerReleased(e); base.OnPointerReleased(e);
if (e.MouseButton == MouseButton.Left) if (e.InitialPressMouseButton == MouseButton.Left)
{ {
StopTimer(); StopTimer();
} }
} }
} }
} }

4
src/Avalonia.Controls/ScrollViewer.cs

@ -163,8 +163,8 @@ namespace Avalonia.Controls
{ {
AffectsValidation(ExtentProperty, OffsetProperty); AffectsValidation(ExtentProperty, OffsetProperty);
AffectsValidation(ViewportProperty, OffsetProperty); AffectsValidation(ViewportProperty, OffsetProperty);
HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged); HorizontalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>((x, e) => x.ScrollBarVisibilityChanged(e));
VerticalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>(x => x.ScrollBarVisibilityChanged); VerticalScrollBarVisibilityProperty.Changed.AddClassHandler<ScrollViewer>((x, e) => x.ScrollBarVisibilityChanged(e));
} }
/// <summary> /// <summary>

6
src/Avalonia.Controls/Slider.cs

@ -45,9 +45,9 @@ namespace Avalonia.Controls
OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal); OrientationProperty.OverrideDefaultValue(typeof(Slider), Orientation.Horizontal);
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical"); PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Vertical, ":vertical");
PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal"); PseudoClass<Slider, Orientation>(OrientationProperty, o => o == Orientation.Horizontal, ":horizontal");
Thumb.DragStartedEvent.AddClassHandler<Slider>(x => x.OnThumbDragStarted, RoutingStrategies.Bubble); Thumb.DragStartedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
Thumb.DragDeltaEvent.AddClassHandler<Slider>(x => x.OnThumbDragDelta, RoutingStrategies.Bubble); Thumb.DragDeltaEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragDelta(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<Slider>(x => x.OnThumbDragCompleted, RoutingStrategies.Bubble); Thumb.DragCompletedEvent.AddClassHandler<Slider>((x, e) => x.OnThumbDragCompleted(e), RoutingStrategies.Bubble);
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/TabControl.cs

@ -196,7 +196,7 @@ namespace Avalonia.Controls
protected override void OnPointerReleased(PointerReleasedEventArgs e) protected override void OnPointerReleased(PointerReleasedEventArgs e)
{ {
if (e.MouseButton == MouseButton.Left && e.Pointer.Type != PointerType.Mouse) if (e.InitialPressMouseButton == MouseButton.Left && e.Pointer.Type != PointerType.Mouse)
{ {
var container = GetContainerFromEventSource(e.Source); var container = GetContainerFromEventSource(e.Source);
if (container != null if (container != null

4
src/Avalonia.Controls/TabItem.cs

@ -30,8 +30,8 @@ namespace Avalonia.Controls
{ {
SelectableMixin.Attach<TabItem>(IsSelectedProperty); SelectableMixin.Attach<TabItem>(IsSelectedProperty);
FocusableProperty.OverrideDefaultValue(typeof(TabItem), true); FocusableProperty.OverrideDefaultValue(typeof(TabItem), true);
IsSelectedProperty.Changed.AddClassHandler<TabItem>(x => x.UpdateSelectedContent); IsSelectedProperty.Changed.AddClassHandler<TabItem>((x, e) => x.UpdateSelectedContent(e));
DataContextProperty.Changed.AddClassHandler<TabItem>(x => x.UpdateHeader); DataContextProperty.Changed.AddClassHandler<TabItem>((x, e) => x.UpdateHeader(e));
} }
/// <summary> /// <summary>

8
src/Avalonia.Controls/TopLevel.cs

@ -271,7 +271,7 @@ namespace Avalonia.Controls
{ {
(this as IInputRoot).MouseDevice?.TopLevelClosed(this); (this as IInputRoot).MouseDevice?.TopLevelClosed(this);
PlatformImpl = null; PlatformImpl = null;
Closed?.Invoke(this, EventArgs.Empty); OnClosed(EventArgs.Empty);
Renderer?.Dispose(); Renderer?.Dispose();
Renderer = null; Renderer = null;
} }
@ -317,6 +317,12 @@ namespace Avalonia.Controls
/// <param name="e">The event args.</param> /// <param name="e">The event args.</param>
protected virtual void OnOpened(EventArgs e) => Opened?.Invoke(this, e); protected virtual void OnOpened(EventArgs e) => Opened?.Invoke(this, e);
/// <summary>
/// Raises the <see cref="Closed"/> event.
/// </summary>
/// <param name="e">The event args.</param>
protected virtual void OnClosed(EventArgs e) => Closed?.Invoke(this, e);
/// <summary> /// <summary>
/// Tries to get a service from an <see cref="IAvaloniaDependencyResolver"/>, logging a /// Tries to get a service from an <see cref="IAvaloniaDependencyResolver"/>, logging a
/// warning if not found. /// warning if not found.

2
src/Avalonia.Controls/TreeViewItem.cs

@ -54,7 +54,7 @@ namespace Avalonia.Controls
SelectableMixin.Attach<TreeViewItem>(IsSelectedProperty); SelectableMixin.Attach<TreeViewItem>(IsSelectedProperty);
FocusableProperty.OverrideDefaultValue<TreeViewItem>(true); FocusableProperty.OverrideDefaultValue<TreeViewItem>(true);
ItemsPanelProperty.OverrideDefaultValue<TreeViewItem>(DefaultPanel); ItemsPanelProperty.OverrideDefaultValue<TreeViewItem>(DefaultPanel);
RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>(x => x.OnRequestBringIntoView); RequestBringIntoViewEvent.AddClassHandler<TreeViewItem>((x, e) => x.OnRequestBringIntoView(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Controls/Utils/SelectingItemsControlSelectionAdapter.cs

@ -178,7 +178,7 @@ namespace Avalonia.Controls.Utils
/// <param name="e">The event data.</param> /// <param name="e">The event data.</param>
private void OnSelectorPointerReleased(object sender, PointerReleasedEventArgs e) private void OnSelectorPointerReleased(object sender, PointerReleasedEventArgs e)
{ {
if (e.MouseButton == MouseButton.Left) if (e.InitialPressMouseButton == MouseButton.Left)
{ {
OnCommit(); OnCommit();
} }

8
src/Avalonia.Controls/Window.cs

@ -261,13 +261,13 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Starts moving a window with left button being held. Should be called from left mouse button press event handler /// Starts moving a window with left button being held. Should be called from left mouse button press event handler
/// </summary> /// </summary>
public void BeginMoveDrag() => PlatformImpl?.BeginMoveDrag(); public void BeginMoveDrag(PointerPressedEventArgs e) => PlatformImpl?.BeginMoveDrag(e);
/// <summary> /// <summary>
/// Starts resizing a window. This function is used if an application has window resizing controls. /// Starts resizing a window. This function is used if an application has window resizing controls.
/// Should be called from left mouse button press event handler /// Should be called from left mouse button press event handler
/// </summary> /// </summary>
public void BeginResizeDrag(WindowEdge edge) => PlatformImpl?.BeginResizeDrag(edge); public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e) => PlatformImpl?.BeginResizeDrag(edge, e);
/// <summary> /// <summary>
/// Carries out the arrange pass of the window. /// Carries out the arrange pass of the window.
@ -557,7 +557,7 @@ namespace Avalonia.Controls
return result; return result;
} }
protected override void HandleClosed() protected sealed override void HandleClosed()
{ {
RaiseEvent(new RoutedEventArgs(WindowClosedEvent)); RaiseEvent(new RoutedEventArgs(WindowClosedEvent));
@ -565,7 +565,7 @@ namespace Avalonia.Controls
} }
/// <inheritdoc/> /// <inheritdoc/>
protected override void HandleResized(Size clientSize) protected sealed override void HandleResized(Size clientSize)
{ {
if (!AutoSizing) if (!AutoSizing)
{ {

2
src/Avalonia.Controls/WindowBase.cs

@ -47,7 +47,7 @@ namespace Avalonia.Controls
static WindowBase() static WindowBase()
{ {
IsVisibleProperty.OverrideDefaultValue<WindowBase>(false); IsVisibleProperty.OverrideDefaultValue<WindowBase>(false);
IsVisibleProperty.Changed.AddClassHandler<WindowBase>(x => x.IsVisibleChanged); IsVisibleProperty.Changed.AddClassHandler<WindowBase>((x,e) => x.IsVisibleChanged(e));
TopmostProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetTopmost((bool)e.NewValue)); TopmostProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetTopmost((bool)e.NewValue));

5
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@ -2,6 +2,7 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Remote.Server; using Avalonia.Controls.Remote.Server;
using Avalonia.Input;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Remote.Protocol; using Avalonia.Remote.Protocol;
using Avalonia.Remote.Protocol.Viewport; using Avalonia.Remote.Protocol.Viewport;
@ -27,11 +28,11 @@ namespace Avalonia.DesignerSupport.Remote
{ {
} }
public void BeginMoveDrag() public void BeginMoveDrag(PointerPressedEventArgs e)
{ {
} }
public void BeginResizeDrag(WindowEdge edge) public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{ {
} }

14
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@ -46,7 +46,7 @@ namespace Avalonia.DesignerSupport.Remote
Resize(size); Resize(size);
})); }));
} }
public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer(root); public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer(root);
public void Dispose() public void Dispose()
{ {
@ -75,11 +75,11 @@ namespace Avalonia.DesignerSupport.Remote
{ {
} }
public void BeginMoveDrag() public void BeginMoveDrag(PointerPressedEventArgs e)
{ {
} }
public void BeginResizeDrag(WindowEdge edge) public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{ {
} }
@ -93,7 +93,7 @@ namespace Avalonia.DesignerSupport.Remote
public void Move(PixelPoint point) public void Move(PixelPoint point)
{ {
} }
public IScreenImpl Screen { get; } = new ScreenStub(); public IScreenImpl Screen { get; } = new ScreenStub();
@ -153,7 +153,7 @@ namespace Avalonia.DesignerSupport.Remote
{ {
public void Save(Stream outputStream) public void Save(Stream outputStream)
{ {
} }
} }
@ -167,10 +167,10 @@ namespace Avalonia.DesignerSupport.Remote
class SystemDialogsStub : ISystemDialogImpl class SystemDialogsStub : ISystemDialogImpl
{ {
public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) => public Task<string[]> ShowFileDialogAsync(FileDialog dialog, IWindowImpl parent) =>
Task.FromResult((string[]) null); Task.FromResult((string[])null);
public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) => public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent) =>
Task.FromResult((string) null); Task.FromResult((string)null);
} }
class ScreenStub : IScreenImpl class ScreenStub : IScreenImpl

2
src/Avalonia.Input/Gestures.cs

@ -97,7 +97,7 @@ namespace Avalonia.Input
if (s_lastPress.TryGetTarget(out var target) && target == e.Source) if (s_lastPress.TryGetTarget(out var target) && target == e.Source)
{ {
var et = e.MouseButton != MouseButton.Right ? TappedEvent : RightTappedEvent; var et = e.InitialPressMouseButton != MouseButton.Right ? TappedEvent : RightTappedEvent;
e.Source.RaiseEvent(new RoutedEventArgs(et)); e.Source.RaiseEvent(new RoutedEventArgs(et));
} }
} }

24
src/Avalonia.Input/InputElement.cs

@ -169,18 +169,18 @@ namespace Avalonia.Input
{ {
IsEnabledProperty.Changed.Subscribe(IsEnabledChanged); IsEnabledProperty.Changed.Subscribe(IsEnabledChanged);
GotFocusEvent.AddClassHandler<InputElement>(x => x.OnGotFocus); GotFocusEvent.AddClassHandler<InputElement>((x, e) => x.OnGotFocus(e));
LostFocusEvent.AddClassHandler<InputElement>(x => x.OnLostFocus); LostFocusEvent.AddClassHandler<InputElement>((x, e) => x.OnLostFocus(e));
KeyDownEvent.AddClassHandler<InputElement>(x => x.OnKeyDown); KeyDownEvent.AddClassHandler<InputElement>((x, e) => x.OnKeyDown(e));
KeyUpEvent.AddClassHandler<InputElement>(x => x.OnKeyUp); KeyUpEvent.AddClassHandler<InputElement>((x, e) => x.OnKeyUp(e));
TextInputEvent.AddClassHandler<InputElement>(x => x.OnTextInput); TextInputEvent.AddClassHandler<InputElement>((x, e) => x.OnTextInput(e));
PointerEnterEvent.AddClassHandler<InputElement>(x => x.OnPointerEnterCore); PointerEnterEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerEnterCore(e));
PointerLeaveEvent.AddClassHandler<InputElement>(x => x.OnPointerLeaveCore); PointerLeaveEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerLeaveCore(e));
PointerMovedEvent.AddClassHandler<InputElement>(x => x.OnPointerMoved); PointerMovedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerMoved(e));
PointerPressedEvent.AddClassHandler<InputElement>(x => x.OnPointerPressed); PointerPressedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerPressed(e));
PointerReleasedEvent.AddClassHandler<InputElement>(x => x.OnPointerReleased); PointerReleasedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerReleased(e));
PointerCaptureLostEvent.AddClassHandler<InputElement>(x => x.OnPointerCaptureLost); PointerCaptureLostEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerCaptureLost(e));
PointerWheelChangedEvent.AddClassHandler<InputElement>(x => x.OnPointerWheelChanged); PointerWheelChangedEvent.AddClassHandler<InputElement>((x, e) => x.OnPointerWheelChanged(e));
PseudoClass<InputElement, bool>(IsEffectivelyEnabledProperty, x => !x, ":disabled"); PseudoClass<InputElement, bool>(IsEffectivelyEnabledProperty, x => !x, ":disabled");
PseudoClass<InputElement>(IsFocusedProperty, ":focus"); PseudoClass<InputElement>(IsFocusedProperty, ":focus");

5
src/Avalonia.Input/MouseDevice.cs

@ -221,7 +221,7 @@ namespace Avalonia.Input
_lastClickTime = timestamp; _lastClickTime = timestamp;
_lastClickRect = new Rect(p, new Size()) _lastClickRect = new Rect(p, new Size())
.Inflate(new Thickness(settings.DoubleClickSize.Width / 2, settings.DoubleClickSize.Height / 2)); .Inflate(new Thickness(settings.DoubleClickSize.Width / 2, settings.DoubleClickSize.Height / 2));
_lastMouseDownButton = properties.GetObsoleteMouseButton(); _lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton();
var e = new PointerPressedEventArgs(source, _pointer, root, p, timestamp, properties, inputModifiers, _clickCount); var e = new PointerPressedEventArgs(source, _pointer, root, p, timestamp, properties, inputModifiers, _clickCount);
source.RaiseEvent(e); source.RaiseEvent(e);
return e.Handled; return e.Handled;
@ -267,7 +267,8 @@ namespace Avalonia.Input
if (hit != null) if (hit != null)
{ {
var source = GetSource(hit); var source = GetSource(hit);
var e = new PointerReleasedEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers); var e = new PointerReleasedEventArgs(source, _pointer, root, p, timestamp, props, inputModifiers,
_lastMouseDownButton);
source?.RaiseEvent(e); source?.RaiseEvent(e);
_pointer.Capture(null); _pointer.Capture(null);

29
src/Avalonia.Input/PointerEventArgs.cs

@ -88,9 +88,20 @@ namespace Avalonia.Input
return _rootVisualPosition * _rootVisual.TransformToVisual(relativeTo) ?? default; return _rootVisualPosition * _rootVisual.TransformToVisual(relativeTo) ?? default;
} }
public PointerPoint GetPointerPoint(IVisual relativeTo) [Obsolete("Use GetCurrentPoint")]
public PointerPoint GetPointerPoint(IVisual relativeTo) => GetCurrentPoint(relativeTo);
/// <summary>
/// Returns the PointerPoint associated with the current event
/// </summary>
/// <param name="relativeTo">The visual which coordinate system to use. Pass null for toplevel coordinate system</param>
/// <returns></returns>
public PointerPoint GetCurrentPoint(IVisual relativeTo)
=> new PointerPoint(Pointer, GetPosition(relativeTo), _properties); => new PointerPoint(Pointer, GetPosition(relativeTo), _properties);
/// <summary>
/// Returns the current pointer point properties
/// </summary>
protected PointerPointProperties Properties => _properties; protected PointerPointProperties Properties => _properties;
} }
@ -124,7 +135,7 @@ namespace Avalonia.Input
public int ClickCount => _obsoleteClickCount; public int ClickCount => _obsoleteClickCount;
[Obsolete("Use PointerUpdateKind")] [Obsolete("Use PointerUpdateKind")]
public MouseButton MouseButton => Properties.GetObsoleteMouseButton(); public MouseButton MouseButton => Properties.PointerUpdateKind.GetMouseButton();
} }
public class PointerReleasedEventArgs : PointerEventArgs public class PointerReleasedEventArgs : PointerEventArgs
@ -132,15 +143,21 @@ namespace Avalonia.Input
public PointerReleasedEventArgs( public PointerReleasedEventArgs(
IInteractive source, IPointer pointer, IInteractive source, IPointer pointer,
IVisual rootVisual, Point rootVisualPosition, ulong timestamp, IVisual rootVisual, Point rootVisualPosition, ulong timestamp,
PointerPointProperties properties, KeyModifiers modifiers) PointerPointProperties properties, KeyModifiers modifiers,
MouseButton initialPressMouseButton)
: base(InputElement.PointerReleasedEvent, source, pointer, rootVisual, rootVisualPosition, : base(InputElement.PointerReleasedEvent, source, pointer, rootVisual, rootVisualPosition,
timestamp, properties, modifiers) timestamp, properties, modifiers)
{ {
InitialPressMouseButton = initialPressMouseButton;
} }
[Obsolete("Use PointerUpdateKind")] /// <summary>
public MouseButton MouseButton => Properties.GetObsoleteMouseButton(); /// Gets the mouse button that triggered the corresponding PointerPressed event
/// </summary>
public MouseButton InitialPressMouseButton { get; }
[Obsolete("Either use GetCurrentPoint(this).Properties.PointerUpdateKind or InitialPressMouseButton, see https://github.com/AvaloniaUI/Avalonia/wiki/Pointer-events-in-0.9 for more details", true)]
public MouseButton MouseButton => InitialPressMouseButton;
} }
public class PointerCaptureLostEventArgs : RoutedEventArgs public class PointerCaptureLostEventArgs : RoutedEventArgs

25
src/Avalonia.Input/PointerPoint.cs

@ -49,17 +49,6 @@ namespace Avalonia.Input
} }
public static PointerPointProperties None { get; } = new PointerPointProperties(); public static PointerPointProperties None { get; } = new PointerPointProperties();
public MouseButton GetObsoleteMouseButton()
{
if (PointerUpdateKind == PointerUpdateKind.LeftButtonPressed || PointerUpdateKind == PointerUpdateKind.LeftButtonReleased)
return MouseButton.Left;
if (PointerUpdateKind == PointerUpdateKind.MiddleButtonPressed || PointerUpdateKind == PointerUpdateKind.MiddleButtonReleased)
return MouseButton.Middle;
if (PointerUpdateKind == PointerUpdateKind.RightButtonPressed || PointerUpdateKind == PointerUpdateKind.RightButtonReleased)
return MouseButton.Right;
return MouseButton.None;
}
} }
public enum PointerUpdateKind public enum PointerUpdateKind
@ -72,4 +61,18 @@ namespace Avalonia.Input
RightButtonReleased, RightButtonReleased,
Other Other
} }
public static class PointerUpdateKindExtensions
{
public static MouseButton GetMouseButton(this PointerUpdateKind kind)
{
if (kind == PointerUpdateKind.LeftButtonPressed || kind == PointerUpdateKind.LeftButtonReleased)
return MouseButton.Left;
if (kind == PointerUpdateKind.MiddleButtonPressed || kind == PointerUpdateKind.MiddleButtonReleased)
return MouseButton.Middle;
if (kind == PointerUpdateKind.RightButtonPressed || kind == PointerUpdateKind.RightButtonReleased)
return MouseButton.Right;
return MouseButton.None;
}
}
} }

2
src/Avalonia.Input/TouchDevice.cs

@ -60,7 +60,7 @@ namespace Avalonia.Input
args.Root, args.Position, ev.Timestamp, args.Root, args.Position, ev.Timestamp,
new PointerPointProperties(GetModifiers(args.InputModifiers, false), new PointerPointProperties(GetModifiers(args.InputModifiers, false),
PointerUpdateKind.LeftButtonReleased), PointerUpdateKind.LeftButtonReleased),
GetKeyModifiers(args.InputModifiers))); GetKeyModifiers(args.InputModifiers), MouseButton.Left));
} }
} }

30
src/Avalonia.Interactivity/RoutedEvent.cs

@ -113,24 +113,38 @@ namespace Avalonia.Interactivity
Contract.Requires<ArgumentNullException>(ownerType != null); Contract.Requires<ArgumentNullException>(ownerType != null);
} }
[Obsolete("Use overload taking Action<TTarget, TEventArgs>.")]
public IDisposable AddClassHandler<TTarget>( public IDisposable AddClassHandler<TTarget>(
Func<TTarget, Action<TEventArgs>> handler, Func<TTarget, Action<TEventArgs>> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false) bool handledEventsToo = false)
where TTarget : class, IInteractive where TTarget : class, IInteractive
{ {
EventHandler<RoutedEventArgs> adapter = (sender, e) => void Adapter(object sender, RoutedEventArgs e)
{ {
var target = sender as TTarget; if (sender is TTarget target && e is TEventArgs args)
var args = e as TEventArgs;
if (target != null && args != null)
{ {
handler(target)(args); handler(target)(args);
} }
}; }
return AddClassHandler(typeof(TTarget), Adapter, routes, handledEventsToo);
}
public IDisposable AddClassHandler<TTarget>(
Action<TTarget, TEventArgs> handler,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false) where TTarget : class, IInteractive
{
void Adapter(object sender, RoutedEventArgs e)
{
if (sender is TTarget target && e is TEventArgs args)
{
handler(target, args);
}
}
return AddClassHandler(typeof(TTarget), adapter, routes, handledEventsToo); return AddClassHandler(typeof(TTarget), Adapter, routes, handledEventsToo);
} }
} }
} }

142
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@ -5,12 +5,89 @@ using System.Linq;
using System.Text; using System.Text;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
using Avalonia.Platform.Interop; using Avalonia.Platform.Interop;
using Avalonia.Threading; using Avalonia.Threading;
namespace Avalonia.Native namespace Avalonia.Native
{ {
enum OsxUnicodeSpecialKey
{
NSUpArrowFunctionKey = 0xF700,
NSDownArrowFunctionKey = 0xF701,
NSLeftArrowFunctionKey = 0xF702,
NSRightArrowFunctionKey = 0xF703,
NSF1FunctionKey = 0xF704,
NSF2FunctionKey = 0xF705,
NSF3FunctionKey = 0xF706,
NSF4FunctionKey = 0xF707,
NSF5FunctionKey = 0xF708,
NSF6FunctionKey = 0xF709,
NSF7FunctionKey = 0xF70A,
NSF8FunctionKey = 0xF70B,
NSF9FunctionKey = 0xF70C,
NSF10FunctionKey = 0xF70D,
NSF11FunctionKey = 0xF70E,
NSF12FunctionKey = 0xF70F,
NSF13FunctionKey = 0xF710,
NSF14FunctionKey = 0xF711,
NSF15FunctionKey = 0xF712,
NSF16FunctionKey = 0xF713,
NSF17FunctionKey = 0xF714,
NSF18FunctionKey = 0xF715,
NSF19FunctionKey = 0xF716,
NSF20FunctionKey = 0xF717,
NSF21FunctionKey = 0xF718,
NSF22FunctionKey = 0xF719,
NSF23FunctionKey = 0xF71A,
NSF24FunctionKey = 0xF71B,
NSF25FunctionKey = 0xF71C,
NSF26FunctionKey = 0xF71D,
NSF27FunctionKey = 0xF71E,
NSF28FunctionKey = 0xF71F,
NSF29FunctionKey = 0xF720,
NSF30FunctionKey = 0xF721,
NSF31FunctionKey = 0xF722,
NSF32FunctionKey = 0xF723,
NSF33FunctionKey = 0xF724,
NSF34FunctionKey = 0xF725,
NSF35FunctionKey = 0xF726,
NSInsertFunctionKey = 0xF727,
NSDeleteFunctionKey = 0xF728,
NSHomeFunctionKey = 0xF729,
NSBeginFunctionKey = 0xF72A,
NSEndFunctionKey = 0xF72B,
NSPageUpFunctionKey = 0xF72C,
NSPageDownFunctionKey = 0xF72D,
NSPrintScreenFunctionKey = 0xF72E,
NSScrollLockFunctionKey = 0xF72F,
NSPauseFunctionKey = 0xF730,
NSSysReqFunctionKey = 0xF731,
NSBreakFunctionKey = 0xF732,
NSResetFunctionKey = 0xF733,
NSStopFunctionKey = 0xF734,
NSMenuFunctionKey = 0xF735,
NSUserFunctionKey = 0xF736,
NSSystemFunctionKey = 0xF737,
NSPrintFunctionKey = 0xF738,
NSClearLineFunctionKey = 0xF739,
NSClearDisplayFunctionKey = 0xF73A,
NSInsertLineFunctionKey = 0xF73B,
NSDeleteLineFunctionKey = 0xF73C,
NSInsertCharFunctionKey = 0xF73D,
NSDeleteCharFunctionKey = 0xF73E,
NSPrevFunctionKey = 0xF73F,
NSNextFunctionKey = 0xF740,
NSSelectFunctionKey = 0xF741,
NSExecuteFunctionKey = 0xF742,
NSUndoFunctionKey = 0xF743,
NSRedoFunctionKey = 0xF744,
NSFindFunctionKey = 0xF745,
NSHelpFunctionKey = 0xF746,
NSModeSwitchFunctionKey = 0xF747
}
public class MenuActionCallback : CallbackBase, IAvnActionCallback public class MenuActionCallback : CallbackBase, IAvnActionCallback
{ {
private Action _action; private Action _action;
@ -50,6 +127,57 @@ namespace Avalonia.Native
private IAvnWindow _nativeWindow; private IAvnWindow _nativeWindow;
private List<NativeMenuItem> _menuItems = new List<NativeMenuItem>(); private List<NativeMenuItem> _menuItems = new List<NativeMenuItem>();
private static Dictionary<Key, OsxUnicodeSpecialKey> osxKeys = new Dictionary<Key, OsxUnicodeSpecialKey>
{
{Key.Up, OsxUnicodeSpecialKey.NSUpArrowFunctionKey },
{Key.Down, OsxUnicodeSpecialKey.NSDownArrowFunctionKey },
{Key.Left, OsxUnicodeSpecialKey.NSLeftArrowFunctionKey },
{Key.Right, OsxUnicodeSpecialKey.NSRightArrowFunctionKey },
{ Key.F1, OsxUnicodeSpecialKey.NSF1FunctionKey },
{ Key.F2, OsxUnicodeSpecialKey.NSF2FunctionKey },
{ Key.F3, OsxUnicodeSpecialKey.NSF3FunctionKey },
{ Key.F4, OsxUnicodeSpecialKey.NSF4FunctionKey },
{ Key.F5, OsxUnicodeSpecialKey.NSF5FunctionKey },
{ Key.F6, OsxUnicodeSpecialKey.NSF6FunctionKey },
{ Key.F7, OsxUnicodeSpecialKey.NSF7FunctionKey },
{ Key.F8, OsxUnicodeSpecialKey.NSF8FunctionKey },
{ Key.F9, OsxUnicodeSpecialKey.NSF9FunctionKey },
{ Key.F10, OsxUnicodeSpecialKey.NSF10FunctionKey },
{ Key.F11, OsxUnicodeSpecialKey.NSF11FunctionKey },
{ Key.F12, OsxUnicodeSpecialKey.NSF12FunctionKey },
{ Key.F13, OsxUnicodeSpecialKey.NSF13FunctionKey },
{ Key.F14, OsxUnicodeSpecialKey.NSF14FunctionKey },
{ Key.F15, OsxUnicodeSpecialKey.NSF15FunctionKey },
{ Key.F16, OsxUnicodeSpecialKey.NSF16FunctionKey },
{ Key.F17, OsxUnicodeSpecialKey.NSF17FunctionKey },
{ Key.F18, OsxUnicodeSpecialKey.NSF18FunctionKey },
{ Key.F19, OsxUnicodeSpecialKey.NSF19FunctionKey },
{ Key.F20, OsxUnicodeSpecialKey.NSF20FunctionKey },
{ Key.F21, OsxUnicodeSpecialKey.NSF21FunctionKey },
{ Key.F22, OsxUnicodeSpecialKey.NSF22FunctionKey },
{ Key.F23, OsxUnicodeSpecialKey.NSF23FunctionKey },
{ Key.F24, OsxUnicodeSpecialKey.NSF24FunctionKey },
{ Key.Insert, OsxUnicodeSpecialKey.NSInsertFunctionKey },
{ Key.Delete, OsxUnicodeSpecialKey.NSDeleteFunctionKey },
{ Key.Home, OsxUnicodeSpecialKey.NSHomeFunctionKey },
//{ Key.Begin, OsxUnicodeSpecialKey.NSBeginFunctionKey },
{ Key.End, OsxUnicodeSpecialKey.NSEndFunctionKey },
{ Key.PageUp, OsxUnicodeSpecialKey.NSPageUpFunctionKey },
{ Key.PageDown, OsxUnicodeSpecialKey.NSPageDownFunctionKey },
{ Key.PrintScreen, OsxUnicodeSpecialKey.NSPrintScreenFunctionKey },
{ Key.Scroll, OsxUnicodeSpecialKey.NSScrollLockFunctionKey },
//{ Key.SysReq, OsxUnicodeSpecialKey.NSSysReqFunctionKey },
//{ Key.Break, OsxUnicodeSpecialKey.NSBreakFunctionKey },
//{ Key.Reset, OsxUnicodeSpecialKey.NSResetFunctionKey },
//{ Key.Stop, OsxUnicodeSpecialKey.NSStopFunctionKey },
//{ Key.Menu, OsxUnicodeSpecialKey.NSMenuFunctionKey },
//{ Key.UserFunction, OsxUnicodeSpecialKey.NSUserFunctionKey },
//{ Key.SystemFunction, OsxUnicodeSpecialKey.NSSystemFunctionKey },
{ Key.Print, OsxUnicodeSpecialKey.NSPrintFunctionKey },
//{ Key.ClearLine, OsxUnicodeSpecialKey.NSClearLineFunctionKey },
//{ Key.ClearDisplay, OsxUnicodeSpecialKey.NSClearDisplayFunctionKey },
};
public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory) public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory)
{ {
_factory = factory; _factory = factory;
@ -147,6 +275,18 @@ namespace Avalonia.Native
} }
} }
private static string ConvertOSXSpecialKeyCodes(Key key)
{
if (osxKeys.ContainsKey(key))
{
return ((char)osxKeys[key]).ToString();
}
else
{
return key.ToString().ToLower();
}
}
private void SetChildren(IAvnAppMenu menu, ICollection<NativeMenuItemBase> children) private void SetChildren(IAvnAppMenu menu, ICollection<NativeMenuItemBase> children)
{ {
foreach (var i in children) foreach (var i in children)
@ -164,7 +304,7 @@ namespace Avalonia.Native
if (item.Gesture != null) if (item.Gesture != null)
{ {
using (var buffer = new Utf8Buffer(item.Gesture.Key.ToString().ToLower())) using (var buffer = new Utf8Buffer(ConvertOSXSpecialKeyCodes(item.Gesture.Key)))
{ {
menuItem.SetGesture(buffer.DangerousGetHandle(), (AvnInputModifiers)item.Gesture.KeyModifiers); menuItem.SetGesture(buffer.DangerousGetHandle(), (AvnInputModifiers)item.Gesture.KeyModifiers);
} }

4
src/Avalonia.Native/WindowImplBase.cs

@ -301,7 +301,7 @@ namespace Avalonia.Native
_native.Hide(); _native.Hide();
} }
public void BeginMoveDrag() public void BeginMoveDrag(PointerPressedEventArgs e)
{ {
_native.BeginMoveDrag(); _native.BeginMoveDrag();
} }
@ -343,7 +343,7 @@ namespace Avalonia.Native
_native.SetMinMaxSize(minSize.ToAvnSize(), maxSize.ToAvnSize()); _native.SetMinMaxSize(minSize.ToAvnSize(), maxSize.ToAvnSize());
} }
public void BeginResizeDrag(WindowEdge edge) public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{ {
} }

2
src/Avalonia.Styling/StyledElement.cs

@ -73,7 +73,7 @@ namespace Avalonia
/// </summary> /// </summary>
static StyledElement() static StyledElement()
{ {
DataContextProperty.Changed.AddClassHandler<StyledElement>(x => x.OnDataContextChangedCore); DataContextProperty.Changed.AddClassHandler<StyledElement>((x,e) => x.OnDataContextChangedCore(e));
} }
/// <summary> /// <summary>

2
src/Avalonia.Visuals/Media/Geometry.cs

@ -22,7 +22,7 @@ namespace Avalonia.Media
static Geometry() static Geometry()
{ {
TransformProperty.Changed.AddClassHandler<Geometry>(x => x.TransformChanged); TransformProperty.Changed.AddClassHandler<Geometry>((x,e) => x.TransformChanged(e));
} }
/// <summary> /// <summary>

4
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@ -240,6 +240,10 @@ namespace Avalonia.Rendering.SceneGraph
} }
} }
} }
else
{
contextImpl.BeginUpdate(node).Dispose();
}
} }
private void UpdateSize(Scene scene) private void UpdateSize(Scene scene)

2
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -218,7 +218,7 @@ namespace Avalonia.Rendering.SceneGraph
if (first < _children?.Count) if (first < _children?.Count)
{ {
EnsureChildrenCreated(); EnsureChildrenCreated();
for (int i = first; i < _children.Count - first; i++) for (int i = first; i < _children.Count; i++)
{ {
_children[i].Dispose(); _children[i].Dispose();
} }

12
src/Avalonia.X11/X11Window.cs

@ -878,21 +878,23 @@ namespace Avalonia.X11
} }
void BeginMoveResize(NetWmMoveResize side) void BeginMoveResize(NetWmMoveResize side, PointerPressedEventArgs e)
{ {
var pos = GetCursorPos(_x11); var pos = GetCursorPos(_x11);
XUngrabPointer(_x11.Display, new IntPtr(0)); XUngrabPointer(_x11.Display, new IntPtr(0));
SendNetWMMessage (_x11.Atoms._NET_WM_MOVERESIZE, (IntPtr) pos.x, (IntPtr) pos.y, SendNetWMMessage (_x11.Atoms._NET_WM_MOVERESIZE, (IntPtr) pos.x, (IntPtr) pos.y,
(IntPtr) side, (IntPtr) side,
(IntPtr) 1, (IntPtr)1); // left button (IntPtr) 1, (IntPtr)1); // left button
e.Pointer.Capture(null);
} }
public void BeginMoveDrag() public void BeginMoveDrag(PointerPressedEventArgs e)
{ {
BeginMoveResize(NetWmMoveResize._NET_WM_MOVERESIZE_MOVE); BeginMoveResize(NetWmMoveResize._NET_WM_MOVERESIZE_MOVE, e);
} }
public void BeginResizeDrag(WindowEdge edge) public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{ {
var side = NetWmMoveResize._NET_WM_MOVERESIZE_CANCEL; var side = NetWmMoveResize._NET_WM_MOVERESIZE_CANCEL;
if (edge == WindowEdge.East) if (edge == WindowEdge.East)
@ -911,7 +913,7 @@ namespace Avalonia.X11
side = NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; side = NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
if (edge == WindowEdge.SouthWest) if (edge == WindowEdge.SouthWest)
side = NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; side = NetWmMoveResize._NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
BeginMoveResize(side); BeginMoveResize(side, e);
} }
public void SetTitle(string title) public void SetTitle(string title)

5
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -331,11 +331,12 @@ namespace Avalonia.Win32
ShowWindow(_showWindowState); ShowWindow(_showWindowState);
} }
public void BeginMoveDrag() public void BeginMoveDrag(PointerPressedEventArgs e)
{ {
WindowsMouseDevice.Instance.Capture(null); WindowsMouseDevice.Instance.Capture(null);
UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, UnmanagedMethods.DefWindowProc(_hwnd, (int)UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN,
new IntPtr((int)UnmanagedMethods.HitTestValues.HTCAPTION), IntPtr.Zero); new IntPtr((int)UnmanagedMethods.HitTestValues.HTCAPTION), IntPtr.Zero);
e.Pointer.Capture(null);
} }
static readonly Dictionary<WindowEdge, UnmanagedMethods.HitTestValues> EdgeDic = new Dictionary<WindowEdge, UnmanagedMethods.HitTestValues> static readonly Dictionary<WindowEdge, UnmanagedMethods.HitTestValues> EdgeDic = new Dictionary<WindowEdge, UnmanagedMethods.HitTestValues>
@ -350,7 +351,7 @@ namespace Avalonia.Win32
{WindowEdge.West, UnmanagedMethods.HitTestValues.HTLEFT} {WindowEdge.West, UnmanagedMethods.HitTestValues.HTLEFT}
}; };
public void BeginResizeDrag(WindowEdge edge) public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e)
{ {
#if USE_MANAGED_DRAG #if USE_MANAGED_DRAG
_managedDrag.BeginResizeDrag(edge, ScreenToClient(MouseDevice.Position)); _managedDrag.BeginResizeDrag(edge, ScreenToClient(MouseDevice.Position));

4
tests/Avalonia.Controls.UnitTests/Platform/DefaultMenuInteractionHandlerTests.cs

@ -18,7 +18,9 @@ namespace Avalonia.Controls.UnitTests.Platform
default); default);
static PointerReleasedEventArgs CreateReleased(IInteractive source) => new PointerReleasedEventArgs(source, static PointerReleasedEventArgs CreateReleased(IInteractive source) => new PointerReleasedEventArgs(source,
new FakePointer(), (IVisual)source, default,0, new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonReleased), default); new FakePointer(), (IVisual)source, default,0,
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonReleased),
default, MouseButton.Left);
public class TopLevel public class TopLevel
{ {

2
tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs

@ -331,7 +331,7 @@ namespace Avalonia.Interactivity.UnitTests
var target = CreateTree(ev, null, 0); var target = CreateTree(ev, null, 0);
ev.AddClassHandler<TestInteractive>(x => x.ClassHandler, RoutingStrategies.Bubble); ev.AddClassHandler<TestInteractive>((x, e) => x.ClassHandler(e), RoutingStrategies.Bubble);
var args = new RoutedEventArgs(ev, target); var args = new RoutedEventArgs(ev, target);
target.RaiseEvent(args); target.RaiseEvent(args);

3
tests/Avalonia.UnitTests/MouseTestHelper.cs

@ -86,8 +86,7 @@ namespace Avalonia.UnitTests
{ {
_pointer.Capture(null); _pointer.Capture(null);
target.RaiseEvent(new PointerReleasedEventArgs(source, _pointer, (IVisual)target, position, target.RaiseEvent(new PointerReleasedEventArgs(source, _pointer, (IVisual)target, position,
Timestamp(), props, Timestamp(), props, GetModifiers(modifiers), _pressedButton));
GetModifiers(modifiers)));
} }
else else
Move(target, source, position); Move(target, source, position);

53
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs

@ -577,6 +577,59 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
} }
} }
[Fact]
public void Should_Not_Dispose_Active_VisualNode_When_Control_Reparented_And_Child_Made_Invisible()
{
// Issue #3115
using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface))
{
StackPanel panel;
Border border1;
Border border2;
var tree = new TestRoot
{
Width = 100,
Height = 100,
Child = panel = new StackPanel
{
Children =
{
(border1 = new Border
{
Background = Brushes.Red,
}),
(border2 = new Border
{
Background = Brushes.Green,
}),
}
}
};
tree.Measure(Size.Infinity);
tree.Arrange(new Rect(tree.DesiredSize));
var scene = new Scene(tree);
var sceneBuilder = new SceneBuilder();
sceneBuilder.UpdateAll(scene);
var decorator = new Decorator();
tree.Child = null;
decorator.Child = panel;
tree.Child = decorator;
border1.IsVisible = false;
scene = scene.CloneScene();
var panelNode = (VisualNode)scene.FindNode(panel);
sceneBuilder.Update(scene, decorator);
Assert.Equal(2, panelNode.Children.Count);
Assert.False(panelNode.Children[0].Disposed);
Assert.False(panelNode.Children[1].Disposed);
}
}
[Fact] [Fact]
public void Should_Update_ClipBounds_For_Negative_Margin() public void Should_Update_ClipBounds_For_Negative_Margin()
{ {

19
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/VisualNodeTests.cs

@ -101,5 +101,24 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
node.SortChildren(scene); node.SortChildren(scene);
} }
[Fact]
public void TrimChildren_Should_Work_Correctly()
{
var parent = new VisualNode(Mock.Of<IVisual>(), null);
var child1 = new VisualNode(Mock.Of<IVisual>(), null);
var child2 = new VisualNode(Mock.Of<IVisual>(), null);
var child3 = new VisualNode(Mock.Of<IVisual>(), null);
parent.AddChild(child1);
parent.AddChild(child2);
parent.AddChild(child3);
parent.TrimChildren(2);
Assert.Equal(2, parent.Children.Count);
Assert.False(child1.Disposed);
Assert.False(child2.Disposed);
Assert.True(child3.Disposed);
}
} }
} }

Loading…
Cancel
Save