Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: chrome/browser/ui/cocoa/apps/native_app_window_cocoa.mm

Issue 916833005: [Mac] Use a custom view to implement colored app windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix a couple of nits. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 17 matching lines...) Expand all
44 43
45 using extensions::AppWindow; 44 using extensions::AppWindow;
46 45
47 @interface NSWindow (NSPrivateApis) 46 @interface NSWindow (NSPrivateApis)
48 - (void)setBottomCornerRounded:(BOOL)rounded; 47 - (void)setBottomCornerRounded:(BOOL)rounded;
49 - (BOOL)_isTitleHidden; 48 - (BOOL)_isTitleHidden;
50 @end 49 @end
51 50
52 namespace { 51 namespace {
53 52
53 const CGFloat kTitlebarBackgroundViewPaintHeight = 60.0;
tapted 2015/02/19 03:11:02 nit: comment for this (i.e. why 60 -- does it just
jackhou1 2015/02/19 04:28:58 Done.
54
54 void SetFullScreenCollectionBehavior(NSWindow* window, bool allow_fullscreen) { 55 void SetFullScreenCollectionBehavior(NSWindow* window, bool allow_fullscreen) {
55 NSWindowCollectionBehavior behavior = [window collectionBehavior]; 56 NSWindowCollectionBehavior behavior = [window collectionBehavior];
56 if (allow_fullscreen) 57 if (allow_fullscreen)
57 behavior |= NSWindowCollectionBehaviorFullScreenPrimary; 58 behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
58 else 59 else
59 behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary; 60 behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary;
60 [window setCollectionBehavior:behavior]; 61 [window setCollectionBehavior:behavior];
61 } 62 }
62 63
63 void SetWorkspacesCollectionBehavior(NSWindow* window, bool always_visible) { 64 void SetWorkspacesCollectionBehavior(NSWindow* window, bool always_visible) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 202
202 - (BOOL)handledByExtensionCommand:(NSEvent*)event 203 - (BOOL)handledByExtensionCommand:(NSEvent*)event
203 priority:(ui::AcceleratorManager::HandlerPriority)priority { 204 priority:(ui::AcceleratorManager::HandlerPriority)priority {
204 if (appWindow_) 205 if (appWindow_)
205 return appWindow_->HandledByExtensionCommand(event, priority); 206 return appWindow_->HandledByExtensionCommand(event, priority);
206 return NO; 207 return NO;
207 } 208 }
208 209
209 @end 210 @end
210 211
211 // This is really a method on NSGrayFrame, so it should only be called on the 212 @implementation TitlebarBackgroundView
212 // view passed into -[NSWindow drawCustomFrameRect:forView:].
213 @interface NSView (PrivateMethods)
214 - (CGFloat)roundedCornerRadius;
215 @end
216 213
217 // TODO(jamescook): Should these be AppNSWindow to match AppWindow? 214 - (void)drawRect:(NSRect)rect {
218 // http://crbug.com/344082 215 // Only the top corners are rounded. For simplicity, round all 4 corners but
219 @interface ShellNSWindow : ChromeEventProcessingWindow 216 // draw the bottom corners outside of the visible bounds.
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
252 base::scoped_nsobject<NSColor> color_;
253 base::scoped_nsobject<NSColor> inactiveColor_;
254 }
255
256 - (void)setColor:(NSColor*)color
257 inactiveColor:(NSColor*)inactiveColor;
258
259 @end
260
261 @implementation ShellCustomFrameNSWindow
262
263 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view {
264 [[NSBezierPath bezierPathWithRect:rect] addClip];
265 [[NSColor clearColor] set];
266 NSRectFill(rect);
267
268 // Set up our clip.
269 CGFloat cornerRadius = 4.0; 217 CGFloat cornerRadius = 4.0;
270 if ([view respondsToSelector:@selector(roundedCornerRadius)]) 218 NSRect roundedRect = [self bounds];
271 cornerRadius = [view roundedCornerRadius]; 219 roundedRect.origin.y -= cornerRadius;
272 [[NSBezierPath bezierPathWithRoundedRect:[view bounds] 220 roundedRect.size.height += cornerRadius;
221 [[NSBezierPath bezierPathWithRoundedRect:roundedRect
273 xRadius:cornerRadius 222 xRadius:cornerRadius
274 yRadius:cornerRadius] addClip]; 223 yRadius:cornerRadius] addClip];
275 if ([self isMainWindow] || [self isKeyWindow]) 224 if ([[self window] isMainWindow] || [[self window] isKeyWindow])
276 [color_ set]; 225 [color_ set];
277 else 226 else
278 [inactiveColor_ set]; 227 [inactiveColor_ set];
279 NSRectFill(rect); 228 NSRectFill(rect);
280 } 229 }
281 230
282 - (void)setColor:(NSColor*)color 231 - (void)setColor:(NSColor*)color
283 inactiveColor:(NSColor*)inactiveColor { 232 inactiveColor:(NSColor*)inactiveColor {
284 color_.reset([color retain]); 233 color_.reset([color retain]);
285 inactiveColor_.reset([inactiveColor retain]); 234 inactiveColor_.reset([inactiveColor retain]);
286 } 235 }
287 236
288 @end 237 @end
289 238
239 // TODO(jamescook): Should these be AppNSWindow to match AppWindow?
240 // http://crbug.com/344082
241 @interface ShellNSWindow : ChromeEventProcessingWindow
242 @end
243
244 @implementation ShellNSWindow
245
246 // Similar to ChromeBrowserWindow, don't draw the title, but allow it to be seen
247 // in menus, Expose, etc.
248 - (BOOL)_isTitleHidden {
249 return YES;
250 }
251
252 @end
253
290 @interface ShellFramelessNSWindow : ShellNSWindow 254 @interface ShellFramelessNSWindow : ShellNSWindow
291 @end 255 @end
292 256
293 @implementation ShellFramelessNSWindow 257 @implementation ShellFramelessNSWindow
294 258
295 - (void)drawCustomFrameRect:(NSRect)rect forView:(NSView*)view {}
296
297 + (NSRect)frameRectForContentRect:(NSRect)contentRect 259 + (NSRect)frameRectForContentRect:(NSRect)contentRect
298 styleMask:(NSUInteger)mask { 260 styleMask:(NSUInteger)mask {
299 return contentRect; 261 return contentRect;
300 } 262 }
301 263
302 + (NSRect)contentRectForFrameRect:(NSRect)frameRect 264 + (NSRect)contentRectForFrameRect:(NSRect)frameRect
303 styleMask:(NSUInteger)mask { 265 styleMask:(NSUInteger)mask {
304 return frameRect; 266 return frameRect;
305 } 267 }
306 268
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 is_fullscreen_(false), 305 is_fullscreen_(false),
344 is_resizable_(params.resizable), 306 is_resizable_(params.resizable),
345 shows_resize_controls_(true), 307 shows_resize_controls_(true),
346 shows_fullscreen_controls_(true), 308 shows_fullscreen_controls_(true),
347 has_frame_color_(params.has_frame_color), 309 has_frame_color_(params.has_frame_color),
348 active_frame_color_(params.active_frame_color), 310 active_frame_color_(params.active_frame_color),
349 inactive_frame_color_(params.inactive_frame_color) { 311 inactive_frame_color_(params.inactive_frame_color) {
350 Observe(WebContents()); 312 Observe(WebContents());
351 313
352 base::scoped_nsobject<NSWindow> window; 314 base::scoped_nsobject<NSWindow> window;
353 Class window_class; 315 Class window_class = has_frame_ ?
354 if (has_frame_) { 316 [ShellNSWindow class] : [ShellFramelessNSWindow class];
355 window_class = has_frame_color_ ?
356 [ShellCustomFrameNSWindow class] : [ShellNSWindow class];
357 } else {
358 window_class = [ShellFramelessNSWindow class];
359 }
360 317
361 // Estimate the initial bounds of the window. Once the frame insets are known, 318 // Estimate the initial bounds of the window. Once the frame insets are known,
362 // the window bounds and constraints can be set precisely. 319 // the window bounds and constraints can be set precisely.
363 NSRect cocoa_bounds = GfxToCocoaBounds( 320 NSRect cocoa_bounds = GfxToCocoaBounds(
364 params.GetInitialWindowBounds(gfx::Insets())); 321 params.GetInitialWindowBounds(gfx::Insets()));
365 window.reset([[window_class alloc] 322 window.reset([[window_class alloc]
366 initWithContentRect:cocoa_bounds 323 initWithContentRect:cocoa_bounds
367 styleMask:GetWindowStyleMask() 324 styleMask:GetWindowStyleMask()
368 backing:NSBackingStoreBuffered 325 backing:NSBackingStoreBuffered
369 defer:NO]); 326 defer:NO]);
370 327
371 std::string name; 328 std::string name;
372 const extensions::Extension* extension = app_window_->GetExtension(); 329 const extensions::Extension* extension = app_window_->GetExtension();
373 if (extension) 330 if (extension)
374 name = extension->name(); 331 name = extension->name();
375 [window setTitle:base::SysUTF8ToNSString(name)]; 332 [window setTitle:base::SysUTF8ToNSString(name)];
376 [[window contentView] setWantsLayer:YES]; 333 [[window contentView] setWantsLayer:YES];
377 if (has_frame_ && has_frame_color_) { 334 if (has_frame_ && has_frame_color_) {
378 [base::mac::ObjCCastStrict<ShellCustomFrameNSWindow>(window) 335 NSView* window_view = [[window contentView] superview];
336 titlebar_background_view_.reset([[TitlebarBackgroundView alloc]
337 initWithFrame:NSMakeRect(0,
338 NSMaxY([window_view bounds]) -
339 kTitlebarBackgroundViewPaintHeight,
340 NSWidth([window_view bounds]),
341 kTitlebarBackgroundViewPaintHeight)]);
342 [titlebar_background_view_
343 setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin];
344 [window_view addSubview:titlebar_background_view_
345 positioned:NSWindowBelow
346 relativeTo:nil];
347 [titlebar_background_view_
379 setColor:gfx::SkColorToSRGBNSColor(active_frame_color_) 348 setColor:gfx::SkColorToSRGBNSColor(active_frame_color_)
380 inactiveColor:gfx::SkColorToSRGBNSColor(inactive_frame_color_)]; 349 inactiveColor:gfx::SkColorToSRGBNSColor(inactive_frame_color_)];
381 } 350 }
382 351
383 if (base::mac::IsOSSnowLeopard() && 352 if (base::mac::IsOSSnowLeopard() &&
384 [window respondsToSelector:@selector(setBottomCornerRounded:)]) 353 [window respondsToSelector:@selector(setBottomCornerRounded:)])
385 [window setBottomCornerRounded:NO]; 354 [window setBottomCornerRounded:NO];
386 355
387 if (params.always_on_top) 356 if (params.always_on_top)
388 [window setLevel:AlwaysOnTopWindowLevel()]; 357 [window setLevel:AlwaysOnTopWindowLevel()];
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 NOTIMPLEMENTED(); 782 NOTIMPLEMENTED();
814 } 783 }
815 784
816 void NativeAppWindowCocoa::WindowWillClose() { 785 void NativeAppWindowCocoa::WindowWillClose() {
817 [window_controller_ setAppWindow:NULL]; 786 [window_controller_ setAppWindow:NULL];
818 app_window_->OnNativeWindowChanged(); 787 app_window_->OnNativeWindowChanged();
819 app_window_->OnNativeClose(); 788 app_window_->OnNativeClose();
820 } 789 }
821 790
822 void NativeAppWindowCocoa::WindowDidBecomeKey() { 791 void NativeAppWindowCocoa::WindowDidBecomeKey() {
792 [titlebar_background_view_ setNeedsDisplay:YES];
823 content::RenderWidgetHostView* rwhv = 793 content::RenderWidgetHostView* rwhv =
824 WebContents()->GetRenderWidgetHostView(); 794 WebContents()->GetRenderWidgetHostView();
825 if (rwhv) 795 if (rwhv)
826 rwhv->SetActive(true); 796 rwhv->SetActive(true);
827 app_window_->OnNativeWindowActivated(); 797 app_window_->OnNativeWindowActivated();
828 798
829 WebContents()->RestoreFocus(); 799 WebContents()->RestoreFocus();
830 } 800 }
831 801
832 void NativeAppWindowCocoa::WindowDidResignKey() { 802 void NativeAppWindowCocoa::WindowDidResignKey() {
833 // If our app is still active and we're still the key window, ignore this 803 // 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") 804 // 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 805 // was activated; we'll get another |-windowDidResignKey| if we ever really
836 // lose key window status. 806 // lose key window status.
837 if ([NSApp isActive] && ([NSApp keyWindow] == window())) 807 if ([NSApp isActive] && ([NSApp keyWindow] == window()))
838 return; 808 return;
839 809
810 [titlebar_background_view_ setNeedsDisplay:YES];
811
840 WebContents()->StoreFocus(); 812 WebContents()->StoreFocus();
841 813
842 content::RenderWidgetHostView* rwhv = 814 content::RenderWidgetHostView* rwhv =
843 WebContents()->GetRenderWidgetHostView(); 815 WebContents()->GetRenderWidgetHostView();
844 if (rwhv) 816 if (rwhv)
845 rwhv->SetActive(false); 817 rwhv->SetActive(false);
846 } 818 }
847 819
848 void NativeAppWindowCocoa::WindowDidFinishResize() { 820 void NativeAppWindowCocoa::WindowDidFinishResize() {
849 // Update |is_maximized_| if needed: 821 // Update |is_maximized_| if needed:
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 } 973 }
1002 974
1003 void NativeAppWindowCocoa::UpdateRestoredBounds() { 975 void NativeAppWindowCocoa::UpdateRestoredBounds() {
1004 if (IsRestored(*this)) 976 if (IsRestored(*this))
1005 restored_bounds_ = [window() frame]; 977 restored_bounds_ = [window() frame];
1006 } 978 }
1007 979
1008 void NativeAppWindowCocoa::HideWithoutMarkingHidden() { 980 void NativeAppWindowCocoa::HideWithoutMarkingHidden() {
1009 [window() orderOut:window_controller_]; 981 [window() orderOut:window_controller_];
1010 } 982 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698