-
Notifications
You must be signed in to change notification settings - Fork 729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(macOS): add native elements support for macOS/Skia #18793
Open
spouliot
wants to merge
37
commits into
master
Choose a base branch
from
dev/spouliot/macos-desktop-native-embedding
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+514
−14
Open
Changes from 35 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
66daa65
feat: Add native embedding to netXX-desktop/macOS
spouliot f13004a
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 14c0f99
chore: rework logging code
spouliot f606e5f
chore: change sample native element background to red
spouliot 4d62ae0
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 7496a4f
chore: keep a ref when attaching, drop it when detaching
spouliot bd0aae9
chore: fix flipped view and plugin svg clipping code (not yet working)
spouliot 1a55f3a
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 313e2cf
chore: fix clipping removal
spouliot 49e741c
chore: implement SVG parsing for clipping
spouliot 9ac7d6a
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot c297452
fix: fix native element visibility (reset by clipping)
spouliot dc317ea
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 12e7d07
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot daf304d
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 45ec5e5
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot d4500f1
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 619b34b
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot d7a9213
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 9cff94a
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot df15280
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 11be12e
chore: cleanup without native element clipping
spouliot c260496
chore: cleanup without native element clipping
spouliot 5b7c0fc
fix: change how we handle the keyboard
spouliot 76e4883
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot b52c713
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 2b31ad2
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 4b9f24e
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 1df5a8b
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot f80f7ff
chore: fix xcode project post merge (crashed Xcode)
spouliot 124cb84
chore: better/simpler basic clipping
spouliot 84d13cf
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot 026226b
fix(macOS): native clip on the provided path/svg
spouliot 610789c
chore: fix UnoNativeMac.xcodeproj/project.pbxproj
spouliot bd3d611
Merge branch 'master' into dev/spouliot/macos-desktop-native-embedding
spouliot f20b0b8
fix: reverse clip and set fillrule to oddeven
spouliot ab73de5
fix: parse floating point values in svg path
spouliot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
157 changes: 157 additions & 0 deletions
157
src/Uno.UI.Runtime.Skia.MacOS/MacOSNativeElementHostingExtension.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
#nullable enable | ||
|
||
using Windows.Foundation; | ||
using Windows.UI.Core; | ||
using Microsoft.UI.Xaml.Controls; | ||
|
||
using Uno.Foundation.Extensibility; | ||
using Uno.Foundation.Logging; | ||
|
||
namespace Uno.UI.Runtime.Skia.MacOS; | ||
|
||
internal class MacOSNativeElement : Microsoft.UI.Xaml.FrameworkElement | ||
{ | ||
public nint NativeHandle { get; internal set; } | ||
|
||
internal bool Detached { get; set; } | ||
} | ||
|
||
internal class MacOSNativeElementHostingExtension : ContentPresenter.INativeElementHostingExtension | ||
{ | ||
private readonly ContentPresenter _presenter; | ||
Check notice on line 21 in src/Uno.UI.Runtime.Skia.MacOS/MacOSNativeElementHostingExtension.cs Codacy Production / Codacy Static Code Analysissrc/Uno.UI.Runtime.Skia.MacOS/MacOSNativeElementHostingExtension.cs#L21
|
||
private readonly MacOSWindowNative? _window; | ||
|
||
private MacOSNativeElementHostingExtension(ContentPresenter contentPresenter) | ||
{ | ||
_presenter = contentPresenter; | ||
_window = _presenter.XamlRoot?.HostWindow?.NativeWindow as MacOSWindowNative; | ||
} | ||
|
||
public static void Register() => ApiExtensibility.Register<ContentPresenter>(typeof(ContentPresenter.INativeElementHostingExtension), o => new MacOSNativeElementHostingExtension(o)); | ||
|
||
public void ArrangeNativeElement(object content, Rect arrangeRect, Rect clipRect) | ||
{ | ||
if (content is MacOSNativeElement element) | ||
{ | ||
if (element.Detached) | ||
{ | ||
this.Log().Debug($"Cannot arrange element `{nameof(content)}` of type {content.GetType().FullName} since it was detached."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe also a |
||
} | ||
else | ||
{ | ||
NativeUno.uno_native_arrange(element.NativeHandle, arrangeRect.Left, arrangeRect.Top, arrangeRect.Width, arrangeRect.Height, clipRect.Left, clipRect.Top, clipRect.Width, clipRect.Height); | ||
} | ||
} | ||
else if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"Object `{nameof(content)}` is a {content.GetType().FullName} and not a MacOSNativeElement subclass."); | ||
} | ||
} | ||
|
||
public void AttachNativeElement(object content) | ||
{ | ||
if (content is MacOSNativeElement element) | ||
{ | ||
NativeUno.uno_native_attach(element.NativeHandle); | ||
} | ||
else if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"Object `{nameof(content)}` is a {content.GetType().FullName} and not a MacOSNativeElement subclass."); | ||
} | ||
} | ||
|
||
public void ChangeNativeElementOpacity(object content, double opacity) | ||
{ | ||
if (content is MacOSNativeElement element) | ||
{ | ||
// https://developer.apple.com/documentation/appkit/nsview/1483560-alphavalue?language=objc | ||
// note: no marshaling needed as CGFloat is double for 64bits apps | ||
NativeUno.uno_native_set_opacity(element.NativeHandle, opacity); | ||
} | ||
else if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"Object `{nameof(content)}` is a {content.GetType().FullName} and not a MacOSNativeElement subclass."); | ||
} | ||
} | ||
|
||
public void ChangeNativeElementVisibility(object content, bool visible) | ||
{ | ||
if (content is MacOSNativeElement element) | ||
{ | ||
// https://developer.apple.com/documentation/appkit/nsview/1483369-hidden?language=objc | ||
NativeUno.uno_native_set_visibility(element.NativeHandle, visible); | ||
} | ||
else if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"Object `{nameof(content)}` is a {content.GetType().FullName} and not a MacOSNativeElement subclass."); | ||
} | ||
} | ||
|
||
public object? CreateSampleComponent(string text) | ||
{ | ||
if (_window is null) | ||
{ | ||
if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"CreateSampleComponent failed as no MacOSWindowNative instance could be found."); | ||
} | ||
return null; | ||
} | ||
|
||
var handle = NativeUno.uno_native_create_sample(_window.Handle, text); | ||
return new MacOSNativeElement() | ||
{ | ||
NativeHandle = handle, | ||
AccessKey = text // FIXME: debug helper, to be removed | ||
}; | ||
} | ||
|
||
public void DetachNativeElement(object content) | ||
{ | ||
if (content is MacOSNativeElement element) | ||
{ | ||
if (element.Detached) | ||
{ | ||
this.Log().Debug($"Object `{nameof(content)}` of type {content.GetType().FullName} was already detached."); | ||
} | ||
else | ||
{ | ||
NativeUno.uno_native_detach(element.NativeHandle); | ||
element.Detached = true; | ||
} | ||
} | ||
else if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"Object `{nameof(content)}` is a {content.GetType().FullName} and not a MacOSNativeElement subclass."); | ||
} | ||
} | ||
|
||
public bool IsNativeElement(object content) => content is MacOSNativeElement; | ||
|
||
public bool IsNativeElementAttached(object owner, object nativeElement) | ||
{ | ||
if (nativeElement is MacOSNativeElement element) | ||
{ | ||
return NativeUno.uno_native_is_attached(element.NativeHandle); | ||
} | ||
else if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"Object `{nameof(owner)}` is a {owner.GetType().FullName} and not a MacOSNativeElement subclass."); | ||
} | ||
return false; | ||
} | ||
|
||
public Size MeasureNativeElement(object content, Size childMeasuredSize, Size availableSize) | ||
{ | ||
if (content is MacOSNativeElement element) | ||
{ | ||
NativeUno.uno_native_measure(element.NativeHandle, childMeasuredSize.Width, childMeasuredSize.Height, availableSize.Width, availableSize.Height, out var width, out var height); | ||
return new Size(width, height); | ||
} | ||
else if (this.Log().IsEnabled(LogLevel.Debug)) | ||
{ | ||
this.Log().Debug($"Object `{nameof(content)}` is a {content.GetType().FullName} and not a MacOSNativeElement subclass."); | ||
} | ||
return Size.Empty; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/Uno.UI.Runtime.Skia.MacOS/UnoNativeMac/UnoNativeMac/UNONative.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// | ||
// UNONative.h | ||
// | ||
|
||
#pragma once | ||
|
||
#import "UnoNativeMac.h" | ||
#import "UNOWindow.h" | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@protocol UNONativeElement | ||
|
||
@property (nonatomic) bool visible; | ||
|
||
-(void) detach; | ||
|
||
@end | ||
|
||
@interface UNORedView : NSView<UNONativeElement> | ||
|
||
@end | ||
|
||
NSView* uno_native_create_sample(NSWindow *window, const char* _Nullable text); | ||
|
||
void uno_native_arrange(NSView *element, double arrangeLeft, double arrangeTop, double arrangeWidth, double arrangeHeight, double clipLeft, double clipTop, double clipWidth, double clipHeight); | ||
|
||
void uno_native_attach(NSView* element); | ||
|
||
void uno_native_detach(NSView* element); | ||
|
||
bool uno_native_is_attached(NSView* element); | ||
|
||
void uno_native_measure(NSView* element, double childWidth, double childHeight, double availableWidth, double availableHeight, double* width, double* height); | ||
|
||
void uno_native_set_opacity(NSView* element, double opacity); | ||
|
||
void uno_native_set_visibility(NSView* element, bool visible); | ||
|
||
NS_ASSUME_NONNULL_END |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heads up: I compiled SkiaSharp 3 a while ago to try it with Uno and this blew up in my face. I think they may have removed GetObject or something. The software renderer worked though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, I'll PR something to SkiaSharp so that reflection is not needed for 3.x