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

Side by Side Diff: chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm

Issue 9265018: Change grow box computation back to a method on BrowserWindow (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits Created 8 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/memory/scoped_nsobject.h" 9 #include "base/memory/scoped_nsobject.h"
10 #include "content/browser/renderer_host/render_view_host.h" 10 #include "content/browser/renderer_host/render_view_host.h"
11 #include "content/browser/renderer_host/render_widget_host_view.h" 11 #include "content/browser/renderer_host/render_widget_host_view.h"
12 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/notification_observer.h"
14 #include "content/public/browser/notification_registrar.h"
15 #include "content/public/browser/notification_details.h"
16 #include "content/public/browser/notification_source.h"
17 #include "content/public/browser/notification_types.h"
18 #include "content/public/browser/web_contents.h" 12 #include "content/public/browser/web_contents.h"
19 13
20 using content::NavigationController;
21 using content::WebContents; 14 using content::WebContents;
22 15
23 @interface TabContentsController(Private)
24 // Forwards frame update to |delegate_| (ResizeNotificationView calls it).
25 - (void)tabContentsViewFrameWillChange:(NSRect)frameRect;
26 // Notification from WebContents (forwarded by TabContentsNotificationBridge).
27 - (void)tabContentsRenderViewHostChanged:(RenderViewHost*)oldHost
28 newHost:(RenderViewHost*)newHost;
29 @end
30
31
32 // A supporting C++ bridge object to register for TabContents notifications.
33
34 class TabContentsNotificationBridge : public content::NotificationObserver {
35 public:
36 explicit TabContentsNotificationBridge(TabContentsController* controller);
37
38 // Overriden from content::NotificationObserver.
39 virtual void Observe(int type,
40 const content::NotificationSource& source,
41 const content::NotificationDetails& details);
42 // Register for |contents|'s notifications, remove all prior registrations.
43 void ChangeWebContents(WebContents* contents);
44 private:
45 content::NotificationRegistrar registrar_;
46 TabContentsController* controller_; // weak, owns us
47 };
48
49 TabContentsNotificationBridge::TabContentsNotificationBridge(
50 TabContentsController* controller)
51 : controller_(controller) {
52 }
53
54 void TabContentsNotificationBridge::Observe(
55 int type,
56 const content::NotificationSource& source,
57 const content::NotificationDetails& details) {
58 if (type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED) {
59 std::pair<RenderViewHost*, RenderViewHost*>* switched_details =
60 content::Details<std::pair<RenderViewHost*, RenderViewHost*> >(
61 details).ptr();
62 [controller_ tabContentsRenderViewHostChanged:switched_details->first
63 newHost:switched_details->second];
64 } else {
65 NOTREACHED();
66 }
67 }
68
69 void TabContentsNotificationBridge::ChangeWebContents(WebContents* contents) {
70 registrar_.RemoveAll();
71 if (contents) {
72 registrar_.Add(
73 this,
74 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
75 content::Source<NavigationController>(&contents->GetController()));
76 }
77 }
78
79
80 // A custom view that notifies |controller| that view's frame is changing.
81
82 @interface ResizeNotificationView : NSView {
83 TabContentsController* controller_;
84 }
85 - (id)initWithController:(TabContentsController*)controller;
86 @end
87
88 @implementation ResizeNotificationView
89
90 - (id)initWithController:(TabContentsController*)controller {
91 if ((self = [super initWithFrame:NSZeroRect])) {
92 controller_ = controller;
93 }
94 return self;
95 }
96
97 - (void)setFrame:(NSRect)frameRect {
98 [controller_ tabContentsViewFrameWillChange:frameRect];
99 [super setFrame:frameRect];
100 }
101
102 @end
103
104 16
105 @implementation TabContentsController 17 @implementation TabContentsController
106 @synthesize webContents = contents_; 18 @synthesize webContents = contents_;
107 19
108 - (id)initWithContents:(WebContents*)contents 20 - (id)initWithContents:(WebContents*)contents {
109 delegate:(id<TabContentsControllerDelegate>)delegate {
110 if ((self = [super initWithNibName:nil bundle:nil])) { 21 if ((self = [super initWithNibName:nil bundle:nil])) {
111 contents_ = contents; 22 contents_ = contents;
112 delegate_ = delegate;
113 tabContentsBridge_.reset(new TabContentsNotificationBridge(self));
114 tabContentsBridge_->ChangeWebContents(contents);
115 } 23 }
116 return self; 24 return self;
117 } 25 }
118 26
119 - (void)dealloc { 27 - (void)dealloc {
120 // make sure our contents have been removed from the window 28 // make sure our contents have been removed from the window
121 [[self view] removeFromSuperview]; 29 [[self view] removeFromSuperview];
122 [super dealloc]; 30 [super dealloc];
123 } 31 }
124 32
125 - (void)loadView { 33 - (void)loadView {
126 scoped_nsobject<ResizeNotificationView> view( 34 scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:NSZeroRect]);
127 [[ResizeNotificationView alloc] initWithController:self]);
128 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; 35 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable];
129 [self setView:view]; 36 [self setView:view];
130 } 37 }
131 38
132 - (void)ensureContentsSizeDoesNotChange { 39 - (void)ensureContentsSizeDoesNotChange {
133 if (contents_) { 40 NSView* contentsContainer = [self view];
134 NSView* contentsContainer = [self view]; 41 NSArray* subviews = [contentsContainer subviews];
135 NSArray* subviews = [contentsContainer subviews]; 42 if ([subviews count] > 0)
136 if ([subviews count] > 0) 43 [contents_->GetNativeView() setAutoresizingMask:NSViewNotSizable];
137 [contents_->GetNativeView() setAutoresizingMask:NSViewNotSizable];
138 }
139 } 44 }
140 45
141 // Call when the tab view is properly sized and the render widget host view 46 // Call when the tab view is properly sized and the render widget host view
142 // should be put into the view hierarchy. 47 // should be put into the view hierarchy.
143 - (void)ensureContentsVisible { 48 - (void)ensureContentsVisible {
144 if (!contents_) 49 if (!contents_)
145 return; 50 return;
146 NSView* contentsContainer = [self view]; 51 NSView* contentsContainer = [self view];
147 NSArray* subviews = [contentsContainer subviews]; 52 NSArray* subviews = [contentsContainer subviews];
148 NSView* contentsNativeView = contents_->GetNativeView(); 53 NSView* contentsNativeView = contents_->GetNativeView();
149 54 [contentsNativeView setFrame:[contentsContainer frame]];
150 NSRect contentsNativeViewFrame = [contentsContainer frame];
151 contentsNativeViewFrame.origin = NSZeroPoint;
152
153 [delegate_ tabContentsViewFrameWillChange:self
154 frameRect:contentsNativeViewFrame];
155
156 // Native view is resized to the actual size before it becomes visible
157 // to avoid flickering.
158 [contentsNativeView setFrame:contentsNativeViewFrame];
159 if ([subviews count] == 0) { 55 if ([subviews count] == 0) {
160 [contentsContainer addSubview:contentsNativeView]; 56 [contentsContainer addSubview:contentsNativeView];
161 } else if ([subviews objectAtIndex:0] != contentsNativeView) { 57 } else if ([subviews objectAtIndex:0] != contentsNativeView) {
162 [contentsContainer replaceSubview:[subviews objectAtIndex:0] 58 [contentsContainer replaceSubview:[subviews objectAtIndex:0]
163 with:contentsNativeView]; 59 with:contentsNativeView];
164 } 60 }
165 // Restore autoresizing properties possibly stripped by
166 // ensureContentsSizeDoesNotChange call.
167 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| 61 [contentsNativeView setAutoresizingMask:NSViewWidthSizable|
168 NSViewHeightSizable]; 62 NSViewHeightSizable];
169 } 63 }
170 64
171 - (void)changeWebContents:(WebContents*)newContents { 65 - (void)changeWebContents:(WebContents*)newContents {
172 contents_ = newContents; 66 contents_ = newContents;
173 tabContentsBridge_->ChangeWebContents(contents_);
174 } 67 }
175 68
176 - (void)tabContentsViewFrameWillChange:(NSRect)frameRect { 69 // Returns YES if the tab represented by this controller is the front-most.
177 [delegate_ tabContentsViewFrameWillChange:self frameRect:frameRect]; 70 - (BOOL)isCurrentTab {
178 } 71 // We're the current tab if we're in the view hierarchy, otherwise some other
179 72 // tab is.
180 - (void)tabContentsRenderViewHostChanged:(RenderViewHost*)oldHost 73 return [[self view] superview] ? YES : NO;
181 newHost:(RenderViewHost*)newHost {
182 if (oldHost && newHost && oldHost->view() && newHost->view()) {
183 newHost->view()->set_reserved_contents_rect(
184 oldHost->view()->reserved_contents_rect());
185 } else {
186 [delegate_ tabContentsViewFrameWillChange:self
187 frameRect:[[self view] frame]];
188 }
189 } 74 }
190 75
191 - (void)willBecomeUnselectedTab { 76 - (void)willBecomeUnselectedTab {
192 // The RWHV is ripped out of the view hierarchy on tab switches, so it never 77 // The RWHV is ripped out of the view hierarchy on tab switches, so it never
193 // formally resigns first responder status. Handle this by explicitly sending 78 // formally resigns first responder status. Handle this by explicitly sending
194 // a Blur() message to the renderer, but only if the RWHV currently has focus. 79 // a Blur() message to the renderer, but only if the RWHV currently has focus.
195 RenderViewHost* rvh = [self webContents]->GetRenderViewHost(); 80 RenderViewHost* rvh = [self webContents]->GetRenderViewHost();
196 if (rvh && rvh->view() && rvh->view()->HasFocus()) 81 if (rvh && rvh->view() && rvh->view()->HasFocus())
197 rvh->Blur(); 82 rvh->Blur();
198 } 83 }
199 84
200 - (void)willBecomeSelectedTab { 85 - (void)willBecomeSelectedTab {
201 // Do not explicitly call Focus() here, as the RWHV may not actually have 86 // Do not explicitly call Focus() here, as the RWHV may not actually have
202 // focus (for example, if the omnibox has focus instead). The TabContents 87 // focus (for example, if the omnibox has focus instead). The TabContents
203 // logic will restore focus to the appropriate view. 88 // logic will restore focus to the appropriate view.
204 } 89 }
205 90
206 - (void)tabDidChange:(WebContents*)updatedContents { 91 - (void)tabDidChange:(WebContents*)updatedContents {
207 // Calling setContentView: here removes any first responder status 92 // Calling setContentView: here removes any first responder status
208 // the view may have, so avoid changing the view hierarchy unless 93 // the view may have, so avoid changing the view hierarchy unless
209 // the view is different. 94 // the view is different.
210 if ([self webContents] != updatedContents) { 95 if ([self webContents] != updatedContents) {
211 [self changeWebContents:updatedContents]; 96 contents_ = updatedContents;
212 if ([self webContents]) 97 [self ensureContentsVisible];
213 [self ensureContentsVisible];
214 } 98 }
215 } 99 }
216 100
217 @end 101 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h ('k') | chrome/browser/ui/cocoa/tabs/tab_strip_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698