| 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 |