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 |