Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Composition and layout refactor#1318

Merged
jaredhms merged 7 commits into
microsoft:ux/uxefrom
jaredhms:compositor_refactor
Nov 9, 2016
Merged

Composition and layout refactor#1318
jaredhms merged 7 commits into
microsoft:ux/uxefrom
jaredhms:compositor_refactor

Conversation

@jaredhms

@jaredhms jaredhms commented Nov 4, 2016

Copy link
Copy Markdown
Contributor

This change refactors WinObjC's QuartzCore and UIKit stacks to align more closely with Xaml, as detailed in the docs/CoreAnimation/WinObjc.Composition.and.Layout.docx dev spec.

Some highlights include:

1.	Streamlines the usage of arbitrary Xaml FrameworkElements by allowing them to be positioned just as any other UIView in the application.
2.	Supports rendering over Xaml-backed UIKit controls; adding adornments, etc.
3.	Supports adding subviews and sublayers to Xaml-backed UIKit controls.
4.	Separates the complex details of our Core Animation composition layer into distinct and manageable subcomponents � improving maintainability.
5.	Defines a concrete relationship between every UIView, its root CALayer, and its backing Xaml FrameworkElement.
6.	Streamlines the UIElement tree by removing unnecessary UIElements (for example; this results in a ~30% reduction of UIElements on the initial scene of WOCCatalog).
7.	Simplifies app rendering by removing our two custom Panel implementations; thus eliminating the need to take part in Arrange and Measure passes.
8.	Paves the way for eventual Xaml-markup-driven UIElement trees in ported WinObjC apps, because we no longer require re-parenting Xaml FrameworkElements that are positioned by Core Animation.
9.	Moves the rest of the Core Animation composition layer over to C++, to benefit from modern programming constructs such as RAII, external ref-counting (shared_ptr), etc.

In order to implement these changes, we had to move UILabel over to a fully Xaml-backed implementation (rather than following a more complicated path with fake 'textures' down into the compositor). As a result, there are some known issues around text layout in one of our internal test apps (MM); we'll address those issues (and anything else that comes up) in a stabilization pass after these changes go in.


This change is Reviewable

…more closely with Xaml, as detailed in the docs/CoreAnimation/WinObjc.Composition.and.Layout.docx dev spec.

Some highlights include:

    1.	Streamlines the usage of arbitrary Xaml FrameworkElements by allowing them to be positioned just as any other UIView in the application.
    2.	Supports rendering over Xaml-backed UIKit controls; adding adornments, etc.
    3.	Supports adding subviews and sublayers to Xaml-backed UIKit controls.
    4.	Separates the complex details of our Core Animation composition layer into distinct and manageable subcomponents � improving maintainability.
    5.	Defines a concrete relationship between every UIView, its root CALayer, and its backing Xaml FrameworkElement.
    6.	Streamlines the UIElement tree by removing unnecessary UIElements (for example; this results in a ~30% reduction of UIElements on the initial scene of WOCCatalog).
    7.	Simplifies app rendering by removing our two custom Panel implementations; thus eliminating the need to take part in Arrange and Measure passes.
    8.	Paves the way for eventual Xaml-markup-driven UIElement trees in ported WinObjC apps, because we no longer require re-parenting Xaml FrameworkElements that are positioned by Core Animation.
    9.	Moves the rest of the Core Animation composition layer over to C++, to benefit from modern programming constructs such as RAII, external ref-counting (shared_ptr), etc.

In order to implement these changes, we had to move UILabel over to a fully Xaml-backed implementation (rather than following a more complicated path with fake 'textures' down into the compositor).  As a result, there are some known issues around text layout in one of our internal test apps (MM); we'll address those issues (and anything else that comes up) in a stabilization pass after these changes go in.
@jaredhms

jaredhms commented Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

@msft-Jeyaram is added to the review. #Closed

@jaredhms

jaredhms commented Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

@ashvarma is added to the review. #Closed

@jaredhms

jaredhms commented Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

@bviglietta is added to the review. #Closed

@bbowman

bbowman commented Nov 4, 2016

Copy link
Copy Markdown
Member

//

doesn't seem changed? #Resolved


Refers to: Frameworks/include/MockClass.h:4 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

//

just some clang-format whitespace changes....


In reply to: 258527516 [](ancestors = 258527516)


Refers to: Frameworks/include/MockClass.h:4 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

#import "CAAnimationInternal.h"
#import "CALayerInternal.h"

static const wchar_t* TAG = L"LayerTransaction";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LayerTransaction [](start = 30, length = 16)

