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

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

Powered by Google App Engine
This is Rietveld 408576698