diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 6b910fc615..4e34d4b132 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -4,7 +4,6 @@ about: Create a report to help us improve Avalonia
title: ''
labels: bug
assignees: ''
-
---
**Describe the bug**
@@ -12,6 +11,7 @@ A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
+
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
@@ -24,8 +24,9 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- - OS: [e.g. Windows, Mac, Linux (State distribution)]
- - Version [e.g. 0.10.0-rc1 or 0.9.12]
+
+- OS: [e.g. Windows, Mac, Linux (State distribution)]
+- Version [e.g. 0.10.0-rc1 or 0.9.12]
**Additional context**
Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..687355d825
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,8 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Questions, Discussions, Ideas
+ url: https://github.com/AvaloniaUI/Avalonia/discussions/new
+ about: Please ask and answer questions here.
+ - name: Avalonia Community Support on Gitter
+ url: https://gitter.im/AvaloniaUI/Avalonia
+ about: Please ask and answer questions here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 11fc491ef1..5f0a04cee3 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -4,7 +4,6 @@ about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
-
---
**Is your feature request related to a problem? Please describe.**
diff --git a/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject b/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
index 319cd523ce..95a483b433 100644
--- a/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
+++ b/.ncrunch/Avalonia.MicroCom.v3.ncrunchproject
@@ -1,5 +1,3 @@
-
- True
-
+
\ No newline at end of file
diff --git a/.ncrunch/Avalonia.Win32.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.v3.ncrunchproject
index e12537d535..a764f36a24 100644
--- a/.ncrunch/Avalonia.Win32.v3.ncrunchproject
+++ b/.ncrunch/Avalonia.Win32.v3.ncrunchproject
@@ -1,5 +1,8 @@
+
+ ..\..\tools\MicroComGenerator\bin\Debug\netcoreapp3.1\**.*
+
MissingOrIgnoredProjectReference
diff --git a/.ncrunch/Direct3DInteropSample.v3.ncrunchproject b/.ncrunch/Direct3DInteropSample.v3.ncrunchproject
index e12537d535..21fcdee3a6 100644
--- a/.ncrunch/Direct3DInteropSample.v3.ncrunchproject
+++ b/.ncrunch/Direct3DInteropSample.v3.ncrunchproject
@@ -3,6 +3,7 @@
MissingOrIgnoredProjectReference
+ True
True
\ No newline at end of file
diff --git a/native/Avalonia.Native/src/OSX/Screens.mm b/native/Avalonia.Native/src/OSX/Screens.mm
index 455cfa2e41..10f698ff45 100644
--- a/native/Avalonia.Native/src/OSX/Screens.mm
+++ b/native/Avalonia.Native/src/OSX/Screens.mm
@@ -5,12 +5,6 @@ class Screens : public ComSingleObject
public:
FORWARD_IUNKNOWN()
- private:
- CGFloat PrimaryDisplayHeight()
- {
- return NSMaxY([[[NSScreen screens] firstObject] frame]);
- }
-
public:
virtual HRESULT GetScreenCount (int* ret) override
{
@@ -36,12 +30,12 @@ public:
ret->Bounds.Height = [screen frame].size.height;
ret->Bounds.Width = [screen frame].size.width;
ret->Bounds.X = [screen frame].origin.x;
- ret->Bounds.Y = PrimaryDisplayHeight() - [screen frame].origin.y - ret->Bounds.Height;
+ ret->Bounds.Y = ConvertPointY(ToAvnPoint([screen frame].origin)).Y - ret->Bounds.Height;
ret->WorkingArea.Height = [screen visibleFrame].size.height;
ret->WorkingArea.Width = [screen visibleFrame].size.width;
ret->WorkingArea.X = [screen visibleFrame].origin.x;
- ret->WorkingArea.Y = ret->Bounds.Height - [screen visibleFrame].origin.y - ret->WorkingArea.Height;
+ ret->WorkingArea.Y = ConvertPointY(ToAvnPoint([screen visibleFrame].origin)).Y - ret->WorkingArea.Height;
ret->PixelDensity = [screen backingScaleFactor];
diff --git a/native/Avalonia.Native/src/OSX/common.h b/native/Avalonia.Native/src/OSX/common.h
index 871bca086d..ea48a19874 100644
--- a/native/Avalonia.Native/src/OSX/common.h
+++ b/native/Avalonia.Native/src/OSX/common.h
@@ -34,6 +34,7 @@ extern NSApplicationActivationPolicy AvnDesiredActivationPolicy;
extern NSPoint ToNSPoint (AvnPoint p);
extern AvnPoint ToAvnPoint (NSPoint p);
extern AvnPoint ConvertPointY (AvnPoint p);
+extern CGFloat PrimaryDisplayHeight();
extern NSSize ToNSSize (AvnSize s);
#ifdef DEBUG
#define NSDebugLog(...) NSLog(__VA_ARGS__)
diff --git a/native/Avalonia.Native/src/OSX/main.mm b/native/Avalonia.Native/src/OSX/main.mm
index cd6ef73826..72f5aa0a7d 100644
--- a/native/Avalonia.Native/src/OSX/main.mm
+++ b/native/Avalonia.Native/src/OSX/main.mm
@@ -299,10 +299,14 @@ AvnPoint ToAvnPoint (NSPoint p)
AvnPoint ConvertPointY (AvnPoint p)
{
- auto sw = [NSScreen.screens objectAtIndex:0].frame;
+ auto primaryDisplayHeight = NSMaxY([[[NSScreen screens] firstObject] frame]);
- auto t = MAX(sw.origin.y, sw.origin.y + sw.size.height);
- p.Y = t - p.Y;
+ p.Y = primaryDisplayHeight - p.Y;
return p;
}
+
+CGFloat PrimaryDisplayHeight()
+{
+ return NSMaxY([[[NSScreen screens] firstObject] frame]);
+}
diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index 8419258fe9..9d49025398 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -1391,17 +1391,20 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
[super viewDidChangeBackingProperties];
}
-- (bool) ignoreUserInput
+- (bool) ignoreUserInput:(bool)trigerInputWhenDisabled
{
auto parentWindow = objc_cast([self window]);
if(parentWindow == nil || ![parentWindow shouldTryToHandleEvents])
{
- auto window = dynamic_cast(_parent.getRaw());
-
- if(window != nullptr)
+ if(trigerInputWhenDisabled)
{
- window->WindowEvents->GotInputWhenDisabled();
+ auto window = dynamic_cast(_parent.getRaw());
+
+ if(window != nullptr)
+ {
+ window->WindowEvents->GotInputWhenDisabled();
+ }
}
return TRUE;
@@ -1412,7 +1415,9 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
{
- if([self ignoreUserInput])
+ bool triggerInputWhenDisabled = type != Move;
+
+ if([self ignoreUserInput: triggerInputWhenDisabled])
{
return;
}
@@ -1578,7 +1583,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
- (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type
{
- if([self ignoreUserInput])
+ if([self ignoreUserInput: false])
{
return;
}
diff --git a/samples/ControlCatalog/Pages/ScreenPage.cs b/samples/ControlCatalog/Pages/ScreenPage.cs
index c39f414b44..4edb0f137a 100644
--- a/samples/ControlCatalog/Pages/ScreenPage.cs
+++ b/samples/ControlCatalog/Pages/ScreenPage.cs
@@ -29,7 +29,7 @@ namespace ControlCatalog.Pages
var screens = w.Screens.All;
var scaling = ((IRenderRoot)w).RenderScaling;
- var drawBrush = Brushes.Green;
+ var drawBrush = Brushes.Black;
Pen p = new Pen(drawBrush);
if (screens != null)
foreach (Screen screen in screens)
@@ -45,18 +45,16 @@ namespace ControlCatalog.Pages
screen.Bounds.Height / 10f);
Rect workingAreaRect = new Rect(screen.WorkingArea.X / 10f + Math.Abs(_leftMost), screen.WorkingArea.Y / 10f, screen.WorkingArea.Width / 10f,
screen.WorkingArea.Height / 10f);
+
context.DrawRectangle(p, boundsRect);
context.DrawRectangle(p, workingAreaRect);
-
- FormattedText text = new FormattedText()
- {
- Typeface = Typeface.Default
- };
- text.Text = $"Bounds: {screen.Bounds.Width}:{screen.Bounds.Height}";
+ var text = new FormattedText() { Typeface = new Typeface("Arial"), FontSize = 18 };
+
+ text.Text = $"Bounds: {screen.Bounds.TopLeft} {screen.Bounds.Width}:{screen.Bounds.Height}";
context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height), text);
- text.Text = $"WorkArea: {screen.WorkingArea.Width}:{screen.WorkingArea.Height}";
+ text.Text = $"WorkArea: {screen.WorkingArea.TopLeft} {screen.WorkingArea.Width}:{screen.WorkingArea.Height}";
context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 20), text);
text.Text = $"Scaling: {screen.PixelDensity * 100}%";
@@ -69,7 +67,7 @@ namespace ControlCatalog.Pages
context.DrawText(drawBrush, boundsRect.Position.WithY(boundsRect.Size.Height + 80), text);
}
- context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10, w.Bounds.Width / 10, w.Bounds.Height / 10));
+ context.DrawRectangle(p, new Rect(w.Position.X / 10f + Math.Abs(_leftMost), w.Position.Y / 10f, w.Bounds.Width / 10, w.Bounds.Height / 10));
}
}
}
diff --git a/src/Avalonia.Controls/Button.cs b/src/Avalonia.Controls/Button.cs
index 91eef3947b..c779e4b0cb 100644
--- a/src/Avalonia.Controls/Button.cs
+++ b/src/Avalonia.Controls/Button.cs
@@ -80,6 +80,7 @@ namespace Avalonia.Controls
private ICommand _command;
private bool _commandCanExecute = true;
+ private KeyGesture _hotkey;
///
/// Initializes static members of the class.
@@ -207,6 +208,11 @@ namespace Avalonia.Controls
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
+ if (_hotkey != null) // Control attached again, set Hotkey to create a hotkey manager for this control
+ {
+ HotKey = _hotkey;
+ }
+
base.OnAttachedToLogicalTree(e);
if (Command != null)
@@ -217,6 +223,13 @@ namespace Avalonia.Controls
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
+ // This will cause the hotkey manager to dispose the observer and the reference to this control
+ if (HotKey != null)
+ {
+ _hotkey = HotKey;
+ HotKey = null;
+ }
+
base.OnDetachedFromLogicalTree(e);
if (Command != null)
diff --git a/src/Avalonia.Controls/MenuItem.cs b/src/Avalonia.Controls/MenuItem.cs
index d034f54df2..2d91a2ee7e 100644
--- a/src/Avalonia.Controls/MenuItem.cs
+++ b/src/Avalonia.Controls/MenuItem.cs
@@ -102,6 +102,7 @@ namespace Avalonia.Controls
private ICommand? _command;
private bool _commandCanExecute = true;
private Popup? _popup;
+ private KeyGesture _hotkey;
///
/// Initializes static members of the class.
@@ -111,6 +112,7 @@ namespace Avalonia.Controls
SelectableMixin.Attach