Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(347)

Unified Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 659233002: STASH: Epic Experimental patch for toolkit-views App List on Mac Base URL: https://chromium.googlesource.com/chromium/src.git/+/master
Patch Set: Fix a few things. Works@master Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/cocoa/bridged_native_widget_unittest.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/cocoa/bridged_native_widget.mm
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
index 560f533009df6cd8efb4132130a2ed2640e7074a..9ad0ffeda8afae70ba847ce2b95d392568aa8191 100644
--- a/ui/views/cocoa/bridged_native_widget.mm
+++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -10,7 +10,9 @@
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/input_method_factory.h"
#include "ui/base/ui_base_switches_util.h"
+#include "ui/gfx/display.h"
#import "ui/gfx/mac/coordinate_conversion.h"
+#include "ui/gfx/screen.h"
#import "ui/views/cocoa/bridged_content_view.h"
#import "ui/views/cocoa/views_nswindow_delegate.h"
#include "ui/views/widget/native_widget_mac.h"
@@ -19,13 +21,35 @@
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
+#include "base/bind.h"
+
+#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
+
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/image/image_skia_rep.h"
+#include "ui/gfx/canvas.h"
+
+namespace {
+
+float GetDeviceScaleFactorFromDisplay(NSView* view) {
+ gfx::Display display = gfx::Screen::GetScreenFor(view)->
+ GetDisplayNearestWindow(view);
+ DCHECK(display.is_valid());
+ return display.device_scale_factor();
+}
+
+} // namespace
+
namespace views {
BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent)
: native_widget_mac_(parent),
focus_manager_(NULL),
target_fullscreen_state_(false),
- in_fullscreen_transition_(false) {
+ in_fullscreen_transition_(false),
+ window_visible_(false) {
DCHECK(parent);
window_delegate_.reset(
[[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]);
@@ -50,6 +74,18 @@ void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window,
window_.swap(window);
[window_ setDelegate:window_delegate_];
+ // Register for application hide notifications so that visibility can be
+ // properly tracked. This is not done in the delegate so that the lifetime is
+ // tied to the C++ object, rather than the delegate (which may be reference
+ // counted). This is required since the application hides do not send an
+ // orderOut: to individual windows. Unhide, however, does send an order
+ // message.
+ [[NSNotificationCenter defaultCenter]
+ addObserver:window_delegate_
+ selector:@selector(onWindowOrderChanged:)
+ name:NSApplicationDidHideNotification
+ object:nil];
+
// Validate the window's initial state, otherwise the bridge's initial
// tracking state will be incorrect.
DCHECK(![window_ isVisible]);
@@ -59,6 +95,13 @@ void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window,
// Use NSWindow to manage child windows. This won't automatically close them
// but it will maintain relative positioning of the window layer and origin.
[[params.parent window] addChildWindow:window_ ordered:NSWindowAbove];
+
+ // Windows with a parent that are not explicitly child windows are transient
+ // children.
+ if (!params.child) {
+ [window setExcludedFromWindowsMenu:YES];
+ [window_delegate_ setTransientChild:YES];
+ }
}
}
@@ -75,10 +118,24 @@ void BridgedNativeWidget::SetFocusManager(FocusManager* focus_manager) {
focus_manager_ = focus_manager;
}
+void BridgedNativeWidget::SetBounds(const gfx::Rect& new_bounds) {
+ [window_ setFrame:gfx::ScreenRectToNSRect(new_bounds)
+ display:YES
+ animate:NO];
+
+ // If not visible, -[NSWindowDelegate windowDidResize:] is not triggered.
+ if (![window_ isVisible])
+ OnSizeChanged();
+}
+
void BridgedNativeWidget::SetRootView(views::View* view) {
if (view == [bridged_view_ hostedView])
return;
+ // If this is ever false, the compositor will need to be properly torn down
+ // and replaced, pointing at the new view.
+ DCHECK(!view || !compositor_view_);
+
[bridged_view_ clearView];
bridged_view_.reset();
// Note that there can still be references to the old |bridged_view_|
@@ -97,6 +154,7 @@ void BridgedNativeWidget::SetRootView(views::View* view) {
void BridgedNativeWidget::OnWindowWillClose() {
[[window_ parentWindow] removeChildWindow:window_];
[window_ setDelegate:nil];
+ [[NSNotificationCenter defaultCenter] removeObserver:window_delegate_];
native_widget_mac_->OnWindowWillClose();
}
@@ -155,6 +213,28 @@ void BridgedNativeWidget::ToggleDesiredFullscreenState() {
[window_ setCollectionBehavior:behavior];
}
+void BridgedNativeWidget::OnSizeChanged() {
+ NSSize new_size = [window_ frame].size;
+ native_widget_mac_->GetWidget()->OnNativeWidgetSizeChanged(
+ gfx::Size(new_size.width, new_size.height));
+ if (layer())
+ SetLayerSize(native_widget_mac_->GetClientAreaBoundsInScreen().size());
+}
+
+void BridgedNativeWidget::OnVisibilityChanged() {
+ OnSizeChanged();
+ if (window_visible_ == [window_ isVisible])
+ return;
+
+ window_visible_ = [window_ isVisible];
+ native_widget_mac_->GetWidget()->OnNativeWidgetVisibilityChanged(
+ window_visible_);
+}
+
+void BridgedNativeWidget::OnDisplayChanged() {
+ NOTIMPLEMENTED();
+}
+
InputMethod* BridgedNativeWidget::CreateInputMethod() {
if (switches::IsTextInputFocusManagerEnabled())
return new NullInputMethod();
@@ -178,6 +258,35 @@ gfx::Rect BridgedNativeWidget::GetRestoredBounds() const {
return gfx::ScreenRectFromNSRect([window_ frame]);
}
+ui::Layer* BridgedNativeWidget::GetOrCreateLayer() {
+ if (!bridged_view_)
+ return NULL;
+
+ if (layer())
+ return layer();
+
+ NSView* host_view = BrowserCompositorSuperview();
+ [host_view setWantsLayer:YES];
+ // Next line does nothing.
+ [[host_view layer] setBackgroundColor:CGColorGetConstantColor(kCGColorClear)];
+
+ SetLayer(new ui::Layer());
+ layer()->set_delegate(this);
+ // DCHECK_EQ(0u, [[bridged_view_ subviews] count]);
+ compositor_view_.reset(new content::BrowserCompositorViewMac(this));
+
+ DCHECK(compositor_view_->GetCompositor());
+ DCHECK_EQ(compositor_view_->GetCompositor(), layer()->GetCompositor());
+
+ [window_ setOpaque:NO];
+ layer()->GetCompositor()->SetHostHasTransparentBackground(true);
+ layer()->SetFillsBoundsCompletely(true);
+
+ SetLayerSize(native_widget_mac_->GetClientAreaBoundsInScreen().size());
+
+ return layer();
+}
+
////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidget, internal::InputMethodDelegate:
@@ -190,6 +299,38 @@ void BridgedNativeWidget::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
focus_manager_->OnKeyEvent(key);
}
+////////////////////////////////////////////////////////////////////////////////
+// BridgedNativeWidget, content::BrowserCompositorViewMacClient:
+
+bool BridgedNativeWidget::BrowserCompositorViewShouldAckImmediately() const {
+ return false;
+}
+
+void BridgedNativeWidget::BrowserCompositorViewFrameSwapped(
+ const std::vector<ui::LatencyInfo>& latency_info) {
+}
+
+NSView* BridgedNativeWidget::BrowserCompositorSuperview() {
+ if (!compositor_superview_) {
+ compositor_superview_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
+ if ([[bridged_view_ subviews] count] == 0) {
+ [bridged_view_ addSubview:compositor_superview_];
+ } else {
+ [bridged_view_ addSubview:compositor_superview_
+ positioned:NSWindowBelow
+ relativeTo:[[bridged_view_ subviews] objectAtIndex:0]];
+ }
+ }
+ return compositor_superview_;
+}
+
+ui::Layer* BridgedNativeWidget::BrowserCompositorRootLayer() {
+ return layer();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// BridgedNativeWidget, FocusChangeListener:
+
void BridgedNativeWidget::OnWillChangeFocus(View* focused_before,
View* focused_now) {
}
@@ -202,6 +343,61 @@ void BridgedNativeWidget::OnDidChangeFocus(View* focused_before,
}
////////////////////////////////////////////////////////////////////////////////
+// BridgedNativeWidget, LayerDelegate:
+
+static bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path,
+ bool discard_transparency) {
+ std::vector<unsigned char> png_data;
+ if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap,
+ discard_transparency,
+ &png_data) &&
+ base::CreateDirectory(file_path.DirName())) {
+ char* data = reinterpret_cast<char*>(&png_data[0]);
+ int size = static_cast<int>(png_data.size());
+ bool result = base::WriteFile(file_path, data, size) == size;
+ return result;
+ }
+ return false;
+}
+
+static void ReadbackResult(scoped_ptr<cc::CopyOutputResult> result) {
+ return;
+ DLOG(INFO) << "result!";
+ scoped_ptr<SkBitmap> result_bitmap = result->TakeBitmap().Pass();
+ static int filectr = 0;
+ std::ostringstream oss;
+ oss << "file" << filectr++ << ".png";
+ WritePNGFile(*result_bitmap, base::FilePath().AppendASCII(oss.str().c_str()), false);
+}
+
+void BridgedNativeWidget::OnPaintLayer(gfx::Canvas* canvas) {
+ native_widget_mac_->GetWidget()->OnNativeWidgetPaint(canvas);
+return;
+ layer()->RequestCopyOfOutput(cc::CopyOutputRequest::CreateBitmapRequest(base::Bind(&ReadbackResult)));
+ native_widget_mac_->GetWidget()->OnNativeWidgetPaint(canvas);
+ gfx::ImageSkiaRep image = canvas->ExtractImageRep();
+ static int filectr = 0;
+ std::ostringstream oss;
+ oss << "bpass" << filectr++ << ".png";
+ WritePNGFile(image.sk_bitmap(), base::FilePath().AppendASCII(oss.str().c_str()), false);
+
+}
+
+void BridgedNativeWidget::OnDelegatedFrameDamage(
+ const gfx::Rect& damage_rect_in_dip) {
+ NOTIMPLEMENTED();
+}
+
+void BridgedNativeWidget::OnDeviceScaleFactorChanged(
+ float device_scale_factor) {
+}
+
+base::Closure BridgedNativeWidget::PrepareForLayerBoundsChange() {
+ return base::Bind(&BridgedNativeWidget::OnWindowBoundsChanged,
+ base::Unretained(this));
+}
+
+////////////////////////////////////////////////////////////////////////////////
// BridgedNativeWidget, private:
void BridgedNativeWidget::RemoveOrDestroyChildren() {
@@ -211,4 +407,25 @@ void BridgedNativeWidget::RemoveOrDestroyChildren() {
[child_windows makeObjectsPerformSelector:@selector(close)];
}
+void BridgedNativeWidget::SetLayerSize(const gfx::Size& size_in_dip) {
+ DLOG(INFO) << "SetLayerSize: " << size_in_dip.ToString();
+ DCHECK(layer());
+ DCHECK(compositor_superview_);
+
+ layer()->SetBounds(gfx::Rect(size_in_dip));
+ NSRect view_frame = [compositor_superview_ frame];
+ view_frame.size.width = size_in_dip.width();
+ view_frame.size.height = size_in_dip.height();
+ [compositor_superview_ setFrame:view_frame];
+
+ float scale_factor = GetDeviceScaleFactorFromDisplay(compositor_superview_);
+ gfx::Size size_in_pixels(size_in_dip.width() * scale_factor,
+ size_in_dip.height() * scale_factor);
+ compositor_view_->GetCompositor()->SetScaleAndSize(scale_factor,
+ size_in_pixels);
+}
+
+void BridgedNativeWidget::OnWindowBoundsChanged() {
+}
+
} // namespace views
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | ui/views/cocoa/bridged_native_widget_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698