• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/menu/multi_menu_layout_algorithm.h"
17 
18 #include "core/components/common/layout/grid_system_manager.h"
19 #include "core/components_ng/pattern/menu/menu_theme.h"
20 #include "core/components_ng/pattern/menu/menu_pattern.h"
21 #include "core/components_ng/pattern/menu/menu_item/menu_item_layout_property.h"
22 #include "core/components_ng/pattern/select_overlay/select_overlay_node.h"
23 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
24 
25 namespace OHOS::Ace::NG {
26 namespace {
27 struct SelectOverlayRightClickMenuLayoutHelper {
AdjustLayoutConstraintsOHOS::Ace::NG::__anon8ebb139c0111::SelectOverlayRightClickMenuLayoutHelper28     static void AdjustLayoutConstraints(
29         LayoutConstraintF& constrainMinWidth, const RefPtr<LayoutWrapper>& child, LayoutWrapper* layoutWrapper)
30     {
31         auto host = layoutWrapper->GetHostNode();
32         CHECK_NULL_VOID(host);
33         auto scrollNode = host->GetParentFrameNode();
34         CHECK_NULL_VOID(scrollNode);
35         auto outterMenuNode = scrollNode->GetParentFrameNode();
36         CHECK_NULL_VOID(outterMenuNode);
37         auto outterMenuPattern = outterMenuNode->GetPattern<MenuPattern>();
38         CHECK_NULL_VOID(outterMenuPattern);
39         auto menuWrapperNode = outterMenuNode->GetParentFrameNode();
40         CHECK_NULL_VOID(menuWrapperNode);
41         auto childLayoutProperty = child->GetLayoutProperty();
42         CHECK_NULL_VOID(childLayoutProperty);
43         if (menuWrapperNode->GetInspectorIdValue("") != SelectOverlayRrightClickMenuWrapper ||
44             !outterMenuPattern->IsSelectOverlayRightClickMenu() ||
45             child->GetHostTag() != V2::RELATIVE_CONTAINER_ETS_TAG) {
46             return;
47         }
48         childLayoutProperty->UpdateUserDefinedIdealSize(
49             { CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(0.0, DimensionUnit::AUTO) });
50         constrainMinWidth.percentReference.SetWidth(constrainMinWidth.selfIdealSize.Width().value());
51         auto row = child->GetChildByIndex(0);
52         CHECK_NULL_VOID(row);
53         auto layoutProperty = row->GetLayoutProperty();
54         CHECK_NULL_VOID(layoutProperty);
55         layoutProperty->UpdateUserDefinedIdealSize(
56             { CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(1.0, DimensionUnit::AUTO) });
57         auto pasteButtonRow = child->GetChildByIndex(1);
58         CHECK_NULL_VOID(pasteButtonRow);
59         auto pasteButton = pasteButtonRow->GetChildByIndex(0);
60         CHECK_NULL_VOID(pasteButton);
61         auto pasteButtonLayoutProperty = pasteButton->GetLayoutProperty();
62         CHECK_NULL_VOID(pasteButtonLayoutProperty);
63         pasteButtonLayoutProperty->UpdateUserDefinedIdealSize(
64             { CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(1.0, DimensionUnit::PERCENT) });
65     }
66 
AdjustLayoutConstraintsAutoWidthOHOS::Ace::NG::__anon8ebb139c0111::SelectOverlayRightClickMenuLayoutHelper67     static void AdjustLayoutConstraintsAutoWidth(const RefPtr<LayoutWrapper>& child, LayoutWrapper* layoutWrapper)
68     {
69         auto host = layoutWrapper->GetHostNode();
70         CHECK_NULL_VOID(host);
71         auto scrollNode = host->GetParentFrameNode();
72         CHECK_NULL_VOID(scrollNode);
73         auto outterMenuNode = scrollNode->GetParentFrameNode();
74         CHECK_NULL_VOID(outterMenuNode);
75         auto outterMenuPattern = outterMenuNode->GetPattern<MenuPattern>();
76         CHECK_NULL_VOID(outterMenuPattern);
77         auto menuWrapperNode = outterMenuNode->GetParentFrameNode();
78         CHECK_NULL_VOID(menuWrapperNode);
79         auto childLayoutProperty = child->GetLayoutProperty();
80         CHECK_NULL_VOID(childLayoutProperty);
81         if (menuWrapperNode->GetInspectorIdValue("") != SelectOverlayRrightClickMenuWrapper ||
82             !outterMenuPattern->IsSelectOverlayRightClickMenu() ||
83             child->GetHostTag() != V2::RELATIVE_CONTAINER_ETS_TAG) {
84             return;
85         }
86         childLayoutProperty->UpdateUserDefinedIdealSize(
87             { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
88         auto row = child->GetChildByIndex(0);
89         CHECK_NULL_VOID(row);
90         auto layoutProperty = row->GetLayoutProperty();
91         CHECK_NULL_VOID(layoutProperty);
92         layoutProperty->UpdateUserDefinedIdealSize(
93             { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
94         auto pasteButtonRow = child->GetChildByIndex(1);
95         CHECK_NULL_VOID(pasteButtonRow);
96         auto pasteButton = pasteButtonRow->GetChildByIndex(0);
97         CHECK_NULL_VOID(pasteButton);
98         auto pasteButtonLayoutProperty = pasteButton->GetLayoutProperty();
99         CHECK_NULL_VOID(pasteButtonLayoutProperty);
100         pasteButtonLayoutProperty->UpdateUserDefinedIdealSize(
101             { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
102     }
103 };
104 } // namespace
105 
UpdateColumnWidth(const RefPtr<FrameNode> & frameNode,const RefPtr<GridColumnInfo> & columnInfo)106 bool UpdateColumnWidth(const RefPtr<FrameNode>& frameNode, const RefPtr<GridColumnInfo>& columnInfo)
107 {
108     CHECK_NULL_RETURN(frameNode && columnInfo, false);
109     auto pipeline = frameNode->GetContext();
110     CHECK_NULL_RETURN(pipeline, false);
111     if (Positive(pipeline->GetRootWidth())) {
112         return false;
113     }
114 
115     auto currentId = Container::CurrentId();
116     CHECK_NULL_RETURN(currentId >= MIN_SUBCONTAINER_ID, false);
117     auto subwindowManager = SubwindowManager::GetInstance();
118     CHECK_NULL_RETURN(subwindowManager, false);
119     auto subwindow = subwindowManager->GetSubwindowByType(pipeline->GetInstanceId(), SubwindowType::TYPE_MENU);
120     CHECK_NULL_RETURN(subwindow, false);
121     auto width = subwindow->GetRect().Width();
122     CHECK_NULL_RETURN(Positive(width), false);
123     auto parent = columnInfo->GetParent();
124     CHECK_NULL_RETURN(parent, false);
125     parent->BuildColumnWidth(width);
126     return true;
127 }
128 
Measure(LayoutWrapper * layoutWrapper)129 void MultiMenuLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
130 {
131     CHECK_NULL_VOID(layoutWrapper);
132     auto layoutProperty = layoutWrapper->GetLayoutProperty();
133     CHECK_NULL_VOID(layoutProperty);
134     auto layoutConstraint = layoutProperty->GetLayoutConstraint();
135     CHECK_NULL_VOID(layoutConstraint);
136     auto childConstraint = layoutProperty->CreateChildConstraint();
137     childConstraint.maxSize.SetWidth(layoutConstraint->maxSize.Width());
138     // constraint max size minus padding
139     const auto& padding = layoutProperty->CreatePaddingAndBorder();
140     auto node = layoutWrapper->GetHostNode();
141     CHECK_NULL_VOID(node);
142     auto pattern = node->GetPattern<MenuPattern>();
143     CHECK_NULL_VOID(pattern);
144     if (!pattern->IsEmbedded()) {
145         MinusPaddingToSize(padding, childConstraint.maxSize);
146     } else {
147         UpdateEmbeddedPercentReference(layoutWrapper, childConstraint, layoutConstraint);
148     }
149     if (layoutConstraint->selfIdealSize.Width().has_value()) {
150         // when Menu is set self ideal width, make children node adaptively fill up.
151         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
152             if (LessNotEqual(layoutConstraint->selfIdealSize.Width().value(), MIN_MENU_WIDTH.ConvertToPx())) {
153                 RefPtr<GridColumnInfo> columnInfo;
154                 columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::MENU);
155                 CHECK_NULL_VOID(columnInfo);
156                 auto columnParent = columnInfo->GetParent();
157                 CHECK_NULL_VOID(columnParent);
158                 columnParent->BuildColumnWidth();
159                 auto minWidth = static_cast<float>(columnInfo->GetWidth(MENU_MIN_GRID_COUNTS));
160                 layoutConstraint->selfIdealSize.SetWidth(minWidth);
161 
162                 UpdateMenuDefaultConstraintByDevice(pattern, childConstraint, padding.Width(), layoutConstraint, true);
163             }
164         }
165         auto idealWidth =
166             std::max(layoutConstraint->minSize.Width(),
167                 std::min(layoutConstraint->maxSize.Width(), layoutConstraint->selfIdealSize.Width().value())) -
168             padding.Width();
169         childConstraint.selfIdealSize.SetWidth(idealWidth);
170     } else {
171         // constraint min width base on grid column
172         auto columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::MENU);
173         CHECK_NULL_VOID(columnInfo);
174         auto columnParent = columnInfo->GetParent();
175         CHECK_NULL_VOID(columnParent);
176         if (!UpdateSelectOverlayMenuMinWidth(pattern, columnInfo) && !UpdateColumnWidth(node, columnInfo)) {
177             columnParent->BuildColumnWidth();
178         }
179         auto minWidth = static_cast<float>(columnInfo->GetWidth()) - padding.Width();
180         childConstraint.minSize.SetWidth(minWidth);
181 
182         UpdateMenuDefaultConstraintByDevice(pattern, childConstraint, padding.Width(), layoutConstraint, false);
183     }
184     // Calculate max width of menu items
185     UpdateConstraintBaseOnMenuItems(layoutWrapper, childConstraint);
186     UpdateSelfSize(layoutWrapper, childConstraint, layoutConstraint);
187 }
188 
UpdateMenuDefaultConstraintByDevice(const RefPtr<MenuPattern> & pattern,LayoutConstraintF & childConstraint,float paddingWidth,std::optional<LayoutConstraintF> & layoutConstraint,bool idealSizeHasVal)189 void MultiMenuLayoutAlgorithm::UpdateMenuDefaultConstraintByDevice(const RefPtr<MenuPattern>& pattern,
190     LayoutConstraintF& childConstraint, float paddingWidth, std::optional<LayoutConstraintF>& layoutConstraint,
191     bool idealSizeHasVal)
192 {
193     CHECK_NULL_VOID(pattern);
194 
195     // only 2in1 device has restrictions on the menu width in API13
196     CHECK_NULL_VOID(Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_THIRTEEN));
197     auto pipeline = PipelineBase::GetCurrentContext();
198     CHECK_NULL_VOID(pipeline);
199     auto theme = pipeline->GetTheme<SelectTheme>();
200     CHECK_NULL_VOID(theme);
201     auto expandDisplay = theme->GetExpandDisplay();
202     CHECK_NULL_VOID(expandDisplay);
203 
204     auto mainMenuPattern = pattern->GetMainMenuPattern();
205     CHECK_NULL_VOID(mainMenuPattern);
206     if (!mainMenuPattern->IsContextMenu() && !mainMenuPattern->IsMenu() &&
207         !mainMenuPattern->IsSelectOverlayRightClickMenu()) {
208         return;
209     }
210 
211     if (idealSizeHasVal) {
212         layoutConstraint->selfIdealSize.SetWidth(theme->GetMenuDefaultWidth().ConvertToPx());
213     } else {
214         childConstraint.minSize.SetWidth(theme->GetMenuDefaultWidth().ConvertToPx() - paddingWidth);
215     }
216 }
217 
Layout(LayoutWrapper * layoutWrapper)218 void MultiMenuLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
219 {
220     CHECK_NULL_VOID(layoutWrapper);
221     BoxLayoutAlgorithm::PerformLayout(layoutWrapper);
222 
223     auto pipeline = PipelineBase::GetCurrentContext();
224     CHECK_NULL_VOID(pipeline);
225     auto theme = pipeline->GetTheme<SelectTheme>();
226     CHECK_NULL_VOID(theme);
227     auto layoutProperty = layoutWrapper->GetLayoutProperty();
228     CHECK_NULL_VOID(layoutProperty);
229     auto node = layoutWrapper->GetHostNode();
230     CHECK_NULL_VOID(node);
231     auto pattern = node->GetPattern<MenuPattern>();
232     CHECK_NULL_VOID(pattern);
233     OffsetF translate(0.0f, 0.0f);
234     const auto& padding = layoutProperty->CreatePaddingAndBorder();
235     auto outPadding = static_cast<float>(theme->GetMenuPadding().ConvertToPx());
236     if (!pattern->IsEmbedded()) {
237         translate.AddX(padding.left.value_or(outPadding));
238         translate.AddY(padding.top.value_or(outPadding));
239     }
240     // translate each option by the height of previous options
241     for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
242         child->GetGeometryNode()->SetMarginFrameOffset(translate);
243         child->Layout();
244         translate.AddY(child->GetGeometryNode()->GetMarginFrameSize().Height());
245     }
246 }
247 
UpdateEmbeddedPercentReference(LayoutWrapper * layoutWrapper,LayoutConstraintF & childConstraint,std::optional<LayoutConstraintF> & layoutConstraint)248 void MultiMenuLayoutAlgorithm::UpdateEmbeddedPercentReference(LayoutWrapper* layoutWrapper,
249     LayoutConstraintF& childConstraint, std::optional<LayoutConstraintF>& layoutConstraint)
250 {
251     // Set percent reference for embedded menu the same as for parent menu item
252     auto node = layoutWrapper->GetHostNode();
253     CHECK_NULL_VOID(node);
254     auto parentNode = AceType::DynamicCast<FrameNode>(node->GetParent());
255     CHECK_NULL_VOID(parentNode);
256     auto parentProperty = parentNode->GetLayoutProperty<MenuItemLayoutProperty>();
257     CHECK_NULL_VOID(parentProperty);
258     auto parentConstraint = parentProperty->GetLayoutConstraint();
259     CHECK_NULL_VOID(parentConstraint);
260     auto parentPercentReference = parentConstraint->percentReference.Height();
261     layoutConstraint->percentReference.SetHeight(parentPercentReference);
262 
263     auto props = layoutWrapper->GetLayoutProperty();
264     CHECK_NULL_VOID(props);
265     const auto& calcConstraint = props->GetCalcLayoutConstraint();
266     if (calcConstraint && calcConstraint->selfIdealSize.has_value() &&
267         calcConstraint->selfIdealSize.value().Height().has_value()) {
268         ScaleProperty scaleProperty;
269         if (layoutWrapper->GetGeometryNode() && layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()) {
270             scaleProperty = layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()->scaleProperty;
271         } else {
272             scaleProperty = layoutConstraint->scaleProperty;
273         }
274         userHeight_ = ConvertToPx(calcConstraint->selfIdealSize.value().Height()->GetDimension(),
275             scaleProperty, layoutConstraint->percentReference.Height()).value_or(0.0f);
276     }
277 
278     // Update embedded menu items percent reference dependent of the submenu constraint
279     if (GreatNotEqual(userHeight_, 0.0f)) {
280         childConstraint.percentReference.SetHeight(userHeight_);
281     } else {
282         childConstraint.percentReference.SetHeight(parentPercentReference);
283     }
284 }
285 
UpdateSelfSize(LayoutWrapper * layoutWrapper,LayoutConstraintF & childConstraint,std::optional<LayoutConstraintF> & layoutConstraint)286 void MultiMenuLayoutAlgorithm::UpdateSelfSize(LayoutWrapper* layoutWrapper,
287     LayoutConstraintF& childConstraint, std::optional<LayoutConstraintF>& layoutConstraint)
288 {
289     auto node = layoutWrapper->GetHostNode();
290     CHECK_NULL_VOID(node);
291     auto pattern = node->GetPattern<MenuPattern>();
292     CHECK_NULL_VOID(pattern);
293 
294     float contentHeight = 0.0f;
295     float contentWidth = childConstraint.selfIdealSize.Width().value();
296     for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
297         if (!child) {
298             TAG_LOGW(AceLogTag::ACE_MENU, "child is null in MultiMenu");
299             continue;
300         }
301         auto resetLayoutConstraint = ResetLayoutConstraintMinWidth(child, childConstraint);
302         SelectOverlayRightClickMenuLayoutHelper::AdjustLayoutConstraints(
303             resetLayoutConstraint, child, layoutWrapper);
304         if (pattern->IsEmbedded() && (resetLayoutConstraint.minSize.Width() > resetLayoutConstraint.maxSize.Width())) {
305             resetLayoutConstraint.minSize.SetWidth(resetLayoutConstraint.maxSize.Width());
306         }
307         child->Measure(resetLayoutConstraint);
308         auto childGeometryNode = child->GetGeometryNode();
309         CHECK_NULL_VOID(childGeometryNode);
310         auto childHeight = std::max(childGeometryNode->GetMarginFrameSize().Height(),
311             childGeometryNode->GetContentSize().Height());
312         contentHeight += childHeight;
313     }
314     layoutWrapper->GetGeometryNode()->SetContentSize(SizeF(contentWidth, contentHeight));
315     BoxLayoutAlgorithm::PerformMeasureSelf(layoutWrapper);
316 
317     // Stack or Embedded submenu must follow parent width
318     if (pattern->IsStackSubmenu() || pattern->IsEmbedded()) {
319         auto idealSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
320         auto width = layoutConstraint->maxSize.Width();
321         idealSize.SetWidth(width);
322         if (pattern->IsEmbedded()) {
323             auto idealHeight = GreatNotEqual(userHeight_, 0.0f) ? userHeight_ : contentHeight;
324             idealSize.SetHeight(idealHeight);
325         }
326         layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
327     } else if (layoutConstraint->selfIdealSize.Width().has_value()) {
328         auto idealWidth = std::max(layoutConstraint->minSize.Width(),
329             std::min(layoutConstraint->maxSize.Width(), layoutConstraint->selfIdealSize.Width().value()));
330         auto idealSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
331         idealSize.SetWidth(idealWidth);
332         layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
333     }
334 }
335 
UpdateConstraintBaseOnMenuItems(LayoutWrapper * layoutWrapper,LayoutConstraintF & constraint)336 void MultiMenuLayoutAlgorithm::UpdateConstraintBaseOnMenuItems(
337     LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint)
338 {
339     // multiMenu children are menuItem or menuItemGroup, constrain width is same as the menu
340     auto maxChildrenWidth = GetChildrenMaxWidth(layoutWrapper, constraint);
341     constraint.selfIdealSize.SetWidth(maxChildrenWidth);
342 }
343 
GetChildrenMaxWidth(LayoutWrapper * layoutWrapper,const LayoutConstraintF & layoutConstraint)344 float MultiMenuLayoutAlgorithm::GetChildrenMaxWidth(
345     LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint)
346 {
347     float maxWidth = 0.0f;
348     auto node = layoutWrapper->GetHostNode();
349     CHECK_NULL_RETURN(node, maxWidth);
350     auto pattern = node->GetPattern<MenuPattern>();
351     CHECK_NULL_RETURN(pattern, maxWidth);
352     for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
353         auto childConstraint = ResetLayoutConstraintMinWidth(child, layoutConstraint);
354         if (pattern->IsEmbedded() && (childConstraint.minSize.Width() > childConstraint.maxSize.Width())) {
355             childConstraint.minSize.SetWidth(childConstraint.maxSize.Width());
356         }
357         SelectOverlayRightClickMenuLayoutHelper::AdjustLayoutConstraintsAutoWidth(child, layoutWrapper);
358         child->Measure(childConstraint);
359         auto childSize = child->GetGeometryNode()->GetMarginFrameSize();
360         maxWidth = std::max(maxWidth, childSize.Width());
361     }
362     return maxWidth;
363 }
364 
ResetLayoutConstraintMinWidth(const RefPtr<LayoutWrapper> & child,const LayoutConstraintF & layoutConstraint)365 LayoutConstraintF MultiMenuLayoutAlgorithm::ResetLayoutConstraintMinWidth(
366     const RefPtr<LayoutWrapper>& child, const LayoutConstraintF& layoutConstraint)
367 {
368     auto childLayoutProps = child->GetLayoutProperty();
369     CHECK_NULL_RETURN(childLayoutProps, layoutConstraint);
370     auto childConstraint = layoutConstraint;
371     const auto& calcConstraint = childLayoutProps->GetCalcLayoutConstraint();
372     if (calcConstraint && calcConstraint->selfIdealSize.has_value() &&
373         calcConstraint->selfIdealSize.value().Width().has_value()) {
374         childConstraint.minSize.Reset();
375     }
376     return childConstraint;
377 }
378 
UpdateSelectOverlayMenuMinWidth(const RefPtr<MenuPattern> & pattern,const RefPtr<GridColumnInfo> & columnInfo)379 bool MultiMenuLayoutAlgorithm::UpdateSelectOverlayMenuMinWidth(
380     const RefPtr<MenuPattern>& pattern, const RefPtr<GridColumnInfo>& columnInfo)
381 {
382     CHECK_NULL_RETURN(pattern, false);
383     auto mainMenuPattern = pattern->GetMainMenuPattern();
384     CHECK_NULL_RETURN(mainMenuPattern, false);
385     CHECK_NULL_RETURN(mainMenuPattern->IsSelectOverlayRightClickMenu(), false);
386     auto menuWrapper = pattern->GetMenuWrapper();
387     CHECK_NULL_RETURN(menuWrapper, false);
388     auto menuWrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
389     CHECK_NULL_RETURN(menuWrapperPattern, false);
390     CHECK_NULL_RETURN(menuWrapperPattern->GetIsSelectOverlaySubWindowWrapper(), false);
391     auto mainWindowContainerId = menuWrapperPattern->GetContainerId();
392     auto container = Container::GetContainer(mainWindowContainerId);
393     CHECK_NULL_RETURN(container, false);
394     auto pipelineContext = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
395     CHECK_NULL_RETURN(pipelineContext, false);
396     auto displayWindowRect = pipelineContext->GetDisplayWindowRectInfo();
397     auto mainWindowWidth = displayWindowRect.Width();
398     if (Positive(mainWindowWidth)) {
399         auto parent = columnInfo->GetParent();
400         CHECK_NULL_RETURN(parent, false);
401         parent->BuildColumnWidth(mainWindowWidth);
402         TAG_LOGD(
403             AceLogTag::ACE_MENU, "Update select overlay right click menu min width with main window width constraint.");
404         return true;
405     }
406     return false;
407 }
408 } // namespace OHOS::Ace::NG
409