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 #include "chrome/browser/ui/cocoa/panels/panel_window_controller_cocoa.h" | 5 #include "chrome/browser/ui/cocoa/panels/panel_window_controller_cocoa.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #import "chrome/browser/ui/cocoa/panels/panel_cocoa.h" | 21 #import "chrome/browser/ui/cocoa/panels/panel_cocoa.h" |
22 #import "chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.h" | 22 #import "chrome/browser/ui/cocoa/panels/panel_titlebar_view_cocoa.h" |
23 #import "chrome/browser/ui/cocoa/panels/panel_utils_cocoa.h" | 23 #import "chrome/browser/ui/cocoa/panels/panel_utils_cocoa.h" |
24 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util_mac.h" | 24 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util_mac.h" |
25 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" | 25 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" |
26 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" | 26 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" |
27 #include "chrome/browser/ui/panels/panel_bounds_animation.h" | 27 #include "chrome/browser/ui/panels/panel_bounds_animation.h" |
28 #include "chrome/browser/ui/panels/panel_collection.h" | 28 #include "chrome/browser/ui/panels/panel_collection.h" |
29 #include "chrome/browser/ui/panels/panel_constants.h" | 29 #include "chrome/browser/ui/panels/panel_constants.h" |
30 #include "chrome/browser/ui/panels/panel_manager.h" | 30 #include "chrome/browser/ui/panels/panel_manager.h" |
| 31 #include "chrome/browser/ui/panels/stacked_panel_collection.h" |
31 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 32 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
32 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" | 33 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" |
33 #include "content/public/browser/render_widget_host_view.h" | 34 #include "content/public/browser/render_widget_host_view.h" |
34 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
35 #include "content/public/browser/web_contents_view.h" | 36 #include "content/public/browser/web_contents_view.h" |
36 #include "grit/ui_resources.h" | 37 #include "grit/ui_resources.h" |
37 #include "third_party/WebKit/public/web/WebCursorInfo.h" | |
38 #include "ui/base/resource/resource_bundle.h" | 38 #include "ui/base/resource/resource_bundle.h" |
39 #include "ui/gfx/image/image.h" | 39 #include "ui/gfx/image/image.h" |
40 #include "webkit/common/cursors/webcursor.h" | |
41 | 40 |
42 using content::WebContents; | 41 using content::WebContents; |
43 | 42 |
44 const int kMinimumWindowSize = 1; | 43 const int kMinimumWindowSize = 1; |
45 const double kBoundsAnimationSpeedPixelsPerSecond = 1000; | 44 const double kBoundsAnimationSpeedPixelsPerSecond = 1000; |
46 const double kBoundsAnimationMaxDurationSeconds = 0.18; | 45 const double kBoundsAnimationMaxDurationSeconds = 0.18; |
47 | 46 |
48 // Resize edge thickness, in screen pixels. | 47 // Edge thickness to trigger user resizing via system, in screen pixels. |
49 const double kWidthOfMouseResizeArea = 4.0; | 48 const double kWidthOfMouseResizeArea = 15.0; |
50 | 49 |
51 @interface PanelWindowControllerCocoa (PanelsCanBecomeKey) | 50 @interface PanelWindowControllerCocoa (PanelsCanBecomeKey) |
52 // Internal helper method for extracting the total number of panel windows | 51 // Internal helper method for extracting the total number of panel windows |
53 // from the panel manager. Used to decide if panel can become the key window. | 52 // from the panel manager. Used to decide if panel can become the key window. |
54 - (int)numPanels; | 53 - (int)numPanels; |
55 @end | 54 @end |
56 | 55 |
57 @implementation PanelWindowCocoaImpl | 56 @implementation PanelWindowCocoaImpl |
58 // The panels cannot be reduced to 3-px windows on the edge of the screen | 57 // The panels cannot be reduced to 3-px windows on the edge of the screen |
59 // active area (above Dock). Default constraining logic makes at least a height | 58 // active area (above Dock). Default constraining logic makes at least a height |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 // Ignore key events if window cannot become key window to fix problem | 100 // Ignore key events if window cannot become key window to fix problem |
102 // where keyboard input is still going into a minimized panel even though | 101 // where keyboard input is still going into a minimized panel even though |
103 // the app has been deactivated in -[PanelWindowControllerCocoa deactivate:]. | 102 // the app has been deactivated in -[PanelWindowControllerCocoa deactivate:]. |
104 - (void)sendEvent:(NSEvent*)anEvent { | 103 - (void)sendEvent:(NSEvent*)anEvent { |
105 NSEventType eventType = [anEvent type]; | 104 NSEventType eventType = [anEvent type]; |
106 if ((eventType == NSKeyDown || eventType == NSKeyUp) && | 105 if ((eventType == NSKeyDown || eventType == NSKeyUp) && |
107 ![self canBecomeKeyWindow]) | 106 ![self canBecomeKeyWindow]) |
108 return; | 107 return; |
109 [super sendEvent:anEvent]; | 108 [super sendEvent:anEvent]; |
110 } | 109 } |
111 @end | |
112 | 110 |
113 // Transparent view covering the whole panel in order to intercept mouse | 111 - (BOOL)acceptsMouseMovedEvents { |
114 // messages for custom user resizing. We need custom resizing because panels | 112 return YES; |
115 // use their own constrained layout. | 113 } |
116 @interface PanelResizeByMouseOverlay : NSView <MouseDragControllerClient> { | 114 |
117 @private | 115 - (void)mouseMoved:(NSEvent*)event { |
118 Panel* panel_; | 116 // Cocoa does not support letting the application determine the edges that |
119 base::scoped_nsobject<MouseDragController> dragController_; | 117 // can trigger the user resizing. To work around this, we track the mouse |
120 base::scoped_nsobject<NSCursor> dragCursor_; | 118 // location. When it is close to the edge/corner where the user resizing |
121 base::scoped_nsobject<NSCursor> eastWestCursor_; | 119 // is not desired, we force the min and max size of the window to be same |
122 base::scoped_nsobject<NSCursor> northSouthCursor_; | 120 // as current window size. For all other cases, we restore the min and max |
123 base::scoped_nsobject<NSCursor> northEastSouthWestCursor_; | 121 // size. |
124 base::scoped_nsobject<NSCursor> northWestSouthEastCursor_; | 122 PanelWindowControllerCocoa* controller = |
125 NSRect leftCursorRect_; | 123 base::mac::ObjCCast<PanelWindowControllerCocoa>([self windowController]); |
126 NSRect rightCursorRect_; | 124 Panel* panel = [controller panel]; |
127 NSRect topCursorRect_; | 125 panel::Resizability resizability = panel->CanResizeByMouse(); |
128 NSRect bottomCursorRect_; | 126 BOOL canResize = YES; |
129 NSRect topLeftCursorRect_; | 127 NSRect frame = [self frame]; |
130 NSRect topRightCursorRect_; | 128 NSPoint point = [NSEvent mouseLocation]; |
131 NSRect bottomLeftCursorRect_; | 129 |
132 NSRect bottomRightCursorRect_; | 130 BOOL mouseNearBottom = point.y < NSMinY(frame) + kWidthOfMouseResizeArea; |
| 131 if (mouseNearBottom) { |
| 132 if (point.x < NSMinX(frame) + kWidthOfMouseResizeArea && |
| 133 (resizability & panel::RESIZABLE_BOTTOM_LEFT) == 0) { |
| 134 canResize = NO; |
| 135 } else if (point.x > NSMaxX(frame) - kWidthOfMouseResizeArea && |
| 136 (resizability & panel::RESIZABLE_BOTTOM_RIGHT) == 0) { |
| 137 canResize = NO; |
| 138 } else if ((resizability & panel::RESIZABLE_BOTTOM) == 0) { |
| 139 canResize = NO; |
| 140 } |
| 141 } else if (point.y > NSMaxY(frame) - kWidthOfMouseResizeArea) { |
| 142 if (point.x < NSMinX(frame) + kWidthOfMouseResizeArea && |
| 143 (resizability & panel::RESIZABLE_TOP_LEFT) == 0) { |
| 144 canResize = NO; |
| 145 } else if (point.x > NSMaxX(frame) - kWidthOfMouseResizeArea && |
| 146 (resizability & panel::RESIZABLE_TOP_RIGHT) == 0) { |
| 147 canResize = NO; |
| 148 } else if ((resizability & panel::RESIZABLE_TOP) == 0) { |
| 149 canResize = NO; |
| 150 } |
| 151 } else { |
| 152 if (point.x < NSMinX(frame) + kWidthOfMouseResizeArea && |
| 153 (resizability & panel::RESIZABLE_LEFT) == 0) { |
| 154 canResize = NO; |
| 155 } else if (point.x > NSMaxX(frame) - kWidthOfMouseResizeArea && |
| 156 (resizability & panel::RESIZABLE_RIGHT) == 0) { |
| 157 canResize = NO; |
| 158 } |
| 159 } |
| 160 |
| 161 if (canResize) { |
| 162 [self setMinSize:NSMakeSize(panel::kPanelMinWidth, |
| 163 panel::kPanelMinHeight)]; |
| 164 |
| 165 // Mac window server limits window sizes to 10000. |
| 166 NSSize maxSize = NSMakeSize(10000, 10000); |
| 167 // If the user is resizing a stacked panel by its bottom edge, make sure its |
| 168 // height cannot grow more than what the panel below it could offer. This is |
| 169 // because growing a stacked panel by y amount will shrink the panel below |
| 170 // it by same amount and we do not want the panel below it being shrunk to |
| 171 // be smaller than the titlebar. |
| 172 if (panel->stack()) { |
| 173 Panel* belowPanel = panel->stack()->GetPanelBelow(panel); |
| 174 if (belowPanel && !belowPanel->IsMinimized()) { |
| 175 maxSize.height = panel->GetBounds().height() + |
| 176 belowPanel->GetBounds().height() - panel::kTitlebarHeight; |
| 177 } |
| 178 } |
| 179 |
| 180 [self setMaxSize:maxSize]; |
| 181 } else { |
| 182 [self setMinSize:frame.size]; |
| 183 [self setMaxSize:frame.size]; |
| 184 } |
| 185 |
| 186 [super mouseMoved:event]; |
133 } | 187 } |
134 @end | 188 @end |
135 | 189 |
136 namespace { | |
137 NSCursor* LoadWebKitCursor(WebKit::WebCursorInfo::Type type) { | |
138 return WebCursor(WebCursor::CursorInfo(type)).GetNativeCursor(); | |
139 } | |
140 } | |
141 | |
142 @implementation PanelResizeByMouseOverlay | |
143 - (PanelResizeByMouseOverlay*)initWithFrame:(NSRect)frame panel:(Panel*)panel { | |
144 if ((self = [super initWithFrame:frame])) { | |
145 panel_ = panel; | |
146 dragController_.reset([[MouseDragController alloc] initWithClient:self]); | |
147 | |
148 eastWestCursor_.reset( | |
149 [LoadWebKitCursor(WebKit::WebCursorInfo::TypeEastWestResize) retain]); | |
150 northSouthCursor_.reset( | |
151 [LoadWebKitCursor(WebKit::WebCursorInfo::TypeNorthSouthResize) retain]); | |
152 northEastSouthWestCursor_.reset( | |
153 [LoadWebKitCursor(WebKit::WebCursorInfo::TypeNorthEastSouthWestResize) | |
154 retain]); | |
155 northWestSouthEastCursor_.reset( | |
156 [LoadWebKitCursor(WebKit::WebCursorInfo::TypeNorthWestSouthEastResize) | |
157 retain]); | |
158 } | |
159 return self; | |
160 } | |
161 | |
162 - (BOOL)acceptsFirstMouse:(NSEvent*)event { | |
163 return YES; | |
164 } | |
165 | |
166 // |pointInWindow| is in window coordinates. | |
167 - (panel::ResizingSides)edgeHitTest:(NSPoint)pointInWindow { | |
168 panel::Resizability resizability = panel_->CanResizeByMouse(); | |
169 DCHECK_NE(panel::NOT_RESIZABLE, resizability); | |
170 | |
171 NSPoint point = [self convertPoint:pointInWindow fromView:nil]; | |
172 BOOL flipped = [self isFlipped]; | |
173 | |
174 if ((resizability & panel::RESIZABLE_TOP_LEFT) && | |
175 NSMouseInRect(point, topLeftCursorRect_, flipped)) { | |
176 return panel::RESIZE_TOP_LEFT; | |
177 } | |
178 if ((resizability & panel::RESIZABLE_TOP_RIGHT) && | |
179 NSMouseInRect(point, topRightCursorRect_, flipped)) { | |
180 return panel::RESIZE_TOP_RIGHT; | |
181 } | |
182 if ((resizability & panel::RESIZABLE_BOTTOM_LEFT) && | |
183 NSMouseInRect(point, bottomLeftCursorRect_, flipped)) { | |
184 return panel::RESIZE_BOTTOM_LEFT; | |
185 } | |
186 if ((resizability & panel::RESIZABLE_BOTTOM_RIGHT) && | |
187 NSMouseInRect(point, bottomRightCursorRect_, flipped)) { | |
188 return panel::RESIZE_BOTTOM_RIGHT; | |
189 } | |
190 | |
191 if ((resizability & panel::RESIZABLE_LEFT) && | |
192 NSMouseInRect(point, leftCursorRect_, flipped)) { | |
193 return panel::RESIZE_LEFT; | |
194 } | |
195 if ((resizability & panel::RESIZABLE_RIGHT) && | |
196 NSMouseInRect(point, rightCursorRect_, flipped)) { | |
197 return panel::RESIZE_RIGHT; | |
198 } | |
199 if ((resizability & panel::RESIZABLE_TOP) && | |
200 NSMouseInRect(point, topCursorRect_, flipped)) { | |
201 return panel::RESIZE_TOP; | |
202 } | |
203 if ((resizability & panel::RESIZABLE_BOTTOM) && | |
204 NSMouseInRect(point, bottomCursorRect_, flipped)) { | |
205 return panel::RESIZE_BOTTOM; | |
206 } | |
207 | |
208 return panel::RESIZE_NONE; | |
209 } | |
210 | |
211 // NSWindow uses this method to figure out if this view is under the mouse | |
212 // and hence the one to handle the incoming mouse event. | |
213 // Since this view covers the whole panel, it is asked first. | |
214 // See if this is the mouse event we are interested in (in the resize areas) | |
215 // and return 'nil' to let NSWindow find another candidate otherwise. | |
216 // |point| is in coordinate system of the parent view. | |
217 - (NSView*)hitTest:(NSPoint)point { | |
218 // If panel is not resizable, let the mouse events fall through. | |
219 if (panel::NOT_RESIZABLE == panel_->CanResizeByMouse()) | |
220 return nil; | |
221 | |
222 NSPoint pointInWindow = [[self superview] convertPoint:point toView:nil]; | |
223 return [self edgeHitTest:pointInWindow] == panel::RESIZE_NONE ? nil : self; | |
224 } | |
225 | |
226 // Delegate these to MouseDragController, it will call back on | |
227 // MouseDragControllerClient protocol. | |
228 - (void)mouseDown:(NSEvent*)event { | |
229 [dragController_ mouseDown:event]; | |
230 } | |
231 | |
232 - (void)mouseDragged:(NSEvent*)event { | |
233 [dragController_ mouseDragged:event]; | |
234 } | |
235 | |
236 - (void)mouseUp:(NSEvent*)event { | |
237 [dragController_ mouseUp:event]; | |
238 } | |
239 | |
240 // MouseDragControllerClient protocol. | |
241 | |
242 - (void)prepareForDrag { | |
243 // If the panel is not resizable, hitTest should have failed and no mouse | |
244 // events should have come here. | |
245 DCHECK_NE(panel::NOT_RESIZABLE, panel_->CanResizeByMouse()); | |
246 | |
247 // Make sure the cursor stays the same during whole resize operation. | |
248 // The cursor rects normally do not guarantee the same cursor, since the | |
249 // mouse may temporarily leave the cursor rect area (or even the window) so | |
250 // the cursor will flicker. Disable cursor rects and grab the current cursor | |
251 // so we can set it on mouseDragged: events to avoid flicker. | |
252 [[self window] disableCursorRects]; | |
253 dragCursor_.reset([[NSCursor currentCursor] retain]); | |
254 } | |
255 | |
256 - (void)cleanupAfterDrag { | |
257 [[self window] enableCursorRects]; | |
258 dragCursor_.reset(); | |
259 } | |
260 | |
261 - (void)dragStarted:(NSPoint)initialMouseLocation { | |
262 NSPoint initialMouseLocationScreen = | |
263 [[self window] convertBaseToScreen:initialMouseLocation]; | |
264 | |
265 panel_->manager()->StartResizingByMouse( | |
266 panel_, | |
267 cocoa_utils::ConvertPointFromCocoaCoordinates(initialMouseLocationScreen), | |
268 [self edgeHitTest:initialMouseLocation]); | |
269 } | |
270 | |
271 - (void)dragProgress:(NSPoint)mouseLocation { | |
272 NSPoint mouseLocationScreen = | |
273 [[self window] convertBaseToScreen:mouseLocation]; | |
274 panel_->manager()->ResizeByMouse( | |
275 cocoa_utils::ConvertPointFromCocoaCoordinates(mouseLocationScreen)); | |
276 | |
277 // Set the resize cursor on every mouse drag event in case the mouse | |
278 // wandered outside the window and was switched to another one. | |
279 // This does not produce flicker, seems the real cursor is updated after | |
280 // mouseDrag is processed. | |
281 [dragCursor_ set]; | |
282 } | |
283 | |
284 - (void)dragEnded:(BOOL)cancelled { | |
285 panel_->manager()->EndResizingByMouse(cancelled); | |
286 } | |
287 | |
288 - (void)resetCursorRects { | |
289 panel::Resizability resizability = panel_->CanResizeByMouse(); | |
290 if (panel::NOT_RESIZABLE == resizability) | |
291 return; | |
292 | |
293 NSRect bounds = [self bounds]; | |
294 | |
295 // Left vertical edge. | |
296 if (resizability & panel::RESIZABLE_LEFT) { | |
297 leftCursorRect_ = NSMakeRect( | |
298 NSMinX(bounds), | |
299 NSMinY(bounds) + kWidthOfMouseResizeArea, | |
300 kWidthOfMouseResizeArea, | |
301 NSHeight(bounds) - 2 * kWidthOfMouseResizeArea); | |
302 [self addCursorRect:leftCursorRect_ cursor:eastWestCursor_]; | |
303 } | |
304 | |
305 // Right vertical edge. | |
306 if (resizability & panel::RESIZABLE_RIGHT) { | |
307 rightCursorRect_ = leftCursorRect_; | |
308 rightCursorRect_.origin.x = NSMaxX(bounds) - kWidthOfMouseResizeArea; | |
309 [self addCursorRect:rightCursorRect_ cursor:eastWestCursor_]; | |
310 } | |
311 | |
312 // Top horizontal edge. | |
313 if (resizability & panel::RESIZABLE_TOP) { | |
314 topCursorRect_ = NSMakeRect(NSMinX(bounds) + kWidthOfMouseResizeArea, | |
315 NSMaxY(bounds) - kWidthOfMouseResizeArea, | |
316 NSWidth(bounds) - 2 * kWidthOfMouseResizeArea, | |
317 kWidthOfMouseResizeArea); | |
318 [self addCursorRect:topCursorRect_ cursor:northSouthCursor_]; | |
319 } | |
320 | |
321 // Top left corner. | |
322 if (resizability & panel::RESIZABLE_TOP_LEFT) { | |
323 topLeftCursorRect_ = NSMakeRect(NSMinX(bounds), | |
324 NSMaxY(bounds) - kWidthOfMouseResizeArea, | |
325 kWidthOfMouseResizeArea, | |
326 NSMaxY(bounds)); | |
327 [self addCursorRect:topLeftCursorRect_ cursor:northWestSouthEastCursor_]; | |
328 } | |
329 | |
330 // Top right corner. | |
331 if (resizability & panel::RESIZABLE_TOP_RIGHT) { | |
332 topRightCursorRect_ = topLeftCursorRect_; | |
333 topRightCursorRect_.origin.x = NSMaxX(bounds) - kWidthOfMouseResizeArea; | |
334 [self addCursorRect:topRightCursorRect_ cursor:northEastSouthWestCursor_]; | |
335 } | |
336 | |
337 // Bottom horizontal edge. | |
338 if (resizability & panel::RESIZABLE_BOTTOM) { | |
339 bottomCursorRect_ = topCursorRect_; | |
340 bottomCursorRect_.origin.y = NSMinY(bounds); | |
341 [self addCursorRect:bottomCursorRect_ cursor:northSouthCursor_]; | |
342 } | |
343 | |
344 // Bottom right corner. | |
345 if (resizability & panel::RESIZABLE_BOTTOM_RIGHT) { | |
346 bottomRightCursorRect_ = topRightCursorRect_; | |
347 bottomRightCursorRect_.origin.y = NSMinY(bounds); | |
348 [self addCursorRect:bottomRightCursorRect_ | |
349 cursor:northWestSouthEastCursor_]; | |
350 } | |
351 | |
352 // Bottom left corner. | |
353 if (resizability & panel::RESIZABLE_BOTTOM_LEFT) { | |
354 bottomLeftCursorRect_ = bottomRightCursorRect_; | |
355 bottomLeftCursorRect_.origin.x = NSMinX(bounds); | |
356 [self addCursorRect:bottomLeftCursorRect_ cursor:northEastSouthWestCursor_]; | |
357 } | |
358 } | |
359 @end | |
360 | |
361 // ChromeEventProcessingWindow expects its controller to implement the | 190 // ChromeEventProcessingWindow expects its controller to implement the |
362 // BrowserCommandExecutor protocol. | 191 // BrowserCommandExecutor protocol. |
363 @interface PanelWindowControllerCocoa (InternalAPI) <BrowserCommandExecutor> | 192 @interface PanelWindowControllerCocoa (InternalAPI) <BrowserCommandExecutor> |
364 | 193 |
365 // BrowserCommandExecutor methods. | 194 // BrowserCommandExecutor methods. |
366 - (void)executeCommand:(int)command; | 195 - (void)executeCommand:(int)command; |
367 | 196 |
368 @end | 197 @end |
369 | 198 |
370 @implementation PanelWindowControllerCocoa (InternalAPI) | 199 @implementation PanelWindowControllerCocoa (InternalAPI) |
(...skipping 11 matching lines...) Expand all Loading... |
382 [base::mac::FrameworkBundle() pathForResource:@"Panel" ofType:@"nib"]; | 211 [base::mac::FrameworkBundle() pathForResource:@"Panel" ofType:@"nib"]; |
383 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 212 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
384 windowShim_.reset(window); | 213 windowShim_.reset(window); |
385 animateOnBoundsChange_ = YES; | 214 animateOnBoundsChange_ = YES; |
386 canBecomeKeyWindow_ = YES; | 215 canBecomeKeyWindow_ = YES; |
387 activationRequestedByPanel_ = NO; | 216 activationRequestedByPanel_ = NO; |
388 } | 217 } |
389 return self; | 218 return self; |
390 } | 219 } |
391 | 220 |
| 221 - (Panel*)panel { |
| 222 return windowShim_->panel(); |
| 223 } |
| 224 |
392 - (void)awakeFromNib { | 225 - (void)awakeFromNib { |
393 NSWindow* window = [self window]; | 226 NSWindow* window = [self window]; |
394 | 227 |
395 DCHECK(window); | 228 DCHECK(window); |
396 DCHECK(titlebar_view_); | 229 DCHECK(titlebar_view_); |
397 DCHECK_EQ(self, [window delegate]); | 230 DCHECK_EQ(self, [window delegate]); |
398 | 231 |
399 [self updateWindowLevel]; | 232 [self updateWindowLevel]; |
400 | 233 |
401 [self updateWindowCollectionBehavior]; | 234 [self updateWindowCollectionBehavior]; |
402 | 235 |
403 [titlebar_view_ attach]; | 236 [titlebar_view_ attach]; |
404 | 237 |
405 // Set initial size of the window to match the size of the panel to give | 238 // Set initial size of the window to match the size of the panel to give |
406 // the renderer the proper size to work with earlier, avoiding a resize | 239 // the renderer the proper size to work with earlier, avoiding a resize |
407 // after the window is revealed. | 240 // after the window is revealed. |
408 gfx::Rect panelBounds = windowShim_->panel()->GetBounds(); | 241 gfx::Rect panelBounds = windowShim_->panel()->GetBounds(); |
409 NSRect frame = [window frame]; | 242 NSRect frame = [window frame]; |
410 frame.size.width = panelBounds.width(); | 243 frame.size.width = panelBounds.width(); |
411 frame.size.height = panelBounds.height(); | 244 frame.size.height = panelBounds.height(); |
412 [window setFrame:frame display:NO]; | 245 [window setFrame:frame display:NO]; |
413 | 246 |
414 // Add a transparent overlay on top of the whole window to process mouse | 247 [self updateTrackingArea]; |
415 // events - for example, user-resizing. | |
416 NSView* superview = [[window contentView] superview]; | |
417 NSRect bounds = [superview bounds]; | |
418 overlayView_.reset( | |
419 [[PanelResizeByMouseOverlay alloc] initWithFrame:bounds | |
420 panel:windowShim_->panel()]); | |
421 // Set autoresizing behavior: glued to edges. | |
422 [overlayView_ setAutoresizingMask:(NSViewHeightSizable | NSViewWidthSizable)]; | |
423 [superview addSubview:overlayView_ positioned:NSWindowAbove relativeTo:nil]; | |
424 } | 248 } |
425 | 249 |
426 - (void)updateWebContentsViewFrame { | 250 - (void)updateWebContentsViewFrame { |
427 content::WebContents* webContents = windowShim_->panel()->GetWebContents(); | 251 content::WebContents* webContents = windowShim_->panel()->GetWebContents(); |
428 if (!webContents) | 252 if (!webContents) |
429 return; | 253 return; |
430 | 254 |
431 // Compute the size of the web contents view. Don't assume it's similar to the | 255 // Compute the size of the web contents view. Don't assume it's similar to the |
432 // size of the contentView, because the contentView is managed by the Cocoa | 256 // size of the contentView, because the contentView is managed by the Cocoa |
433 // to be (window - standard titlebar), while we have taller custom titlebar | 257 // to be (window - standard titlebar), while we have taller custom titlebar |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 - (void)windowDidBecomeKey:(NSNotification*)notification { | 610 - (void)windowDidBecomeKey:(NSNotification*)notification { |
787 // We need to activate the controls (in the "WebView"). To do this, get the | 611 // We need to activate the controls (in the "WebView"). To do this, get the |
788 // selected WebContents's RenderWidgetHostView and tell it to activate. | 612 // selected WebContents's RenderWidgetHostView and tell it to activate. |
789 if (WebContents* contents = windowShim_->panel()->GetWebContents()) { | 613 if (WebContents* contents = windowShim_->panel()->GetWebContents()) { |
790 if (content::RenderWidgetHostView* rwhv = | 614 if (content::RenderWidgetHostView* rwhv = |
791 contents->GetRenderWidgetHostView()) | 615 contents->GetRenderWidgetHostView()) |
792 rwhv->SetActive(true); | 616 rwhv->SetActive(true); |
793 } | 617 } |
794 | 618 |
795 windowShim_->panel()->OnActiveStateChanged(true); | 619 windowShim_->panel()->OnActiveStateChanged(true); |
| 620 |
| 621 // Make the window user-resizable when it gains the focus. |
| 622 [[self window] setStyleMask: |
| 623 [[self window] styleMask] | NSResizableWindowMask]; |
796 } | 624 } |
797 | 625 |
798 - (void)windowDidResignKey:(NSNotification*)notification { | 626 - (void)windowDidResignKey:(NSNotification*)notification { |
799 // If our app is still active and we're still the key window, ignore this | 627 // If our app is still active and we're still the key window, ignore this |
800 // message, since it just means that a menu extra (on the "system status bar") | 628 // message, since it just means that a menu extra (on the "system status bar") |
801 // was activated; we'll get another |-windowDidResignKey| if we ever really | 629 // was activated; we'll get another |-windowDidResignKey| if we ever really |
802 // lose key window status. | 630 // lose key window status. |
803 if ([NSApp isActive] && ([NSApp keyWindow] == [self window])) | 631 if ([NSApp isActive] && ([NSApp keyWindow] == [self window])) |
804 return; | 632 return; |
805 | 633 |
806 [self onWindowDidResignKey]; | 634 [self onWindowDidResignKey]; |
| 635 |
| 636 // Make the window not user-resizable when it loses the focus. This is to |
| 637 // solve the problem that the bottom edge of the active panel does not |
| 638 // trigger the user-resizing if this panel stacks with another inactive |
| 639 // panel at the bottom. |
| 640 [[self window] setStyleMask: |
| 641 [[self window] styleMask] & ~NSResizableWindowMask]; |
| 642 } |
| 643 |
| 644 - (void)windowWillStartLiveResize:(NSNotification*)notification { |
| 645 if (userResizing_) |
| 646 return; |
| 647 userResizing_ = YES; |
| 648 windowShim_->panel()->OnPanelStartUserResizing(); |
| 649 } |
| 650 |
| 651 - (void)windowDidEndLiveResize:(NSNotification*)notification { |
| 652 userResizing_ = NO; |
| 653 |
| 654 Panel* panel = windowShim_->panel(); |
| 655 panel->OnPanelEndUserResizing(); |
| 656 |
| 657 gfx::Rect newBounds = |
| 658 cocoa_utils::ConvertRectFromCocoaCoordinates([[self window] frame]); |
| 659 if (windowShim_->panel()->GetBounds() == newBounds) |
| 660 return; |
| 661 windowShim_->set_cached_bounds_directly(newBounds); |
| 662 |
| 663 panel->IncreaseMaxSize(newBounds.size()); |
| 664 panel->set_full_size(newBounds.size()); |
| 665 |
| 666 panel->collection()->RefreshLayout(); |
807 } | 667 } |
808 | 668 |
809 - (void)windowDidResize:(NSNotification*)notification { | 669 - (void)windowDidResize:(NSNotification*)notification { |
| 670 Panel* panel = windowShim_->panel(); |
| 671 |
| 672 if (userResizing_) { |
| 673 panel->collection()->OnPanelResizedByMouse( |
| 674 panel, |
| 675 cocoa_utils::ConvertRectFromCocoaCoordinates([[self window] frame])); |
| 676 } |
| 677 |
| 678 [self updateTrackingArea]; |
| 679 |
810 // Remove the web contents view from the view hierarchy when the panel is not | 680 // Remove the web contents view from the view hierarchy when the panel is not |
811 // taller than the titlebar. Put it back when the panel grows taller than | 681 // taller than the titlebar. Put it back when the panel grows taller than |
812 // the titlebar. Note that RenderWidgetHostViewMac works for the case that | 682 // the titlebar. Note that RenderWidgetHostViewMac works for the case that |
813 // the web contents view does not exist in the view hierarchy (i.e. the tab | 683 // the web contents view does not exist in the view hierarchy (i.e. the tab |
814 // is not the main one), but it does not work well, like causing occasional | 684 // is not the main one), but it does not work well, like causing occasional |
815 // crashes (http://crbug.com/265932), if the web contents view is made hidden. | 685 // crashes (http://crbug.com/265932), if the web contents view is made hidden. |
816 // | 686 // |
817 // The reason for doing this is to ensure that our titlebar view, that is | 687 // The reason for doing this is to ensure that our titlebar view, that is |
818 // somewhat taller than the standard titlebar, does not overlap with the web | 688 // somewhat taller than the standard titlebar, does not overlap with the web |
819 // contents view because the the web contents view assumes that its view will | 689 // contents view because the the web contents view assumes that its view will |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 - (void)updateWindowCollectionBehavior { | 821 - (void)updateWindowCollectionBehavior { |
952 if (![self isWindowLoaded]) | 822 if (![self isWindowLoaded]) |
953 return; | 823 return; |
954 NSWindowCollectionBehavior collectionBehavior = | 824 NSWindowCollectionBehavior collectionBehavior = |
955 NSWindowCollectionBehaviorParticipatesInCycle; | 825 NSWindowCollectionBehaviorParticipatesInCycle; |
956 if (windowShim_->panel()->IsAlwaysOnTop()) | 826 if (windowShim_->panel()->IsAlwaysOnTop()) |
957 collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces; | 827 collectionBehavior |= NSWindowCollectionBehaviorCanJoinAllSpaces; |
958 [[self window] setCollectionBehavior:collectionBehavior]; | 828 [[self window] setCollectionBehavior:collectionBehavior]; |
959 } | 829 } |
960 | 830 |
961 - (void)enableResizeByMouse:(BOOL)enable { | 831 - (void)updateTrackingArea { |
962 if (![self isWindowLoaded]) | 832 NSView* superview = [[[self window] contentView] superview]; |
963 return; | 833 |
964 [[self window] invalidateCursorRectsForView:overlayView_]; | 834 if (trackingArea_.get()) |
| 835 [superview removeTrackingArea:trackingArea_.get()]; |
| 836 |
| 837 trackingArea_.reset( |
| 838 [[CrTrackingArea alloc] initWithRect:[superview bounds] |
| 839 options:NSTrackingInVisibleRect | |
| 840 NSTrackingMouseMoved | |
| 841 NSTrackingActiveAlways |
| 842 owner:superview |
| 843 userInfo:nil]); |
| 844 [superview addTrackingArea:trackingArea_.get()]; |
965 } | 845 } |
966 | 846 |
967 - (void)showShadow:(BOOL)show { | 847 - (void)showShadow:(BOOL)show { |
968 if (![self isWindowLoaded]) | 848 if (![self isWindowLoaded]) |
969 return; | 849 return; |
970 [[self window] setHasShadow:show]; | 850 [[self window] setHasShadow:show]; |
971 } | 851 } |
972 | 852 |
973 - (void)miniaturize { | 853 - (void)miniaturize { |
974 [[self window] miniaturize:nil]; | 854 [[self window] miniaturize:nil]; |
(...skipping 17 matching lines...) Expand all Loading... |
992 - (NSRect)contentRectForFrameRect:(NSRect)frameRect { | 872 - (NSRect)contentRectForFrameRect:(NSRect)frameRect { |
993 NSRect contentRect = [[[self window] contentView] convertRect:frameRect | 873 NSRect contentRect = [[[self window] contentView] convertRect:frameRect |
994 fromView:nil]; | 874 fromView:nil]; |
995 contentRect.size.height -= panel::kTitlebarHeight; | 875 contentRect.size.height -= panel::kTitlebarHeight; |
996 if (contentRect.size.height < 0) | 876 if (contentRect.size.height < 0) |
997 contentRect.size.height = 0; | 877 contentRect.size.height = 0; |
998 return contentRect; | 878 return contentRect; |
999 } | 879 } |
1000 | 880 |
1001 @end | 881 @end |
OLD | NEW |