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

Side by Side Diff: ui/views/cocoa/bridged_content_view.mm

Issue 1718043003: MacViews: Clip contents for non-rectangular windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #import "ui/views/cocoa/bridged_content_view.h" 5 #import "ui/views/cocoa/bridged_content_view.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #import "base/mac/mac_util.h" 8 #import "base/mac/mac_util.h"
9 #import "base/mac/scoped_nsobject.h" 9 #import "base/mac/scoped_nsobject.h"
10 #include "base/strings/sys_string_conversions.h" 10 #include "base/strings/sys_string_conversions.h"
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 eventFlags:(int)eventFlags; 184 eventFlags:(int)eventFlags;
185 185
186 // Menu action handlers. 186 // Menu action handlers.
187 - (void)undo:(id)sender; 187 - (void)undo:(id)sender;
188 - (void)redo:(id)sender; 188 - (void)redo:(id)sender;
189 - (void)cut:(id)sender; 189 - (void)cut:(id)sender;
190 - (void)copy:(id)sender; 190 - (void)copy:(id)sender;
191 - (void)paste:(id)sender; 191 - (void)paste:(id)sender;
192 - (void)selectAll:(id)sender; 192 - (void)selectAll:(id)sender;
193 193
194 // Update windowMask_ as per the current view bounds.
195 - (void)updateWindowMask;
196
194 @end 197 @end
195 198
196 @implementation BridgedContentView 199 @implementation BridgedContentView
197 200
198 @synthesize hostedView = hostedView_; 201 @synthesize hostedView = hostedView_;
199 @synthesize textInputClient = textInputClient_; 202 @synthesize textInputClient = textInputClient_;
200 @synthesize drawMenuBackgroundForBlur = drawMenuBackgroundForBlur_; 203 @synthesize drawMenuBackgroundForBlur = drawMenuBackgroundForBlur_;
201 @synthesize mouseDownCanMoveWindow = mouseDownCanMoveWindow_; 204 @synthesize mouseDownCanMoveWindow = mouseDownCanMoveWindow_;
202 205
203 - (id)initWithView:(views::View*)viewToHost { 206 - (id)initWithView:(views::View*)viewToHost {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 views::View::ConvertPointToTarget(hostedView_, view, &viewPoint); 263 views::View::ConvertPointToTarget(hostedView_, view, &viewPoint);
261 if (!view->GetTooltipText(viewPoint, &newTooltipText)) 264 if (!view->GetTooltipText(viewPoint, &newTooltipText))
262 DCHECK(newTooltipText.empty()); 265 DCHECK(newTooltipText.empty());
263 } 266 }
264 if (newTooltipText != lastTooltipText_) { 267 if (newTooltipText != lastTooltipText_) {
265 std::swap(newTooltipText, lastTooltipText_); 268 std::swap(newTooltipText, lastTooltipText_);
266 [self setToolTipAtMousePoint:base::SysUTF16ToNSString(lastTooltipText_)]; 269 [self setToolTipAtMousePoint:base::SysUTF16ToNSString(lastTooltipText_)];
267 } 270 }
268 } 271 }
269 272
270 - (void)updateWindowMask { 273 - (void)onSizeChanged {
271 DCHECK(![self inLiveResize]); 274 [self updateWindowMask];
272 DCHECK(base::mac::IsOSMavericksOrEarlier()); 275 }
273 DCHECK(hostedView_);
274 276
275 views::Widget* widget = hostedView_->GetWidget(); 277 - (NSBezierPath*)windowMask {
276 if (!widget->non_client_view()) 278 return windowMask_.get();
277 return;
278
279 const NSRect frameRect = [self bounds];
280 gfx::Path mask;
281 widget->non_client_view()->GetWindowMask(gfx::Size(frameRect.size), &mask);
282 if (mask.isEmpty())
283 return;
284
285 windowMask_.reset([gfx::CreateNSBezierPathFromSkPath(mask) retain]);
286
287 // Convert to AppKit coordinate system.
288 NSAffineTransform* flipTransform = [NSAffineTransform transform];
289 [flipTransform translateXBy:0.0 yBy:frameRect.size.height];
290 [flipTransform scaleXBy:1.0 yBy:-1.0];
291 [windowMask_ transformUsingAffineTransform:flipTransform];
292 } 279 }
293 280
294 // BridgedContentView private implementation. 281 // BridgedContentView private implementation.
295 282
296 - (void)handleKeyEvent:(NSEvent*)theEvent { 283 - (void)handleKeyEvent:(NSEvent*)theEvent {
297 if (!hostedView_) 284 if (!hostedView_)
298 return; 285 return;
299 286
300 DCHECK(theEvent); 287 DCHECK(theEvent);
301 ui::KeyEvent event(theEvent); 288 ui::KeyEvent event(theEvent);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 } 359 }
373 360
374 - (void)selectAll:(id)sender { 361 - (void)selectAll:(id)sender {
375 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_SELECT_ALL)); 362 DCHECK(textInputClient_->IsEditCommandEnabled(IDS_APP_SELECT_ALL));
376 [self handleAction:IDS_APP_SELECT_ALL 363 [self handleAction:IDS_APP_SELECT_ALL
377 keyCode:ui::VKEY_A 364 keyCode:ui::VKEY_A
378 domCode:ui::DomCode::US_A 365 domCode:ui::DomCode::US_A
379 eventFlags:ui::EF_CONTROL_DOWN]; 366 eventFlags:ui::EF_CONTROL_DOWN];
380 } 367 }
381 368
369 - (void)updateWindowMask {
370 DCHECK(hostedView_);
371
372 views::Widget* widget = hostedView_->GetWidget();
373 if (!widget->non_client_view())
374 return;
375
376 const NSRect frameRect = [self bounds];
377 gfx::Path mask;
378 widget->non_client_view()->GetWindowMask(gfx::Size(frameRect.size), &mask);
379 if (mask.isEmpty())
380 return;
381
382 windowMask_.reset([gfx::CreateNSBezierPathFromSkPath(mask) retain]);
383
384 // Convert to AppKit coordinate system.
385 NSAffineTransform* flipTransform = [NSAffineTransform transform];
386 [flipTransform translateXBy:0.0 yBy:frameRect.size.height];
387 [flipTransform scaleXBy:1.0 yBy:-1.0];
388 [windowMask_ transformUsingAffineTransform:flipTransform];
389 }
390
382 // BaseView implementation. 391 // BaseView implementation.
383 392
384 // Don't use tracking areas from BaseView. BridgedContentView's tracks 393 // Don't use tracking areas from BaseView. BridgedContentView's tracks
385 // NSTrackingCursorUpdate and Apple's documentation suggests it's incompatible. 394 // NSTrackingCursorUpdate and Apple's documentation suggests it's incompatible.
386 - (void)enableTracking { 395 - (void)enableTracking {
387 } 396 }
388 397
389 // Translates the location of |theEvent| to toolkit-views coordinates and passes 398 // Translates the location of |theEvent| to toolkit-views coordinates and passes
390 // the event to NativeWidgetMac for handling. 399 // the event to NativeWidgetMac for handling.
391 - (void)mouseEvent:(NSEvent*)theEvent { 400 - (void)mouseEvent:(NSEvent*)theEvent {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 [super setFrameSize:newSize]; 437 [super setFrameSize:newSize];
429 if (!hostedView_) 438 if (!hostedView_)
430 return; 439 return;
431 440
432 hostedView_->SetSize(gfx::Size(newSize.width, newSize.height)); 441 hostedView_->SetSize(gfx::Size(newSize.width, newSize.height));
433 } 442 }
434 443
435 - (void)viewDidEndLiveResize { 444 - (void)viewDidEndLiveResize {
436 [super viewDidEndLiveResize]; 445 [super viewDidEndLiveResize];
437 446
438 // We prevent updating the window mask and clipping the border around the 447 // During a live resize, we prevent clipping the border around the view, which
439 // view, during a live resize. Hence update the window mask and redraw the 448 // is required to generate drop shadows on OSX 10.9. Hence redraw the view
440 // view after resize has completed. 449 // after resize has completed.
441 if (base::mac::IsOSMavericksOrEarlier()) { 450 if (base::mac::IsOSMavericksOrEarlier())
442 [self updateWindowMask];
443 [self setNeedsDisplay:YES]; 451 [self setNeedsDisplay:YES];
444 }
445 } 452 }
446 453
447 - (void)drawRect:(NSRect)dirtyRect { 454 - (void)drawRect:(NSRect)dirtyRect {
448 // Note that BridgedNativeWidget uses -[NSWindow setAutodisplay:NO] to 455 // Note that BridgedNativeWidget uses -[NSWindow setAutodisplay:NO] to
449 // suppress calls to this when the window is known to be hidden. 456 // suppress calls to this when the window is known to be hidden.
450 if (!hostedView_) 457 if (!hostedView_)
451 return; 458 return;
452 459
453 if (drawMenuBackgroundForBlur_) { 460 if (drawMenuBackgroundForBlur_) {
454 const CGFloat radius = views::MenuConfig::instance().corner_radius; 461 const CGFloat radius = views::MenuConfig::instance().corner_radius;
455 [skia::SkColorToSRGBNSColor(0x01000000) set]; 462 [skia::SkColorToSRGBNSColor(0x01000000) set];
456 [[NSBezierPath bezierPathWithRoundedRect:[self bounds] 463 [[NSBezierPath bezierPathWithRoundedRect:[self bounds]
457 xRadius:radius 464 xRadius:radius
458 yRadius:radius] fill]; 465 yRadius:radius] fill];
459 } 466 }
460 467
461 // On OS versions earlier than Yosemite, to generate a drop shadow, we set an 468 // On OS versions earlier than Yosemite, to generate a drop shadow, we set an
462 // opaque background. This causes windows with non rectangular shapes to have 469 // opaque background. This causes windows with non rectangular shapes to have
463 // square corners. To get around this, fill the path outside the window 470 // square corners. To get around this, fill the path outside the window
464 // boundary with clearColor and tell Cococa to regenerate drop shadow. See 471 // boundary with clearColor and tell Cococa to regenerate drop shadow. See
465 // crbug.com/543671. 472 // crbug.com/543671.
466 if (windowMask_ && ![self inLiveResize] && 473 if (windowMask_ && ![self inLiveResize] &&
467 !IsRectInsidePath(dirtyRect, windowMask_)) { 474 !IsRectInsidePath(dirtyRect, windowMask_) &&
468 DCHECK(base::mac::IsOSMavericksOrEarlier()); 475 base::mac::IsOSMavericksOrEarlier()) {
469 gfx::ScopedNSGraphicsContextSaveGState state; 476 gfx::ScopedNSGraphicsContextSaveGState state;
470 477
471 // The outer rectangular path corresponding to the window. 478 // The outer rectangular path corresponding to the window.
472 NSBezierPath* outerPath = [NSBezierPath bezierPathWithRect:[self bounds]]; 479 NSBezierPath* outerPath = [NSBezierPath bezierPathWithRect:[self bounds]];
473 480
474 [outerPath appendBezierPath:windowMask_]; 481 [outerPath appendBezierPath:windowMask_];
475 [outerPath setWindingRule:NSEvenOddWindingRule]; 482 [outerPath setWindingRule:NSEvenOddWindingRule];
476 [[NSGraphicsContext currentContext] 483 [[NSGraphicsContext currentContext]
477 setCompositingOperation:NSCompositeCopy]; 484 setCompositingOperation:NSCompositeCopy];
478 [[NSColor clearColor] set]; 485 [[NSColor clearColor] set];
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 } 911 }
905 912
906 return [super accessibilityAttributeValue:attribute]; 913 return [super accessibilityAttributeValue:attribute];
907 } 914 }
908 915
909 - (id)accessibilityHitTest:(NSPoint)point { 916 - (id)accessibilityHitTest:(NSPoint)point {
910 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point]; 917 return [hostedView_->GetNativeViewAccessible() accessibilityHitTest:point];
911 } 918 }
912 919
913 @end 920 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698