vcl/osx/salnativewidgets.cxx    |   10 ++++++--
 vcl/source/control/imivctl1.cxx |   47 ++++++++++++++++++++++++++++++++++++----
 vcl/source/control/ivctrl.cxx   |    7 +++++
 3 files changed, 57 insertions(+), 7 deletions(-)

New commits:
commit b9a390c5add74147bf8ed1b9b3658e7a36c20a66
Author:     Patrick Luby <guibmac...@gmail.com>
AuthorDate: Tue Jun 10 15:56:52 2025 -0400
Commit:     Patrick Luby <guibomac...@gmail.com>
CommitDate: Wed Jun 11 16:56:27 2025 +0200

    Related: tdf#163008 draw the selected tab using a push button on macOS
    
    On macOS, more closely match the vertical tab style of the
    sidebar in the System Settings application. As of macOS Sequoia,
    the sidebar only shows the default style push button for the
    selected tab. The unselected tabs are only text and images so
    no native control needs to be drawn for unselected tabs.
    
    Also, remove the vertical tab's 3D border.
    
    Change-Id: I0df77b7613e37897213ce656f894f324ebf2ba14
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186340
    Reviewed-by: Heiko Tietze <heiko.tie...@documentfoundation.org>
    Reviewed-by: Patrick Luby <guibomac...@gmail.com>
    Tested-by: Jenkins

