DesktopSegmentedButton and focus ring

I have a dialog with 2 segmented buttons, 3 checkboxes and some push buttons.
When I pressed a segment I got a focus ring around the selected segment (which I hate). After some experimenting I discovered that whichever segmented button I press first exhibits this behaviour, the other doesn’t. However the button that has the focus ring is stuck with it.
After some more experimenting, if I click one of the checkboxes first then no focus ring anywhere.

Anyway of stopping this?

There are some declares in earlier topics that got rid of the rings but they no longer work.They won’t compile, one of the operands is now an integer whereas the examples I have use pointers.

They don’t work because Xojo decided to change the type of the “handle” property. You need to cast the ‘ptr’ to a ‘integer’. This change breaks decades of existing code.

The following code should work if placed in the Open event (or whatever it was renamed too). I have not tested it.

declare sub NSView_setFocusRingType lib "AppKit" selector "setFocusRingType:" ( NSViewInstance as integer, focusRingType as UInteger ) // --- Requires Mac OS X 10.3 or newer.
const NSFocusRingTypeNone = 1 // --- We include this here, so we know the name of the value we're passing to the declare.
NSView_setFocusRingType( integer( me.handle ), NSFocusRingTypeNone )

That seems to have cured my problem. Thanks for that.
I still think there might be a bug in there, the focus ring should be there, or it shouldn’t and it should affect all segmented buttons, not just one.

I’ll try and create it in a mini program and report it.

Thanks again.

Thank you Sam but it doesn’t work for me (I’m running Mojave).

I have the same problem with the SegmentedButton focus ring and I did some test.
Run the project FocusRingBug.xojo_binary_project.

  • Click the S (segemntedbutton) and validate the MessageBox. It will have the focus ring.
  • click in the SearchField to have the cursor in it → the SearchField has the focus ring, click the S button → It does not have the focus ring.
  • click it again one or two times, it will have the focus ring back again. As if you click in the background of window.
    Check “Focus to canv” is a workarround, but if the searchfield has the focus it will lost it.

Another strange thing, hit the TabKey to change the control which has the focus, the checkbox “focus to canv” will have have a focus ring. In the begging of my test it was “Btn 2” that’s why I added Btn3 and Btn4 but now it is the checkbox. I don’t know why???

On more strange thing, but I don’t know how to reproduce, sometimes when I hit the TabKey, the SearchField got the focus but without have the focus ring.

I’ve created a standalone app that recreates the problem and am about to raise a bug report.
My first attempt created a document window and it showed no problem. The affected window in my app is a modal dialog, so I created a second window with a button on it, press that and it called a modal dialog. That has the problem.

Created a bug report, issue number 69024.

Bug, not but.

You should be alble to edit your post during some time to correct “but” → “bug”.

I think I found a workarround, I will put this code at the end of the event “Pressed” of my DesktopSegmentedBtton :

Dim CeCtrl as DesktopControl '  CanvFocus  is a Canvas
Dim CeRectCtrl as DesktopUIControl

CeCtrl = Self.Focus
If CeCtrl = Nil Then
  CeRectCtrl = CanvFocus ' Give focus to what you want
ElseIf CeCtrl IsA DesktopSegmentedButton Then ' This is the bug as should not be
  CeRectCtrl = CanvFocus ' Give focus to what you want
ElseIf CeCtrl isa DesktopUIControl Then
  CeRectCtrl = DesktopUIControl(CeCtrl)
End If
' MessageBox "CeRectCtrl.Name : " + CeRectCtrl.Name + EndOfLine + "CeRectCtrl.Seg : " + Cstr(CeRectCtrl IsA DesktopSegmentedButton)
CeRectCtrl.SetFocus

I will look at your bug report end test again my workarround later, I stop now, I will pay bocce. :slight_smile:

Be careful with that. Keyboard oriented users (think accessibility) may not be able to use your interface if you muck with what control has focus when the control gets clicked.

On a segmented control, the button with the focus ring is the button that gets pressed when the SPACE bar is pressed. Pressing the TAB or SHIFT-TAB keys should advance or reverse the selected button respectively.

On macOS, you can turn on keyboard accessibility in the Keyboard System Preferences.

1 Like

I added comment on your bug report John.
This workarround is better (I put it in a Module to call from any SegmentedButton from anywere) :


Dim CeCtrl as DesktopControl
' Dim CeRectCtrl as DesktopUIControl

CeCtrl = CetFenetr.Focus
If CeCtrl = Nil Then
  ClearFocus
ElseIf CeCtrl IsA DesktopSegmentedButton Then ' Ne devrait pas arriver, Bug #69024
  ClearFocus
ElseIf CeCtrl isa DesktopUIControl Then
  ' CeRectCtrl = DesktopUIControl(CeCtrl)
  ' MessageBox "CeRectCtrl.Name : " + CeRectCtrl.Name + EndOfLine + "CeRectCtrl.Seg : " + Cstr(CeRectCtrl IsA DesktopSegmentedButton)
  DesktopUIControl(CeCtrl).SetFocus
End If

And at the end of the Pressed event of my segmentedcontrol :

WkarSegButFocusBug(Self)

Edit : I just see that ClearFocus is Deprecated (when I verify my project). Then my first workarround may be better.

Ok … thanks for that. Will have a look at it shortly.

John

I had to change my workarround:


Dim CeCtrl as DesktopControl
' Dim CeRectCtrl as DesktopUIControl

CeCtrl = CetFenetr.Focus
If CeCtrl = Nil Then
  CetFenetr.SetFocus ' ClearFocus
ElseIf CeCtrl IsA DesktopSegmentedButton Then ' Ne devrait pas arriver, Bug #69024
  CetFenetr.SetFocus ' ClearFocus
ElseIf CeCtrl isa DesktopUIControl Then
  ' CeRectCtrl = DesktopUIControl(CeCtrl)
  ' MessageBox "CeRectCtrl.Name : " + CeRectCtrl.Name + EndOfLine + "CeRectCtrl.Seg : " + Cstr(CeRectCtrl IsA DesktopSegmentedButton)
  ' MessageBox "CeCtrl.Name : " + CeCtrl.Name + EndOfLine + "CeCtrl.Seg : " + Cstr(CeCtrl IsA DesktopSegmentedButton)
  DesktopUIControl(CeCtrl).SetFocus
End If