mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 00:02:23 +00:00
fix(settings): give the settings pages the scrollbar the rest of the app has
The tab sidebar, the file tree, the right panel and the SFTP browser all
run their scroll area through `with_vertical_scrollbar`. The settings
pages — the longest scrolling surfaces tty7 has, several viewports of them
on Appearance and Terminal — had no bar at all: no thumb, no sense of how
far down the page you were or how much was left. The SSH host list, the SSH
form and the theme picker's list were the same.
All four now carry the shared bar. It follows the OS "show scroll bars"
preference like every other one, so nothing appears for anyone who asked
for scrollbars to stay hidden.
The scroll areas move inside a wrapper that holds the constraints they used
to hold themselves, and two of those do not survive the move. `min_w_0` on
a column child means the *cross* axis, and carrying it inside let the SSH
form's label column shrink to nothing while the toggles stayed put; it
belongs on the wrapper, which is still the row item it always was. And the
wrapper has to take its width explicitly rather than by stretching, or the
`w_full` inside has no width to be a percentage of — which is how the
settings reading column lost its 640px cap on the Chinese page, exactly the
way 00ad4eb first found it.
This commit is contained in:
@@ -3816,6 +3816,9 @@ impl Tty7App {
|
||||
section: SettingsSection::Appearance,
|
||||
search: settings_search,
|
||||
content_scroll,
|
||||
ssh_master_scroll: gpui::ScrollHandle::new(),
|
||||
ssh_detail_scroll: gpui::ScrollHandle::new(),
|
||||
theme_list_scroll: gpui::ScrollHandle::new(),
|
||||
search_anchor,
|
||||
reveal_first_hit: Cell::new(false),
|
||||
font_select,
|
||||
|
||||
@@ -11,6 +11,12 @@ pub(crate) fn with_vertical_scrollbar(
|
||||
.relative()
|
||||
.flex_1()
|
||||
.min_h_0()
|
||||
// Stretching would size this the same, but not *definitely*: a `w_full`
|
||||
// inside the scroll area would then have no width to be a percentage
|
||||
// of, and would fall back to its content. That is how the settings
|
||||
// reading column lost its 640px cap on the Chinese page — one wide row
|
||||
// measured wider, and every row followed it.
|
||||
.w_full()
|
||||
.child(scroll_area)
|
||||
.child(
|
||||
div()
|
||||
|
||||
+75
-40
@@ -474,6 +474,9 @@ pub(crate) struct SettingsState {
|
||||
/// claims. Searching tells you "Appearance (2)"; these are what carry you
|
||||
/// to the two, which on a long page start well below the fold.
|
||||
pub(crate) content_scroll: gpui::ScrollHandle,
|
||||
pub(crate) ssh_master_scroll: gpui::ScrollHandle,
|
||||
pub(crate) ssh_detail_scroll: gpui::ScrollHandle,
|
||||
pub(crate) theme_list_scroll: gpui::ScrollHandle,
|
||||
pub(crate) search_anchor: gpui::ScrollAnchor,
|
||||
/// Set when the query or the section changes, and spent by the next render
|
||||
/// that has somewhere to go. A `Cell` because that render only holds `&self`.
|
||||
@@ -961,13 +964,11 @@ impl Tty7App {
|
||||
.h_full()
|
||||
.bg(background)
|
||||
.child(content)
|
||||
.into_any_element()
|
||||
} else {
|
||||
v_flex()
|
||||
let body = v_flex()
|
||||
.id("settings-content")
|
||||
.flex_1()
|
||||
.min_w_0()
|
||||
.h_full()
|
||||
.bg(background)
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
.when_some(self.active_settings(), |pane, s| {
|
||||
pane.track_scroll(&s.content_scroll)
|
||||
@@ -987,7 +988,20 @@ impl Tty7App {
|
||||
.children(no_match_note)
|
||||
.child(content),
|
||||
),
|
||||
)
|
||||
);
|
||||
v_flex()
|
||||
.flex_1()
|
||||
.min_w_0()
|
||||
.h_full()
|
||||
.bg(background)
|
||||
.when_some(self.active_settings(), |pane, s| {
|
||||
pane.child(crate::ui::scrollbar::with_vertical_scrollbar(
|
||||
"settings-content-scrollbar",
|
||||
body,
|
||||
&s.content_scroll,
|
||||
))
|
||||
})
|
||||
.into_any_element()
|
||||
};
|
||||
|
||||
let root = div()
|
||||
@@ -1704,43 +1718,58 @@ impl Tty7App {
|
||||
|
||||
fn render_settings_ssh(&self, cx: &mut Context<Self>) -> AnyElement {
|
||||
let border = cx.theme().border;
|
||||
let Some((master_scroll, detail_scroll)) = self
|
||||
.active_settings()
|
||||
.map(|s| (s.ssh_master_scroll.clone(), s.ssh_detail_scroll.clone()))
|
||||
else {
|
||||
return div().into_any_element();
|
||||
};
|
||||
let master = v_flex()
|
||||
.id("ssh-master")
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
.track_scroll(&master_scroll)
|
||||
.child(self.render_ssh_master(cx));
|
||||
let detail = v_flex()
|
||||
.id("ssh-detail")
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
.track_scroll(&detail_scroll)
|
||||
.child(
|
||||
div()
|
||||
.pt(px(crate::ui::app::TITLE_BAR_HEIGHT))
|
||||
.px_8()
|
||||
.pb_8()
|
||||
.child(
|
||||
div()
|
||||
.w_full()
|
||||
.max_w(px(720.))
|
||||
.child(self.render_ssh_detail(cx)),
|
||||
),
|
||||
);
|
||||
h_flex()
|
||||
.size_full()
|
||||
.items_start()
|
||||
.child(
|
||||
v_flex()
|
||||
.id("ssh-master")
|
||||
.flex_shrink_0()
|
||||
.w(px(280.))
|
||||
.h_full()
|
||||
.border_r_1()
|
||||
.border_color(border)
|
||||
.overflow_y_scroll()
|
||||
.child(self.render_ssh_master(cx)),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
.id("ssh-detail")
|
||||
.flex_1()
|
||||
// Without this the flex default `min-width: auto` keeps the
|
||||
// column at its content width, so a narrow window pushes the
|
||||
// form off the right edge instead of squeezing the labels.
|
||||
.min_w_0()
|
||||
.h_full()
|
||||
.overflow_y_scroll()
|
||||
.child(
|
||||
div()
|
||||
.pt(px(crate::ui::app::TITLE_BAR_HEIGHT))
|
||||
.px_8()
|
||||
.pb_8()
|
||||
.child(
|
||||
div()
|
||||
.w_full()
|
||||
.max_w(px(720.))
|
||||
.child(self.render_ssh_detail(cx)),
|
||||
),
|
||||
),
|
||||
.child(crate::ui::scrollbar::with_vertical_scrollbar(
|
||||
"ssh-master-scrollbar",
|
||||
master,
|
||||
&master_scroll,
|
||||
)),
|
||||
)
|
||||
.child(v_flex().flex_1().min_w_0().h_full().child(
|
||||
crate::ui::scrollbar::with_vertical_scrollbar(
|
||||
"ssh-detail-scrollbar",
|
||||
detail,
|
||||
&detail_scroll,
|
||||
),
|
||||
))
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
@@ -4602,6 +4631,7 @@ impl Tty7App {
|
||||
),
|
||||
None => return div().into_any_element(),
|
||||
};
|
||||
let list_scroll = self.active_settings().map(|s| s.theme_list_scroll.clone());
|
||||
let config = cx.global::<Config>();
|
||||
let slot = match (config.theme_follow_system, slot) {
|
||||
(false, _) => ThemeSlot::Manual,
|
||||
@@ -4769,14 +4799,19 @@ impl Tty7App {
|
||||
.child(header)
|
||||
.child(subtitle)
|
||||
.child(search_box)
|
||||
.child(
|
||||
v_flex()
|
||||
.id("theme-panel-list")
|
||||
.flex_1()
|
||||
.overflow_y_scroll()
|
||||
.children(rejected_note)
|
||||
.child(list),
|
||||
)
|
||||
.when_some(list_scroll, |panel, scroll| {
|
||||
panel.child(crate::ui::scrollbar::with_vertical_scrollbar(
|
||||
"theme-panel-scrollbar",
|
||||
v_flex()
|
||||
.id("theme-panel-list")
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
.track_scroll(&scroll)
|
||||
.children(rejected_note)
|
||||
.child(list),
|
||||
&scroll,
|
||||
))
|
||||
})
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user