A lot of this came from CompositorInterface.mm. #Resolved


void LayerProxy::SetTexture(const std::shared_ptr<IDisplayTexture>& texture, float width, float height, float contentScale) {
_currentTexture = texture;
_SetContents((texture ? texture->GetContent() : nullptr), width, height, contentScale);

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of this came from CompositorInterface.mm. #Resolved


_type = [type retain];
_subType = [subType retain];
beginTime = 0;

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of this came from CompositorInterface.mm; sorry it's not easy to diff. #Resolved


using namespace Microsoft::WRL;

static const wchar_t* TAG = L"DisplayTexture";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DisplayTexture [](start = 30, length = 14)

A lot of this came from CompositorInterface.mm; sorry it's not easy to diff. #Resolved


#import <algorithm>

static const wchar_t* TAG = L"DisplayProperties";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DisplayProperties [](start = 30, length = 17)

A lot of this came from CompositorInterface.mm; sorry it's not easy to diff. #Resolved

Comment thread include/UIKit/UIView.h
@@ -381,7 +381,9 @@ UIKIT_EXPORT_CLASS
// WinObjC Xaml Extensions

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dustin; I don't think we currently have an annotation for this. #Resolved

Comment thread include/UIKit/UIView.h
@class WXFrameworkElement;
@interface UIView (UIKitXamlExtensions)
@property (nonatomic, retain) WXFrameworkElement* xamlElement;
+ (WXFrameworkElement*)createXamlElement;

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't go with the 'layerClass' model here, because the types we want to create are in UIKit.Xaml and are not yet projected to ObjC. #Resolved

using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Media;

static const wchar_t* TAG = L"DisplayTexture";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DisplayTexture [](start = 30, length = 14)

A lot of this came from either CALayerXaml.cpp or XamlCompositor.cpp; sorry it's not easy to diff. #Resolved

using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Media::Imaging;

static const wchar_t* TAG = L"LayerAnimation";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LayerAnimation [](start = 30, length = 14)

A lot of this came from either CALayerXaml.cpp or XamlCompositor.cpp; sorry it's not easy to diff. #Resolved

using namespace Windows::UI::Xaml::Media::Animation;
using namespace Windows::UI::Xaml::Media::Imaging;

static const wchar_t* TAG = L"LayerCoordinator";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LayerCoordinator [](start = 30, length = 16)

A lot of this came from either CALayerXaml.cpp or XamlCompositor.cpp; sorry it's not easy to diff. #Resolved

using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Media;

static const wchar_t* TAG = L"LayerProxy";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LayerProxy [](start = 30, length = 10)

A lot of this came from either CALayerXaml.cpp or XamlCompositor.cpp; sorry it's not easy to diff. #Resolved

using namespace Windows::UI::Xaml::Media::Animation;
using namespace Windows::UI::Xaml::Media::Imaging;

static const wchar_t* TAG = L"StoryboardManager";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StoryboardManager [](start = 30, length = 17)

A lot of this came from either CALayerXaml.cpp or XamlCompositor.cpp; sorry it's not easy to diff. #Resolved


using namespace Microsoft::WRL;

static const wchar_t* TAG = L"XamlCompositor";

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XamlCompositor [](start = 30, length = 14)

This is the remains of CompositorInterface.mm. #Resolved


/**
Microsoft Extension
All CALayers are ultimately backed by a Xaml FrameworkElement. Passing nil here will

@DHowett-MSFT DHowett-MSFT Nov 4, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should push for a @status to note this, it'd be cool to show our additions in another chart area #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a good idea; i'll follow up on it.


In reply to: 86620194 [](ancestors = 86620194)

Comment thread Frameworks/QuartzCore/CALayer.mm Outdated
@Status Interoperable
*/
- (CGAffineTransform)affineTransform {
CGAffineTransform ret;

@DHowett-MSFT DHowett-MSFT Nov 4, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eTransform re [](start = 11, length = 13)

Instead of poking at these directly, you can use CGAffineTransformMake(a,b,c,d,tx,ty) #Resolved

Comment thread Frameworks/QuartzCore/CALayer.mm Outdated
// Query for our backing XAML node.
// ILayerProxy will have created one if the xamlElement passed into the previous CreateLayerProxy call was nullptr.
Microsoft::WRL::ComPtr<IInspectable> inspectable(_layerProxy->GetXamlElement());
_xamlElement = _createRtProxy([WXFrameworkElement class], inspectable.Get());

@aballway aballway Nov 4, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use createwith here? #Resolved

before ? [before _priv]->_presentationNode : NULL,
after ? [after _priv]->_presentationNode : NULL);
[self _currentLayerTransaction]->MoveLayer([layer _layerProxy],
before ? [before _layerProxy] : nullptr,

@aballway aballway Nov 4, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: shouldn't need to make ternary with messages here #ByDesign

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah: if before is nil, [nil _layerProxy] will return the right thing. Unless it's a C++ type, but really the ideal here is to do the right thing :P


In reply to: 86621323 [](ancestors = 86621323)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the compiler on the reference platform memsets an out struct pointer to 0 if the destination of the message is nil.


In reply to: 86900544 [](ancestors = 86900544,86621323)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_layerProxy returns an std::shared_ptr; not doing the nil check lead to AVs.


In reply to: 86900578 [](ancestors = 86900578,86900544,86621323)

ret = [CATransaction _implicitAnimationForKey:key];
if (ret != nil) {
NSObject* value = GetCACompositor()->getDisplayProperty(priv->_presentationNode, [key UTF8String]);
NSObject* value = reinterpret_cast<NSObject*>(priv->_layerProxy->GetPropertyValue([key UTF8String]));

@oliversa-msft oliversa-msft Nov 7, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priv->_layerProxy->GetPropertyValue [](start = 62, length = 35)

Sweet! #Resolved

@jaredhms

jaredhms commented Nov 7, 2016

Copy link
Copy Markdown
Contributor Author
    }

what code change are you referring to? I just deleted a bunch of dead code around setting the 'shouldAnimate' flag.


In reply to: 258998954 [](ancestors = 258998954)


Refers to: Frameworks/QuartzCore/CALayer.mm:1803 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)


// Get the backing sublayer xaml UIElement for fromLayer
// We use the sublayer element to support proper point conversion within a scrolled view.
WXUIElement* fromLayerElement = [fromLayer _getSublayerXamlElement];

@oliversa-msft oliversa-msft Nov 8, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WXUIElement* [](start = 4, length = 12)

Could we make this work with WXFrameworkElement instead? Just wondering if we need to keep it consistent for readability or is there something else that is used in the parent class. #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transformToVisual is on UIElement.


In reply to: 86898072 [](ancestors = 86898072)

@yiyang-msft

Copy link
Copy Markdown
Contributor

:shipit:

@oliversa-msft

oliversa-msft commented Nov 8, 2016

Copy link
Copy Markdown
Contributor

__declspec(thread) CATransaction* _curTransaction, *_rootTransaction;

Really should be prefixed with g_ #Resolved


Refers to: Frameworks/QuartzCore/CATransaction.mm:35 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@@ -36,14 +36,15 @@

@DHowett-MSFT DHowett-MSFT Nov 8, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nits about these guys:

  • __declspec(thread) objective-C things will not be properly ref-counted.
  • they're being compared against NULL (not even nullptr!) instead of nil everywhere in this file.
    #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to change this now, but I'll add a TODO in the code.


In reply to: 86900474 [](ancestors = 86900474)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author

~bad merge; good catch


In reply to: 258638949 [](ancestors = 258638949)


Refers to: Frameworks/UIKit.Xaml/ObjCXamlControls.h:75 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author

#define CACompositorRotation90CounterClockwise 270.0f

good point - these should have moved along with the rest of the DisplayProperties -- into DisplayProperties.h -- and switched to an enum.


In reply to: 258740082 [](ancestors = 258740082)


Refers to: Frameworks/include/CACompositor.h:117 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author
CGColorRef _backgroundColor, _borderColor;

there's no reason. they should all be underscored, but i'm not going to do that in this change - I don't want to unnecessarily add to the churn.


In reply to: 258966276 [](ancestors = 258966276)


Refers to: Frameworks/include/CALayerInternal.h:65 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author
CGColorRef _backgroundColor, _borderColor;

ideally they would all be private, too....so it's easier to see which state is accessed externally, but I'm not fixing that now, either.


In reply to: 259010707 [](ancestors = 259010707,258966276)


Refers to: Frameworks/include/CALayerInternal.h:65 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author
  • (void)exchangeSublayer:(CALayer_)layer1 withLayer:(CALayer_)layer2;

there are a lot of missing underscores, but I'm not going to address them with this change.


In reply to: 258967895 [](ancestors = 258967895)


Refers to: Frameworks/include/CALayerInternal.h:111 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author
  • (void)exchangeSubviewAtIndex:(int)index1 withSubviewAtIndex:(int)index2;

I'm not going to remove any more code with this change.


In reply to: 258968776 [](ancestors = 258968776)


Refers to: Frameworks/include/CALayerInternal.h:112 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author
  • (void)bringSublayerToFront:(CALayer*)sublayer;

see above; i'm not going to fix the missing underscore issue with this change.


In reply to: 258968087 [](ancestors = 258968087)


Refers to: Frameworks/include/CALayerInternal.h:114 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

@jaredhms

jaredhms commented Nov 8, 2016

Copy link
Copy Markdown
Contributor Author

CACompositorInterface* _globalCompositor;

could have, but didn't bother making that change with this refactor. it may open up additional cans of worms, and isn't necessary at this time.


In reply to: 258982393 [](ancestors = 258982393)


Refers to: Frameworks/QuartzCore/CALayer.mm:101 in ff95a9a. [](commit_id = ff95a9a, deletion_comment = False)

Comment thread Frameworks/UIKit/UIView.mm Outdated
Microsoft Extension
*/
+ (WXFrameworkElement*)createXamlElement {
// Default to CALayer's default backing Xaml element

@oliversa-msft oliversa-msft Nov 9, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Default to CALayer's default backing Xaml element [](start = 4, length = 52)

Stale comment? #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, but i'll change it to '// Use CALayer's default backing Xaml element' since i was overusing 'default' :)


In reply to: 87280021 [](ancestors = 87280021)

@oliversa-msft

oliversa-msft commented Nov 9, 2016

Copy link
Copy Markdown
Contributor
return self;

Shouldn't this one be the designated initializer and call [super init] as well? You can then pipe initWithIdentifier through it for a simple optimization of the autoResizingMask setting. #Pending


Refers to: Frameworks/UIKit/UIViewController.mm:248 in 6d10e3d. [](commit_id = 6d10e3d, deletion_comment = False)

@jaredhms

jaredhms commented Nov 9, 2016

Copy link
Copy Markdown
Contributor Author
return self;

maybe? I didn't add/change this code though.


In reply to: 259531590 [](ancestors = 259531590)


Refers to: Frameworks/UIKit/UIViewController.mm:248 in 6d10e3d. [](commit_id = 6d10e3d, deletion_comment = False)

Comment thread Frameworks/UIKit/UIViewController.mm Outdated
[_pageMappings setObject:self forKey:(id)(void*)pageObj.Get()];

// Create a template UIView
priv->_page = CreateRtProxy([WXCPage class], pageObj.Get());

@oliversa-msft oliversa-msft Nov 9, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateRtProxy [](start = 18, length = 13)

This utility function doesn't have the autorelease support. Is that intentional? #Pending

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should file a bug to get rid of CreateRtProxy. I'll move this one to createWith.


In reply to: 87281267 [](ancestors = 87281267)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also - why doesn't CreateRtProxy autorelease? Quite strange.


In reply to: 87281492 [](ancestors = 87281492,87281267)

- (instancetype)initWithFrame:(CGRect)frame {
// Run on the main thread because the underlying XAML objects can only be
// called from the UI thread
RunSynchronouslyOnMainThread(^{

@oliversa-msft oliversa-msft Nov 9, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RunSynchronouslyOnMainThread [](start = 4, length = 28)

Should we have called [super init] preceded this as well? UIView -> UIResponder -> NSObject? I noticed that UIWebView has this pattern. #Pending

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe? Although, UIView's init calls initWithFrame, which is the designated initializer for UIView. Regardless, I'd prefer to get this in before we make any more changes to UIView's init path (assuming this is functionally correct and isn't introducing any regressions).


In reply to: 87282018 [](ancestors = 87282018)

Comment thread Frameworks/UIKit.Xaml/Label.xaml.cpp Outdated

Label::Label() {
InitializeComponent();
Name = L"UILabel";

@oliversa-msft oliversa-msft Nov 9, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name = L"UILabel"; [](start = 4, length = 18)

I wonder if we did this in the other controls as well. Seems like a good idea. #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move it up to UILabel.mm so we can set the name of the actual (potentially derived) class.


In reply to: 87285187 [](ancestors = 87285187)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, it's already handled in UIView.mm, so I'll delete it from here and also from UIButton.mm.


In reply to: 87285928 [](ancestors = 87285928,87285187)

@oliversa-msft

Copy link
Copy Markdown
Contributor

:shipit:

@jaredhms jaredhms merged commit ec80479 into microsoft:ux/uxe Nov 9, 2016
@jaredhms jaredhms deleted the compositor_refactor branch November 9, 2016 22:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.