|
8 | 8 | #include "ui/gfx/animation/animation_runner.h" |
9 | 9 | #include "ui/gfx/canvas.h" |
10 | 10 | #include "ui/gfx/color_utils.h" |
11 | | -@@ -410,6 +411,10 @@ namespace { |
| 11 | +@@ -330,6 +331,8 @@ |
| 12 | + #include "ui/views/accessibility/view_accessibility.h" |
| 13 | + #include "ui/views/accessibility/view_accessibility_utils.h" |
| 14 | + #include "ui/views/animation/compositor_animation_runner.h" |
| 15 | ++#include "ui/views/animation/ink_drop.h" |
| 16 | ++#include "ui/views/animation/ink_drop_state.h" |
| 17 | + #include "ui/views/bubble/bubble_dialog_delegate_view.h" |
| 18 | + #include "ui/views/controls/button/menu_button.h" |
| 19 | + #include "ui/views/controls/textfield/textfield.h" |
| 20 | +@@ -410,6 +413,14 @@ namespace { |
12 | 21 | // The visible height of the shadow above the tabs. Clicks in this area are |
13 | 22 | // treated as clicks to the frame, rather than clicks to the tab. |
14 | 23 | const int kTabShadowSize = 2; |
15 | 24 | +constexpr int kZenModeRevealTriggerThickness = 10; |
16 | 25 | +constexpr int kZenModeChromeHoverLeeway = 8; |
17 | 26 | +constexpr base::TimeDelta kZenModeRevealAnimationDuration = |
18 | 27 | + base::Milliseconds(100); |
| 28 | ++constexpr base::TimeDelta kZenModeCursorExitGracePeriod = |
| 29 | ++ base::Milliseconds(1000); |
| 30 | ++constexpr base::TimeDelta kZenModeHoverExitGracePeriod = |
| 31 | ++ base::Milliseconds(250); |
19 | 32 |
|
20 | 33 | #if BUILDFLAG(IS_CHROMEOS) |
21 | 34 | // UMA histograms that record animation smoothness for tab loading animation. |
22 | | -@@ -955,7 +960,9 @@ BrowserView::BrowserView(Browser* browse |
| 35 | +@@ -955,7 +966,9 @@ BrowserView::BrowserView(Browser* browse |
23 | 36 | std::make_unique<ExclusiveAccessContextImpl>(*this)), |
24 | 37 | browser_(browser), |
25 | 38 | accessibility_mode_observer_( |
|
30 | 43 | if (auto* manager = InitialWebUIWindowMetricsManager::From(browser_.get())) { |
31 | 44 | manager->OnBrowserWindowCreated(); |
32 | 45 | } |
33 | | -@@ -983,6 +990,12 @@ BrowserView::BrowserView(Browser* browse |
| 46 | +@@ -983,6 +996,14 @@ BrowserView::BrowserView(Browser* browse |
34 | 47 | } |
35 | 48 |
|
36 | 49 | SetProperty(views::kElementIdentifierKey, kBrowserViewElementId); |
37 | 50 | + zen_top_chrome_animation_.SetSlideDuration( |
38 | 51 | + gfx::Animation::RichAnimationDuration(kZenModeRevealAnimationDuration)); |
| 52 | ++ zen_top_chrome_animation_.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_3); |
39 | 53 | + zen_top_chrome_animation_.Reset(1); |
40 | 54 | + zen_side_chrome_animation_.SetSlideDuration( |
41 | 55 | + gfx::Animation::RichAnimationDuration(kZenModeRevealAnimationDuration)); |
| 56 | ++ zen_side_chrome_animation_.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN_3); |
42 | 57 | + zen_side_chrome_animation_.Reset(1); |
43 | 58 |
|
44 | 59 | // Add any legal notices required for the user to the queue. |
45 | 60 | QueueLegalAndPrivacyNotices(browser_->GetProfile()); |
46 | | -@@ -1174,6 +1187,7 @@ BrowserView::~BrowserView() { |
| 61 | +@@ -1174,6 +1195,7 @@ BrowserView::~BrowserView() { |
47 | 62 | // Stop the animation timer explicitly here to avoid running it in a nested |
48 | 63 | // message loop, which may run by Browser destructor. |
49 | 64 | loading_animation_timer_.Stop(); |
50 | 65 | + zen_mode_event_monitor_.reset(); |
51 | 66 |
|
52 | 67 | // Reset autofill bubble handler to make sure it does not out-live toolbar, |
53 | 68 | // since it is responsible for showing autofill related bubbles from toolbar's |
54 | | -@@ -1392,6 +1406,13 @@ bool BrowserView::GetTabStripVisible() c |
| 69 | +@@ -1392,6 +1414,13 @@ bool BrowserView::GetTabStripVisible() c |
55 | 70 | return false; |
56 | 71 | } |
57 | 72 |
|
|
65 | 80 | // In non-fullscreen the tabstrip should always be visible. |
66 | 81 | auto* const immersive_mode_controller = |
67 | 82 | ImmersiveModeController::From(browser()); |
68 | | -@@ -1578,6 +1599,52 @@ float BrowserView::GetTopControlsSlideBe |
| 83 | +@@ -1578,6 +1607,52 @@ float BrowserView::GetTopControlsSlideBe |
69 | 84 | return 1.f; |
70 | 85 | } |
71 | 86 |
|
|
118 | 133 | views::Widget* BrowserView::GetWidgetForAnchoring() { |
119 | 134 | #if BUILDFLAG(IS_MAC) |
120 | 135 | if (UsesImmersiveFullscreenMode()) { |
121 | | -@@ -1602,6 +1669,7 @@ void BrowserView::OnVerticalTabStripMode |
| 136 | +@@ -1602,6 +1677,7 @@ void BrowserView::OnVerticalTabStripMode |
122 | 137 | const bool should_be_vertical = controller->ShouldDisplayVerticalTabs(); |
123 | 138 | if (vertical_initialized == should_be_vertical) { |
124 | 139 | // Mode is unchanged; just re-layout so alignment-dependent views update. |
125 | 140 | + UpdateZenCollapseButtonVisibility(); |
126 | 141 | InvalidateLayout(); |
127 | 142 | return; |
128 | 143 | } |
129 | | -@@ -1641,10 +1709,208 @@ void BrowserView::OnToolbarTabStripState |
| 144 | +@@ -1641,10 +1717,263 @@ void BrowserView::OnToolbarTabStripState |
130 | 145 | toolbar_->UpdateToolbarLayout(); |
131 | 146 | } |
132 | 147 |
|
|
205 | 220 | + } |
206 | 221 | + |
207 | 222 | + gfx::Point cursor; |
| 223 | ++ // When the cursor leaves the window, start a timer before collapsing. |
| 224 | ++ // Brief cursor excursions outside the window shouldn't collapse |
| 225 | ++ // the chrome. |
208 | 226 | + if (!GetCursorLocationInBrowserView(&cursor) || |
209 | 227 | + !GetLocalBounds().Contains(cursor)) { |
210 | | -+ UpdateZenModeReveal(/*reveal_top=*/false, /*reveal_side=*/false); |
| 228 | ++ if (!zen_cursor_exit_timer_.IsRunning()) { |
| 229 | ++ zen_cursor_exit_timer_.Start( |
| 230 | ++ FROM_HERE, kZenModeCursorExitGracePeriod, |
| 231 | ++ base::BindOnce(&BrowserView::UpdateZenModeReveal, |
| 232 | ++ base::Unretained(this), /*reveal_top=*/false, |
| 233 | ++ /*reveal_side=*/false)); |
| 234 | ++ } |
211 | 235 | + return; |
212 | 236 | + } |
213 | 237 | + |
|
221 | 245 | + const bool in_side_chrome = IsPointInZenSideChromeBounds(cursor); |
222 | 246 | + bool reveal_side = !reveal_top && (in_side_trigger || in_side_chrome); |
223 | 247 | + |
| 248 | ++ // Defer the collapse briefly so quick excursions don't cause the |
| 249 | ++ // chrome to snap closed. |
| 250 | ++ if (!reveal_top && !reveal_side) { |
| 251 | ++ if (!zen_cursor_exit_timer_.IsRunning()) { |
| 252 | ++ zen_cursor_exit_timer_.Start( |
| 253 | ++ FROM_HERE, kZenModeHoverExitGracePeriod, |
| 254 | ++ base::BindOnce(&BrowserView::UpdateZenModeReveal, |
| 255 | ++ base::Unretained(this), /*reveal_top=*/false, |
| 256 | ++ /*reveal_side=*/false)); |
| 257 | ++ } |
| 258 | ++ return; |
| 259 | ++ } |
| 260 | ++ |
| 261 | ++ zen_cursor_exit_timer_.Stop(); |
224 | 262 | + UpdateZenModeReveal(reveal_top, reveal_side); |
225 | 263 | +} |
226 | 264 | + |
|
245 | 283 | + reveal_top = true; |
246 | 284 | + } |
247 | 285 | + |
| 286 | ++ // Keep the top chrome visible while a bubble/popup anchored inside |
| 287 | ++ // the top container is open (e.g. extensions menu, page info bubble). |
| 288 | ++ if (HasOpenBubbleAnchoredInTopContainer()) { |
| 289 | ++ reveal_top = true; |
| 290 | ++ } |
| 291 | ++ |
248 | 292 | + if (reveal_top) { |
249 | 293 | + if (!zen_top_chrome_animation_.IsShowing()) { |
250 | 294 | + zen_top_chrome_animation_.Show(); |
|
293 | 337 | + return point.x() < kZenModeRevealTriggerThickness; |
294 | 338 | +} |
295 | 339 | + |
| 340 | ++namespace { |
| 341 | ++ |
| 342 | ++bool HasActivatedInkDropInSubtree(views::View* view) { |
| 343 | ++ if (auto* host = views::InkDrop::Get(view)) { |
| 344 | ++ auto* ink_drop = host->GetInkDrop(); |
| 345 | ++ if (ink_drop && |
| 346 | ++ ink_drop->GetTargetInkDropState() == views::InkDropState::ACTIVATED) { |
| 347 | ++ return true; |
| 348 | ++ } |
| 349 | ++ } |
| 350 | ++ |
| 351 | ++ for (views::View* child : view->children()) { |
| 352 | ++ if (HasActivatedInkDropInSubtree(child)) { |
| 353 | ++ return true; |
| 354 | ++ } |
| 355 | ++ } |
| 356 | ++ |
| 357 | ++ return false; |
| 358 | ++} |
| 359 | ++ |
| 360 | ++} // namespace |
| 361 | ++ |
| 362 | ++bool BrowserView::HasOpenBubbleAnchoredInTopContainer() const { |
| 363 | ++ return top_container_ && HasActivatedInkDropInSubtree(top_container_); |
| 364 | ++} |
| 365 | ++ |
296 | 366 | +bool BrowserView::IsPointInZenTopChromeBounds(const gfx::Point& point) const { |
297 | 367 | + if (!top_container_ || !top_container_->parent()) { |
298 | 368 | + return false; |
|
335 | 405 | void BrowserView::OnProjectsPanelStateChanged( |
336 | 406 | ProjectsPanelStateController* controller) { |
337 | 407 | projects_panel_container_->OnProjectsPanelStateChanged(controller); |
338 | | -@@ -2397,6 +2663,8 @@ void BrowserView::FullscreenStateChanged |
| 408 | +@@ -2397,6 +2726,8 @@ void BrowserView::FullscreenStateChanged |
339 | 409 | ShowSplitView(GetActiveContentsWebView()->HasFocus()); |
340 | 410 | } |
341 | 411 | } |
|
344 | 414 | } |
345 | 415 |
|
346 | 416 | void BrowserView::SetToolbarButtonProvider(ToolbarButtonProvider* provider) { |
347 | | -@@ -2449,6 +2717,17 @@ void BrowserView::SetFocusToLocationBar( |
| 417 | +@@ -2449,6 +2780,17 @@ void BrowserView::SetFocusToLocationBar( |
348 | 418 | return; |
349 | 419 | } |
350 | 420 |
|
|
362 | 432 | LocationBar* location_bar = GetLocationBar(); |
363 | 433 | location_bar->FocusLocation(is_user_initiated, |
364 | 434 | /*clear_focus_if_failed=*/true); |
365 | | -@@ -3203,7 +3482,7 @@ bool BrowserView::IsToolbarVisible() con |
| 435 | +@@ -3203,7 +3545,7 @@ bool BrowserView::IsToolbarVisible() con |
366 | 436 | } |
367 | 437 |
|
368 | 438 | bool BrowserView::IsToolbarShowing() const { |
|
371 | 441 | } |
372 | 442 |
|
373 | 443 | bool BrowserView::IsLocationBarVisible() const { |
374 | | -@@ -5239,6 +5518,8 @@ void BrowserView::AddedToWidget() { |
| 444 | +@@ -4400,6 +4742,11 @@ void BrowserView::OnWidgetActivationChan |
| 445 | + } |
| 446 | + } |
| 447 | + |
| 448 | ++ // Collapse zen mode chrome when the window is deactivated. |
| 449 | ++ if (!active && zen_mode_enabled_) { |
| 450 | ++ UpdateZenModeReveal(/*reveal_top=*/false, /*reveal_side=*/false); |
| 451 | ++ } |
| 452 | ++ |
| 453 | + browser_->GetFeatures() |
| 454 | + .extension_keybinding_registry() |
| 455 | + ->OnHostActivationChanged(active); |
| 456 | +@@ -5239,6 +5586,8 @@ void BrowserView::AddedToWidget() { |
375 | 457 | base::BindRepeating(&BrowserView::OnToolbarTabStripStateChanged, |
376 | 458 | base::Unretained(this))); |
377 | 459 | OnToolbarTabStripStateChanged(helium_layout_controller); |
|
380 | 462 | } |
381 | 463 |
|
382 | 464 | UpdateTabSearchBubbleHost(); |
383 | | -@@ -5388,6 +5669,7 @@ void BrowserView::AddedToWidget() { |
| 465 | +@@ -5388,6 +5737,7 @@ void BrowserView::AddedToWidget() { |
384 | 466 | } |
385 | 467 |
|
386 | 468 | void BrowserView::RemovedFromWidget() { |
387 | 469 | + zen_mode_event_monitor_.reset(); |
388 | 470 | CHECK(GetFocusManager()); |
389 | 471 | focus_manager_observation_.Reset(); |
390 | 472 | } |
391 | | -@@ -5416,6 +5698,14 @@ void BrowserView::OnThemeChanged() { |
| 473 | +@@ -5416,6 +5766,14 @@ void BrowserView::OnThemeChanged() { |
392 | 474 | } |
393 | 475 |
|
394 | 476 | FrameColorsChanged(); |
|
403 | 485 | } |
404 | 486 |
|
405 | 487 | bool BrowserView::GetDropFormats( |
406 | | -@@ -5746,6 +6036,9 @@ void BrowserView::UpdateFastResizeForCon |
| 488 | +@@ -5746,6 +6104,9 @@ void BrowserView::UpdateFastResizeForCon |
407 | 489 | } |
408 | 490 |
|
409 | 491 | int BrowserView::GetClientAreaTop() { |
|
413 | 495 | views::View* top_view = toolbar_; |
414 | 496 | #if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) |
415 | 497 | // If webui_tab_strip is displayed, the client area starts at its top, |
416 | | -@@ -6300,6 +6593,42 @@ void BrowserView::OnWillChangeFocus(View |
| 498 | +@@ -6300,6 +6661,42 @@ void BrowserView::OnWillChangeFocus(View |
417 | 499 | } |
418 | 500 | void BrowserView::OnDidChangeFocus(View* focused_before, View* focused_now) { |
419 | 501 | UpdateAccessibleNameForRootView(); |
|
523 | 605 | // Testing interface: |
524 | 606 | views::View* GetContentsContainerForTest() { return contents_container_; } |
525 | 607 | BrowserViewLayout* GetBrowserViewLayoutForTesting() { |
526 | | -@@ -953,6 +978,19 @@ class BrowserView : public BrowserWindow |
| 608 | +@@ -953,6 +978,20 @@ class BrowserView : public BrowserWindow |
527 | 609 |
|
528 | 610 | void OnProjectsPanelStateChanged(ProjectsPanelStateController* controller); |
529 | 611 |
|
|
538 | 620 | + bool IsPointInZenSideTrigger(const gfx::Point& point) const; |
539 | 621 | + bool IsPointInZenTopChromeBounds(const gfx::Point& point) const; |
540 | 622 | + bool IsPointInZenSideChromeBounds(const gfx::Point& point) const; |
| 623 | ++ bool HasOpenBubbleAnchoredInTopContainer() const; |
541 | 624 | + bool GetCursorLocationInBrowserView(gfx::Point* cursor_location) const; |
542 | 625 | + |
543 | 626 | // Make sure the WebUI tab strip exists if it should. |
544 | 627 | void MaybeInitializeWebUITabStrip(); |
545 | 628 |
|
546 | | -@@ -1468,6 +1506,12 @@ class BrowserView : public BrowserWindow |
| 629 | +@@ -1468,6 +1507,13 @@ class BrowserView : public BrowserWindow |
547 | 630 |
|
548 | 631 | std::unique_ptr<TabCyclingEventHandler> tab_cycling_event_handler_; |
549 | 632 |
|
550 | 633 | + // Zen mode state. |
551 | 634 | + std::unique_ptr<views::EventMonitor> zen_mode_event_monitor_; |
552 | 635 | + gfx::SlideAnimation zen_top_chrome_animation_; |
553 | 636 | + gfx::SlideAnimation zen_side_chrome_animation_; |
| 637 | ++ base::OneShotTimer zen_cursor_exit_timer_; |
554 | 638 | + bool zen_mode_enabled_ = false; |
555 | 639 | + |
556 | 640 | mutable base::WeakPtrFactory<BrowserView> weak_ptr_factory_{this}; |
|
655 | 739 |
|
656 | 740 | --- a/chrome/browser/ui/views/frame/layout/browser_view_tabbed_layout_impl.cc |
657 | 741 | +++ b/chrome/browser/ui/views/frame/layout/browser_view_tabbed_layout_impl.cc |
658 | | -@@ -34,10 +34,12 @@ |
| 742 | +@@ -34,9 +34,11 @@ |
659 | 743 | #include "chrome/browser/ui/views/tabs/projects/layout_constants.h" |
660 | 744 | #include "chrome/browser/ui/views/tabs/projects/projects_panel_utils.h" |
661 | 745 | #include "chrome/browser/ui/views/tabs/projects/projects_panel_view.h" |
662 | 746 | +#include "ui/compositor/layer.h" |
663 | 747 | #include "ui/gfx/geometry/outsets.h" |
664 | 748 | #include "ui/gfx/geometry/size.h" |
665 | 749 | #include "ui/views/controls/separator.h" |
666 | | - #include "ui/views/view_class_properties.h" |
667 | 750 | +#include "ui/views/layout/layout_provider.h" |
| 751 | + #include "ui/views/view_class_properties.h" |
668 | 752 | #include "ui/views/view_utils.h" |
669 | 753 |
|
670 | | - #if BUILDFLAG(IS_MAC) |
671 | 754 | @@ -59,6 +61,28 @@ constexpr int kVerticalTabsGrabHandleSiz |
672 | 755 | // against the frame controls when it is the top-most row. |
673 | 756 | constexpr int kTopToolbarExclusion = 10; |
|
0 commit comments