| 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 "apps/app_shim/extension_app_shim_handler_mac.h" | 7 #include "apps/app_shim/extension_app_shim_handler_mac.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/mac/foundation_util.h" |
| 9 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
| 11 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 12 #include "chrome/browser/ui/cocoa/browser_window_utils.h" | 13 #include "chrome/browser/ui/cocoa/browser_window_utils.h" |
| 13 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" | 14 #import "chrome/browser/ui/cocoa/chrome_event_processing_window.h" |
| 14 #include "chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa
.h" | 15 #include "chrome/browser/ui/cocoa/extensions/extension_keybinding_registry_cocoa
.h" |
| 15 #include "chrome/browser/ui/cocoa/extensions/extension_view_mac.h" | 16 #include "chrome/browser/ui/cocoa/extensions/extension_view_mac.h" |
| 16 #import "chrome/browser/ui/cocoa/nsview_additions.h" | 17 #import "chrome/browser/ui/cocoa/nsview_additions.h" |
| 17 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
| 18 #include "content/public/browser/native_web_keyboard_event.h" | 19 #include "content/public/browser/native_web_keyboard_event.h" |
| 19 #include "content/public/browser/render_widget_host_view.h" | 20 #include "content/public/browser/render_widget_host_view.h" |
| 20 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
| 21 #include "content/public/browser/web_contents_view.h" | 22 #include "content/public/browser/web_contents_view.h" |
| 22 #include "extensions/common/extension.h" | 23 #include "extensions/common/extension.h" |
| 24 #include "skia/ext/skia_utils_mac.h" |
| 23 #include "third_party/skia/include/core/SkRegion.h" | 25 #include "third_party/skia/include/core/SkRegion.h" |
| 24 #include "ui/gfx/skia_util.h" | 26 #include "ui/gfx/skia_util.h" |
| 25 | 27 |
| 26 // NOTE: State Before Update. | 28 // NOTE: State Before Update. |
| 27 // | 29 // |
| 28 // Internal state, such as |is_maximized_|, must be set before the window | 30 // Internal state, such as |is_maximized_|, must be set before the window |
| 29 // state is changed so that it is accurate when e.g. a resize results in a call | 31 // state is changed so that it is accurate when e.g. a resize results in a call |
| 30 // to |OnNativeWindowChanged|. | 32 // to |OnNativeWindowChanged|. |
| 31 | 33 |
| 32 // NOTE: Maximize and Zoom. | 34 // NOTE: Maximize and Zoom. |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 - (CGFloat)roundedCornerRadius; | 218 - (CGFloat)roundedCornerRadius; |
| 217 @end | 219 @end |
| 218 | 220 |
| 219 // TODO(jamescook): Should these be AppNSWindow to match apps::AppWindow? | 221 // TODO(jamescook): Should these be AppNSWindow to match apps::AppWindow? |
| 220 // http://crbug.com/344082 | 222 // http://crbug.com/344082 |
| 221 @interface ShellNSWindow : ChromeEventProcessingWindow | 223 @interface ShellNSWindow : ChromeEventProcessingWindow |
| 222 @end | 224 @end |
| 223 @implementation ShellNSWindow | 225 @implementation ShellNSWindow |
| 224 @end | 226 @end |
| 225 | 227 |
| 226 @interface ShellCustomFrameNSWindow : ShellNSWindow | 228 @interface ShellCustomFrameNSWindow : ShellNSWindow { |
| 229 @private |
| 230 base::scoped_nsobject<NSColor> color_; |
| 231 base::scoped_nsobject<NSColor> inactiveColor_; |
| 232 } |
| 227 | 233 |
| 228 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view; | 234 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view; |
| 235 - (void)setColor:(NSColor*)color |
| 236 inactiveColor:(NSColor*)inactiveColor; |
| 229 | 237 |
| 230 @end | 238 @end |
| 231 | 239 |
| 232 @implementation ShellCustomFrameNSWindow | 240 @implementation ShellCustomFrameNSWindow |
| 233 | 241 |
| 234 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view { | 242 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view { |
| 235 [[NSBezierPath bezierPathWithRect:rect] addClip]; | 243 [[NSBezierPath bezierPathWithRect:rect] addClip]; |
| 236 [[NSColor clearColor] set]; | 244 [[NSColor clearColor] set]; |
| 237 NSRectFill(rect); | 245 NSRectFill(rect); |
| 238 | 246 |
| 239 // Set up our clip. | 247 // Set up our clip. |
| 240 CGFloat cornerRadius = 4.0; | 248 CGFloat cornerRadius = 4.0; |
| 241 if ([view respondsToSelector:@selector(roundedCornerRadius)]) | 249 if ([view respondsToSelector:@selector(roundedCornerRadius)]) |
| 242 cornerRadius = [view roundedCornerRadius]; | 250 cornerRadius = [view roundedCornerRadius]; |
| 243 [[NSBezierPath bezierPathWithRoundedRect:[view bounds] | 251 [[NSBezierPath bezierPathWithRoundedRect:[view bounds] |
| 244 xRadius:cornerRadius | 252 xRadius:cornerRadius |
| 245 yRadius:cornerRadius] addClip]; | 253 yRadius:cornerRadius] addClip]; |
| 246 [[NSColor whiteColor] set]; | 254 if ([self isMainWindow] || [self isKeyWindow]) |
| 255 [color_ set]; |
| 256 else |
| 257 [inactiveColor_ set]; |
| 247 NSRectFill(rect); | 258 NSRectFill(rect); |
| 248 } | 259 } |
| 249 | 260 |
| 261 - (void)setColor:(NSColor*)color |
| 262 inactiveColor:(NSColor*)inactiveColor { |
| 263 color_.reset([color retain]); |
| 264 inactiveColor_.reset([inactiveColor retain]); |
| 265 } |
| 266 |
| 250 @end | 267 @end |
| 251 | 268 |
| 252 @interface ShellFramelessNSWindow : ShellCustomFrameNSWindow | 269 @interface ShellFramelessNSWindow : ShellNSWindow |
| 253 | 270 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view; |
| 254 @end | 271 @end |
| 255 | 272 |
| 256 @implementation ShellFramelessNSWindow | 273 @implementation ShellFramelessNSWindow |
| 257 | 274 |
| 275 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view { |
| 276 } |
| 277 |
| 258 + (NSRect)frameRectForContentRect:(NSRect)contentRect | 278 + (NSRect)frameRectForContentRect:(NSRect)contentRect |
| 259 styleMask:(NSUInteger)mask { | 279 styleMask:(NSUInteger)mask { |
| 260 return contentRect; | 280 return contentRect; |
| 261 } | 281 } |
| 262 | 282 |
| 263 + (NSRect)contentRectForFrameRect:(NSRect)frameRect | 283 + (NSRect)contentRectForFrameRect:(NSRect)frameRect |
| 264 styleMask:(NSUInteger)mask { | 284 styleMask:(NSUInteger)mask { |
| 265 return frameRect; | 285 return frameRect; |
| 266 } | 286 } |
| 267 | 287 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 const AppWindow::CreateParams& params) | 319 const AppWindow::CreateParams& params) |
| 300 : app_window_(app_window), | 320 : app_window_(app_window), |
| 301 has_frame_(params.frame == AppWindow::FRAME_CHROME), | 321 has_frame_(params.frame == AppWindow::FRAME_CHROME), |
| 302 is_hidden_(false), | 322 is_hidden_(false), |
| 303 is_hidden_with_app_(false), | 323 is_hidden_with_app_(false), |
| 304 is_maximized_(false), | 324 is_maximized_(false), |
| 305 is_fullscreen_(false), | 325 is_fullscreen_(false), |
| 306 is_resizable_(params.resizable), | 326 is_resizable_(params.resizable), |
| 307 shows_resize_controls_(true), | 327 shows_resize_controls_(true), |
| 308 shows_fullscreen_controls_(true), | 328 shows_fullscreen_controls_(true), |
| 329 has_frame_color_(params.has_frame_color), |
| 330 active_frame_color_(params.active_frame_color), |
| 331 inactive_frame_color_(params.inactive_frame_color), |
| 309 attention_request_id_(0) { | 332 attention_request_id_(0) { |
| 310 Observe(web_contents()); | 333 Observe(web_contents()); |
| 311 | 334 |
| 312 base::scoped_nsobject<NSWindow> window; | 335 base::scoped_nsobject<NSWindow> window; |
| 313 Class window_class; | 336 Class window_class; |
| 314 if (has_frame_) { | 337 if (has_frame_) { |
| 315 bool should_use_native_frame = | 338 window_class = has_frame_color_ ? |
| 316 CommandLine::ForCurrentProcess()->HasSwitch( | 339 [ShellCustomFrameNSWindow class] : [ShellNSWindow class]; |
| 317 switches::kAppsUseNativeFrame); | |
| 318 window_class = should_use_native_frame ? | |
| 319 [ShellNSWindow class] : [ShellCustomFrameNSWindow class]; | |
| 320 } else { | 340 } else { |
| 321 window_class = [ShellFramelessNSWindow class]; | 341 window_class = [ShellFramelessNSWindow class]; |
| 322 } | 342 } |
| 323 | 343 |
| 324 // Estimate the initial bounds of the window. Once the frame insets are known, | 344 // Estimate the initial bounds of the window. Once the frame insets are known, |
| 325 // the window bounds and constraints can be set precisely. | 345 // the window bounds and constraints can be set precisely. |
| 326 NSRect cocoa_bounds = GfxToCocoaBounds( | 346 NSRect cocoa_bounds = GfxToCocoaBounds( |
| 327 params.GetInitialWindowBounds(gfx::Insets())); | 347 params.GetInitialWindowBounds(gfx::Insets())); |
| 328 window.reset([[window_class alloc] | 348 window.reset([[window_class alloc] |
| 329 initWithContentRect:cocoa_bounds | 349 initWithContentRect:cocoa_bounds |
| 330 styleMask:GetWindowStyleMask() | 350 styleMask:GetWindowStyleMask() |
| 331 backing:NSBackingStoreBuffered | 351 backing:NSBackingStoreBuffered |
| 332 defer:NO]); | 352 defer:NO]); |
| 333 [window setTitle:base::SysUTF8ToNSString(extension()->name())]; | 353 [window setTitle:base::SysUTF8ToNSString(extension()->name())]; |
| 334 [[window contentView] cr_setWantsLayer:YES]; | 354 [[window contentView] cr_setWantsLayer:YES]; |
| 355 if (has_frame_ && has_frame_color_) { |
| 356 [base::mac::ObjCCastStrict<ShellCustomFrameNSWindow>(window) |
| 357 setColor:gfx::SkColorToSRGBNSColor(active_frame_color_) |
| 358 inactiveColor:gfx::SkColorToSRGBNSColor(inactive_frame_color_)]; |
| 359 } |
| 335 | 360 |
| 336 if (base::mac::IsOSSnowLeopard() && | 361 if (base::mac::IsOSSnowLeopard() && |
| 337 [window respondsToSelector:@selector(setBottomCornerRounded:)]) | 362 [window respondsToSelector:@selector(setBottomCornerRounded:)]) |
| 338 [window setBottomCornerRounded:NO]; | 363 [window setBottomCornerRounded:NO]; |
| 339 | 364 |
| 340 if (params.always_on_top) | 365 if (params.always_on_top) |
| 341 [window setLevel:AlwaysOnTopWindowLevel()]; | 366 [window setLevel:AlwaysOnTopWindowLevel()]; |
| 342 InitCollectionBehavior(window); | 367 InitCollectionBehavior(window); |
| 343 | 368 |
| 344 window_controller_.reset( | 369 window_controller_.reset( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 366 window, | 391 window, |
| 367 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY, | 392 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY, |
| 368 NULL)); | 393 NULL)); |
| 369 } | 394 } |
| 370 | 395 |
| 371 NSUInteger NativeAppWindowCocoa::GetWindowStyleMask() const { | 396 NSUInteger NativeAppWindowCocoa::GetWindowStyleMask() const { |
| 372 NSUInteger style_mask = NSTitledWindowMask | NSClosableWindowMask | | 397 NSUInteger style_mask = NSTitledWindowMask | NSClosableWindowMask | |
| 373 NSMiniaturizableWindowMask; | 398 NSMiniaturizableWindowMask; |
| 374 if (shows_resize_controls_) | 399 if (shows_resize_controls_) |
| 375 style_mask |= NSResizableWindowMask; | 400 style_mask |= NSResizableWindowMask; |
| 376 if (!has_frame_ || | 401 if (!has_frame_) |
| 377 !CommandLine::ForCurrentProcess()->HasSwitch( | |
| 378 switches::kAppsUseNativeFrame)) { | |
| 379 style_mask |= NSTexturedBackgroundWindowMask; | 402 style_mask |= NSTexturedBackgroundWindowMask; |
| 380 } | |
| 381 return style_mask; | 403 return style_mask; |
| 382 } | 404 } |
| 383 | 405 |
| 384 void NativeAppWindowCocoa::InstallView() { | 406 void NativeAppWindowCocoa::InstallView() { |
| 385 NSView* view = web_contents()->GetView()->GetNativeView(); | 407 NSView* view = web_contents()->GetView()->GetNativeView(); |
| 386 if (has_frame_) { | 408 if (has_frame_) { |
| 387 [view setFrame:[[window() contentView] bounds]]; | 409 [view setFrame:[[window() contentView] bounds]]; |
| 388 [[window() contentView] addSubview:view]; | 410 [[window() contentView] addSubview:view]; |
| 389 if (!shows_fullscreen_controls_) | 411 if (!shows_fullscreen_controls_) |
| 390 [[window() standardWindowButton:NSWindowZoomButton] setEnabled:NO]; | 412 [[window() standardWindowButton:NSWindowZoomButton] setEnabled:NO]; |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 void NativeAppWindowCocoa::RenderViewCreated(content::RenderViewHost* rvh) { | 734 void NativeAppWindowCocoa::RenderViewCreated(content::RenderViewHost* rvh) { |
| 713 if (IsActive()) | 735 if (IsActive()) |
| 714 web_contents()->GetView()->RestoreFocus(); | 736 web_contents()->GetView()->RestoreFocus(); |
| 715 } | 737 } |
| 716 | 738 |
| 717 bool NativeAppWindowCocoa::IsFrameless() const { | 739 bool NativeAppWindowCocoa::IsFrameless() const { |
| 718 return !has_frame_; | 740 return !has_frame_; |
| 719 } | 741 } |
| 720 | 742 |
| 721 bool NativeAppWindowCocoa::HasFrameColor() const { | 743 bool NativeAppWindowCocoa::HasFrameColor() const { |
| 722 // TODO(benwells): Implement this. | 744 return has_frame_color_; |
| 723 return false; | |
| 724 } | 745 } |
| 725 | 746 |
| 726 SkColor NativeAppWindowCocoa::ActiveFrameColor() const { | 747 SkColor NativeAppWindowCocoa::ActiveFrameColor() const { |
| 727 // TODO(benwells): Implement this. | 748 return active_frame_color_; |
| 728 return SkColor(); | |
| 729 } | 749 } |
| 730 | 750 |
| 731 SkColor NativeAppWindowCocoa::InactiveFrameColor() const { | 751 SkColor NativeAppWindowCocoa::InactiveFrameColor() const { |
| 732 // TODO(benwells): Implement this. | 752 return inactive_frame_color_; |
| 733 return SkColor(); | |
| 734 } | 753 } |
| 735 | 754 |
| 736 gfx::Insets NativeAppWindowCocoa::GetFrameInsets() const { | 755 gfx::Insets NativeAppWindowCocoa::GetFrameInsets() const { |
| 737 if (!has_frame_) | 756 if (!has_frame_) |
| 738 return gfx::Insets(); | 757 return gfx::Insets(); |
| 739 | 758 |
| 740 // Flip the coordinates based on the main screen. | 759 // Flip the coordinates based on the main screen. |
| 741 NSInteger screen_height = | 760 NSInteger screen_height = |
| 742 NSHeight([[[NSScreen screens] objectAtIndex:0] frame]); | 761 NSHeight([[[NSScreen screens] objectAtIndex:0] frame]); |
| 743 | 762 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 NSRect screen = [[window() screen] visibleFrame]; | 837 NSRect screen = [[window() screen] visibleFrame]; |
| 819 if (!NSEqualSizes(frame.size, screen.size)) | 838 if (!NSEqualSizes(frame.size, screen.size)) |
| 820 is_maximized_ = false; | 839 is_maximized_ = false; |
| 821 else if (NSEqualPoints(frame.origin, screen.origin)) | 840 else if (NSEqualPoints(frame.origin, screen.origin)) |
| 822 is_maximized_ = true; | 841 is_maximized_ = true; |
| 823 | 842 |
| 824 // Update |is_fullscreen_| if needed. | 843 // Update |is_fullscreen_| if needed. |
| 825 is_fullscreen_ = ([window() styleMask] & NSFullScreenWindowMask) != 0; | 844 is_fullscreen_ = ([window() styleMask] & NSFullScreenWindowMask) != 0; |
| 826 // If not fullscreen but the window is constrained, disable the fullscreen UI | 845 // If not fullscreen but the window is constrained, disable the fullscreen UI |
| 827 // control. | 846 // control. |
| 828 if (!is_fullscreen_ && !shows_fullscreen_controls_) | 847 if (!is_fullscreen_ && !shows_fullscreen_controls_ && |
| 848 base::mac::IsOSLionOrLater()) { |
| 829 SetFullScreenCollectionBehavior(window(), false); | 849 SetFullScreenCollectionBehavior(window(), false); |
| 850 } |
| 830 | 851 |
| 831 UpdateRestoredBounds(); | 852 UpdateRestoredBounds(); |
| 832 } | 853 } |
| 833 | 854 |
| 834 void NativeAppWindowCocoa::WindowDidResize() { | 855 void NativeAppWindowCocoa::WindowDidResize() { |
| 835 app_window_->OnNativeWindowChanged(); | 856 app_window_->OnNativeWindowChanged(); |
| 836 UpdateDraggableRegionViews(); | 857 UpdateDraggableRegionViews(); |
| 837 } | 858 } |
| 838 | 859 |
| 839 void NativeAppWindowCocoa::WindowDidMove() { | 860 void NativeAppWindowCocoa::WindowDidMove() { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 is_resizable_ && !size_constraints_.HasFixedSize(); | 930 is_resizable_ && !size_constraints_.HasFixedSize(); |
| 910 shows_fullscreen_controls_ = | 931 shows_fullscreen_controls_ = |
| 911 is_resizable_ && !size_constraints_.HasMaximumSize() && has_frame_; | 932 is_resizable_ && !size_constraints_.HasMaximumSize() && has_frame_; |
| 912 | 933 |
| 913 if (!is_fullscreen_) { | 934 if (!is_fullscreen_) { |
| 914 [window() setStyleMask:GetWindowStyleMask()]; | 935 [window() setStyleMask:GetWindowStyleMask()]; |
| 915 | 936 |
| 916 // Set the window to participate in Lion Fullscreen mode. Setting this flag | 937 // Set the window to participate in Lion Fullscreen mode. Setting this flag |
| 917 // has no effect on Snow Leopard or earlier. UI controls for fullscreen are | 938 // has no effect on Snow Leopard or earlier. UI controls for fullscreen are |
| 918 // only shown for apps that have unbounded size. | 939 // only shown for apps that have unbounded size. |
| 919 SetFullScreenCollectionBehavior(window(), shows_fullscreen_controls_); | 940 if (base::mac::IsOSLionOrLater()) |
| 941 SetFullScreenCollectionBehavior(window(), shows_fullscreen_controls_); |
| 920 } | 942 } |
| 921 | 943 |
| 922 if (has_frame_) { | 944 if (has_frame_) { |
| 923 [window() setShowsResizeIndicator:shows_resize_controls_]; | 945 [window() setShowsResizeIndicator:shows_resize_controls_]; |
| 924 [[window() standardWindowButton:NSWindowZoomButton] | 946 [[window() standardWindowButton:NSWindowZoomButton] |
| 925 setEnabled:shows_fullscreen_controls_]; | 947 setEnabled:shows_fullscreen_controls_]; |
| 926 } | 948 } |
| 927 } | 949 } |
| 928 | 950 |
| 929 void NativeAppWindowCocoa::SetAlwaysOnTop(bool always_on_top) { | 951 void NativeAppWindowCocoa::SetAlwaysOnTop(bool always_on_top) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 941 } | 963 } |
| 942 | 964 |
| 943 void NativeAppWindowCocoa::UpdateRestoredBounds() { | 965 void NativeAppWindowCocoa::UpdateRestoredBounds() { |
| 944 if (IsRestored(*this)) | 966 if (IsRestored(*this)) |
| 945 restored_bounds_ = [window() frame]; | 967 restored_bounds_ = [window() frame]; |
| 946 } | 968 } |
| 947 | 969 |
| 948 void NativeAppWindowCocoa::HideWithoutMarkingHidden() { | 970 void NativeAppWindowCocoa::HideWithoutMarkingHidden() { |
| 949 [window() orderOut:window_controller_]; | 971 [window() orderOut:window_controller_]; |
| 950 } | 972 } |
| OLD | NEW |