| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/apps/native_app_window_cocoa.h" | 5 #include "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/mac/foundation_util.h" | 8 #include "base/mac/foundation_util.h" |
| 9 #include "base/mac/mac_util.h" | 9 #include "base/mac/mac_util.h" |
| 10 #include "base/mac/sdk_forward_declarations.h" | 10 #include "base/mac/sdk_forward_declarations.h" |
| 11 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
| 12 #include "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h" | 12 #include "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/browser/ui/cocoa/browser_window_utils.h" | 14 #include "chrome/browser/ui/cocoa/browser_window_utils.h" |
| 15 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" | 15 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" |
| 16 #import "chrome/browser/ui/cocoa/custom_frame_view.h" | |
| 17 #include "chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa
.h" | 16 #include "chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa
.h" |
| 18 #include "chrome/browser/ui/cocoa/extensions/extension_view_mac.h" | 17 #include "chrome/browser/ui/cocoa/extensions/extension_view_mac.h" |
| 19 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| 20 #include "content/public/browser/native_web_keyboard_event.h" | 19 #include "content/public/browser/native_web_keyboard_event.h" |
| 21 #include "content/public/browser/render_widget_host_view.h" | 20 #include "content/public/browser/render_widget_host_view.h" |
| 22 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
| 23 #include "extensions/common/extension.h" | 22 #include "extensions/common/extension.h" |
| 24 #include "skia/ext/skia_utils_mac.h" | 23 #include "skia/ext/skia_utils_mac.h" |
| 25 #include "third_party/skia/include/core/SkRegion.h" | 24 #include "third_party/skia/include/core/SkRegion.h" |
| 26 #include "ui/gfx/skia_util.h" | 25 #include "ui/gfx/skia_util.h" |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 | 200 |
| 202 - (BOOL)handledByExtensionCommand:(NSEvent*)event | 201 - (BOOL)handledByExtensionCommand:(NSEvent*)event |
| 203 priority:(ui::AcceleratorManager::HandlerPriority)priority { | 202 priority:(ui::AcceleratorManager::HandlerPriority)priority { |
| 204 if (appWindow_) | 203 if (appWindow_) |
| 205 return appWindow_->HandledByExtensionCommand(event, priority); | 204 return appWindow_->HandledByExtensionCommand(event, priority); |
| 206 return NO; | 205 return NO; |
| 207 } | 206 } |
| 208 | 207 |
| 209 @end | 208 @end |
| 210 | 209 |
| 211 // This is really a method on NSGrayFrame, so it should only be called on the | 210 // A view that paints a solid color. Used to change the title bar background. |
| 212 // view passed into -[NSWindow drawCustomFrameRect:forView:]. | 211 @interface TitlebarBackgroundView : NSView { |
| 213 @interface NSView (PrivateMethods) | |
| 214 - (CGFloat)roundedCornerRadius; | |
| 215 @end | |
| 216 | |
| 217 // TODO(jamescook): Should these be AppNSWindow to match AppWindow? | |
| 218 // http://crbug.com/344082 | |
| 219 @interface ShellNSWindow : ChromeEventProcessingWindow | |
| 220 @end | |
| 221 @implementation ShellNSWindow | |
| 222 | |
| 223 // Similar to ChromeBrowserWindow, don't draw the title, but allow it to be seen | |
| 224 // in menus, Expose, etc. | |
| 225 - (BOOL)_isTitleHidden { | |
| 226 return YES; | |
| 227 } | |
| 228 | |
| 229 - (void)drawCustomFrameRect:(NSRect)frameRect forView:(NSView*)view { | |
| 230 // Make the background color of the content area white. We can't just call | |
| 231 // -setBackgroundColor as that causes the title bar to be drawn in a solid | |
| 232 // color. | |
| 233 NSRect rect = [self contentRectForFrameRect:frameRect]; | |
| 234 [[NSColor whiteColor] set]; | |
| 235 NSRectFill(rect); | |
| 236 | |
| 237 // Draw the native title bar. We remove the content area since the native | |
| 238 // implementation draws a gray background. | |
| 239 rect.origin.y = NSMaxY(rect); | |
| 240 rect.size.height = CGFLOAT_MAX; | |
| 241 rect = NSIntersectionRect(rect, frameRect); | |
| 242 | |
| 243 [NSBezierPath clipRect:rect]; | |
| 244 [super drawCustomFrameRect:frameRect | |
| 245 forView:view]; | |
| 246 } | |
| 247 | |
| 248 @end | |
| 249 | |
| 250 @interface ShellCustomFrameNSWindow : ShellNSWindow { | |
| 251 @private | 212 @private |
| 252 base::scoped_nsobject<NSColor> color_; | 213 base::scoped_nsobject<NSColor> color_; |
| 253 base::scoped_nsobject<NSColor> inactiveColor_; | 214 base::scoped_nsobject<NSColor> inactiveColor_; |
| 254 } | 215 } |
| 255 | |
| 256 - (void)setColor:(NSColor*)color | 216 - (void)setColor:(NSColor*)color |
| 257 inactiveColor:(NSColor*)inactiveColor; | 217 inactiveColor:(NSColor*)inactiveColor; |
| 258 | |
| 259 @end | 218 @end |
| 260 | 219 |
| 261 @implementation ShellCustomFrameNSWindow | 220 @implementation TitlebarBackgroundView |
| 262 | 221 |
| 263 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view { | 222 - (void)drawRect:(NSRect)rect { |
| 264 [[NSBezierPath bezierPathWithRect:rect] addClip]; | 223 // Only the top corners are rounded. For simplicity, round all 4 corners but |
| 265 [[NSColor clearColor] set]; | 224 // draw the bottom corners outside of the visible bounds. |
| 266 NSRectFill(rect); | |
| 267 | |
| 268 // Set up our clip. | |
| 269 CGFloat cornerRadius = 4.0; | 225 CGFloat cornerRadius = 4.0; |
| 270 if ([view respondsToSelector:@selector(roundedCornerRadius)]) | 226 NSRect roundedRect = [self bounds]; |
| 271 cornerRadius = [view roundedCornerRadius]; | 227 roundedRect.origin.y -= cornerRadius; |
| 272 [[NSBezierPath bezierPathWithRoundedRect:[view bounds] | 228 roundedRect.size.height += cornerRadius; |
| 229 [[NSBezierPath bezierPathWithRoundedRect:roundedRect |
| 273 xRadius:cornerRadius | 230 xRadius:cornerRadius |
| 274 yRadius:cornerRadius] addClip]; | 231 yRadius:cornerRadius] addClip]; |
| 275 if ([self isMainWindow] || [self isKeyWindow]) | 232 if ([[self window] isMainWindow] || [[self window] isKeyWindow]) |
| 276 [color_ set]; | 233 [color_ set]; |
| 277 else | 234 else |
| 278 [inactiveColor_ set]; | 235 [inactiveColor_ set]; |
| 279 NSRectFill(rect); | 236 NSRectFill(rect); |
| 280 } | 237 } |
| 281 | 238 |
| 282 - (void)setColor:(NSColor*)color | 239 - (void)setColor:(NSColor*)color |
| 283 inactiveColor:(NSColor*)inactiveColor { | 240 inactiveColor:(NSColor*)inactiveColor { |
| 284 color_.reset([color retain]); | 241 color_.reset([color retain]); |
| 285 inactiveColor_.reset([inactiveColor retain]); | 242 inactiveColor_.reset([inactiveColor retain]); |
| 286 } | 243 } |
| 287 | 244 |
| 288 @end | 245 @end |
| 289 | 246 |
| 247 // TODO(jamescook): Should these be AppNSWindow to match AppWindow? |
| 248 // http://crbug.com/344082 |
| 249 @interface ShellNSWindow : ChromeEventProcessingWindow |
| 250 @end |
| 251 |
| 252 @implementation ShellNSWindow |
| 253 |
| 254 // Similar to ChromeBrowserWindow, don't draw the title, but allow it to be seen |
| 255 // in menus, Expose, etc. |
| 256 - (BOOL)_isTitleHidden { |
| 257 return YES; |
| 258 } |
| 259 |
| 260 @end |
| 261 |
| 290 @interface ShellFramelessNSWindow : ShellNSWindow | 262 @interface ShellFramelessNSWindow : ShellNSWindow |
| 291 @end | 263 @end |
| 292 | 264 |
| 293 @implementation ShellFramelessNSWindow | 265 @implementation ShellFramelessNSWindow |
| 294 | 266 |
| 295 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view {} | |
| 296 | |
| 297 + (NSRect)frameRectForContentRect:(NSRect)contentRect | 267 + (NSRect)frameRectForContentRect:(NSRect)contentRect |
| 298 styleMask:(NSUInteger)mask { | 268 styleMask:(NSUInteger)mask { |
| 299 return contentRect; | 269 return contentRect; |
| 300 } | 270 } |
| 301 | 271 |
| 302 + (NSRect)contentRectForFrameRect:(NSRect)frameRect | 272 + (NSRect)contentRectForFrameRect:(NSRect)frameRect |
| 303 styleMask:(NSUInteger)mask { | 273 styleMask:(NSUInteger)mask { |
| 304 return frameRect; | 274 return frameRect; |
| 305 } | 275 } |
| 306 | 276 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 is_fullscreen_(false), | 313 is_fullscreen_(false), |
| 344 is_resizable_(params.resizable), | 314 is_resizable_(params.resizable), |
| 345 shows_resize_controls_(true), | 315 shows_resize_controls_(true), |
| 346 shows_fullscreen_controls_(true), | 316 shows_fullscreen_controls_(true), |
| 347 has_frame_color_(params.has_frame_color), | 317 has_frame_color_(params.has_frame_color), |
| 348 active_frame_color_(params.active_frame_color), | 318 active_frame_color_(params.active_frame_color), |
| 349 inactive_frame_color_(params.inactive_frame_color) { | 319 inactive_frame_color_(params.inactive_frame_color) { |
| 350 Observe(WebContents()); | 320 Observe(WebContents()); |
| 351 | 321 |
| 352 base::scoped_nsobject<NSWindow> window; | 322 base::scoped_nsobject<NSWindow> window; |
| 353 Class window_class; | 323 Class window_class = has_frame_ ? |
| 354 if (has_frame_) { | 324 [ShellNSWindow class] : [ShellFramelessNSWindow class]; |
| 355 window_class = has_frame_color_ ? | |
| 356 [ShellCustomFrameNSWindow class] : [ShellNSWindow class]; | |
| 357 } else { | |
| 358 window_class = [ShellFramelessNSWindow class]; | |
| 359 } | |
| 360 | 325 |
| 361 // Estimate the initial bounds of the window. Once the frame insets are known, | 326 // Estimate the initial bounds of the window. Once the frame insets are known, |
| 362 // the window bounds and constraints can be set precisely. | 327 // the window bounds and constraints can be set precisely. |
| 363 NSRect cocoa_bounds = GfxToCocoaBounds( | 328 NSRect cocoa_bounds = GfxToCocoaBounds( |
| 364 params.GetInitialWindowBounds(gfx::Insets())); | 329 params.GetInitialWindowBounds(gfx::Insets())); |
| 365 window.reset([[window_class alloc] | 330 window.reset([[window_class alloc] |
| 366 initWithContentRect:cocoa_bounds | 331 initWithContentRect:cocoa_bounds |
| 367 styleMask:GetWindowStyleMask() | 332 styleMask:GetWindowStyleMask() |
| 368 backing:NSBackingStoreBuffered | 333 backing:NSBackingStoreBuffered |
| 369 defer:NO]); | 334 defer:NO]); |
| 370 | 335 |
| 371 std::string name; | 336 std::string name; |
| 372 const extensions::Extension* extension = app_window_->GetExtension(); | 337 const extensions::Extension* extension = app_window_->GetExtension(); |
| 373 if (extension) | 338 if (extension) |
| 374 name = extension->name(); | 339 name = extension->name(); |
| 375 [window setTitle:base::SysUTF8ToNSString(name)]; | 340 [window setTitle:base::SysUTF8ToNSString(name)]; |
| 376 [[window contentView] setWantsLayer:YES]; | 341 [[window contentView] setWantsLayer:YES]; |
| 377 if (has_frame_ && has_frame_color_) { | 342 if (has_frame_ && has_frame_color_) { |
| 378 [base::mac::ObjCCastStrict<ShellCustomFrameNSWindow>(window) | 343 // AppKit only officially supports adding subviews to the window's |
| 344 // contentView and not its superview (an NSNextStepFrame). The 10.10 SDK |
| 345 // allows adding an NSTitlebarAccessoryViewController to a window, but the |
| 346 // view can only be placed above the window control buttons, so we'd have to |
| 347 // replicate those. |
| 348 NSView* window_view = [[window contentView] superview]; |
| 349 CGFloat height = NSHeight([window_view bounds]) - |
| 350 NSHeight([[window contentView] bounds]); |
| 351 titlebar_background_view_.reset([[TitlebarBackgroundView alloc] |
| 352 initWithFrame:NSMakeRect(0, NSMaxY([window_view bounds]) - height, |
| 353 NSWidth([window_view bounds]), height)]); |
| 354 [titlebar_background_view_ |
| 355 setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; |
| 356 [window_view addSubview:titlebar_background_view_ |
| 357 positioned:NSWindowBelow |
| 358 relativeTo:nil]; |
| 359 [titlebar_background_view_ |
| 379 setColor:gfx::SkColorToSRGBNSColor(active_frame_color_) | 360 setColor:gfx::SkColorToSRGBNSColor(active_frame_color_) |
| 380 inactiveColor:gfx::SkColorToSRGBNSColor(inactive_frame_color_)]; | 361 inactiveColor:gfx::SkColorToSRGBNSColor(inactive_frame_color_)]; |
| 381 } | 362 } |
| 382 | 363 |
| 383 if (base::mac::IsOSSnowLeopard() && | 364 if (base::mac::IsOSSnowLeopard() && |
| 384 [window respondsToSelector:@selector(setBottomCornerRounded:)]) | 365 [window respondsToSelector:@selector(setBottomCornerRounded:)]) |
| 385 [window setBottomCornerRounded:NO]; | 366 [window setBottomCornerRounded:NO]; |
| 386 | 367 |
| 387 if (params.always_on_top) | 368 if (params.always_on_top) |
| 388 [window setLevel:AlwaysOnTopWindowLevel()]; | 369 [window setLevel:AlwaysOnTopWindowLevel()]; |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 NOTIMPLEMENTED(); | 794 NOTIMPLEMENTED(); |
| 814 } | 795 } |
| 815 | 796 |
| 816 void NativeAppWindowCocoa::WindowWillClose() { | 797 void NativeAppWindowCocoa::WindowWillClose() { |
| 817 [window_controller_ setAppWindow:NULL]; | 798 [window_controller_ setAppWindow:NULL]; |
| 818 app_window_->OnNativeWindowChanged(); | 799 app_window_->OnNativeWindowChanged(); |
| 819 app_window_->OnNativeClose(); | 800 app_window_->OnNativeClose(); |
| 820 } | 801 } |
| 821 | 802 |
| 822 void NativeAppWindowCocoa::WindowDidBecomeKey() { | 803 void NativeAppWindowCocoa::WindowDidBecomeKey() { |
| 804 [titlebar_background_view_ setNeedsDisplay:YES]; |
| 823 content::RenderWidgetHostView* rwhv = | 805 content::RenderWidgetHostView* rwhv = |
| 824 WebContents()->GetRenderWidgetHostView(); | 806 WebContents()->GetRenderWidgetHostView(); |
| 825 if (rwhv) | 807 if (rwhv) |
| 826 rwhv->SetActive(true); | 808 rwhv->SetActive(true); |
| 827 app_window_->OnNativeWindowActivated(); | 809 app_window_->OnNativeWindowActivated(); |
| 828 | 810 |
| 829 WebContents()->RestoreFocus(); | 811 WebContents()->RestoreFocus(); |
| 830 } | 812 } |
| 831 | 813 |
| 832 void NativeAppWindowCocoa::WindowDidResignKey() { | 814 void NativeAppWindowCocoa::WindowDidResignKey() { |
| 833 // If our app is still active and we're still the key window, ignore this | 815 // If our app is still active and we're still the key window, ignore this |
| 834 // message, since it just means that a menu extra (on the "system status bar") | 816 // message, since it just means that a menu extra (on the "system status bar") |
| 835 // was activated; we'll get another |-windowDidResignKey| if we ever really | 817 // was activated; we'll get another |-windowDidResignKey| if we ever really |
| 836 // lose key window status. | 818 // lose key window status. |
| 837 if ([NSApp isActive] && ([NSApp keyWindow] == window())) | 819 if ([NSApp isActive] && ([NSApp keyWindow] == window())) |
| 838 return; | 820 return; |
| 839 | 821 |
| 822 [titlebar_background_view_ setNeedsDisplay:YES]; |
| 823 |
| 840 WebContents()->StoreFocus(); | 824 WebContents()->StoreFocus(); |
| 841 | 825 |
| 842 content::RenderWidgetHostView* rwhv = | 826 content::RenderWidgetHostView* rwhv = |
| 843 WebContents()->GetRenderWidgetHostView(); | 827 WebContents()->GetRenderWidgetHostView(); |
| 844 if (rwhv) | 828 if (rwhv) |
| 845 rwhv->SetActive(false); | 829 rwhv->SetActive(false); |
| 846 } | 830 } |
| 847 | 831 |
| 848 void NativeAppWindowCocoa::WindowDidFinishResize() { | 832 void NativeAppWindowCocoa::WindowDidFinishResize() { |
| 849 // Update |is_maximized_| if needed: | 833 // Update |is_maximized_| if needed: |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 } | 985 } |
| 1002 | 986 |
| 1003 void NativeAppWindowCocoa::UpdateRestoredBounds() { | 987 void NativeAppWindowCocoa::UpdateRestoredBounds() { |
| 1004 if (IsRestored(*this)) | 988 if (IsRestored(*this)) |
| 1005 restored_bounds_ = [window() frame]; | 989 restored_bounds_ = [window() frame]; |
| 1006 } | 990 } |
| 1007 | 991 |
| 1008 void NativeAppWindowCocoa::HideWithoutMarkingHidden() { | 992 void NativeAppWindowCocoa::HideWithoutMarkingHidden() { |
| 1009 [window() orderOut:window_controller_]; | 993 [window() orderOut:window_controller_]; |
| 1010 } | 994 } |
| OLD | NEW |