-
-
Notifications
You must be signed in to change notification settings - Fork 106
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
Initial implementation of tabs bar #1468
base: main
Are you sure you want to change the base?
Conversation
641b268
to
eb31be6
Compare
eb31be6
to
22da6fa
Compare
3756d48
to
8acbe88
Compare
e791cfd
to
543e9bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't reviewed the code in detail yet but I have some comments
- Do we really want to have all those possibilities to show the tabs, I think we should select the best one and stick to it. Giving users too many options is not something I think is necessarily good
- The bar in horizontal mode is wider than the window
- The bar in horizontal mode hides the top bar widget which allows you to close windows
- The vertical mode does not look good in multiwindow mode IMO, it does overlap with multiple windows
Instead of having them permanently on top, what do you think about having a small UI element that when on hovered "unrolls" the tabs bar (either vertical or horizontal)?
Early video, to show the feature in action: 2024-10-02-tabs.mp4 |
543e9bd
to
af15e21
Compare
I have updated the PR to hide the tabs bar when the window is being resized, and also to ensure that it updates its size correctly. 2024-10-03-tabs.mp4 |
1c3428e
to
3fccc3e
Compare
The Tabs Bar is a small window that sits next to the current window and which lists the open tabs. There are two implementations: - HorizontalTabsBar on the top of the window - VerticalTabsBar on the side of the window The Tabs Bar is managed by VRBrowserActivity. SessionStore now keeps a list of session change listeners. TabDelegate is moved to a separate interface. The current tabs style can be changed in Settings -> Display. WindowViewModel gets three new fields: - isTabsBarVisible - usesHorizontalTabsBar - usesVerticalTabsBar TopBarWidget uses two of these fields to update its placement so as to not overlap with the tabs bar. Note that we don't (yet) link windows and tabs, so the interface gets a bit confusing when we have more than one window open.
3fccc3e
to
49e6435
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job, it's actually quite some work. I left some comments inline.
Apart from that I have some comments about the UI:
- Tabs are not well aligned with the windows, the vertical one is a little bit up, and the horizontal one is a little bit shifted right. It doesn't give a good impression
- We should add some margin between the vertical tabs bar and the top bar widget (the one with the X to close the window) as they're too close.
if (aPrevWindow != null) { | ||
updateWidget(mNavigationBar); | ||
updateWidget(mTabsBar); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a mistake. You have the good one bellow with the null check
recenterUIYaw(WidgetManagerDelegate.YAW_TARGET_ALL); | ||
} else if (Objects.equals(key, getString(R.string.settings_key_tabs_location))) { | ||
|
||
Log.e(LOGTAG, "update tabs location"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this
|
||
// remove the previous widget | ||
if (mTabsBar != null) { | ||
Log.e(LOGTAG, "remove previous widget"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same
mTabsBar.releaseWidget(); | ||
} | ||
|
||
if (mSettings.getTabsLocation() == SettingsStore.TABS_LOCATION_TRAY) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a switch-case statement fits better for this use case
@@ -358,6 +361,10 @@ public Session getActiveSession() { | |||
return mActiveSession; | |||
} | |||
|
|||
public List<Session> getSessions(boolean aPrivateMode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this having the getSortedSessions already available?
if (position == 0) { | ||
return 0; | ||
} else { | ||
return mTabs.get(position - 1).getId().hashCode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return position == 0 ? 0 : mTabs.get....
@@ -43,7 +45,7 @@ public TrayViewModel(@NonNull Application application) { | |||
isVisible.setValue(new ObservableBoolean(false)); | |||
time = new MutableLiveData<>(); | |||
pm = new MutableLiveData<>(); | |||
pm = new MutableLiveData<>(); | |||
needsTabsButton = new MutableLiveData<>(new ObservableBoolean(true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is a bit of bikeshedding, but perhaps we could have a more descriptive name, "needsTabs" does not mean anything to me. What about something like detachedTabsButton or similar?
@@ -361,7 +361,7 @@ void updateScrollPosition(int offsetX, int offsetY) { | |||
int verticalContentLength = mRecyclerView.computeVerticalScrollRange(); | |||
int verticalVisibleLength = mRecyclerViewHeight; | |||
mNeedVerticalScrollbar = verticalContentLength - verticalVisibleLength > 0 | |||
&& mRecyclerViewHeight >= mScrollbarMinimumRange || mNeedHorizontalScrollbar; | |||
&& mRecyclerViewHeight >= mScrollbarMinimumRange || mNeedVerticalScrollbar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, this could even be a separate commit. Not sure if that was causing any actual visible bug.
import com.igalia.wolvic.browser.engine.SessionStore; | ||
import com.igalia.wolvic.ui.adapters.TabsBarAdapter; | ||
|
||
public class HorizontalTabsBar extends AbstractTabsBar implements SessionChangeListener { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the implements is needed, isn't it?
@@ -101,7 +101,7 @@ public void setContextElement(WSession.ContentDelegate.ContextElement aContextEl | |||
// Open link in a new tab | |||
mItems.add(new MenuWidget.MenuItem(getContext().getString(R.string.context_menu_open_link_new_tab_1), 0, () -> { | |||
if (!StringUtils.isEmpty(aContextElement.linkUri)) { | |||
widgetManager.openNewTab(aContextElement.linkUri); | |||
widgetManager.openNewTabForeground(aContextElement.linkUri); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this?
The Tabs Bar is a small window that sits next to the current window and which lists the open tabs.
There are two implementations in this PR:
HorizontalTabsBar
on the top of the windowVerticalTabsBar
on the side of the windowThe Tabs Bar is managed by
VRBrowserActivity
.SessionStore
now keeps a list of session change listeners so the tabs bar can be updated.SessionChangeListener
andTabDelegate
are moved to separate files.The location of tabs can be changed in Settings -> Display.
Note that Wolvic does not keep track of the relationship between windows and tabs. There is one single list of tabs that can be dynamically displayed on one or more windows. Unfortunately, this means that the interface tends to get a bit confusing when we have more than one window open.