99#include " render/scene/input_area.h"
1010#include " render/scene/node.h"
1111#include " render/scene/rect_node.h"
12+ #include " shell/surface_shadow.h"
1213#include " ui/controls/box.h"
1314#include " ui/controls/glyph.h"
1415#include " ui/controls/label.h"
@@ -30,9 +31,23 @@ namespace {
3031
3132 constexpr Logger kLog (" select-dropdown-popup" );
3233 constexpr float kMenuPadding = Style::spaceXs;
34+ constexpr std::int32_t kShadowSafetyPadding = 2 ;
3335
3436 Color resolved (ColorRole role, float alpha = 1 .0f ) { return colorForRole (role, alpha); }
3537
38+ shell::surface_shadow::Bleed shadowInsets (const ShellConfig::ShadowConfig& shadow) {
39+ if (!shell::surface_shadow::enabled (true , shadow)) {
40+ return {};
41+ }
42+
43+ auto insets = shell::surface_shadow::bleed (true , shadow);
44+ insets.left += kShadowSafetyPadding ;
45+ insets.right += kShadowSafetyPadding ;
46+ insets.up += kShadowSafetyPadding ;
47+ insets.down += kShadowSafetyPadding ;
48+ return insets;
49+ }
50+
3651} // namespace
3752
3853SelectDropdownPopup::SelectDropdownPopup (WaylandConnection& wayland, RenderContext& renderContext)
@@ -52,6 +67,16 @@ void SelectDropdownPopup::setParent(xdg_surface* xdgSurface, wl_output* output)
5267 m_parentOutput = output;
5368}
5469
70+ void SelectDropdownPopup::setShadowConfig (const ShellConfig::ShadowConfig& shadow) {
71+ if (m_shadowConfig == shadow) {
72+ return ;
73+ }
74+ m_shadowConfig = shadow;
75+ if (isSelectDropdownOpen ()) {
76+ closeSelectDropdown ();
77+ }
78+ }
79+
5580void SelectDropdownPopup::openSelectDropdown (const DropdownRequest& request, DropdownCallbacks callbacks) {
5681 closeSelectDropdown ();
5782
@@ -71,6 +96,7 @@ void SelectDropdownPopup::openSelectDropdown(const DropdownRequest& request, Dro
7196 m_viewportHeight = static_cast <float >(visibleCount) * m_optionHeight + kMenuPadding * 2 .0f ;
7297 m_totalHeight = static_cast <float >(m_options.size ()) * m_optionHeight;
7398 m_scrollOffset = 0 .0f ;
99+ const auto shadow = shadowInsets (m_shadowConfig);
74100
75101 if (m_selectedIndex < m_options.size ()) {
76102 const float selectedTop = static_cast <float >(m_selectedIndex) * m_optionHeight;
@@ -81,8 +107,10 @@ void SelectDropdownPopup::openSelectDropdown(const DropdownRequest& request, Dro
81107 clampScrollOffset ();
82108 }
83109
84- const auto popupW = static_cast <std::uint32_t >(std::max (1 .0f , m_menuWidth));
85- const auto popupH = static_cast <std::uint32_t >(std::max (1 .0f , m_viewportHeight));
110+ const auto popupW =
111+ static_cast <std::uint32_t >(std::max (1 .0f , m_menuWidth + static_cast <float >(shadow.left + shadow.right )));
112+ const auto popupH =
113+ static_cast <std::uint32_t >(std::max (1 .0f , m_viewportHeight + static_cast <float >(shadow.up + shadow.down )));
86114
87115 PopupSurfaceConfig popupCfg{
88116 .anchorX = request.anchorX ,
@@ -96,8 +124,8 @@ void SelectDropdownPopup::openSelectDropdown(const DropdownRequest& request, Dro
96124 .constraintAdjustment = XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X |
97125 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y |
98126 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y,
99- .offsetX = 0 ,
100- .offsetY = static_cast <std::int32_t >(Style::spaceXs),
127+ .offsetX = static_cast <std:: int32_t >( std::lround ( static_cast < float >(shadow. right - shadow. left ) * 0 . 5f )) ,
128+ .offsetY = static_cast <std::int32_t >(std::lround ( Style::spaceXs - static_cast < float >(shadow. up )) ),
101129 .serial = m_wayland.lastInputSerial (),
102130 .grab = true ,
103131 };
@@ -159,6 +187,13 @@ void SelectDropdownPopup::openSelectDropdown(const DropdownRequest& request, Dro
159187 return ;
160188 }
161189
190+ m_surface->setInputRegion ({InputRect{
191+ .x = shadow.left ,
192+ .y = shadow.up ,
193+ .width = static_cast <int >(std::lround (m_menuWidth)),
194+ .height = static_cast <int >(std::lround (m_viewportHeight)),
195+ }});
196+
162197 m_wlSurface = m_surface->wlSurface ();
163198}
164199
@@ -182,23 +217,38 @@ bool SelectDropdownPopup::isSelectDropdownOpen() const { return m_surface != nul
182217void SelectDropdownPopup::buildScene (const DropdownRequest& request) {
183218 m_sceneRoot = std::make_unique<Node>();
184219 m_optionViews.clear ();
220+ const auto shadow = shadowInsets (m_shadowConfig);
221+ const float menuX = static_cast <float >(shadow.left );
222+ const float menuY = static_cast <float >(shadow.up );
223+ const float radius = Style::scaledRadiusMd ();
224+
225+ if (shell::surface_shadow::enabled (true , m_shadowConfig)) {
226+ auto shadowNode = std::make_unique<RectNode>();
227+ shadowNode->setStyle (shell::surface_shadow::style (
228+ m_shadowConfig, 1 .0f , shell::surface_shadow::Shape{.radius = Radii{radius, radius, radius, radius}}));
229+ shadowNode->setPosition (menuX + static_cast <float >(m_shadowConfig.offsetX ),
230+ menuY + static_cast <float >(m_shadowConfig.offsetY ));
231+ shadowNode->setFrameSize (m_menuWidth, m_viewportHeight);
232+ shadowNode->setZIndex (-1 );
233+ m_sceneRoot->addChild (std::move (shadowNode));
234+ }
185235
186236 auto bg = std::make_unique<RectNode>();
187237 bg->setStyle (RoundedRectStyle{
188238 .fill = resolved (ColorRole::SurfaceVariant),
189239 .border = resolved (ColorRole::Outline),
190240 .fillMode = FillMode::Solid,
191- .radius = Style::scaledRadiusMd () ,
241+ .radius = radius ,
192242 .softness = 1 .0f ,
193243 .borderWidth = Style::borderWidth,
194244 });
195245 auto * bgNode = static_cast <RectNode*>(m_sceneRoot->addChild (std::move (bg)));
196- bgNode->setPosition (0 . 0f , 0 . 0f );
246+ bgNode->setPosition (menuX, menuY );
197247 bgNode->setFrameSize (m_menuWidth, m_viewportHeight);
198248
199249 auto viewport = std::make_unique<Node>();
200250 viewport->setClipChildren (true );
201- viewport->setPosition (0 . 0f , kMenuPadding );
251+ viewport->setPosition (menuX, menuY + kMenuPadding );
202252 viewport->setFrameSize (m_menuWidth, m_viewportHeight - kMenuPadding * 2 .0f );
203253 auto * viewportNode = m_sceneRoot->addChild (std::move (viewport));
204254
0 commit comments