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

Side by Side Diff: chrome/browser/ui/cocoa/status_bubble_mac.mm

Issue 968263005: [Mac] Cleans up the StatusBubbleMac code. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Crash fixes. Created 5 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
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/status_bubble_mac.h" 5 #include "chrome/browser/ui/cocoa/status_bubble_mac.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 changes([NSAnimationContext currentContext]); 135 changes([NSAnimationContext currentContext]);
136 // At this point, -animationForKey should have been called by CoreAnimation 136 // At this point, -animationForKey should have been called by CoreAnimation
137 // to set up the animation to run. Verify this. 137 // to set up the animation to run. Verify this.
138 DCHECK(completionHandler_ == nil); 138 DCHECK(completionHandler_ == nil);
139 [NSAnimationContext endGrouping]; 139 [NSAnimationContext endGrouping];
140 } 140 }
141 } 141 }
142 142
143 @end 143 @end
144 144
145 // Mac implementation of the status bubble.
146 //
147 // Child windows interact with Spaces in interesting ways, so this code has to
148 // follow these rules:
149 //
150 // 1) NSWindows cannot have zero size. At times when the status bubble window
151 // has no specific size (for example, when hidden), its size is set to
152 // ui::kWindowSizeDeterminedLater.
153 //
154 // 2) Child window frames are in the coordinate space of the screen, not of the
155 // parent window. If a child window has its origin at (0, 0), Spaces will
156 // position it in the corner of the screen but group it with the parent
157 // window in Spaces. This causes Chrome windows to have a large (mostly
158 // blank) area in Spaces. To avoid this, child windows always have their
159 // origin set to the lower-left corner of the window.
160 //
161 // 3) Detached child windows may show up as top-level windows in Spaces. To
162 // avoid this, once the status bubble is Attach()ed to the parent, it is
163 // never detached (except in rare cases when reparenting to a fullscreen
164 // window).
165 //
166 // 4) To avoid unnecessary redraws, if a bubble is in the kBubbleHidden state,
167 // its size is always set to ui::kWindowSizeDeterminedLater. The proper
168 // width for the current URL or status text is not calculated until the
169 // bubble leaves the kBubbleHidden state.
170
145 StatusBubbleMac::StatusBubbleMac(NSWindow* parent, id delegate) 171 StatusBubbleMac::StatusBubbleMac(NSWindow* parent, id delegate)
146 : parent_(parent), 172 : parent_(parent),
147 delegate_(delegate), 173 delegate_(delegate),
148 window_(nil), 174 window_(nil),
149 status_text_(nil), 175 status_text_(nil),
150 url_text_(nil), 176 url_text_(nil),
151 state_(kBubbleHidden), 177 state_(kBubbleHidden),
152 immediate_(false), 178 immediate_(false),
153 is_expanded_(false), 179 is_expanded_(false),
154 timer_factory_(this), 180 timer_factory_(this),
(...skipping 16 matching lines...) Expand all
171 197
172 void StatusBubbleMac::SetStatus(const base::string16& status) { 198 void StatusBubbleMac::SetStatus(const base::string16& status) {
173 SetText(status, false); 199 SetText(status, false);
174 } 200 }
175 201
176 void StatusBubbleMac::SetURL(const GURL& url, const std::string& languages) { 202 void StatusBubbleMac::SetURL(const GURL& url, const std::string& languages) {
177 url_ = url; 203 url_ = url;
178 languages_ = languages; 204 languages_ = languages;
179 205
180 CGFloat bubble_width = NSWidth([window_ frame]); 206 CGFloat bubble_width = NSWidth([window_ frame]);
181
182 // Reset frame size when bubble is hidden.
183 if (state_ == kBubbleHidden) { 207 if (state_ == kBubbleHidden) {
184 is_expanded_ = false; 208 DCHECK_EQ(ui::kWindowSizeDeterminedLater.size.width,
185 NSRect frame = [window_ frame]; 209 [window_ frame].size.width);
186 frame.size = ui::kWindowSizeDeterminedLater.size; 210 DCHECK_EQ(ui::kWindowSizeDeterminedLater.size.height,
187 [window_ setFrame:frame display:NO]; 211 [window_ frame].size.height);
188 bubble_width = NSWidth(CalculateWindowFrame(/*expand=*/false)); 212 bubble_width = NSWidth(CalculateWindowFrame(/*expand=*/false));
189 } 213 }
190 214
191 int text_width = static_cast<int>(bubble_width - 215 int text_width = static_cast<int>(bubble_width -
192 kBubbleViewTextPositionX - 216 kBubbleViewTextPositionX -
193 kTextPadding); 217 kTextPadding);
194 218
195 // Scale from view to window coordinates before eliding URL string. 219 // Scale from view to window coordinates before eliding URL string.
196 NSSize scaled_width = NSMakeSize(text_width, 0); 220 NSSize scaled_width = NSMakeSize(text_width, 0);
197 scaled_width = [[parent_ contentView] convertSize:scaled_width fromView:nil]; 221 scaled_width = [[parent_ contentView] convertSize:scaled_width fromView:nil];
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 [window_ orderFront:nil]; 468 [window_ orderFront:nil];
445 [parent_ addChildWindow:window_ ordered:NSWindowAbove]; 469 [parent_ addChildWindow:window_ ordered:NSWindowAbove];
446 470
447 [[window_ contentView] setThemeProvider:parent_]; 471 [[window_ contentView] setThemeProvider:parent_];
448 } 472 }
449 473
450 void StatusBubbleMac::Detach() { 474 void StatusBubbleMac::Detach() {
451 DCHECK(is_attached()); 475 DCHECK(is_attached());
452 476
453 // Magic setFrame: See http://crbug.com/58506 and http://crrev.com/3564021 . 477 // Magic setFrame: See http://crbug.com/58506 and http://crrev.com/3564021 .
454 [window_ setFrame:CalculateWindowFrame(/*expand=*/false) display:NO]; 478 // TODO(rohitrao): Does the frame size actually matter here? Can we always
479 // set it to kWindowSizeDeterminedLater?
rohitrao (ping after 24h) 2015/03/03 15:54:00 I think we can probably get away with always using
480 NSRect frame = CalculateWindowFrame(/*expand=*/false);
481 if (state_ == kBubbleHidden) {
482 frame.size = ui::kWindowSizeDeterminedLater.size;
erikchen 2015/03/03 18:19:50 """ NSRect frame = ui::kWindowSizeDeterminedLater.
rohitrao (ping after 24h) 2015/03/03 18:53:51 Done.
483 }
484 [window_ setFrame:frame display:NO];
455 [parent_ removeChildWindow:window_]; // See crbug.com/28107 ... 485 [parent_ removeChildWindow:window_]; // See crbug.com/28107 ...
456 [window_ orderOut:nil]; // ... and crbug.com/29054. 486 [window_ orderOut:nil]; // ... and crbug.com/29054.
457 487
458 [[window_ contentView] setThemeProvider:nil]; 488 [[window_ contentView] setThemeProvider:nil];
459 } 489 }
460 490
461 void StatusBubbleMac::AnimationDidStop() { 491 void StatusBubbleMac::AnimationDidStop() {
462 DCHECK([NSThread isMainThread]); 492 DCHECK([NSThread isMainThread]);
463 DCHECK(state_ == kBubbleShowingFadeIn || state_ == kBubbleHidingFadeOut); 493 DCHECK(state_ == kBubbleShowingFadeIn || state_ == kBubbleHidingFadeOut);
464 DCHECK(is_attached()); 494 DCHECK(is_attached());
465 495
466 if (state_ == kBubbleShowingFadeIn) { 496 if (state_ == kBubbleShowingFadeIn) {
467 DCHECK_EQ([[window_ animator] alphaValue], kBubbleOpacity); 497 DCHECK_EQ([[window_ animator] alphaValue], kBubbleOpacity);
468 SetState(kBubbleShown); 498 SetState(kBubbleShown);
469 } else { 499 } else {
470 DCHECK_EQ([[window_ animator] alphaValue], 0.0); 500 DCHECK_EQ([[window_ animator] alphaValue], 0.0);
471 SetState(kBubbleHidden); 501 SetState(kBubbleHidden);
472 } 502 }
473 } 503 }
474 504
475 void StatusBubbleMac::SetState(StatusBubbleState state) { 505 void StatusBubbleMac::SetState(StatusBubbleState state) {
476 if (state == state_) 506 if (state == state_)
477 return; 507 return;
478 508
479 if (state == kBubbleHidden) { 509 if (state == kBubbleHidden) {
510 is_expanded_ = false;
erikchen 2015/03/03 18:19:50 is_expanded_ gets set to false in several location
rohitrao (ping after 24h) 2015/03/03 18:53:51 Agreed. I don't fully understand when it needs to
rohitrao (ping after 24h) 2015/03/03 18:53:51 Agreed. I don't fully understand when it needs to
511
480 // When hidden (with alpha of 0), make the window have the minimum size, 512 // When hidden (with alpha of 0), make the window have the minimum size,
481 // while still keeping the same origin. It's important to not set the 513 // while still keeping the same origin. It's important to not set the
482 // origin to 0,0 as that will cause the window to use more space in 514 // origin to 0,0 as that will cause the window to use more space in
483 // Expose/Mission Control. See http://crbug.com/81969. 515 // Expose/Mission Control. See http://crbug.com/81969.
484 // 516 //
485 // Also, doing it this way instead of detaching the window avoids bugs with 517 // Also, doing it this way instead of detaching the window avoids bugs with
486 // Spaces and Cmd-`. See http://crbug.com/31821 and http://crbug.com/61629. 518 // Spaces and Cmd-`. See http://crbug.com/31821 and http://crbug.com/61629.
487 NSRect frame = [window_ frame]; 519 NSRect frame = [window_ frame];
488 frame.size = ui::kWindowSizeDeterminedLater.size; 520 frame.size = ui::kWindowSizeDeterminedLater.size;
489 [window_ setFrame:frame display:YES]; 521 [window_ setFrame:frame display:YES];
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 [NSAnimationContext beginGrouping]; 747 [NSAnimationContext beginGrouping];
716 [[NSAnimationContext currentContext] setDuration:kExpansionDurationSeconds]; 748 [[NSAnimationContext currentContext] setDuration:kExpansionDurationSeconds];
717 [[window_ animator] setFrame:actual_window_frame display:YES]; 749 [[window_ animator] setFrame:actual_window_frame display:YES];
718 [NSAnimationContext endGrouping]; 750 [NSAnimationContext endGrouping];
719 } 751 }
720 752
721 void StatusBubbleMac::UpdateSizeAndPosition() { 753 void StatusBubbleMac::UpdateSizeAndPosition() {
722 if (!window_) 754 if (!window_)
723 return; 755 return;
724 756
725 // Hidden bubbles always have size equal to ui::kWindowSizeDeterminedLater. 757 // There is no need to update the size if the bubble is hidden.
726 if (state_ == kBubbleHidden) { 758 if (state_ == kBubbleHidden) {
727 NSRect frame = [window_ frame]; 759 // Verify that hidden bubbles always have size equal to
728 frame.size = ui::kWindowSizeDeterminedLater.size; 760 // ui::kWindowSizeDeterminedLater.
729 [window_ setFrame:frame display:YES]; 761 DCHECK_EQ(ui::kWindowSizeDeterminedLater.size.width,
762 [window_ frame].size.width);
763 DCHECK_EQ(ui::kWindowSizeDeterminedLater.size.height,
764 [window_ frame].size.height);
730 return; 765 return;
731 } 766 }
732 767
733 SetFrameAvoidingMouse(CalculateWindowFrame(/*expand=*/false), 768 SetFrameAvoidingMouse(CalculateWindowFrame(/*expand=*/false),
734 GetMouseLocation()); 769 GetMouseLocation());
735 } 770 }
736 771
737 void StatusBubbleMac::SwitchParentWindow(NSWindow* parent) { 772 void StatusBubbleMac::SwitchParentWindow(NSWindow* parent) {
738 DCHECK(parent); 773 DCHECK(parent);
739 DCHECK(is_attached()); 774 DCHECK(is_attached());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 } 823 }
789 824
790 // Round the top corners when the bubble is below the parent window. 825 // Round the top corners when the bubble is below the parent window.
791 if (NSMinY(window_frame) < NSMinY(parent_frame)) { 826 if (NSMinY(window_frame) < NSMinY(parent_frame)) {
792 corner_flags |= kRoundedTopLeftCorner | kRoundedTopRightCorner; 827 corner_flags |= kRoundedTopLeftCorner | kRoundedTopRightCorner;
793 } 828 }
794 } 829 }
795 830
796 return corner_flags; 831 return corner_flags;
797 } 832 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/status_bubble_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698