Commit c41b4fb5 authored by Dana Fried's avatar Dana Fried Committed by Commit Bot

Show window title in tablet mode on Windows

Because we now show the caption bar and caption buttons in Windows in
tablet mode in order to provide a dedicated grab handle for moving to/
from split-screen mode (and protect user gestures to open the tabstrip)
there is now empty space above the toolbar.

Filling this empty space with the window title:
- makes us consistent with PWA windows
- provides access to the page title without opening the tabstrip

Currently, this change only affects Windows and not ChromeOS.

Screenshot (Google only):
https://photos.google.com/share/AF1QipP8IFSTPydtpfbRM5vXfqQEfVDPVwq1kJDBMtCwes8AqxEqUdjIwsi5i2v1hUpmFg?key=WFkxdDVZR2ktU3c2dWNPU1lCRFRJSk55TGUtTDFR

Bug: 1116651
Change-Id: Ib90149c6d46bf740505d1a06be824b85d3e5dee1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2364958Reviewed-by: default avatarCollin Baker <collinbaker@chromium.org>
Commit-Queue: Dana Fried <dfried@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800389}
parent 9300cc67
...@@ -2346,15 +2346,39 @@ views::View* BrowserView::GetInitiallyFocusedView() { ...@@ -2346,15 +2346,39 @@ views::View* BrowserView::GetInitiallyFocusedView() {
return nullptr; return nullptr;
} }
#if defined(OS_WIN)
bool BrowserView::CanShowWindowTitle() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR) ||
WebUITabStripContainerView::SupportsTouchableTabStrip(browser());
}
bool BrowserView::CanShowWindowIcon() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR);
}
#endif
bool BrowserView::ShouldShowWindowTitle() const { bool BrowserView::ShouldShowWindowTitle() const {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// For Chrome OS only, trusted windows (apps and settings) do not show a // For Chrome OS only, trusted windows (apps and settings) do not show a
// title, crbug.com/119411. Child windows (i.e. popups) do show a title. // title, crbug.com/119411. Child windows (i.e. popups) do show a title.
if (browser_->is_trusted_source()) { if (browser_->is_trusted_source())
return false; return false;
} #elif defined(OS_WIN)
#endif // OS_CHROMEOS // On Windows in touch mode we display a window title.
if (WebUITabStripContainerView::UseTouchableTabStrip(browser()))
return true;
#endif
return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR);
}
bool BrowserView::ShouldShowWindowIcon() const {
#if defined(OS_CHROMEOS)
// For Chrome OS only, trusted windows (apps and settings) do not show a
// window icon, crbug.com/119411. Child windows (i.e. popups) do show an icon.
if (browser_->is_trusted_source())
return false;
#endif
return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR);
} }
...@@ -2391,11 +2415,6 @@ gfx::ImageSkia BrowserView::GetWindowIcon() { ...@@ -2391,11 +2415,6 @@ gfx::ImageSkia BrowserView::GetWindowIcon() {
return gfx::ImageSkia(); return gfx::ImageSkia();
} }
bool BrowserView::ShouldShowWindowIcon() const {
// Currently the icon and title are always shown together.
return ShouldShowWindowTitle();
}
bool BrowserView::ExecuteWindowsCommand(int command_id) { bool BrowserView::ExecuteWindowsCommand(int command_id) {
// This function handles WM_SYSCOMMAND, WM_APPCOMMAND, and WM_COMMAND. // This function handles WM_SYSCOMMAND, WM_APPCOMMAND, and WM_COMMAND.
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -2971,8 +2990,9 @@ void BrowserView::LoadingAnimationCallback() { ...@@ -2971,8 +2990,9 @@ void BrowserView::LoadingAnimationCallback() {
// be correct). // be correct).
tabstrip_->UpdateLoadingAnimations(base::TimeTicks::Now() - tabstrip_->UpdateLoadingAnimations(base::TimeTicks::Now() -
loading_animation_start_); loading_animation_start_);
} else if (ShouldShowWindowIcon()) { }
// ... or in the window icon area for popups and app windows.
if (ShouldShowWindowIcon()) {
WebContents* web_contents = WebContents* web_contents =
browser_->tab_strip_model()->GetActiveWebContents(); browser_->tab_strip_model()->GetActiveWebContents();
// GetActiveWebContents can return null for example under Purify when // GetActiveWebContents can return null for example under Purify when
......
...@@ -270,6 +270,16 @@ class BrowserView : public BrowserWindow, ...@@ -270,6 +270,16 @@ class BrowserView : public BrowserWindow,
// page. // page.
bool IsTopControlsSlideBehaviorEnabled() const; bool IsTopControlsSlideBehaviorEnabled() const;
#if defined(OS_WIN)
// Returns whether the browser can ever display a titlebar. Used in Windows
// touch mode. Possibly expand to ChromeOS if we add a titlebar back there in
// touch mode.
bool CanShowWindowTitle() const;
// Returns whether the browser can ever display a window icon.
bool CanShowWindowIcon() const;
#endif
// Returns the current shown ratio of the top browser controls. // Returns the current shown ratio of the top browser controls.
float GetTopControlsSlideBehaviorShownRatio() const; float GetTopControlsSlideBehaviorShownRatio() const;
......
...@@ -92,7 +92,7 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, ...@@ -92,7 +92,7 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
// is true. Everything else here is only used when // is true. Everything else here is only used when
// ShouldCustomDrawSystemTitlebar() is true. // ShouldCustomDrawSystemTitlebar() is true.
if (browser_view->ShouldShowWindowIcon()) { if (browser_view->CanShowWindowIcon()) {
InitThrobberIcons(); InitThrobberIcons();
window_icon_ = new TabIconView(this, nullptr); window_icon_ = new TabIconView(this, nullptr);
...@@ -115,7 +115,7 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, ...@@ -115,7 +115,7 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame,
// The window title appears above the web app frame toolbar (if present), // The window title appears above the web app frame toolbar (if present),
// which surrounds the title with minimal-ui buttons on the left, // which surrounds the title with minimal-ui buttons on the left,
// and other controls (such as the app menu button) on the right. // and other controls (such as the app menu button) on the right.
if (browser_view->ShouldShowWindowTitle()) { if (browser_view->CanShowWindowTitle()) {
window_title_ = new views::Label(browser_view->GetWindowTitle()); window_title_ = new views::Label(browser_view->GetWindowTitle());
window_title_->SetSubpixelRenderingEnabled(false); window_title_->SetSubpixelRenderingEnabled(false);
window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
...@@ -207,20 +207,18 @@ SkColor GlassBrowserFrameView::GetCaptionColor( ...@@ -207,20 +207,18 @@ SkColor GlassBrowserFrameView::GetCaptionColor(
} }
void GlassBrowserFrameView::UpdateThrobber(bool running) { void GlassBrowserFrameView::UpdateThrobber(bool running) {
if (ShowCustomIcon()) if (ShouldShowWindowIcon(TitlebarType::kCustom)) {
window_icon_->Update(); window_icon_->Update();
} else if (ShouldShowWindowIcon(TitlebarType::kSystem)) {
if (!ShowSystemIcon()) if (throbber_running_) {
return; if (running) {
DisplayNextThrobberFrame();
if (throbber_running_) { } else {
if (running) { StopThrobber();
DisplayNextThrobberFrame(); }
} else { } else if (running) {
StopThrobber(); StartThrobber();
} }
} else if (running) {
StartThrobber();
} }
} }
...@@ -278,7 +276,7 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { ...@@ -278,7 +276,7 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
// See if we're in the sysmenu region. We still have to check the tabstrip // See if we're in the sysmenu region. We still have to check the tabstrip
// first so that clicks in a tab don't get treated as sysmenu clicks. // first so that clicks in a tab don't get treated as sysmenu clicks.
if (browser_view()->ShouldShowWindowIcon() && frame_component != HTCLIENT) { if (frame_component != HTCLIENT && ShouldShowWindowIcon(TitlebarType::kAny)) {
gfx::Rect sys_menu_region( gfx::Rect sys_menu_region(
0, display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSIZEFRAME), 0, display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSIZEFRAME),
display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSMICON), display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXSMICON),
...@@ -291,7 +289,7 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { ...@@ -291,7 +289,7 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
return frame_component; return frame_component;
// Then see if the point is within any of the window controls. // Then see if the point is within any of the window controls.
if (OwnsCaptionButtons()) { if (caption_button_container_) {
gfx::Point local_point = point; gfx::Point local_point = point;
ConvertPointToTarget(parent(), caption_button_container_, &local_point); ConvertPointToTarget(parent(), caption_button_container_, &local_point);
if (caption_button_container_->HitTestPoint(local_point)) { if (caption_button_container_->HitTestPoint(local_point)) {
...@@ -344,15 +342,14 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) { ...@@ -344,15 +342,14 @@ int GlassBrowserFrameView::NonClientHitTest(const gfx::Point& point) {
} }
void GlassBrowserFrameView::UpdateWindowIcon() { void GlassBrowserFrameView::UpdateWindowIcon() {
if (ShowCustomIcon() && !frame()->IsFullscreen()) if (window_icon_ && window_icon_->GetVisible())
window_icon_->SchedulePaint(); window_icon_->SchedulePaint();
} }
void GlassBrowserFrameView::UpdateWindowTitle() { void GlassBrowserFrameView::UpdateWindowTitle() {
if (ShowCustomTitle() && !frame()->IsFullscreen()) { LayoutTitleBar();
LayoutTitleBar(); if (window_title_ && window_title_->GetVisible())
window_title_->SchedulePaint(); window_title_->SchedulePaint();
}
} }
void GlassBrowserFrameView::ResetWindowControls() { void GlassBrowserFrameView::ResetWindowControls() {
...@@ -368,13 +365,13 @@ void GlassBrowserFrameView::ButtonPressed(views::Button* sender, ...@@ -368,13 +365,13 @@ void GlassBrowserFrameView::ButtonPressed(views::Button* sender,
} }
bool GlassBrowserFrameView::ShouldTabIconViewAnimate() const { bool GlassBrowserFrameView::ShouldTabIconViewAnimate() const {
DCHECK(ShowCustomIcon()); DCHECK(ShouldShowWindowIcon(TitlebarType::kCustom));
content::WebContents* current_tab = browser_view()->GetActiveWebContents(); content::WebContents* current_tab = browser_view()->GetActiveWebContents();
return current_tab && current_tab->IsLoading(); return current_tab && current_tab->IsLoading();
} }
gfx::ImageSkia GlassBrowserFrameView::GetFaviconForTabIconView() { gfx::ImageSkia GlassBrowserFrameView::GetFaviconForTabIconView() {
DCHECK(ShowCustomIcon()); DCHECK(ShouldShowWindowIcon(TitlebarType::kCustom));
return frame()->widget_delegate()->GetWindowIcon(); return frame()->widget_delegate()->GetWindowIcon();
} }
...@@ -402,12 +399,8 @@ void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) { ...@@ -402,12 +399,8 @@ void GlassBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
void GlassBrowserFrameView::Layout() { void GlassBrowserFrameView::Layout() {
TRACE_EVENT0("views.frame", "GlassBrowserFrameView::Layout"); TRACE_EVENT0("views.frame", "GlassBrowserFrameView::Layout");
if (ShouldCustomDrawSystemTitlebar() || IsWebUITabStrip()) LayoutCaptionButtons();
LayoutCaptionButtons(); LayoutTitleBar();
if (ShouldCustomDrawSystemTitlebar())
LayoutTitleBar();
LayoutClientView(); LayoutClientView();
} }
...@@ -550,25 +543,24 @@ int GlassBrowserFrameView::MinimizeButtonX() const { ...@@ -550,25 +543,24 @@ int GlassBrowserFrameView::MinimizeButtonX() const {
: frame()->GetMinimizeButtonOffset(); : frame()->GetMinimizeButtonOffset();
} }
bool GlassBrowserFrameView::ShowCustomIcon() const { bool GlassBrowserFrameView::ShouldShowWindowIcon(TitlebarType type) const {
// Web-app windows don't include the window icon as per UI mocks. if (type == TitlebarType::kCustom && !ShouldCustomDrawSystemTitlebar())
return !web_app_frame_toolbar() && ShouldCustomDrawSystemTitlebar() && return false;
browser_view()->ShouldShowWindowIcon(); if (type == TitlebarType::kSystem && ShouldCustomDrawSystemTitlebar())
} return false;
if (frame()->IsFullscreen() || browser_view()->IsBrowserTypeWebApp())
bool GlassBrowserFrameView::ShowCustomTitle() const { return false;
return ShouldCustomDrawSystemTitlebar() && return browser_view()->ShouldShowWindowIcon();
browser_view()->ShouldShowWindowTitle();
}
bool GlassBrowserFrameView::ShowSystemIcon() const {
return !ShouldCustomDrawSystemTitlebar() &&
browser_view()->ShouldShowWindowIcon();
} }
bool GlassBrowserFrameView::OwnsCaptionButtons() const { bool GlassBrowserFrameView::ShouldShowWindowTitle(TitlebarType type) const {
return caption_button_container_ && if (type == TitlebarType::kCustom && !ShouldCustomDrawSystemTitlebar())
caption_button_container_->parent() == this; return false;
if (type == TitlebarType::kSystem && ShouldCustomDrawSystemTitlebar())
return false;
if (frame()->IsFullscreen())
return false;
return browser_view()->ShouldShowWindowTitle();
} }
SkColor GlassBrowserFrameView::GetTitlebarColor() const { SkColor GlassBrowserFrameView::GetTitlebarColor() const {
...@@ -642,14 +634,21 @@ void GlassBrowserFrameView::PaintTitlebar(gfx::Canvas* canvas) const { ...@@ -642,14 +634,21 @@ void GlassBrowserFrameView::PaintTitlebar(gfx::Canvas* canvas) const {
frame_overlay_image.height() * scale, true); frame_overlay_image.height() * scale, true);
} }
if (ShowCustomTitle()) if (ShouldShowWindowTitle(TitlebarType::kCustom)) {
window_title_->SetEnabledColor( window_title_->SetEnabledColor(
GetCaptionColor(BrowserFrameActiveState::kUseCurrent)); GetCaptionColor(BrowserFrameActiveState::kUseCurrent));
}
} }
void GlassBrowserFrameView::LayoutTitleBar() { void GlassBrowserFrameView::LayoutTitleBar() {
TRACE_EVENT0("views.frame", "GlassBrowserFrameView::LayoutTitleBar"); TRACE_EVENT0("views.frame", "GlassBrowserFrameView::LayoutTitleBar");
if (!ShowCustomIcon() && !ShowCustomTitle()) const bool show_icon = ShouldShowWindowIcon(TitlebarType::kCustom);
const bool show_title = ShouldShowWindowTitle(TitlebarType::kCustom);
if (window_icon_)
window_icon_->SetVisible(show_icon);
if (window_title_)
window_title_->SetVisible(show_title);
if (!show_icon && !show_title && !web_app_frame_toolbar())
return; return;
const int icon_size = const int icon_size =
...@@ -671,7 +670,7 @@ void GlassBrowserFrameView::LayoutTitleBar() { ...@@ -671,7 +670,7 @@ void GlassBrowserFrameView::LayoutTitleBar() {
gfx::Rect(next_leading_x, y, icon_size, icon_size); gfx::Rect(next_leading_x, y, icon_size, icon_size);
constexpr int kIconTitleSpacing = 5; constexpr int kIconTitleSpacing = 5;
if (ShowCustomIcon()) { if (show_icon) {
window_icon_->SetBoundsRect(window_icon_bounds); window_icon_->SetBoundsRect(window_icon_bounds);
next_leading_x = window_icon_bounds.right() + kIconTitleSpacing; next_leading_x = window_icon_bounds.right() + kIconTitleSpacing;
} }
...@@ -685,7 +684,7 @@ void GlassBrowserFrameView::LayoutTitleBar() { ...@@ -685,7 +684,7 @@ void GlassBrowserFrameView::LayoutTitleBar() {
next_trailing_x = remaining_bounds.second; next_trailing_x = remaining_bounds.second;
} }
if (ShowCustomTitle()) { if (show_title) {
// If nothing has been added to the left, match native Windows 10 UWP apps // If nothing has been added to the left, match native Windows 10 UWP apps
// that don't have window icons. // that don't have window icons.
constexpr int kMinimumTitleLeftBorderMargin = 11; constexpr int kMinimumTitleLeftBorderMargin = 11;
...@@ -701,8 +700,16 @@ void GlassBrowserFrameView::LayoutTitleBar() { ...@@ -701,8 +700,16 @@ void GlassBrowserFrameView::LayoutTitleBar() {
void GlassBrowserFrameView::LayoutCaptionButtons() { void GlassBrowserFrameView::LayoutCaptionButtons() {
TRACE_EVENT0("views.frame", "GlassBrowserFrameView::LayoutCaptionButtons"); TRACE_EVENT0("views.frame", "GlassBrowserFrameView::LayoutCaptionButtons");
if (!OwnsCaptionButtons()) if (!caption_button_container_)
return;
// Non-custom system titlebar already contains caption buttons.
if (!ShouldCustomDrawSystemTitlebar()) {
caption_button_container_->SetVisible(false);
return; return;
}
caption_button_container_->SetVisible(true);
const gfx::Size preferred_size = const gfx::Size preferred_size =
caption_button_container_->GetPreferredSize(); caption_button_container_->GetPreferredSize();
...@@ -722,7 +729,7 @@ void GlassBrowserFrameView::LayoutClientView() { ...@@ -722,7 +729,7 @@ void GlassBrowserFrameView::LayoutClientView() {
} }
void GlassBrowserFrameView::StartThrobber() { void GlassBrowserFrameView::StartThrobber() {
DCHECK(ShowSystemIcon()); DCHECK(ShouldShowWindowIcon(TitlebarType::kSystem));
if (!throbber_running_) { if (!throbber_running_) {
throbber_running_ = true; throbber_running_ = true;
throbber_frame_ = 0; throbber_frame_ = 0;
...@@ -734,7 +741,7 @@ void GlassBrowserFrameView::StartThrobber() { ...@@ -734,7 +741,7 @@ void GlassBrowserFrameView::StartThrobber() {
} }
void GlassBrowserFrameView::StopThrobber() { void GlassBrowserFrameView::StopThrobber() {
DCHECK(ShowSystemIcon()); DCHECK(ShouldShowWindowIcon(TitlebarType::kSystem));
if (throbber_running_) { if (throbber_running_) {
throbber_running_ = false; throbber_running_ = false;
......
...@@ -86,6 +86,17 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView, ...@@ -86,6 +86,17 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView,
private: private:
friend class GlassBrowserCaptionButtonContainer; friend class GlassBrowserCaptionButtonContainer;
// Describes the type of titlebar that a window might have; used to query
// whether specific elements may be present.
enum class TitlebarType {
// A custom drawn titlebar, with window title and/or icon.
kCustom,
// The system titlebar, drawn by Windows.
kSystem,
// Any visible titlebar.
kAny
};
// Returns the thickness of the window border for the left, right, and bottom // Returns the thickness of the window border for the left, right, and bottom
// edges of the frame. On Windows 10 this is a mostly-transparent handle that // edges of the frame. On Windows 10 this is a mostly-transparent handle that
// allows you to resize the window. // allows you to resize the window.
...@@ -118,15 +129,13 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView, ...@@ -118,15 +129,13 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView,
// edge of the caption buttons. // edge of the caption buttons.
int MinimizeButtonX() const; int MinimizeButtonX() const;
bool ShowCustomIcon() const; // Returns whether or not the window should display an icon of the specified
bool ShowCustomTitle() const; // |type|.
bool ShowSystemIcon() const; bool ShouldShowWindowIcon(TitlebarType type) const;
// Returns true if caption buttons are present on the frame (as opposed to // Returns whether or not the window should display a title of the specified
// somewhere else, or not present at all). In some modes, the frame can "lend" // |type|.
// the caption buttons to another view which needs to display them - e.g. in bool ShouldShowWindowTitle(TitlebarType type) const;
// tablet mode on Windows.
bool OwnsCaptionButtons() const;
// Paint various sub-components of this view. // Paint various sub-components of this view.
void PaintTitlebar(gfx::Canvas* canvas) const; void PaintTitlebar(gfx::Canvas* canvas) const;
......
...@@ -476,6 +476,13 @@ WebUITabStripContainerView::~WebUITabStripContainerView() { ...@@ -476,6 +476,13 @@ WebUITabStripContainerView::~WebUITabStripContainerView() {
delete tab_counter_; delete tab_counter_;
} }
// static
bool WebUITabStripContainerView::SupportsTouchableTabStrip(
const Browser* browser) {
return browser->is_type_normal() &&
base::FeatureList::IsEnabled(features::kWebUITabStrip);
}
// static // static
bool WebUITabStripContainerView::UseTouchableTabStrip(const Browser* browser) { bool WebUITabStripContainerView::UseTouchableTabStrip(const Browser* browser) {
return browser->is_type_normal() && return browser->is_type_normal() &&
......
...@@ -53,6 +53,7 @@ class WebUITabStripContainerView : public TabStripUIEmbedder, ...@@ -53,6 +53,7 @@ class WebUITabStripContainerView : public TabStripUIEmbedder,
views::View* omnibox); views::View* omnibox);
~WebUITabStripContainerView() override; ~WebUITabStripContainerView() override;
static bool SupportsTouchableTabStrip(const Browser* browser);
static bool UseTouchableTabStrip(const Browser* browser); static bool UseTouchableTabStrip(const Browser* browser);
// For drag-and-drop support: // For drag-and-drop support:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment