Resolves: tdf#136943 limit combobox popups to max available below/above height

If the popup won't fit either above/below then force the menu to scroll
if it won't fit

Change-Id: I03c051606ce29e2eba7046248e05c25fbdbded1a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187096
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Caolán McNamara
2025-06-27 14:53:49 +02:00
parent a67ab7ea6f
commit 794946c9a7
4 changed files with 48 additions and 19 deletions
+2 -1
View File
@@ -522,7 +522,8 @@ public:
void SetAutoWidth( bool b ) { mbAutoWidth = b; }
Size CalcFloatSize() const;
tools::Rectangle GetParentRect() const;
Size CalcFloatSize(const tools::Rectangle& rParentRect) const;
void StartFloat( bool bStartTracking );
virtual void setPosSizePixel( tools::Long nX, tools::Long nY,
+1 -1
View File
@@ -587,7 +587,7 @@ void ComboBox::Resize()
// adjust the size of the FloatingWindow even when invisible
// as KEY_PGUP/DOWN is being processed...
if (m_pFloatWin)
m_pFloatWin->SetSizePixel(m_pFloatWin->CalcFloatSize());
m_pFloatWin->SetSizePixel(m_pFloatWin->CalcFloatSize(m_pFloatWin->GetParentRect()));
}
bool ComboBox::IsDropDownBox() const { return m_pFloatWin != nullptr; }
+44 -16
View File
@@ -2910,7 +2910,7 @@ void ImplListBoxFloatingWindow::Resize()
FloatingWindow::Resize();
}
Size ImplListBoxFloatingWindow::CalcFloatSize() const
Size ImplListBoxFloatingWindow::CalcFloatSize(const tools::Rectangle& rParentRect) const
{
Size aFloatSz( maPrefSz );
@@ -2927,6 +2927,8 @@ Size ImplListBoxFloatingWindow::CalcFloatSize() const
if ( mnDDLineCount )
aFloatSz.setHeight( nMaxHeight );
AbsoluteScreenPixelRectangle aDesktopRect(GetDesktopRectPixel());
if( mbAutoWidth )
{
// AutoSize first only for width...
@@ -2941,13 +2943,32 @@ Size ImplListBoxFloatingWindow::CalcFloatSize() const
aFloatSz.AdjustWidth(nSBWidth );
}
tools::Long nDesktopWidth = GetDesktopRectPixel().getOpenWidth();
tools::Long nDesktopWidth = aDesktopRect.getOpenWidth();
if (aFloatSz.Width() > nDesktopWidth)
// Don't exceed the desktop width.
aFloatSz.setWidth( nDesktopWidth );
}
tools::Long nDesktopHeight = GetDesktopRectPixel().getOpenHeight();
tools::Long nDesktopHeight = aDesktopRect.getOpenHeight();
//tdf#136943. If the popup won't fit either above/below then force the menu
//to scroll if it won't fit
{
const vcl::Window* pRef = this;
if ( pRef->GetParent() )
pRef = pRef->GetParent();
tools::Rectangle normRect( rParentRect ); // rRect is already relative to top-level window
normRect.SetPos( pRef->ScreenToOutputPixel( normRect.TopLeft() ) );
AbsoluteScreenPixelRectangle devRect(pRef->OutputToAbsoluteScreenPixel(normRect.TopLeft()),
pRef->OutputToAbsoluteScreenPixel(normRect.BottomRight()));
tools::Long nHeightAbove = devRect.Top() - aDesktopRect.Top();
tools::Long nHeightBelow = aDesktopRect.Bottom() - devRect.Bottom();
nDesktopHeight = std::min(nDesktopHeight, std::max(nHeightAbove, nHeightBelow));
}
if (aFloatSz.Height() > nDesktopHeight)
aFloatSz.setHeight(nDesktopHeight);
@@ -2967,7 +2988,6 @@ Size ImplListBoxFloatingWindow::CalcFloatSize() const
if ( nInnerHeight % nEntryHeight )
{
nInnerHeight /= nEntryHeight;
nInnerHeight++;
nInnerHeight *= nEntryHeight;
aFloatSz.setHeight( nInnerHeight + nTop + nBottom );
}
@@ -2983,19 +3003,9 @@ Size ImplListBoxFloatingWindow::CalcFloatSize() const
return aFloatSz;
}
void ImplListBoxFloatingWindow::StartFloat( bool bStartTracking )
tools::Rectangle ImplListBoxFloatingWindow::GetParentRect() const
{
if( IsInPopupMode() )
return;
Size aFloatSz = CalcFloatSize();
SetSizePixel( aFloatSz );
mpImplLB->SetSizePixel( GetOutputSizePixel() );
sal_Int32 nPos = mpImplLB->GetEntryList().GetSelectedEntryPos( 0 );
mnPopupModeStartSaveSelection = nPos;
// Get Rectangle at which popup will appear
Size aSz = GetParent()->GetSizePixel();
Point aPos = GetParent()->GetPosPixel();
aPos = GetParent()->GetParent()->OutputToScreenPixel( aPos );
@@ -3021,6 +3031,24 @@ void ImplListBoxFloatingWindow::StartFloat( bool bStartTracking )
if( pGrandparent->GetOutDev()->ImplIsAntiparallel() )
pGrandparentOutDev->ReMirror( aRect );
return aRect;
}
void ImplListBoxFloatingWindow::StartFloat( bool bStartTracking )
{
if( IsInPopupMode() )
return;
tools::Rectangle aRect = GetParentRect();
Size aFloatSz = CalcFloatSize(aRect);
SetSizePixel( aFloatSz );
mpImplLB->SetSizePixel( GetOutputSizePixel() );
sal_Int32 nPos = mpImplLB->GetEntryList().GetSelectedEntryPos( 0 );
mnPopupModeStartSaveSelection = nPos;
mpImplLB->GetMainWindow()->ResetLastPosPixel();
// mouse-button right: close the List-Box-Float-win and don't stop the handling fdo#84795
StartPopupMode( aRect, LISTBOX_FLOATWINPOPUPFLAGS );
+1 -1
View File
@@ -636,7 +636,7 @@ void ListBox::Resize()
// Retain FloatingWindow size even when it's invisible, as we still process KEY_PGUP/DOWN ...
if ( mpFloatWin )
mpFloatWin->SetSizePixel( mpFloatWin->CalcFloatSize() );
mpFloatWin->SetSizePixel( mpFloatWin->CalcFloatSize(mpFloatWin->GetParentRect()) );
Control::Resize();
}