Fix dead-pane regression: drop the absolute highlight overlay
Round 12 painted the inner highlight ring through an absolutely positioned overlay that covered every glass panel. User reports the right pane was unclickable, the search bar wouldn't take input, and sidebar tab close buttons never appeared on hover. Even though the overlay div had no listeners, in this layout it was racing the parent's hit-test for the same pixels — the close glyph in `render_launcher_row` is `opacity(0)` until `group_hover` fires, and the overlay was preventing that hover from registering. Move the highlight onto each panel's own `.border_1()` so the ring is part of the panel paint, not a separate overlay. Painted, never hit-tested. The four wired callers (expanded sidebar, compact sidebar, main pane, command overlay panel) now each carry their inner border directly. `chrome::glass` deletes; nothing else used it. The 1 px brighter top-edge specular sliver from the design is gone — GPUI 0.2.2 has no asymmetric border colors and live clicks beat that single-pixel polish. cargo test --workspace: 440 passed, 0 failed.
This commit is contained in:
@@ -15,7 +15,6 @@ use crate::shell::chrome::command_match::{
|
|||||||
use crate::shell::chrome::command_rows::{
|
use crate::shell::chrome::command_rows::{
|
||||||
render_action_rows, render_bookmark_rows, render_history_rows, render_tab_rows,
|
render_action_rows, render_bookmark_rows, render_history_rows, render_tab_rows,
|
||||||
};
|
};
|
||||||
use crate::shell::chrome::glass::render_inner_highlight;
|
|
||||||
|
|
||||||
const COMMAND_PREFIX: &str = ">";
|
const COMMAND_PREFIX: &str = ">";
|
||||||
|
|
||||||
@@ -72,15 +71,15 @@ fn render_panel(
|
|||||||
.w(px(640.0))
|
.w(px(640.0))
|
||||||
.rounded(px(16.0))
|
.rounded(px(16.0))
|
||||||
.bg(rgba(PANEL_BG))
|
.bg(rgba(PANEL_BG))
|
||||||
|
.border_1()
|
||||||
|
.border_color(rgba(PANEL_BORDER))
|
||||||
.shadow(panel_shadow())
|
.shadow(panel_shadow())
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.relative()
|
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.child(render_header(query_label.clone(), needle.is_empty()))
|
.child(render_header(query_label.clone(), needle.is_empty()))
|
||||||
.child(render_results(snapshot, needle, selected_index, cx))
|
.child(render_results(snapshot, needle, selected_index, cx))
|
||||||
.child(render_command_footer())
|
.child(render_command_footer())
|
||||||
.child(render_inner_highlight(16.0))
|
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +218,7 @@ fn render_empty_state() -> AnyElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PANEL_BG: u32 = 0xfffffff5;
|
const PANEL_BG: u32 = 0xfffffff5;
|
||||||
|
const PANEL_BORDER: u32 = 0xffffff80;
|
||||||
const BACKDROP_BG: u32 = 0x140f0a3d;
|
const BACKDROP_BG: u32 = 0x140f0a3d;
|
||||||
const BADGE_BG: u32 = 0x281e140f;
|
const BADGE_BG: u32 = 0x281e140f;
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
use gpui::{AnyElement, IntoElement, ParentElement, Styled, div, px, rgba};
|
|
||||||
|
|
||||||
/// Inner highlight rings on every glass panel.
|
|
||||||
///
|
|
||||||
/// CSS designs reach for `box-shadow: inset 0 0 0 1px rgba(255,255,255,0.5)`
|
|
||||||
/// to draw a 1 px highlight inside a translucent panel. GPUI 0.2.2's
|
|
||||||
/// `BoxShadow` has no inset flag, so this module composites the same effect
|
|
||||||
/// from real GPUI primitives: an absolutely-positioned overlay div that
|
|
||||||
/// owns the inner border and sits above the panel content, scoped to the
|
|
||||||
/// panel's rounded clip.
|
|
||||||
///
|
|
||||||
/// The highlight color matches the design's `--ely-shadow-window` stack:
|
|
||||||
/// 50% white border + 70% white top-edge highlight.
|
|
||||||
const HIGHLIGHT_BORDER: u32 = 0xffffff80;
|
|
||||||
const HIGHLIGHT_TOP_EDGE: u32 = 0xffffffb3;
|
|
||||||
|
|
||||||
/// Draw a single absolute overlay that paints the inset highlight ring into
|
|
||||||
/// the parent panel. Caller is responsible for `.relative()` on the parent
|
|
||||||
/// and matching `.rounded(...)` so the overlay's clip lines up.
|
|
||||||
pub(crate) fn render_inner_highlight(radius_px: f32) -> AnyElement {
|
|
||||||
div()
|
|
||||||
.absolute()
|
|
||||||
.inset_0()
|
|
||||||
.rounded(px(radius_px))
|
|
||||||
.border_1()
|
|
||||||
.border_color(rgba(HIGHLIGHT_BORDER))
|
|
||||||
// The 1 px top-edge highlight from the design is drawn via a child
|
|
||||||
// div pinned to the top edge — GPUI doesn't have asymmetric border
|
|
||||||
// colors, so a 1-pixel-tall sliver is the cleanest substitute.
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.absolute()
|
|
||||||
.top_0()
|
|
||||||
.left(px(1.0))
|
|
||||||
.right(px(1.0))
|
|
||||||
.h(px(1.0))
|
|
||||||
.bg(rgba(HIGHLIGHT_TOP_EDGE)),
|
|
||||||
)
|
|
||||||
.into_any_element()
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ pub(crate) mod command_footer;
|
|||||||
pub(crate) mod command_match;
|
pub(crate) mod command_match;
|
||||||
pub(crate) mod command_overlay;
|
pub(crate) mod command_overlay;
|
||||||
pub(crate) mod command_rows;
|
pub(crate) mod command_rows;
|
||||||
pub(crate) mod glass;
|
|
||||||
pub(crate) mod home;
|
pub(crate) mod home;
|
||||||
pub(crate) mod plugin_detail_view;
|
pub(crate) mod plugin_detail_view;
|
||||||
pub(crate) mod plugin_labels;
|
pub(crate) mod plugin_labels;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use gpui::{
|
|||||||
use gpui_component::{IconName, StyledExt, scroll::ScrollableElement};
|
use gpui_component::{IconName, StyledExt, scroll::ScrollableElement};
|
||||||
|
|
||||||
use crate::shell::ElyShell;
|
use crate::shell::ElyShell;
|
||||||
use crate::shell::chrome::glass::render_inner_highlight;
|
|
||||||
use crate::shell::chrome::{render_glyph_for, render_sidebar_header};
|
use crate::shell::chrome::{render_glyph_for, render_sidebar_header};
|
||||||
|
|
||||||
impl ElyShell {
|
impl ElyShell {
|
||||||
@@ -27,9 +26,10 @@ impl ElyShell {
|
|||||||
.flex_col()
|
.flex_col()
|
||||||
.rounded(px(spacing::RADIUS_CARD))
|
.rounded(px(spacing::RADIUS_CARD))
|
||||||
.bg(rgba(panel_color))
|
.bg(rgba(panel_color))
|
||||||
|
.border_1()
|
||||||
|
.border_color(rgba(HIGHLIGHT_BORDER))
|
||||||
.shadow(panel_shadow())
|
.shadow(panel_shadow())
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.relative()
|
|
||||||
.child(render_sidebar_header(self, snapshot, cx))
|
.child(render_sidebar_header(self, snapshot, cx))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
@@ -60,7 +60,6 @@ impl ElyShell {
|
|||||||
.child(self.render_new_tab_row(cx)),
|
.child(self.render_new_tab_row(cx)),
|
||||||
)
|
)
|
||||||
.child(self.render_sidebar_footer(snapshot, cx))
|
.child(self.render_sidebar_footer(snapshot, cx))
|
||||||
.child(render_inner_highlight(spacing::RADIUS_CARD))
|
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,6 +413,12 @@ fn section_label(label: &'static str) -> impl IntoElement {
|
|||||||
pub(crate) const ACTIVE_NAV_BG: u32 = 0xffffffd9;
|
pub(crate) const ACTIVE_NAV_BG: u32 = 0xffffffd9;
|
||||||
const UNREAD_BADGE_BG: u32 = 0x281e140f;
|
const UNREAD_BADGE_BG: u32 = 0x281e140f;
|
||||||
|
|
||||||
|
/// 50% white inner border that traces every glass panel — the GPUI
|
||||||
|
/// substitute for the design's `box-shadow: inset 0 0 0 1px rgba(255,255,255,0.5)`.
|
||||||
|
/// Painted as the panel's own border so it stays part of the frame and
|
||||||
|
/// never participates in hit testing.
|
||||||
|
const HIGHLIGHT_BORDER: u32 = 0xffffff80;
|
||||||
|
|
||||||
/// Maps appearance translucency_pct to a panel rgba u32 tinted by the
|
/// Maps appearance translucency_pct to a panel rgba u32 tinted by the
|
||||||
/// active wallpaper theme.
|
/// active wallpaper theme.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use gpui::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::chrome::command_match::visible_command_rows;
|
use super::chrome::command_match::visible_command_rows;
|
||||||
use super::chrome::glass::render_inner_highlight;
|
|
||||||
use super::chrome::{
|
use super::chrome::{
|
||||||
panel_bg, panel_shadow, render_command_overlay,
|
panel_bg, panel_shadow, render_command_overlay,
|
||||||
render_topbar as render_topbar_chrome, render_wallpaper,
|
render_topbar as render_topbar_chrome, render_wallpaper,
|
||||||
@@ -137,11 +136,12 @@ impl ElyShell {
|
|||||||
.flex_1()
|
.flex_1()
|
||||||
.h_full()
|
.h_full()
|
||||||
.min_w_0()
|
.min_w_0()
|
||||||
.relative()
|
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.rounded(px(spacing::RADIUS_CARD))
|
.rounded(px(spacing::RADIUS_CARD))
|
||||||
.bg(rgba(panel_color))
|
.bg(rgba(panel_color))
|
||||||
|
.border_1()
|
||||||
|
.border_color(rgba(MAIN_PANE_HIGHLIGHT_BORDER))
|
||||||
.shadow(panel_shadow())
|
.shadow(panel_shadow())
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(render_topbar_chrome(self, snapshot, active_tab, sidebar_collapsed, cx))
|
.child(render_topbar_chrome(self, snapshot, active_tab, sidebar_collapsed, cx))
|
||||||
@@ -151,7 +151,6 @@ impl ElyShell {
|
|||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(self.render_content_area(snapshot, active_tab, cx)),
|
.child(self.render_content_area(snapshot, active_tab, cx)),
|
||||||
)
|
)
|
||||||
.child(render_inner_highlight(spacing::RADIUS_CARD))
|
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +249,12 @@ impl ElyShell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 50% white inner border that traces every glass panel — the GPUI
|
||||||
|
/// substitute for the design's `box-shadow: inset 0 0 0 1px rgba(255,255,255,0.5)`.
|
||||||
|
/// Painted as the panel's own border so it stays part of the frame and
|
||||||
|
/// never participates in hit testing.
|
||||||
|
const MAIN_PANE_HIGHLIGHT_BORDER: u32 = 0xffffff80;
|
||||||
|
|
||||||
/// Cursor x within this px from the left edge auto-reveals the hidden sidebar.
|
/// Cursor x within this px from the left edge auto-reveals the hidden sidebar.
|
||||||
/// Sized so the user only triggers the reveal when they actually approach the
|
/// Sized so the user only triggers the reveal when they actually approach the
|
||||||
/// rail, not when they hover the page content.
|
/// rail, not when they hover the page content.
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ use gpui_component::{
|
|||||||
button::{Button, ButtonVariants},
|
button::{Button, ButtonVariants},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::chrome::glass::render_inner_highlight;
|
|
||||||
use super::chrome::panel_bg;
|
use super::chrome::panel_bg;
|
||||||
use super::{ElyShell, ShellState, render::tab_profile_label};
|
use super::{ElyShell, ShellState, render::tab_profile_label};
|
||||||
use crate::ToggleSidebar;
|
use crate::ToggleSidebar;
|
||||||
@@ -38,7 +37,6 @@ impl ElyShell {
|
|||||||
div()
|
div()
|
||||||
.w(px(sidebar_width))
|
.w(px(sidebar_width))
|
||||||
.h_full()
|
.h_full()
|
||||||
.relative()
|
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.items_center()
|
.items_center()
|
||||||
@@ -46,6 +44,8 @@ impl ElyShell {
|
|||||||
.p_2()
|
.p_2()
|
||||||
.rounded(px(spacing::RADIUS_CARD))
|
.rounded(px(spacing::RADIUS_CARD))
|
||||||
.bg(rgba(panel_color))
|
.bg(rgba(panel_color))
|
||||||
|
.border_1()
|
||||||
|
.border_color(rgba(HIGHLIGHT_BORDER))
|
||||||
.shadow(panel_shadow())
|
.shadow(panel_shadow())
|
||||||
.children(snapshot.favorites.iter().enumerate().map(|(index, tab)| {
|
.children(snapshot.favorites.iter().enumerate().map(|(index, tab)| {
|
||||||
self.render_compact_tab_button(
|
self.render_compact_tab_button(
|
||||||
@@ -90,7 +90,6 @@ impl ElyShell {
|
|||||||
self.render_compact_archived_button(index, archived_tab, cx)
|
self.render_compact_archived_button(index, archived_tab, cx)
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.child(render_inner_highlight(spacing::RADIUS_CARD))
|
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,6 +260,13 @@ pub(super) fn collapsed_sidebar_active(sidebar_width: f32) -> bool {
|
|||||||
sidebar_width <= f32::from(COLLAPSED_SIDEBAR_WIDTH_PX)
|
sidebar_width <= f32::from(COLLAPSED_SIDEBAR_WIDTH_PX)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 50% white inner border that traces every glass panel — the GPUI
|
||||||
|
/// substitute for the design's `box-shadow: inset 0 0 0 1px rgba(255,255,255,0.5)`.
|
||||||
|
/// Painting it as the panel's own border keeps it part of the frame
|
||||||
|
/// (no separate absolute overlay) so it never participates in hit
|
||||||
|
/// testing and never blocks clicks on inner content.
|
||||||
|
const HIGHLIGHT_BORDER: u32 = 0xffffff80;
|
||||||
|
|
||||||
fn panel_shadow() -> Vec<BoxShadow> {
|
fn panel_shadow() -> Vec<BoxShadow> {
|
||||||
vec![
|
vec![
|
||||||
BoxShadow {
|
BoxShadow {
|
||||||
|
|||||||
Reference in New Issue
Block a user