diff --git a/vcl/osx/salnativewidgets.cxx b/vcl/osx/salnativewidgets.cxx
index dd89133353bb..44c8877c7695 100644
--- a/vcl/osx/salnativewidgets.cxx
+++ b/vcl/osx/salnativewidgets.cxx
@@ -561,7 +561,7 @@ bool 
AquaGraphicsBackendBase::performDrawNativeControl(ControlType nType,
         case ControlType::Pushbutton:
             {
                 NSControlSize eSizeKind = NSControlSizeRegular;
-                NSBezelStyle eBezelStyle = NSBezelStyleRounded;
+                NSBezelStyle eBezelStyle = NSBezelStylePush;
 
                 PushButtonValue const *pPBVal = aValue.getType() == 
ControlType::Pushbutton ?
                                                 static_cast<PushButtonValue 
const *>(&aValue) : nullptr;
@@ -576,6 +576,12 @@ bool 
AquaGraphicsBackendBase::performDrawNativeControl(ControlType nType,
                 {
                     GetThemeMetric(kThemeMetricPushButtonHeight, 
&nPaintHeight);
                 }
+                else if (pPBVal && !pPBVal->mbSingleLine)
+                {
+                    // If not a single line button, allow the button to expand
+                    // its height
+                    eBezelStyle = NSBezelStyleFlexiblePush;
+                }
                 else
                 {
                     // A simple square bezel style that can scale to any size
@@ -602,7 +608,7 @@ bool 
AquaGraphicsBackendBase::performDrawNativeControl(ControlType nType,
                 else
                     [pBtn setKeyEquivalent: @""];
 
-                if (eBezelStyle == NSBezelStyleRounded)
+                if (eBezelStyle == NSBezelStylePush || eBezelStyle == 
NSBezelStyleFlexiblePush)
                 {
                     int nMargin = RoundedMargin[eSizeKind];
                     rc.origin.x -= nMargin;
diff --git a/vcl/source/control/imivctl1.cxx b/vcl/source/control/imivctl1.cxx
index a085d10c7729..e845a69504df 100644
--- a/vcl/source/control/imivctl1.cxx
+++ b/vcl/source/control/imivctl1.cxx
@@ -972,7 +972,12 @@ void 
SvxIconChoiceCtrl_Impl::PaintEntry(SvxIconChoiceCtrlEntry* pEntry, const Po
     const StyleSettings& rSettings = 
rRenderContext.GetSettings().GetStyleSettings();
     vcl::Font aNewFont(rRenderContext.GetFont());
     if (bSelected)
+#ifdef MACOSX
+        // On macOS, selected tabs are drawn as default push buttons
+        
aNewFont.SetColor(rSettings.GetDefaultActionButtonPressedRolloverTextColor());
+#else
         aNewFont.SetColor(rSettings.GetTabHighlightTextColor());
+#endif
     else if (bMouseHovered)
         aNewFont.SetColor(rSettings.GetTabRolloverTextColor());
     else
@@ -999,14 +1004,48 @@ void 
SvxIconChoiceCtrl_Impl::PaintEntry(SvxIconChoiceCtrlEntry* pEntry, const Po
     tools::Rectangle aFocusRect(CalcFocusRect(pEntry));
 
     bool bNativeOK
-        = rRenderContext.IsNativeControlSupported(ControlType::TabItem, 
ControlPart::Entire);
 #ifdef MACOSX
-    // tabs don't size to the focusrect and are drawn with an obtrusive blue 
rectangle
-    bNativeOK = false;
+        = rRenderContext.IsNativeControlSupported(ControlType::Pushbutton, 
ControlPart::Entire);
+#else
+        = rRenderContext.IsNativeControlSupported(ControlType::TabItem, 
ControlPart::Entire);
 #endif
     if (bNativeOK)
     {
         ControlState nState = ControlState::ENABLED;
+        ControlPart nPart(ControlPart::Entire);
+
+#ifdef MACOSX
+        if (bSelected)
+        {
+            // Related: tdf#163008 draw the selected tab using a push button
+            // On macOS, more closely match the vertical tab style of the
+            // sidebar in the System Settings application. As of macOS Sequoia,
+            // the sidebar only shows the default style push button for the
+            // selected tab. The unselected tabs are only text and images so
+            // no native control needs to be drawn for unselected tabs.
+            nState |= ControlState::DEFAULT;
+
+            // Allow the native push button to expand its height to match
+            // the focus rectangle's height.
+            PushButtonValue aControlValue;
+            aControlValue.mbSingleLine = false;
+            aControlValue.m_bFlatButton = true;
+
+            // Eliminate artifacts when this entry becomes unselected by
+            // making the push button slightly narrower than the focus
+            // rectangle so that there is no antialiased pixels drawn
+            // outside the focus rectangle.
+            tools::Rectangle aButtonRect(aFocusRect);
+            if (aButtonRect.GetWidth() > 2)
+            {
+                aButtonRect.SetLeft(aButtonRect.Left() + 1);
+                aButtonRect.SetRight(aButtonRect.Right() - 1);
+            }
+
+            bNativeOK = 
rRenderContext.DrawNativeControl(ControlType::Pushbutton, nPart,
+                                                         aButtonRect, nState, 
aControlValue, OUString());
+        }
+#else
         if (bSelected)
             nState |= ControlState::SELECTED;
         if (pEntry->IsFocused())
@@ -1015,13 +1054,13 @@ void 
SvxIconChoiceCtrl_Impl::PaintEntry(SvxIconChoiceCtrlEntry* pEntry, const Po
             nState |= ControlState::ROLLOVER;
 
         TabitemValue tiValue(aFocusRect, TabBarPosition::Left);
-        ControlPart nPart(ControlPart::Entire);
 #ifdef _WIN32
         // ControlPart::MenuItem prevents drawing line around tabs under win
         nPart = ControlPart::MenuItem;
 #endif
         bNativeOK = rRenderContext.DrawNativeControl(ControlType::TabItem, 
nPart,
                                                      aFocusRect, nState, 
tiValue, OUString());
+#endif
     }
 
     if (!bNativeOK)
diff --git a/vcl/source/control/ivctrl.cxx b/vcl/source/control/ivctrl.cxx
index 9b24c5685c0c..9d43ead8a293 100644
--- a/vcl/source/control/ivctrl.cxx
+++ b/vcl/source/control/ivctrl.cxx
@@ -354,7 +354,12 @@ struct VerticalTabPageData
 
 VerticalTabControl::VerticalTabControl(vcl::Window* pParent, bool bWithIcons)
     : VclHBox(pParent)
-    , m_xChooser(VclPtr<SvtIconChoiceCtrl>::Create(this, WB_3DLOOK | 
(bWithIcons ?  WB_ICON : WB_SMALLICON) | WB_BORDER |
+    , m_xChooser(VclPtr<SvtIconChoiceCtrl>::Create(this, WB_3DLOOK | 
(bWithIcons ?  WB_ICON : WB_SMALLICON) |
+#ifdef MACOSX
+                                                         WB_NOBORDER |
+#else
+                                                         WB_BORDER |
+#endif
                                                          WB_NOCOLUMNHEADER |
                                                          WB_NODRAGSELECTION | 
WB_TABSTOP | WB_CLIPCHILDREN |
                                                          WB_NOHSCROLL))

Reply via email to