| Index: ui/accelerated_widget_mac/accelerated_widget_mac.mm
|
| diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.mm b/ui/accelerated_widget_mac/accelerated_widget_mac.mm
|
| index fc9269bd20fc1ef5e24e9ec5a773e463ba78d1a4..0c4a1438575c89fe9381c617ebf1223df0150d47 100644
|
| --- a/ui/accelerated_widget_mac/accelerated_widget_mac.mm
|
| +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.mm
|
| @@ -17,6 +17,58 @@
|
| #include "ui/gfx/geometry/dip_util.h"
|
| #include "ui/gl/scoped_cgl.h"
|
|
|
| +@interface DetachedModeWindow : NSWindow {
|
| + base::WeakPtr<ui::AcceleratedWidgetMac> accelerated_widget_mac_;
|
| + base::scoped_nsobject<NSWindow> target_window_;
|
| +}
|
| +
|
| +- (id)initWithAcceleratedWidgetMac:
|
| + (base::WeakPtr<ui::AcceleratedWidgetMac>)accelerated_widget_mac;
|
| +- (void)startForwardingEvents:(NSWindow*)target_window;
|
| +- (void)stopForwardingEvents;
|
| +@end
|
| +
|
| +@implementation DetachedModeWindow : NSWindow
|
| +- (id)initWithAcceleratedWidgetMac:
|
| + (base::WeakPtr<ui::AcceleratedWidgetMac>)accelerated_widget_mac {
|
| + if (self = [super
|
| + initWithContentRect:NSMakeRect(0, 0, 100, 100)
|
| + styleMask:NSTitledWindowMask | NSResizableWindowMask |
|
| + NSFullSizeContentViewWindowMask
|
| + backing:NSBackingStoreBuffered
|
| + defer:NO]) {
|
| + [self setReleasedWhenClosed:NO];
|
| + accelerated_widget_mac_ = accelerated_widget_mac;
|
| + return self;
|
| + }
|
| + return nil;
|
| +}
|
| +
|
| +- (void)startForwardingEvents:(NSWindow*)target_window {
|
| + target_window_.reset([target_window retain]);
|
| +}
|
| +
|
| +- (void)stopForwardingEvents {
|
| + target_window_.reset();
|
| +}
|
| +
|
| +- (void)close {
|
| + if (accelerated_widget_mac_)
|
| + accelerated_widget_mac_->DestroyDetachedModeWindow();
|
| + [super close];
|
| +}
|
| +
|
| +- (void)sendEvent:(NSEvent*)event {
|
| + // This doesn't actually fix the issue for mouse move. Eh.
|
| + if (target_window_)
|
| + [target_window_ sendEvent:event];
|
| +}
|
| +@end
|
| +
|
| +@interface NSWindowController (HorribleHack)
|
| +- (void)setDetachedVideoLayer:(base::scoped_nsobject<CALayer>)layer;
|
| +@end
|
| +
|
| @interface CALayer (PrivateAPI)
|
| - (void)setContentsChanged;
|
| @end
|
| @@ -45,7 +97,8 @@ AcceleratedWidgetMac* GetHelperFromAcceleratedWidget(
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // AcceleratedWidgetMac
|
|
|
| -AcceleratedWidgetMac::AcceleratedWidgetMac() : view_(nullptr) {
|
| +AcceleratedWidgetMac::AcceleratedWidgetMac()
|
| + : view_(nullptr), weak_factory_(this) {
|
| // Disable the fade-in animation as the layers are added.
|
| ScopedCAActionDisabler disabler;
|
|
|
| @@ -119,6 +172,8 @@ void AcceleratedWidgetMac::GetVSyncParameters(
|
| void AcceleratedWidgetMac::GotFrame(
|
| CAContextID ca_context_id,
|
| base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
|
| + bool use_detached_mode,
|
| + CAContextID detached_ca_context_id,
|
| const gfx::Size& pixel_size,
|
| float scale_factor) {
|
| TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotFrame");
|
| @@ -135,14 +190,22 @@ void AcceleratedWidgetMac::GotFrame(
|
| last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size);
|
|
|
| if (ca_context_id)
|
| - GotCAContextFrame(ca_context_id, pixel_size, scale_factor);
|
| + GotCAContextFrame(ca_context_id, use_detached_mode, detached_ca_context_id,
|
| + pixel_size, scale_factor);
|
| else
|
| GotIOSurfaceFrame(io_surface, pixel_size, scale_factor);
|
|
|
| + if (use_detached_mode)
|
| + EnterDetachedMode();
|
| + else
|
| + LeaveDetachedMode();
|
| +
|
| view_->AcceleratedWidgetSwapCompleted();
|
| }
|
|
|
| void AcceleratedWidgetMac::GotCAContextFrame(CAContextID ca_context_id,
|
| + bool use_detached,
|
| + CAContextID detached_ca_context_id,
|
| const gfx::Size& pixel_size,
|
| float scale_factor) {
|
| TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotCAContextFrame");
|
| @@ -163,6 +226,14 @@ void AcceleratedWidgetMac::GotCAContextFrame(CAContextID ca_context_id,
|
| [flipped_layer_ addSublayer:ca_context_layer_];
|
| }
|
|
|
| + if ([detached_ca_context_layer_ contextId] != detached_ca_context_id) {
|
| + TRACE_EVENT0("ui", "Creating a new CALayerHost");
|
| + detached_ca_context_layer_.reset([[CALayerHost alloc] init]);
|
| + [detached_ca_context_layer_ setContextId:detached_ca_context_id];
|
| + [detached_ca_context_layer_
|
| + setAutoresizingMask:kCALayerMaxXMargin | kCALayerMaxYMargin];
|
| + }
|
| +
|
| // If this replacing a same-type layer, remove it now that the new layer is
|
| // in the hierarchy.
|
| if (old_ca_context_layer != ca_context_layer_)
|
| @@ -234,6 +305,8 @@ void AcceleratedWidgetMacGotFrame(
|
| gfx::AcceleratedWidget widget,
|
| CAContextID ca_context_id,
|
| base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
|
| + bool use_detached,
|
| + CAContextID detached_ca_context_id,
|
| const gfx::Size& pixel_size,
|
| float scale_factor,
|
| base::TimeTicks* vsync_timebase,
|
| @@ -247,7 +320,8 @@ void AcceleratedWidgetMacGotFrame(
|
| GetHelperFromAcceleratedWidget(widget);
|
|
|
| if (accelerated_widget_mac) {
|
| - accelerated_widget_mac->GotFrame(ca_context_id, io_surface, pixel_size,
|
| + accelerated_widget_mac->GotFrame(ca_context_id, io_surface, use_detached,
|
| + detached_ca_context_id, pixel_size,
|
| scale_factor);
|
| if (vsync_timebase && vsync_interval) {
|
| accelerated_widget_mac->GetVSyncParameters(vsync_timebase,
|
| @@ -256,4 +330,48 @@ void AcceleratedWidgetMacGotFrame(
|
| }
|
| }
|
|
|
| +NSWindow* AcceleratedWidgetMac::CreateDetachedModeWindow() {
|
| + DCHECK(!detached_mode_window_);
|
| +
|
| + detached_mode_window_.reset([[DetachedModeWindow alloc]
|
| + initWithAcceleratedWidgetMac:weak_factory_.GetWeakPtr()]);
|
| +
|
| + NSView* view = [detached_mode_window_ contentView];
|
| + base::scoped_nsobject<CALayer> background_layer([[CALayer alloc] init]);
|
| + [background_layer setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];
|
| + [view setLayer:background_layer];
|
| + [view setWantsLayer:YES];
|
| + [background_layer addSublayer:detached_ca_context_layer_];
|
| + return [detached_mode_window_ retain];
|
| +}
|
| +
|
| +void AcceleratedWidgetMac::EnterDetachedMode() {
|
| + if (!detached_mode_window_ || in_detached_mode_)
|
| + return;
|
| + in_detached_mode_ = true;
|
| + NSWindow* view_window = [view_->AcceleratedWidgetGetNSView() window];
|
| + [detached_mode_window_ setFrame:[view_window frame] display:YES];
|
| + [detached_mode_window_
|
| + setStyleMask:[detached_mode_window_ styleMask] | NSFullScreenWindowMask];
|
| + // FIXME: This causes events to not be forwarded to the correct window.
|
| + [detached_mode_window_ orderWindow:NSWindowAbove
|
| + relativeTo:[view_window windowNumber]];
|
| + [detached_mode_window_ startForwardingEvents:view_window];
|
| +}
|
| +
|
| +void AcceleratedWidgetMac::LeaveDetachedMode() {
|
| + if (!detached_mode_window_ || !in_detached_mode_)
|
| + return;
|
| + in_detached_mode_ = false;
|
| + NSWindow* view_window = [view_->AcceleratedWidgetGetNSView() window];
|
| + [detached_mode_window_ orderWindow:NSWindowBelow
|
| + relativeTo:[view_window windowNumber]];
|
| + [detached_mode_window_ stopForwardingEvents];
|
| +}
|
| +
|
| +void AcceleratedWidgetMac::DestroyDetachedModeWindow() {
|
| + LeaveDetachedMode();
|
| + detached_mode_window_.reset();
|
| +}
|
| +
|
| } // namespace ui
|
|
|