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

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

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

Powered by Google App Engine
This is Rietveld 408576698