Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dismiss Pinned Tab Previews when exiting full screen or hovering the semaphore buttons #2788

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

alessandroboron
Copy link
Contributor

@alessandroboron alessandroboron commented May 16, 2024

Task/Issue URL: https://app.asana.com/0/1177771139624306/1205566350070653/f
Cc: @tomasstrba

Description:
Fix an issue that causes the pinned tab previews to stay on screen when hovering on the semaphore buttons and exiting fullscreen.

Video
https://github.com/duckduckgo/macos-browser/assets/1089358/99f7558d-2324-410d-bcbf-85fdbb9a7c35

Steps to test this PR:

Scenario 1 - Full Screen

  1. Enter full screen.
  2. Point cursor to the screen left corner so the semaphore buttons get shown.
  3. Hover over a leftmost tab so the preview gets shown.
  4. Exit full screen: Tab preview remains on the screen and doesn‘t change its position when hovering over the browser tabs.
    Expected Result: The preview should disappear.

Scenario 2 - Standard Screen

  1. Point to a pinned tab and wait for the preview.
  2. Move the cursor to the green semaphore button and wait for the menu to appear.
  3. Move the cursor away from the window.
    Expected Result: The preview should disappear.

** UPDATE **

I converted this PR into a draft PR to get feedback before I implement tests.

I refactored the logic to present the Tab previews due to entering/exiting full screen.

When we exit full screen the mouse jumps on the tab due to the semaphore buttons appearing on the left-hand side of the tabs. This causes the preview to appear again. And if we prevent the preview from appearing by listening to the exit full screen notification, the preview won’t reappear when the user moves the mouse because mouseEntered/onHover is already triggered.

Instead of presenting the preview when the mouse enters the view, we present it when the mouse moves within the view. In this way, when the mouse jumps due to exiting full screen, the preview is not presented automatically, but it will when the user moves the mouse (the same behaviour as Safari).

I created a TabPreviewEventsHandler. Pinned tabs used a reactive stream to show/dismiss the preview, while non-pinned tabs used imperative code. I actually merged the events of pinned and non-pinned tabs into a publisher so there’s a single source.

** NEW VIDEO **

Screen.Recording.2024-05-23.at.8.12.10.PM.mov

Internal references:

Pull Request Review Checklist
Software Engineering Expectations
Technical Design Template
Pull Request Documentation

…en hovering on the semaphore buttons and exiting fullscreen
@github-actions github-actions bot added the bot: not in app board Added by automation for pull requests with tasks not added to macOS App Board Asana project label May 16, 2024
@alessandroboron alessandroboron removed the bot: not in app board Added by automation for pull requests with tasks not added to macOS App Board Asana project label May 16, 2024
@alessandroboron alessandroboron requested a review from mallexxx May 16, 2024 06:52
Copy link
Collaborator

@mallexxx mallexxx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this didn‘t fix the whole issue:

  • Open window in full screen
  • Show a preview on a tab
  • Hit 🌐+F to exit full screen: the preview stays

I think it should be more of a Tracking Area related fix that also takes major screen updates (like full screen switch or something else maybe).
Do you think there may be a better solution than this (pretty hacky and fragile) patch?

@alessandroboron alessandroboron marked this pull request as draft May 23, 2024 09:33
@alessandroboron alessandroboron force-pushed the alessandro/tab-preview-not-dismissed branch 4 times, most recently from fe7453a to b280ef9 Compare May 23, 2024 09:49
@alessandroboron
Copy link
Contributor Author

Unfortunately this didn‘t fix the whole issue:

  • Open window in full screen
  • Show a preview on a tab
  • Hit 🌐+F to exit full screen: the preview stays

I think it should be more of a Tracking Area related fix that also takes major screen updates (like full screen switch or something else maybe). Do you think there may be a better solution than this (pretty hacky and fragile) patch?

@mallexxx Thanks for the comment. It took a bit of time, but I’ve refactored a bit. I’ve updated the description with what I’ve done. I converted this into a draft PR before I implemented tests. Could you please test the scenarios again?

I’ve also CCd @tomasstrba as he worked on tab preview.

// More Info:
// - RXMarbles: https://rxmarbles.com/#withLatestFrom
// - https://jasdev.me/notes/with-latest-from
extension Publisher {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also import CombineExt package which has same implementation by jasdev but if we’re not using the whole set of operators, probably no need it.

@@ -65,6 +65,8 @@ final class PinnedTabsViewModel: ObservableObject {
}
}

@Published var mouseMoving: Void = ()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the beginning I was passing setting the CGPoint where the mouse location was, but I wasn’t really using it so I changed to Void. If it feels weird we can always change to CGPoint as we may need it in the future we need it

collectionModel?.hoveredItem = isHovered ? model : nil
}
stack
.onHover { [weak collectionModel, weak model] isHovered in
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An approach I tried was to make an operator called onContinuousHovering. The problem with that was that the preview would show again after exiting full screen. And removing mouseEntered(_:) from the Tracking Area view would cause issues to the overlay state of the view when exiting full screen. 😞

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
if self.view.isMouseLocationInsideBounds() == false {
self.hideTabPreview(allowQuickRedisplay: true)
private func subscribeToTabPreviewEvents() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method receive events to show both pinned tabs and non pinned tabs.

tabPreviewEventsHandler.unpinnedTabMouseExited()
}

func tabBarViewItemMouseIsMoving(_ tabBarViewItem: TabBarViewItem) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the mouse moves within the tab we show the preview

@@ -1020,15 +1029,17 @@ extension TabBarViewController: NSCollectionViewDelegate {
extension TabBarViewController: TabBarViewItemDelegate {

func tabBarViewItem(_ tabBarViewItem: TabBarViewItem, isMouseOver: Bool) {
guard !isMouseOver else { return }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the mouse exit the area we dismiss the preview

import Foundation
import Combine

final class TabPreviewEventsHandler {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of this class is to have the logic that leads to a TabPreviewEvent in one place and to avoid having subjects in the VC for the non pinned tabs.

It should technically be easy to test this as something like “when an event on a publisher happens, then this class should send a TabPreviewEvent in a specific state".

@alessandroboron alessandroboron force-pushed the alessandro/tab-preview-not-dismissed branch from b280ef9 to b071dd2 Compare May 24, 2024 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants