OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" | 5 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/mac/scoped_nsobject.h" | 9 #include "base/mac/scoped_nsobject.h" |
10 #include "chrome/browser/devtools/devtools_window.h" | 10 #include "chrome/browser/devtools/devtools_window.h" |
11 #include "content/public/browser/render_view_host.h" | 11 #include "content/public/browser/render_view_host.h" |
12 #include "content/public/browser/render_widget_host_view.h" | 12 #include "content/public/browser/render_widget_host_view.h" |
13 #include "content/public/browser/web_contents.h" | 13 #include "content/public/browser/web_contents.h" |
14 #include "content/public/browser/web_contents_observer.h" | |
14 #include "content/public/browser/web_contents_view.h" | 15 #include "content/public/browser/web_contents_view.h" |
15 | 16 |
16 using content::WebContents; | 17 using content::WebContents; |
18 using content::WebContentsObserver; | |
19 | |
20 // FullscreenObserver is used by TabContentsController to monitor for the | |
21 // showing/destruction of fullscreen render widgets. When notified, | |
22 // TabContentsController will alter its child view hierarchy to either embed a | |
23 // fullscreen render widget view or restore the normal WebContentsView render | |
24 // view. The embedded fullscreen render widget will fill the user's screen in | |
25 // the case where TabContentsController's NSView is a subview of a browser | |
26 // window that has been toggled into fullscreen mode (e.g., via | |
27 // FullscreenController). | |
28 class FullscreenObserver : public WebContentsObserver { | |
29 public: | |
30 explicit FullscreenObserver(TabContentsController* controller) | |
31 : controller_(controller) {} | |
32 | |
33 void Observe(content::WebContents* new_web_contents) { | |
34 WebContentsObserver::Observe(new_web_contents); | |
35 } | |
36 | |
37 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE { | |
38 [controller_ toggleFullscreenWidget:YES]; | |
39 } | |
40 | |
41 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE { | |
42 [controller_ toggleFullscreenWidget:NO]; | |
43 } | |
44 | |
45 private: | |
46 TabContentsController* const controller_; | |
47 | |
48 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); | |
49 }; | |
17 | 50 |
18 @implementation TabContentsController | 51 @implementation TabContentsController |
19 @synthesize webContents = contents_; | 52 @synthesize webContents = contents_; |
20 | 53 |
21 - (id)initWithContents:(WebContents*)contents { | 54 - (id)initWithContents:(WebContents*)contents |
55 andAutoEmbedFullscreen:(BOOL)enableEmbeddedFullscreen { | |
Robert Sesek
2013/09/12 15:11:36
nit: indent 4
miu
2013/09/12 23:16:44
Done.
| |
22 if ((self = [super initWithNibName:nil bundle:nil])) { | 56 if ((self = [super initWithNibName:nil bundle:nil])) { |
23 contents_ = contents; | 57 contents_ = contents; |
58 if (enableEmbeddedFullscreen) { | |
59 fullscreenObserver_.reset(new FullscreenObserver(self)); | |
60 fullscreenObserver_->Observe(contents_); | |
61 } | |
62 isEmbeddingFullscreenWidget_ = NO; | |
24 } | 63 } |
25 return self; | 64 return self; |
26 } | 65 } |
27 | 66 |
28 - (void)dealloc { | 67 - (void)dealloc { |
29 // make sure our contents have been removed from the window | 68 // make sure our contents have been removed from the window |
30 [[self view] removeFromSuperview]; | 69 [[self view] removeFromSuperview]; |
31 [super dealloc]; | 70 [super dealloc]; |
32 } | 71 } |
33 | 72 |
34 - (void)loadView { | 73 - (void)loadView { |
35 base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]); | 74 base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]); |
36 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; | 75 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; |
37 [self setView:view]; | 76 [self setView:view]; |
38 } | 77 } |
39 | 78 |
40 - (void)ensureContentsSizeDoesNotChange { | 79 - (void)ensureContentsSizeDoesNotChange { |
41 NSView* contentsContainer = [self view]; | 80 NSView* contentsContainer = [self view]; |
42 NSArray* subviews = [contentsContainer subviews]; | 81 NSArray* subviews = [contentsContainer subviews]; |
43 if ([subviews count] > 0) { | 82 if ([subviews count] > 0) |
44 [contents_->GetView()->GetNativeView() | 83 [[subviews objectAtIndex:0] setAutoresizingMask:NSViewNotSizable]; |
45 setAutoresizingMask:NSViewNotSizable]; | |
46 } | |
47 } | 84 } |
48 | 85 |
49 // Call when the tab view is properly sized and the render widget host view | 86 // Call when the tab view is properly sized and the render widget host view |
50 // should be put into the view hierarchy. | 87 // should be put into the view hierarchy. |
51 - (void)ensureContentsVisible { | 88 - (void)ensureContentsVisible { |
52 if (!contents_) | 89 if (!contents_) |
53 return; | 90 return; |
54 NSView* contentsContainer = [self view]; | 91 NSView* contentsContainer = [self view]; |
55 NSArray* subviews = [contentsContainer subviews]; | 92 NSArray* subviews = [contentsContainer subviews]; |
56 NSView* contentsNativeView = contents_->GetView()->GetNativeView(); | 93 NSView* contentsNativeView; |
94 content::RenderWidgetHostView* const fullscreen_view = | |
Robert Sesek
2013/09/12 15:11:36
naming: fullscreenView
miu
2013/09/12 23:16:44
Done.
| |
95 isEmbeddingFullscreenWidget_ ? | |
96 contents_->GetFullscreenRenderWidgetHostView() : NULL; | |
97 if (fullscreen_view) { | |
98 contentsNativeView = fullscreen_view->GetNativeView(); | |
99 } else { | |
100 isEmbeddingFullscreenWidget_ = NO; | |
101 contentsNativeView = contents_->GetView()->GetNativeView(); | |
102 } | |
57 [contentsNativeView setFrame:[contentsContainer frame]]; | 103 [contentsNativeView setFrame:[contentsContainer frame]]; |
58 if ([subviews count] == 0) { | 104 if ([subviews count] == 0) { |
59 [contentsContainer addSubview:contentsNativeView]; | 105 [contentsContainer addSubview:contentsNativeView]; |
60 } else if ([subviews objectAtIndex:0] != contentsNativeView) { | 106 } else if ([subviews objectAtIndex:0] != contentsNativeView) { |
61 [contentsContainer replaceSubview:[subviews objectAtIndex:0] | 107 [contentsContainer replaceSubview:[subviews objectAtIndex:0] |
62 with:contentsNativeView]; | 108 with:contentsNativeView]; |
63 } | 109 } |
64 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| | 110 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| |
65 NSViewHeightSizable]; | 111 NSViewHeightSizable]; |
66 // The rendering path with overlapping views disabled causes bugs when | 112 // The rendering path with overlapping views disabled causes bugs when |
67 // transitioning between composited and non-composited mode. | 113 // transitioning between composited and non-composited mode. |
68 // http://crbug.com/279472 | 114 // http://crbug.com/279472 |
69 contents_->GetView()->SetAllowOverlappingViews(true); | 115 if (!fullscreen_view) |
116 contents_->GetView()->SetAllowOverlappingViews(true); | |
70 } | 117 } |
71 | 118 |
72 - (void)changeWebContents:(WebContents*)newContents { | 119 - (void)changeWebContents:(WebContents*)newContents { |
73 contents_ = newContents; | 120 contents_ = newContents; |
121 if (fullscreenObserver_) { | |
122 fullscreenObserver_->Observe(contents_); | |
123 isEmbeddingFullscreenWidget_ = | |
124 contents_ && contents_->GetFullscreenRenderWidgetHostView(); | |
125 } else { | |
126 isEmbeddingFullscreenWidget_ = NO; | |
127 } | |
74 } | 128 } |
75 | 129 |
76 // Returns YES if the tab represented by this controller is the front-most. | 130 // Returns YES if the tab represented by this controller is the front-most. |
77 - (BOOL)isCurrentTab { | 131 - (BOOL)isCurrentTab { |
78 // We're the current tab if we're in the view hierarchy, otherwise some other | 132 // We're the current tab if we're in the view hierarchy, otherwise some other |
79 // tab is. | 133 // tab is. |
80 return [[self view] superview] ? YES : NO; | 134 return [[self view] superview] ? YES : NO; |
81 } | 135 } |
82 | 136 |
83 - (void)willBecomeUnselectedTab { | 137 - (void)willBecomeUnselectedTab { |
(...skipping 23 matching lines...) Expand all Loading... | |
107 // Do not explicitly call Focus() here, as the RWHV may not actually have | 161 // Do not explicitly call Focus() here, as the RWHV may not actually have |
108 // focus (for example, if the omnibox has focus instead). The WebContents | 162 // focus (for example, if the omnibox has focus instead). The WebContents |
109 // logic will restore focus to the appropriate view. | 163 // logic will restore focus to the appropriate view. |
110 } | 164 } |
111 | 165 |
112 - (void)tabDidChange:(WebContents*)updatedContents { | 166 - (void)tabDidChange:(WebContents*)updatedContents { |
113 // Calling setContentView: here removes any first responder status | 167 // Calling setContentView: here removes any first responder status |
114 // the view may have, so avoid changing the view hierarchy unless | 168 // the view may have, so avoid changing the view hierarchy unless |
115 // the view is different. | 169 // the view is different. |
116 if ([self webContents] != updatedContents) { | 170 if ([self webContents] != updatedContents) { |
117 contents_ = updatedContents; | 171 [self changeWebContents:updatedContents]; |
118 [self ensureContentsVisible]; | 172 [self ensureContentsVisible]; |
119 } | 173 } |
120 } | 174 } |
121 | 175 |
176 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen { | |
177 isEmbeddingFullscreenWidget_ = enterFullscreen && | |
178 contents_ && contents_->GetFullscreenRenderWidgetHostView(); | |
179 [self ensureContentsVisible]; | |
180 } | |
181 | |
122 @end | 182 @end |
OLD | NEW |