Index: chrome/browser/ui/views/frame/glass_browser_frame_view.cc |
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc |
index 8f049ca733af21bec5a84a35c0459c14150e997d..5f8319600f31b495679d380b62aac83791a41537 100644 |
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc |
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc |
@@ -25,6 +25,7 @@ |
#include "skia/ext/image_operations.h" |
#include "ui/base/resource/resource_bundle_win.h" |
#include "ui/base/theme_provider.h" |
+#include "ui/display/display.h" |
#include "ui/display/win/dpi.h" |
#include "ui/display/win/screen_win.h" |
#include "ui/gfx/canvas.h" |
@@ -49,7 +50,7 @@ const int kNonClientRestoredExtraThickness = 11; |
// pixels at the end of the top and bottom edges trigger diagonal resizing. |
const int kResizeCornerWidth = 16; |
// How far the profile switcher button is from the left of the minimize button. |
-const int kProfileSwitcherButtonOffset = 5; |
+const int kProfileSwitcherButtonOffset = 1; |
// The content edge images have a shadow built into them. |
const int kContentEdgeShadowThickness = 2; |
// In restored mode, the New Tab button isn't at the same height as the caption |
@@ -60,11 +61,6 @@ const int kNewTabCaptionRestoredSpacing = 5; |
// similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid |
// looking too cluttered. |
const int kNewTabCaptionMaximizedSpacing = 16; |
-// Height of the profile switcher button. Same as the height of the Windows 7/8 |
-// caption buttons. |
-// TODO(bsep): Windows 10 caption buttons look very different and we would like |
-// the profile switcher button to match on that platform. |
-const int kProfileSwitcherButtonHeight = 20; |
// There is a small one-pixel strip right above the caption buttons in which the |
// resize border "peeks" through. |
const int kCaptionButtonTopInset = 1; |
@@ -99,7 +95,8 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, |
restore_button_(nullptr), |
close_button_(nullptr), |
throbber_running_(false), |
- throbber_frame_(0) { |
+ throbber_frame_(0), |
+ tab_strip_(nullptr) { |
// We initialize all fields despite some of them being unused in some modes, |
// since it's possible for modes to flip dynamically (e.g. if the user enables |
// a high-contrast theme). Throbber icons are only used when ShowSystemIcon() |
@@ -132,6 +129,10 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, |
} |
GlassBrowserFrameView::~GlassBrowserFrameView() { |
+ if (tab_strip_) { |
+ tab_strip_->RemoveObserver(this); |
+ tab_strip_ = nullptr; |
+ } |
} |
/////////////////////////////////////////////////////////////////////////////// |
@@ -148,12 +149,14 @@ gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip( |
// The profile switcher button is optionally displayed to the left of the |
// minimize button. |
- if (profile_switcher_.view()) { |
+ views::View* button_view = GetProfileSwitcherButton(); |
+ if (button_view) { |
const int old_end_x = end_x; |
- end_x -= profile_switcher_.view()->width() + kProfileSwitcherButtonOffset; |
+ end_x -= button_view->width() + kProfileSwitcherButtonOffset; |
// In non-maximized mode, allow the new tab button to slide completely |
// under the profile switcher button. |
+ // Note that the button should be "cozy" then, even if it's an MD button. |
if (!IsMaximized()) { |
end_x = std::min(end_x + GetLayoutSize(NEW_TAB_BUTTON).width() + |
kNewTabCaptionRestoredSpacing, |
@@ -213,8 +216,15 @@ gfx::Size GlassBrowserFrameView::GetMinimumSize() const { |
return min_size; |
} |
-views::View* GlassBrowserFrameView::GetProfileSwitcherView() const { |
- return profile_switcher_.view(); |
+views::MenuButton* GlassBrowserFrameView::GetProfileSwitcherButton() const { |
+ return profile_switcher_.button(); |
+} |
+ |
+void GlassBrowserFrameView::OnBrowserViewInitViewsComplete() { |
+ DCHECK(browser_view()->tabstrip()); |
+ DCHECK(!tab_strip_); |
+ tab_strip_ = browser_view()->tabstrip(); |
+ tab_strip_->AddObserver(this); |
} |
/////////////////////////////////////////////////////////////////////////////// |
@@ -270,8 +280,8 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { |
// See if the point is within the incognito icon or the profile switcher menu. |
if ((profile_indicator_icon() && |
profile_indicator_icon()->GetMirroredBounds().Contains(point)) || |
- (profile_switcher_.view() && |
- profile_switcher_.view()->GetMirroredBounds().Contains(point))) |
+ (GetProfileSwitcherButton() && |
+ GetProfileSwitcherButton()->GetMirroredBounds().Contains(point))) |
return HTCLIENT; |
int frame_component = frame()->client_view()->NonClientHitTest(point); |
@@ -434,8 +444,8 @@ bool GlassBrowserFrameView::DoesIntersectRect(const views::View* target, |
profile_indicator_icon() && |
profile_indicator_icon()->GetMirroredBounds().Intersects(rect); |
bool hit_profile_switcher_button = |
- profile_switcher_.view() && |
- profile_switcher_.view()->GetMirroredBounds().Intersects(rect); |
+ GetProfileSwitcherButton() && |
+ GetProfileSwitcherButton()->GetMirroredBounds().Intersects(rect); |
return hit_incognito_icon || hit_profile_switcher_button || |
!frame()->client_view()->bounds().Intersects(rect); |
} |
@@ -715,20 +725,44 @@ void GlassBrowserFrameView::FillClientEdgeRects(int x, |
canvas->FillRect(side, color); |
} |
+void GlassBrowserFrameView::TabStripMaxXChanged(TabStrip* tab_strip) { |
+ // May switch between cozy and tall MD avatar button here. |
+ DCHECK_EQ(tab_strip, tab_strip_); |
+ profile_switcher_.ButtonPreferredSizeChanged(); |
+} |
+ |
+void GlassBrowserFrameView::TabStripRemovedTabAt(TabStrip* tab_strip, |
+ int index) { |
+ // May switch between cozy and tall button here, too. TabStripMaxXChanged |
+ // is not enough when a tab other than the last tab is closed. |
+ DCHECK_EQ(tab_strip, tab_strip_); |
+ profile_switcher_.ButtonPreferredSizeChanged(); |
+} |
+ |
+void GlassBrowserFrameView::TabStripDeleted(TabStrip* tab_strip) { |
+ DCHECK_EQ(tab_strip, tab_strip_); |
+ DCHECK(tab_strip_); |
+ tab_strip_->RemoveObserver(this); |
+ tab_strip_ = nullptr; |
+} |
+ |
void GlassBrowserFrameView::LayoutProfileSwitcher() { |
DCHECK(browser_view()->IsRegularOrGuestSession()); |
- if (!profile_switcher_.view()) |
+ |
+ AvatarButton* avatar_button = profile_switcher_.button(); |
+ if (!avatar_button) |
return; |
- gfx::Size label_size = profile_switcher_.view()->GetPreferredSize(); |
+ gfx::Size button_size = avatar_button->GetPreferredSize(); |
+ int button_width = button_size.width(); |
+ int button_height = button_size.height(); |
int button_x; |
if (CaptionButtonsOnLeadingEdge()) { |
button_x = width() - frame()->GetMinimizeButtonOffset() + |
kProfileSwitcherButtonOffset; |
} else { |
- button_x = |
- MinimizeButtonX() - kProfileSwitcherButtonOffset - label_size.width(); |
+ button_x = MinimizeButtonX() - kProfileSwitcherButtonOffset - button_width; |
} |
int button_y = WindowTopY(); |
@@ -739,8 +773,15 @@ void GlassBrowserFrameView::LayoutProfileSwitcher() { |
// button the same way to match. |
button_y -= 1; |
} |
- profile_switcher_.view()->SetBounds(button_x, button_y, label_size.width(), |
- kProfileSwitcherButtonHeight); |
+ |
+ avatar_button->UpdateButtonHeightForPosition(button_x, &button_height); |
+ // If --force-device-scale-factor is specified it does not affect the size of |
+ // the title bar or caption buttons and therefore should not affect the size |
+ // of the avatar button, but it does, because the avatar button is a View. |
+ // To work around this we adjust for the difference between the forced and |
+ // real scaling factors here to make the button look right. |
+ AdjustForForcedDisplayScaleFactor(&button_height); |
+ avatar_button->SetBounds(button_x, button_y, button_width, button_height); |
} |
void GlassBrowserFrameView::LayoutIncognitoIcon() { |
@@ -749,9 +790,9 @@ void GlassBrowserFrameView::LayoutIncognitoIcon() { |
// In RTL, the icon needs to start after the caption buttons. |
if (CaptionButtonsOnLeadingEdge()) { |
x = width() - frame()->GetMinimizeButtonOffset() + |
- (profile_switcher_.view() ? (profile_switcher_.view()->width() + |
- kProfileSwitcherButtonOffset) |
- : 0); |
+ (GetProfileSwitcherButton() ? (GetProfileSwitcherButton()->width() + |
+ kProfileSwitcherButtonOffset) |
+ : 0); |
} |
const int bottom = GetTopInset(false) + browser_view()->GetTabStripHeight() - |
kAvatarIconPadding; |
@@ -910,6 +951,20 @@ void GlassBrowserFrameView::DisplayNextThrobberFrame() { |
reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); |
} |
+void GlassBrowserFrameView::AdjustForForcedDisplayScaleFactor( |
+ int* height) const { |
+ DCHECK(height); |
+ if (!display::Display::HasForceDeviceScaleFactor()) |
+ return; |
+ |
+ HWND hwnd = views::HWNDForWidget(frame()); |
+ HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); |
+ float unforced_factor = |
+ display::win::ScreenWin::GetUnforcedMonitorScaleFactor(monitor); |
+ float forced_factor = display::Display::GetForcedDeviceScaleFactor(); |
+ *height *= unforced_factor / forced_factor; |
+} |
+ |
// static |
void GlassBrowserFrameView::InitThrobberIcons() { |
static bool initialized = false; |