Skip to content

Commit b785f82

Browse files
committed
feat: select dropdown shadow
1 parent 55affaa commit b785f82

6 files changed

Lines changed: 70 additions & 7 deletions

File tree

src/shell/desktop/desktop_widgets_editor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,9 @@ void DesktopWidgetsEditor::rebuildScene(OverlaySurface& surface) {
385385
root->setAnimationManager(&surface.animations);
386386
if (m_renderContext != nullptr && m_wayland != nullptr) {
387387
surface.selectPopup = std::make_unique<SelectDropdownPopup>(*m_wayland, *m_renderContext);
388+
if (m_config != nullptr) {
389+
surface.selectPopup->setShadowConfig(m_config->config().shell.shadow);
390+
}
388391
surface.selectPopup->setParent(surface.surface->layerSurface(), surface.output);
389392
root->setPopupContext(surface.selectPopup.get());
390393
}

src/shell/panel/panel_manager.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,9 @@ void PanelManager::buildScene(std::uint32_t width, std::uint32_t height) {
13661366
m_sceneRoot->setAnimationManager(&m_animations);
13671367
if (m_layerSurface != nullptr && m_renderContext != nullptr) {
13681368
m_selectPopup = std::make_unique<SelectDropdownPopup>(m_platform->wayland(), *m_renderContext);
1369+
if (m_config != nullptr) {
1370+
m_selectPopup->setShadowConfig(m_config->config().shell.shadow);
1371+
}
13691372
m_selectPopup->setParent(m_layerSurface->layerSurface(), m_output);
13701373
m_sceneRoot->setPopupContext(m_selectPopup.get());
13711374
}

src/shell/settings/session_actions_editor_popup.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ namespace settings {
197197
if (m_selectPopup == nullptr) {
198198
m_selectPopup = std::make_unique<SelectDropdownPopup>(*wayland(), *renderContext());
199199
}
200+
if (config() != nullptr) {
201+
m_selectPopup->setShadowConfig(config()->config().shell.shadow);
202+
}
200203
m_selectPopup->setParent(xdgSurface(), m_parentOutput);
201204
contentParent->setPopupContext(m_selectPopup.get());
202205
}

src/shell/settings/settings_window_scene.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ void SettingsWindow::buildScene(std::uint32_t width, std::uint32_t height) {
796796
m_sceneRoot->setAnimationManager(&m_animations);
797797
if (m_surface != nullptr && m_renderContext != nullptr && m_wayland != nullptr) {
798798
m_selectPopup = std::make_unique<SelectDropdownPopup>(*m_wayland, *m_renderContext);
799+
m_selectPopup->setShadowConfig(cfg.shell.shadow);
799800
m_selectPopup->setParent(m_surface->xdgSurface(), m_output);
800801
m_sceneRoot->setPopupContext(m_selectPopup.get());
801802
}

src/ui/controls/select_dropdown_popup.cpp

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
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

3853
SelectDropdownPopup::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+
5580
void 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
182217
void 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

src/ui/controls/select_dropdown_popup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "config/config_types.h"
34
#include "render/scene/input_dispatcher.h"
45
#include "ui/controls/select_popup_context.h"
56

@@ -30,6 +31,7 @@ class SelectDropdownPopup : public SelectPopupContext {
3031

3132
void setParent(zwlr_layer_surface_v1* layerSurface, wl_output* output);
3233
void setParent(xdg_surface* xdgSurface, wl_output* output);
34+
void setShadowConfig(const ShellConfig::ShadowConfig& shadow);
3335

3436
void openSelectDropdown(const DropdownRequest& request, DropdownCallbacks callbacks) override;
3537
void closeSelectDropdown() override;
@@ -77,5 +79,6 @@ class SelectDropdownPopup : public SelectPopupContext {
7779
float m_viewportHeight = 0.0f;
7880
float m_totalHeight = 0.0f;
7981
float m_menuWidth = 0.0f;
82+
ShellConfig::ShadowConfig m_shadowConfig;
8083
bool m_sceneDirty = false;
8184
};

0 commit comments

Comments
 (0)