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

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: Review. 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?
480 NSRect frame = [window_ frame];
481 frame.size = ui::kWindowSizeDeterminedLater.size;
482 if (state_ != kBubbleHidden) {
483 frame = CalculateWindowFrame(/*expand=*/false);
484 }
485 [window_ setFrame:frame display:NO];
455 [parent_ removeChildWindow:window_]; // See crbug.com/28107 ... 486 [parent_ removeChildWindow:window_]; // See crbug.com/28107 ...
456 [window_ orderOut:nil]; // ... and crbug.com/29054. 487 [window_ orderOut:nil]; // ... and crbug.com/29054.
457 488
458 [[window_ contentView] setThemeProvider:nil]; 489 [[window_ contentView] setThemeProvider:nil];
459 } 490 }
460 491
461 void StatusBubbleMac::AnimationDidStop() { 492 void StatusBubbleMac::AnimationDidStop() {
462 DCHECK([NSThread isMainThread]); 493 DCHECK([NSThread isMainThread]);
463 DCHECK(state_ == kBubbleShowingFadeIn || state_ == kBubbleHidingFadeOut); 494 DCHECK(state_ == kBubbleShowingFadeIn || state_ == kBubbleHidingFadeOut);
464 DCHECK(is_attached()); 495 DCHECK(is_attached());
465 496
466 if (state_ == kBubbleShowingFadeIn) { 497 if (state_ == kBubbleShowingFadeIn) {
467 DCHECK_EQ([[window_ animator] alphaValue], kBubbleOpacity); 498 DCHECK_EQ([[window_ animator] alphaValue], kBubbleOpacity);
468 SetState(kBubbleShown); 499 SetState(kBubbleShown);
469 } else { 500 } else {
470 DCHECK_EQ([[window_ animator] alphaValue], 0.0); 501 DCHECK_EQ([[window_ animator] alphaValue], 0.0);
471 SetState(kBubbleHidden); 502 SetState(kBubbleHidden);
472 } 503 }
473 } 504 }
474 505
475 void StatusBubbleMac::SetState(StatusBubbleState state) { 506 void StatusBubbleMac::SetState(StatusBubbleState state) {
476 if (state == state_) 507 if (state == state_)
477 return; 508 return;
478 509
479 if (state == kBubbleHidden) { 510 if (state == kBubbleHidden) {
511 is_expanded_ = false;
512
480 // When hidden (with alpha of 0), make the window have the minimum size, 513 // 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 514 // 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 515 // origin to 0,0 as that will cause the window to use more space in
483 // Expose/Mission Control. See http://crbug.com/81969. 516 // Expose/Mission Control. See http://crbug.com/81969.
484 // 517 //
485 // Also, doing it this way instead of detaching the window avoids bugs with 518 // 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. 519 // Spaces and Cmd-`. See http://crbug.com/31821 and http://crbug.com/61629.
487 NSRect frame = [window_ frame]; 520 NSRect frame = [window_ frame];
488 frame.size = ui::kWindowSizeDeterminedLater.size; 521 frame.size = ui::kWindowSizeDeterminedLater.size;
489 [window_ setFrame:frame display:YES]; 522 [window_ setFrame:frame display:YES];
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 [NSAnimationContext beginGrouping]; 748 [NSAnimationContext beginGrouping];
716 [[NSAnimationContext currentContext] setDuration:kExpansionDurationSeconds]; 749 [[NSAnimationContext currentContext] setDuration:kExpansionDurationSeconds];
717 [[window_ animator] setFrame:actual_window_frame display:YES]; 750 [[window_ animator] setFrame:actual_window_frame display:YES];
718 [NSAnimationContext endGrouping]; 751 [NSAnimationContext endGrouping];
719 } 752 }
720 753
721 void StatusBubbleMac::UpdateSizeAndPosition() { 754 void StatusBubbleMac::UpdateSizeAndPosition() {
722 if (!window_) 755 if (!window_)
723 return; 756 return;
724 757
725 // Hidden bubbles always have size equal to ui::kWindowSizeDeterminedLater. 758 // There is no need to update the size if the bubble is hidden.
726 if (state_ == kBubbleHidden) { 759 if (state_ == kBubbleHidden) {
727 NSRect frame = [window_ frame]; 760 // Verify that hidden bubbles always have size equal to
728 frame.size = ui::kWindowSizeDeterminedLater.size; 761 // ui::kWindowSizeDeterminedLater.
729 [window_ setFrame:frame display:YES]; 762 DCHECK_EQ(ui::kWindowSizeDeterminedLater.size.width,
763 [window_ frame].size.width);
764 DCHECK_EQ(ui::kWindowSizeDeterminedLater.size.height,
765 [window_ frame].size.height);
730 return; 766 return;
731 } 767 }
732 768
733 SetFrameAvoidingMouse(CalculateWindowFrame(/*expand=*/false), 769 SetFrameAvoidingMouse(CalculateWindowFrame(/*expand=*/false),
734 GetMouseLocation()); 770 GetMouseLocation());
735 } 771 }
736 772
737 void StatusBubbleMac::SwitchParentWindow(NSWindow* parent) { 773 void StatusBubbleMac::SwitchParentWindow(NSWindow* parent) {
738 DCHECK(parent); 774 DCHECK(parent);
739 DCHECK(is_attached()); 775 DCHECK(is_attached());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 } 824 }
789 825
790 // Round the top corners when the bubble is below the parent window. 826 // Round the top corners when the bubble is below the parent window.
791 if (NSMinY(window_frame) < NSMinY(parent_frame)) { 827 if (NSMinY(window_frame) < NSMinY(parent_frame)) {
792 corner_flags |= kRoundedTopLeftCorner | kRoundedTopRightCorner; 828 corner_flags |= kRoundedTopLeftCorner | kRoundedTopRightCorner;
793 } 829 }
794 } 830 }
795 831
796 return corner_flags; 832 return corner_flags;
797 } 833 }
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